projecte_ionic/node_modules/npm-registry-fetch/check-response.js
2022-02-09 18:30:03 +01:00

101 lines
3.2 KiB
JavaScript
Executable file

'use strict'
const errors = require('./errors.js')
const { Response } = require('minipass-fetch')
const defaultOpts = require('./default-opts.js')
const checkResponse =
async ({ method, uri, res, registry, startTime, auth, opts }) => {
opts = { ...defaultOpts, ...opts }
if (res.headers.has('npm-notice') && !res.headers.has('x-local-cache'))
opts.log.notice('', res.headers.get('npm-notice'))
if (res.status >= 400) {
logRequest(method, res, startTime, opts)
if (auth && auth.scopeAuthKey && !auth.token && !auth.auth) {
// we didn't have auth for THIS request, but we do have auth for
// requests to the registry indicated by the spec's scope value.
// Warn the user.
opts.log.warn('registry', `No auth for URI, but auth present for scoped registry.
URI: ${uri}
Scoped Registry Key: ${auth.scopeAuthKey}
More info here: https://github.com/npm/cli/wiki/No-auth-for-URI,-but-auth-present-for-scoped-registry`)
}
return checkErrors(method, res, startTime, opts)
} else {
res.body.on('end', () => logRequest(method, res, startTime, opts))
if (opts.ignoreBody) {
res.body.resume()
return new Response(null, res)
}
return res
}
}
module.exports = checkResponse
function logRequest (method, res, startTime, opts) {
const elapsedTime = Date.now() - startTime
const attempt = res.headers.get('x-fetch-attempts')
const attemptStr = attempt && attempt > 1 ? ` attempt #${attempt}` : ''
const cacheStatus = res.headers.get('x-local-cache-status')
const cacheStr = cacheStatus ? ` (cache ${cacheStatus})` : ''
let urlStr
try {
const { URL } = require('url')
const url = new URL(res.url)
if (url.password)
url.password = '***'
urlStr = url.toString()
} catch (er) {
urlStr = res.url
}
opts.log.http(
'fetch',
`${method.toUpperCase()} ${res.status} ${urlStr} ${elapsedTime}ms${attemptStr}${cacheStr}`
)
}
function checkErrors (method, res, startTime, opts) {
return res.buffer()
.catch(() => null)
.then(body => {
let parsed = body
try {
parsed = JSON.parse(body.toString('utf8'))
} catch (e) {}
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 errors.HttpErrorAuthIPAddress(
method, res, parsed, opts.spec
)
} else if (auth.indexOf('otp') !== -1) {
throw new errors.HttpErrorAuthOTP(
method, res, parsed, opts.spec
)
} else {
throw new errors.HttpErrorAuthUnknown(
method, res, parsed, opts.spec
)
}
} else if (res.status === 401 && body != null && /one-time pass/.test(body.toString('utf8'))) {
// Heuristic for malformed OTP responses that don't include the
// www-authenticate header.
throw new errors.HttpErrorAuthOTP(
method, res, parsed, opts.spec
)
} else {
throw new errors.HttpErrorGeneral(
method, res, parsed, opts.spec
)
}
})
}