update
This commit is contained in:
20
package/node_modules/npm-profile/LICENSE.md
generated
vendored
Normal file
20
package/node_modules/npm-profile/LICENSE.md
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
<!-- This file is automatically added by @npmcli/template-oss. Do not edit. -->
|
||||
|
||||
ISC License
|
||||
|
||||
Copyright npm, Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this
|
||||
software for any purpose with or without fee is hereby
|
||||
granted, provided that the above copyright notice and this
|
||||
permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND NPM DISCLAIMS ALL
|
||||
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
|
||||
EVENT SHALL NPM BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE
|
||||
USE OR PERFORMANCE OF THIS SOFTWARE.
|
278
package/node_modules/npm-profile/lib/index.js
generated
vendored
Normal file
278
package/node_modules/npm-profile/lib/index.js
generated
vendored
Normal file
@@ -0,0 +1,278 @@
|
||||
const { URL } = require('node:url')
|
||||
const timers = require('node:timers/promises')
|
||||
const fetch = require('npm-registry-fetch')
|
||||
const { HttpErrorBase } = require('npm-registry-fetch/lib/errors')
|
||||
const { log } = require('proc-log')
|
||||
|
||||
// try loginWeb, catch the "not supported" message and fall back to couch
|
||||
const login = async (opener, prompter, opts = {}) => {
|
||||
try {
|
||||
return await loginWeb(opener, opts)
|
||||
} catch (er) {
|
||||
if (er instanceof WebLoginNotSupported) {
|
||||
log.verbose('web login', 'not supported, trying couch')
|
||||
const { username, password } = await prompter(opts.creds)
|
||||
return loginCouch(username, password, opts)
|
||||
}
|
||||
throw er
|
||||
}
|
||||
}
|
||||
|
||||
const adduser = async (opener, prompter, opts = {}) => {
|
||||
try {
|
||||
return await adduserWeb(opener, opts)
|
||||
} catch (er) {
|
||||
if (er instanceof WebLoginNotSupported) {
|
||||
log.verbose('web adduser', 'not supported, trying couch')
|
||||
const { username, email, password } = await prompter(opts.creds)
|
||||
return adduserCouch(username, email, password, opts)
|
||||
}
|
||||
throw er
|
||||
}
|
||||
}
|
||||
|
||||
const adduserWeb = (opener, opts = {}) => {
|
||||
log.verbose('web adduser', 'before first POST')
|
||||
return webAuth(opener, opts, { create: true })
|
||||
}
|
||||
|
||||
const loginWeb = (opener, opts = {}) => {
|
||||
log.verbose('web login', 'before first POST')
|
||||
return webAuth(opener, opts, {})
|
||||
}
|
||||
|
||||
const isValidUrl = u => {
|
||||
try {
|
||||
return /^https?:$/.test(new URL(u).protocol)
|
||||
} catch {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
const webAuth = async (opener, opts, body) => {
|
||||
try {
|
||||
const res = await fetch('/-/v1/login', {
|
||||
...opts,
|
||||
method: 'POST',
|
||||
body,
|
||||
})
|
||||
|
||||
const content = await res.json()
|
||||
log.verbose('web auth', 'got response', content)
|
||||
|
||||
const { doneUrl, loginUrl } = content
|
||||
if (!isValidUrl(doneUrl) || !isValidUrl(loginUrl)) {
|
||||
throw new WebLoginInvalidResponse('POST', res, content)
|
||||
}
|
||||
|
||||
return await webAuthOpener(opener, loginUrl, doneUrl, opts)
|
||||
} catch (er) {
|
||||
if ((er.statusCode >= 400 && er.statusCode <= 499) || er.statusCode === 500) {
|
||||
throw new WebLoginNotSupported('POST', {
|
||||
status: er.statusCode,
|
||||
headers: er.headers,
|
||||
}, er.body)
|
||||
}
|
||||
throw er
|
||||
}
|
||||
}
|
||||
|
||||
const webAuthOpener = async (opener, loginUrl, doneUrl, opts) => {
|
||||
const abortController = new AbortController()
|
||||
const { signal } = abortController
|
||||
try {
|
||||
log.verbose('web auth', 'opening url pair')
|
||||
const [, authResult] = await Promise.all([
|
||||
opener(loginUrl, { signal }).catch((err) => {
|
||||
if (err.name === 'AbortError') {
|
||||
abortController.abort()
|
||||
return
|
||||
}
|
||||
throw err
|
||||
}),
|
||||
webAuthCheckLogin(doneUrl, { ...opts, cache: false }, { signal }).then((r) => {
|
||||
log.verbose('web auth', 'done-check finished')
|
||||
abortController.abort()
|
||||
return r
|
||||
}),
|
||||
])
|
||||
return authResult
|
||||
} catch (er) {
|
||||
abortController.abort()
|
||||
throw er
|
||||
}
|
||||
}
|
||||
|
||||
const webAuthCheckLogin = async (doneUrl, opts, { signal } = {}) => {
|
||||
signal?.throwIfAborted()
|
||||
|
||||
const res = await fetch(doneUrl, opts)
|
||||
const content = await res.json()
|
||||
|
||||
if (res.status === 200) {
|
||||
if (!content.token) {
|
||||
throw new WebLoginInvalidResponse('GET', res, content)
|
||||
}
|
||||
return content
|
||||
}
|
||||
|
||||
if (res.status === 202) {
|
||||
const retry = +res.headers.get('retry-after') * 1000
|
||||
if (retry > 0) {
|
||||
await timers.setTimeout(retry, null, { ref: false, signal })
|
||||
}
|
||||
return webAuthCheckLogin(doneUrl, opts, { signal })
|
||||
}
|
||||
|
||||
throw new WebLoginInvalidResponse('GET', res, content)
|
||||
}
|
||||
|
||||
const couchEndpoint = (username) => `/-/user/org.couchdb.user:${encodeURIComponent(username)}`
|
||||
|
||||
const putCouch = async (path, username, body, opts) => {
|
||||
const result = await fetch.json(`${couchEndpoint(username)}${path}`, {
|
||||
...opts,
|
||||
method: 'PUT',
|
||||
body,
|
||||
})
|
||||
result.username = username
|
||||
return result
|
||||
}
|
||||
|
||||
const adduserCouch = async (username, email, password, opts = {}) => {
|
||||
const body = {
|
||||
_id: `org.couchdb.user:${username}`,
|
||||
name: username,
|
||||
password: password,
|
||||
email: email,
|
||||
type: 'user',
|
||||
roles: [],
|
||||
date: new Date().toISOString(),
|
||||
}
|
||||
|
||||
log.verbose('adduser', 'before first PUT', {
|
||||
...body,
|
||||
password: 'XXXXX',
|
||||
})
|
||||
|
||||
return putCouch('', username, body, opts)
|
||||
}
|
||||
|
||||
const loginCouch = async (username, password, opts = {}) => {
|
||||
const body = {
|
||||
_id: `org.couchdb.user:${username}`,
|
||||
name: username,
|
||||
password: password,
|
||||
type: 'user',
|
||||
roles: [],
|
||||
date: new Date().toISOString(),
|
||||
}
|
||||
|
||||
log.verbose('login', 'before first PUT', {
|
||||
...body,
|
||||
password: 'XXXXX',
|
||||
})
|
||||
|
||||
try {
|
||||
return await putCouch('', username, body, opts)
|
||||
} catch (err) {
|
||||
if (err.code === 'E400') {
|
||||
err.message = `There is no user with the username "${username}".`
|
||||
throw err
|
||||
}
|
||||
|
||||
if (err.code !== 'E409') {
|
||||
throw err
|
||||
}
|
||||
}
|
||||
|
||||
const result = await fetch.json(couchEndpoint(username), {
|
||||
...opts,
|
||||
query: { write: true },
|
||||
})
|
||||
|
||||
for (const k of Object.keys(result)) {
|
||||
if (!body[k] || k === 'roles') {
|
||||
body[k] = result[k]
|
||||
}
|
||||
}
|
||||
|
||||
return putCouch(`/-rev/${body._rev}`, username, body, {
|
||||
...opts,
|
||||
forceAuth: {
|
||||
username,
|
||||
password: Buffer.from(password, 'utf8').toString('base64'),
|
||||
otp: opts.otp,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
const get = (opts = {}) => fetch.json('/-/npm/v1/user', opts)
|
||||
|
||||
const set = (profile, opts = {}) => fetch.json('/-/npm/v1/user', {
|
||||
...opts,
|
||||
method: 'POST',
|
||||
// profile keys can't be empty strings, but they CAN be null
|
||||
body: Object.fromEntries(Object.entries(profile).map(([k, v]) => [k, v === '' ? null : v])),
|
||||
})
|
||||
|
||||
const paginate = async (href, opts, items = []) => {
|
||||
const result = await fetch.json(href, opts)
|
||||
items = items.concat(result.objects)
|
||||
if (result.urls.next) {
|
||||
return paginate(result.urls.next, opts, items)
|
||||
}
|
||||
return items
|
||||
}
|
||||
|
||||
const listTokens = (opts = {}) => paginate('/-/npm/v1/tokens', opts)
|
||||
|
||||
const removeToken = async (tokenKey, opts = {}) => {
|
||||
await fetch(`/-/npm/v1/tokens/token/${tokenKey}`, {
|
||||
...opts,
|
||||
method: 'DELETE',
|
||||
ignoreBody: true,
|
||||
})
|
||||
return null
|
||||
}
|
||||
|
||||
const createToken = (password, readonly, cidrs, opts = {}) => fetch.json('/-/npm/v1/tokens', {
|
||||
...opts,
|
||||
method: 'POST',
|
||||
body: {
|
||||
password: password,
|
||||
readonly: readonly,
|
||||
cidr_whitelist: cidrs,
|
||||
},
|
||||
})
|
||||
|
||||
class WebLoginInvalidResponse extends HttpErrorBase {
|
||||
constructor (method, res, body) {
|
||||
super(method, res, body)
|
||||
this.message = 'Invalid response from web login endpoint'
|
||||
}
|
||||
}
|
||||
|
||||
class WebLoginNotSupported extends HttpErrorBase {
|
||||
constructor (method, res, body) {
|
||||
super(method, res, body)
|
||||
this.message = 'Web login not supported'
|
||||
this.code = 'ENYI'
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
adduserCouch,
|
||||
loginCouch,
|
||||
adduserWeb,
|
||||
loginWeb,
|
||||
login,
|
||||
adduser,
|
||||
get,
|
||||
set,
|
||||
listTokens,
|
||||
removeToken,
|
||||
createToken,
|
||||
webAuthCheckLogin,
|
||||
webAuthOpener,
|
||||
}
|
51
package/node_modules/npm-profile/package.json
generated
vendored
Normal file
51
package/node_modules/npm-profile/package.json
generated
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
{
|
||||
"name": "npm-profile",
|
||||
"version": "10.0.0",
|
||||
"description": "Library for updating an npmjs.com profile",
|
||||
"keywords": [],
|
||||
"author": "GitHub Inc.",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"npm-registry-fetch": "^17.0.1",
|
||||
"proc-log": "^4.0.0"
|
||||
},
|
||||
"main": "./lib/index.js",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/npm/npm-profile.git"
|
||||
},
|
||||
"files": [
|
||||
"bin/",
|
||||
"lib/"
|
||||
],
|
||||
"devDependencies": {
|
||||
"@npmcli/eslint-config": "^4.0.0",
|
||||
"@npmcli/template-oss": "4.21.4",
|
||||
"nock": "^13.2.4",
|
||||
"tap": "^16.0.1"
|
||||
},
|
||||
"scripts": {
|
||||
"posttest": "npm run lint",
|
||||
"test": "tap",
|
||||
"snap": "tap",
|
||||
"lint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"",
|
||||
"postlint": "template-oss-check",
|
||||
"lintfix": "npm run lint -- --fix",
|
||||
"template-oss-apply": "template-oss-apply --force"
|
||||
},
|
||||
"tap": {
|
||||
"check-coverage": true,
|
||||
"nyc-arg": [
|
||||
"--exclude",
|
||||
"tap-snapshots/**"
|
||||
]
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.0.0"
|
||||
},
|
||||
"templateOSS": {
|
||||
"//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.",
|
||||
"version": "4.21.4",
|
||||
"publish": true
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user