Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

npm-profile

Package Overview
Dependencies
Maintainers
1
Versions
38
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

npm-profile - npm Package Compare versions

Comparing version 1.0.2 to 2.0.0

254

index.js

@@ -14,5 +14,5 @@ 'use strict'

function adduser (username, email, password, registry, opts) {
validate('SSSS|SSSSO', arguments)
if (!opts) opts = {}
function adduser (username, email, password, conf) {
validate('SSSO', arguments)
if (!conf.opts) conf.opts = {}
const userobj = {

@@ -33,44 +33,9 @@ _id: 'org.couchdb.user:' + username,

const target = url.resolve(registry, '-/user/org.couchdb.user:' + encodeURIComponent(username))
const target = url.resolve(conf.registry, '-/user/org.couchdb.user:' + encodeURIComponent(username))
return fetch.defaults(opts)(target, {
method: 'PUT',
body: JSON.stringify(userobj),
headers: { 'Content-Type': 'application/json' }
}).then(res => {
if (res.status < 200 || res.status >= 300) {
const err = new Error(res.statusText)
err.code = res.status
err.headers = res.headers.raw()
if (res.status === 409) err.message = `A user with the username "${username}" already exists.`
return res.json().then(body => {
if (body.error) err.message = body.error
throw err
})
}
return res.json()
})
return fetchJSON({target: target, method: 'PUT', body: userobj, opts: conf.opts})
}
login.AuthOTP = function (auth) {
Error.call(this)
this.message = 'OTP required for authentication'
Error.captureStackTrace(this, login.AuthOTP)
this.auth = auth
this.code = 'otp'
}
login.AuthOTP.prototype = Error.prototype
login.AuthIPAddress = function (auth) {
Error.call(this)
this.message = 'Login is not allowed from your IP address'
Error.captureStackTrace(this, login.AuthOTP)
this.auth = auth
this.code = 'ip'
}
login.AuthIPAddress.prototype = Error.prototype
function login (username, password, registry, auth, opts) {
validate('SSSO|SSSOO', arguments)
if (!opts) opts = {}
function login (username, password, conf) {
validate('SSO', arguments)
const userobj = {

@@ -84,4 +49,2 @@ _id: 'org.couchdb.user:' + username,

}
const headers = authHeaders(auth)
headers['Content-Type'] = 'application/json'
const logObj = {}

@@ -93,89 +56,32 @@ Object.keys(userobj).forEach(k => {

const target = url.resolve(registry, '-/user/org.couchdb.user:' + encodeURIComponent(username))
const target = url.resolve(conf.registry, '-/user/org.couchdb.user:' + encodeURIComponent(username))
return fetch.defaults(opts)(target, {
method: 'PUT',
headers: headers,
body: JSON.stringify(userobj)
}).then(res => {
if (res.status === 401 && res.headers.get('www-authenticate')) {
const auth = res.headers.get('www-authenticate').split(/,\s*/).map(s => s.toLowerCase())
if (auth.indexOf('ipaddress') !== -1) {
throw new login.AuthIPAddress(res.headers.raw())
} else if (auth.indexOf('otp') !== -1) {
throw new login.AuthOTP(res.headers.raw())
} else {
throw new Error('Unable to authenticate, need: ' + res.headers.get('www-authenticate'))
}
} else if (res.status < 200 || res.status >= 300) {
const err = new Error(res.statusText)
err.code = res.status
err.headers = res.headers.raw()
if (res.status === 400) err.message = `There is no user with the username "${username}".`
throw err
}
return res.json()
return fetchJSON(Object.assign({method: 'PUT', target: target, body: userobj}, conf)).catch(err => {
if (err.code === 'E400') err.message = `There is no user with the username "${username}".`
throw err
})
}
function get (registry, auth, opts) {
validate('SO|SOO', arguments)
if (!opts) opts = {}
const target = url.resolve(registry, '-/npm/v1/user')
const headers = authHeaders(auth)
return fetch.defaults(opts)(target, {headers: headers}).then(res => {
if (res.status < 200 || res.status >= 300) {
const err = new Error(res.statusText)
err.code = res.status
err.headers = res.headers.raw()
throw err
}
return res.json()
})
function get (conf) {
validate('O', arguments)
const target = url.resolve(conf.registry, '-/npm/v1/user')
return fetchJSON(Object.assign({target: target}, conf))
}
function set (profile, registry, auth, opts) {
validate('OSO|OSOO', arguments)
if (!opts) opts = {}
const target = url.resolve(registry, '-/npm/v1/user')
const headers = authHeaders(auth)
headers['Content-Type'] = 'application/json'
return fetch.defaults(opts)(target, {
method: 'POST',
body: JSON.stringify(profile),
headers: headers
}).then(res => {
if (res.status < 200 || res.status >= 300) {
const err = new Error(res.statusText)
err.code = res.status
err.headers = res.headers.raw()
throw err
}
return res.json()
})
function set (profile, conf) {
validate('OO', arguments)
const target = url.resolve(conf.registry, '-/npm/v1/user')
return fetchJSON(Object.assign({target: target, method: 'POST', body: profile}, conf))
}
function listTokens (registry, auth, opts) {
validate('SO|SOO', arguments)
if (!opts) opts = {}
const headers = authHeaders(auth)
function listTokens (conf) {
validate('O', arguments)
return untilLastPage({perPage: 1000, page: 0})
return untilLastPage(`-/npm/v1/tokens`)
function untilLastPage (opts, objects) {
return fetch.defaults(opts)(url.resolve(registry, `-/npm/v1/tokens?perPage=${opts.perPage}&page=${opts.page}`), {
method: 'GET',
headers: headers
}).then(res => {
if (res.status < 200 || res.status >= 300) {
const err = new Error(res.statusText)
err.code = res.status
err.headers = res.headers.raw()
throw err
}
return res.json()
}).then(result => {
function untilLastPage (href, objects) {
return fetchJSON(Object.assign({target: url.resolve(conf.registry, href)}, conf)).then(result => {
objects = objects ? objects.concat(result.objects) : result.objects
if (result.urls.next) {
return untilLastPage({perPage: opts.perPage, page: opts.page + 1}, objects)
return untilLastPage(result.urls.next, objects)
} else {

@@ -188,29 +94,11 @@ return objects

function removeToken (tokenKey, registry, auth, opts) {
validate('SSO|SSOO', arguments)
if (!opts) opts = {}
const target = url.resolve(registry, `-/npm/v1/tokens/token/${tokenKey}`)
const headers = authHeaders(auth)
return fetch.defaults(opts)(target, {
method: 'DELETE',
headers: headers
}).then(res => {
if (res.status < 200 || res.status >= 300) {
const err = new Error(res.statusText)
err.code = res.status
err.headers = res.headers.raw()
throw err
}
return res.buffer()
}).then(body => {
return body.toString('utf8')
})
function removeToken (tokenKey, conf) {
validate('SO', arguments)
const target = url.resolve(conf.registry, `-/npm/v1/tokens/token/${tokenKey}`)
return fetchJSON(Object.assign({target: target, method: 'DELETE'}, conf))
}
function createToken (password, readonly, cidrs, registry, auth, opts) {
validate('SBASO|SBASOO', arguments)
if (!opts) opts = {}
const target = url.resolve(registry, '-/npm/v1/tokens')
const headers = authHeaders(auth)
headers['Content-Type'] = 'application/json'
function createToken (password, readonly, cidrs, conf) {
validate('SBAO', arguments)
const target = url.resolve(conf.registry, '-/npm/v1/tokens')
const props = {

@@ -221,17 +109,32 @@ password: password,

}
return fetch.defaults(opts)(target, {
method: 'POST',
body: JSON.stringify(props),
headers: headers
}).then(res => {
if (res.status < 200 || res.status >= 300) {
const err = new Error(res.statusText)
err.code = res.status
err.headers = res.headers.raw()
throw err
}
return res.json()
})
return fetchJSON(Object.assign({target: target, method: 'POST', body: props}, conf))
}
function AuthOTP (res) {
Error.call(this)
this.message = 'OTP required for authentication'
Error.captureStackTrace(this, AuthOTP)
this.headers = res.headers.raw()
this.code = 'EOTP'
}
AuthOTP.prototype = Error.prototype
function AuthIPAddress (res) {
Error.call(this)
this.message = 'Login is not allowed from your IP address'
Error.captureStackTrace(this, AuthIPAddress)
this.headers = res.headers.raw()
this.code = 'EAUTHIP'
}
AuthIPAddress.prototype = Error.prototype
function AuthUnknown (res) {
Error.call(this)
this.message = 'Unable to authenticate, need: ' + res.headers.get('www-authenticate')
Error.captureStackTrace(this, AuthUnknown)
this.headers = res.headers.raw()
this.code = 'E401'
}
AuthUnknown.prototype = Error.prototype
function authHeaders (auth) {

@@ -249,1 +152,38 @@ const headers = {}

}
function fetchJSON (conf) {
const fetchOpts = {
method: conf.method,
headers: Object.assign({}, conf.headers || (conf.auth && authHeaders(conf.auth)) || {})
}
if (conf.body != null) {
fetchOpts.headers['Content-Type'] = 'application/json'
fetchOpts.body = JSON.stringify(conf.body)
}
return fetch.defaults(conf.opts || {})(conf.target, fetchOpts).then(res => {
if (res.headers.get('content-type') === 'application/json') {
return res.json().then(content => [res, content])
} else {
return res.buffer().then(content => [res, content])
}
}).then(result => {
const res = result[0]
const content = result[1]
if (res.status === 401 && res.headers.get('www-authenticate')) {
const auth = res.headers.get('www-authenticate').split(/,\s*/).map(s => s.toLowerCase())
if (auth.indexOf('ipaddress') !== -1) {
throw new AuthIPAddress(res)
} else if (auth.indexOf('otp') !== -1) {
throw new AuthOTP(res)
} else {
throw new AuthUnknown(res)
}
} else if (res.status < 200 || res.status >= 300) {
const err = new Error(res.statusText)
err.code = 'E' + res.status
err.headers = res.headers.raw()
throw err
}
return content
})
}
{
"name": "npm-profile",
"version": "1.0.2",
"version": "2.0.0",
"description": "Library for updating an npmjs.com profile",

@@ -5,0 +5,0 @@ "keywords": [],

@@ -14,6 +14,6 @@ # npm-profile

### profile.adduser(username, email, password, registry, opts) → Promise
### profile.adduser(username, email, password, config) → Promise
```js
profile.adduser(username, email, password, registry).then(result => {
profile.adduser(username, email, password, {registry}).then(result => {
// do something with result.token

@@ -33,5 +33,6 @@ })

* `password` String
* `registry` String (for reference, the npm registry is `https://registry.npmjs.org`)
* `opts` Object, [make-fetch-happen options](https://www.npmjs.com/package/make-fetch-happen#extra-options) for setting
things like cache, proxy, SSL CA and retry rules.
* `config` Object
* `registry` String (for reference, the npm registry is `https://registry.npmjs.org`)
* `opts` Object, [make-fetch-happen options](https://www.npmjs.com/package/make-fetch-happen#extra-options) for setting
things like cache, proxy, SSL CA and retry rules.

@@ -44,15 +45,21 @@ #### **Promise Value**

An error object indicating what went wrong. It will have a `code` property
set to the HTTP response code and a `headers` property with the HTTP headers
in the response.
An error object indicating what went wrong.
The `headers` property will contain the HTTP headers of the response.
If the action was denied because an OTP is required then `code` will be set
to `otp`.
### profile.login(username, password, registry, auth, opts) → Promise
If the action was denied because it came from an IP address that this action
on this account isn't allowed from then the `code` will be set to `ipaddress`.
Otherwise the code will be the HTTP response code.
### profile.login(username, password, config) → Promise
```js
profile.login(username, email, password, registry, {}).catch(err => {
profile.login(username, password, {registry}).catch(err => {
if (err.code === 'otp') {
return getOTPFromSomewhere().then(otp => {
return profile.login(username, email, password, registry, {otp})
return profile.login(username, password, {registry, auth: {otp}})
})

@@ -72,7 +79,8 @@ }

* `password` String
* `registry` String (for reference, the npm registry is `https://registry.npmjs.org`)
* `auth` Object, properties: `otp` — the one-time password from a two-factor
authentication device.
* `opts` Object, [make-fetch-happen options](https://www.npmjs.com/package/make-fetch-happen#extra-options) for setting
things like cache, proxy, SSL CA and retry rules.
* `config` Object
* `registry` String (for reference, the npm registry is `https://registry.npmjs.org`)
* `auth` Object, properties: `otp` — the one-time password from a two-factor
authentication device.
* `opts` Object, [make-fetch-happen options](https://www.npmjs.com/package/make-fetch-happen#extra-options) for setting
things like cache, proxy, SSL CA and retry rules.

@@ -99,6 +107,6 @@ #### **Promise Value**

### profile.get(registry, auth, opts) → Promise
### profile.get(config) → Promise
```js
profile.get(registry, {token}).then(userProfile => {
profile.get(registry, {auth: {token}}).then(userProfile => {
// do something with userProfile

@@ -110,9 +118,10 @@ })

* `registry` String (for reference, the npm registry is `https://registry.npmjs.org`)
* `auth` Object, properties: `token` — a bearer token returned from
`adduser`, `login` or `createToken`, or, `username`, `password` (and
optionally `otp`). Authenticating for this command via a username and
password will likely not be supported in the future.
* `opts` Object, [make-fetch-happen options](https://www.npmjs.com/package/make-fetch-happen#extra-options) for setting
things like cache, proxy, SSL CA and retry rules.
* `config` Object
* `registry` String (for reference, the npm registry is `https://registry.npmjs.org`)
* `auth` Object, properties: `token` — a bearer token returned from
`adduser`, `login` or `createToken`, or, `username`, `password` (and
optionally `otp`). Authenticating for this command via a username and
password will likely not be supported in the future.
* `opts` Object, [make-fetch-happen options](https://www.npmjs.com/package/make-fetch-happen#extra-options) for setting
things like cache, proxy, SSL CA and retry rules.

@@ -147,11 +156,18 @@ #### **Promise Value**

An error object indicating what went wrong. It will have a `code` property
set to the HTTP response code and a `headers` property with the HTTP headers
in the response.
An error object indicating what went wrong.
The `headers` property will contain the HTTP headers of the response.
### profile.set(profileData, registry, auth, opts) → Promise
If the action was denied because an OTP is required then `code` will be set
to `otp`.
If the action was denied because it came from an IP address that this action
on this account isn't allowed from then the `code` will be set to `ipaddress`.
Otherwise the code will be the HTTP response code.
### profile.set(profileData, config) → Promise
```js
profile.set({github: 'great-github-account-name'}, registry, {token})
profile.set({github: 'great-github-account-name'}, {registry, auth: {token}})
```

@@ -162,17 +178,34 @@

* `profileData` An object, like that returned from `profile.get`, but see
below for caveats relating to `tfa` and `cidr_whitelist`.
* `registry` String (for reference, the npm registry is `https://registry.npmjs.org`)
* `auth` Object, properties: `token` — a bearer token returned from
`adduser`, `login` or `createToken`, or, `username`, `password` (and
optionally `otp`). Authenticating for this command via a username and
password will likely not be supported in the future.
* `opts` Object, [make-fetch-happen options](https://www.npmjs.com/package/make-fetch-happen#extra-options) for setting
things like cache, proxy, SSL CA and retry rules.
below for caveats relating to `password`, `tfa` and `cidr_whitelist`.
* `config` Object
* `registry` String (for reference, the npm registry is `https://registry.npmjs.org`)
* `auth` Object, properties: `token` — a bearer token returned from
`adduser`, `login` or `createToken`, or, `username`, `password` (and
optionally `otp`). Authenticating for this command via a username and
password will likely not be supported in the future.
* `opts` Object, [make-fetch-happen options](https://www.npmjs.com/package/make-fetch-happen#extra-options) for setting
things like cache, proxy, SSL CA and retry rules.
#### **SETTING `cidr-whitelist`**
#### **SETTING `password`**
Only valid CIDR ranges are allowed in this array. Be very careful as it's
possible to lock yourself out of your account with this. This is not
currently exposed in `npm` itself.
This is used to change your password and is not visible (for obvious
reasons) through the `get()` API. The value should be an object with `old`
and `new` properties, where the former has the user's current password and
the latter has the desired new password. For example
```js
profile.set({password: {old: 'abc123', new: 'my new (more secure) password'}}, {registry, auth: {token}})
```
#### **SETTING `cidr_whitelist`**
The value for this is an Array. Only valid CIDR ranges are allowed in it.
Be very careful as it's possible to lock yourself out of your account with
this. This is not currently exposed in `npm` itself.
```js
profile.set({cidr_whitelist: [ '8.8.8.8/32' ], {registry, auth: {token}})
// ↑ only one of google's dns servers can now access this account.
```
#### **SETTING `tfa`**

@@ -182,3 +215,5 @@

1. `profile.set({tfa: {password, mode}}, registry, {token})`
1. Call `profile.get` and check the status of `tfa`. If `pending` is true then
you'll need to disable it with `profile.set({tfa: {password, mode: 'disable'}, …)`.
2. `profile.set({tfa: {password, mode}}, {registry, auth: {token}})`
* Note that the user's `password` is required here in the `tfa` object, regardless of auth.

@@ -188,7 +223,9 @@ * `mode` is either `auth-only` which requires `otp` when calling `login`

required when publishing.
2. If the result from calling `profile.set` has an empty `tfa` property
then that means that enabling `tfa` was already started elsewhere or is
already setup. In either case you'll need to set it to `disable` before
setting it to one of the modes above.
3. If the result has a `tfa` property it will be an `otpauth` URL, as
* Be aware that this set call may require otp as part of the auth object.
If otp is needed it will be indicated through a rejection in the usual
way.
3. If tfa was already enabled then you're just switch modes and a
successful response means that you're done. If the tfa property is empty and
tfa _wasn't_ enabled then it means they were in a pending state.
3. The response will have a `tfa` property set to an `otpauth` URL, as
[used by Google Authenticator](https://github.com/google/google-authenticator/wiki/Key-Uri-Format).

@@ -207,2 +244,9 @@ You will need to show this to the user for them to add to their

Disabling two-factor authentication is more straightforward, set the `tfa`
attribute to an object with a `password` property and a `mode` of `disable`.
```js
profile.set({tfa: {password, mode: 'disable'}, {registry, auth: {token}}}
```
#### **Promise Value**

@@ -214,8 +258,16 @@

An error object indicating what went wrong. It will have a `code` property
set to the HTTP response code and a `headers` property with the HTTP headers
in the response.
An error object indicating what went wrong.
### profile.listTokens(registry, auth, opts) → Promise
The `headers` property will contain the HTTP headers of the response.
If the action was denied because an OTP is required then `code` will be set
to `otp`.
If the action was denied because it came from an IP address that this action
on this account isn't allowed from then the `code` will be set to `ipaddress`.
Otherwise the code will be the HTTP response code.
### profile.listTokens(config) → Promise
```js

@@ -229,9 +281,10 @@ profile.listTokens(registry, {token}).then(tokens => {

* `registry` String (for reference, the npm registry is `https://registry.npmjs.org`)
* `auth` Object, properties: `token` — a bearer token returned from
`adduser`, `login` or `createToken`, or, `username`, `password` (and
optionally `otp`). Authenticating for this command via a username and
password will likely not be supported in the future.
* `opts` Object, [make-fetch-happen options](https://www.npmjs.com/package/make-fetch-happen#extra-options) for setting
things like cache, proxy, SSL CA and retry rules.
* `config` Object
* `registry` String (for reference, the npm registry is `https://registry.npmjs.org`)
* `auth` Object, properties: `token` — a bearer token returned from
`adduser`, `login` or `createToken`, or, `username`, `password` (and
optionally `otp`). Authenticating for this command via a username and
password will likely not be supported in the future.
* `opts` Object, [make-fetch-happen options](https://www.npmjs.com/package/make-fetch-happen#extra-options) for setting
things like cache, proxy, SSL CA and retry rules.

@@ -251,8 +304,16 @@ #### **Promise Value**

An error object indicating what went wrong. It will have a `code` property
set to the HTTP response code and a `headers` property with the HTTP headers
in the response.
An error object indicating what went wrong.
### profile.removeToken(token|key, registry, auth, opts) → Promise
The `headers` property will contain the HTTP headers of the response.
If the action was denied because an OTP is required then `code` will be set
to `otp`.
If the action was denied because it came from an IP address that this action
on this account isn't allowed from then the `code` will be set to `ipaddress`.
Otherwise the code will be the HTTP response code.
### profile.removeToken(token|key, config) → Promise
```js

@@ -267,9 +328,10 @@ profile.removeToken(key, registry, {token}).then(() => {

* `token|key` String, either a complete authentication token or the key returned by `profile.listTokens`.
* `registry` String (for reference, the npm registry is `https://registry.npmjs.org`)
* `auth` Object, properties: `token` — a bearer token returned from
`adduser`, `login` or `createToken`, or, `username`, `password` (and
optionally `otp`). Authenticating for this command via a username and
password will likely not be supported in the future.
* `opts` Object, [make-fetch-happen options](https://www.npmjs.com/package/make-fetch-happen#extra-options) for setting
things like cache, proxy, SSL CA and retry rules.
* `config` Object
* `registry` String (for reference, the npm registry is `https://registry.npmjs.org`)
* `auth` Object, properties: `token` — a bearer token returned from
`adduser`, `login` or `createToken`, or, `username`, `password` (and
optionally `otp`). Authenticating for this command via a username and
password will likely not be supported in the future.
* `opts` Object, [make-fetch-happen options](https://www.npmjs.com/package/make-fetch-happen#extra-options) for setting
things like cache, proxy, SSL CA and retry rules.

@@ -282,8 +344,16 @@ #### **Promise Value**

An error object indicating what went wrong. It will have a `code` property
set to the HTTP response code and a `headers` property with the HTTP headers
in the response.
An error object indicating what went wrong.
### profile.createToken(password, readonly, cidr_whitelist, registry, auth, opts) → Promise
The `headers` property will contain the HTTP headers of the response.
If the action was denied because an OTP is required then `code` will be set
to `otp`.
If the action was denied because it came from an IP address that this action
on this account isn't allowed from then the `code` will be set to `ipaddress`.
Otherwise the code will be the HTTP response code.
### profile.createToken(password, readonly, cidr_whitelist, config) → Promise
```js

@@ -300,9 +370,10 @@ profile.createToken(password, readonly, cidr_whitelist, registry, {token, otp}).then(newToken => {

* `cidr_whitelist` Array
* `registry` String (for reference, the npm registry is `https://registry.npmjs.org`)
* `auth` Object, properties: `token` — a bearer token returned from
`adduser`, `login` or `createToken`, or, `username`, `password` (and
optionally `otp`). Authenticating for this command via a username and
password will likely not be supported in the future.
* `opts` Object, [make-fetch-happen options](https://www.npmjs.com/package/make-fetch-happen#extra-options) for setting
things like cache, proxy, SSL CA and retry rules.
* `config` Object
* `registry` String (for reference, the npm registry is `https://registry.npmjs.org`)
* `auth` Object, properties: `token` — a bearer token returned from
`adduser`, `login` or `createToken`, or, `username`, `password` (and
optionally `otp`). Authenticating for this command via a username and
password will likely not be supported in the future.
* `opts` Object, [make-fetch-happen options](https://www.npmjs.com/package/make-fetch-happen#extra-options) for setting
things like cache, proxy, SSL CA and retry rules.

@@ -326,5 +397,12 @@ #### **Promise Value**

An error object indicating what went wrong. It will have a `code` property
set to the HTTP response code and a `headers` property with the HTTP headers
in the response.
An error object indicating what went wrong.
The `headers` property will contain the HTTP headers of the response.
If the action was denied because an OTP is required then `code` will be set
to `otp`.
If the action was denied because it came from an IP address that this action
on this account isn't allowed from then the `code` will be set to `ipaddress`.
Otherwise the code will be the HTTP response code.
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc