Skip to content

Commit 34d8599

Browse files
committed
deps: npm-registry-fetch@19.1.1
1 parent 4811a86 commit 34d8599

File tree

24 files changed

+2196
-215
lines changed

24 files changed

+2196
-215
lines changed

node_modules/.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,10 @@
180180
!/npm-registry-fetch
181181
!/npm-registry-fetch/node_modules/
182182
/npm-registry-fetch/node_modules/*
183-
!/npm-registry-fetch/node_modules/proc-log
183+
!/npm-registry-fetch/node_modules/@npmcli/
184+
/npm-registry-fetch/node_modules/@npmcli/*
185+
!/npm-registry-fetch/node_modules/@npmcli/redact
186+
!/npm-registry-fetch/node_modules/minipass-fetch
184187
!/npm-user-validate
185188
!/p-map
186189
!/package-json-from-dist
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2024 npm
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
const { serializeError } = require('./error')
2+
3+
const deepMap = (input, handler = v => v, path = ['$'], seen = new Set([input])) => {
4+
// this is in an effort to maintain bole's error logging behavior
5+
if (path.join('.') === '$' && input instanceof Error) {
6+
return deepMap({ err: serializeError(input) }, handler, path, seen)
7+
}
8+
if (input instanceof Error) {
9+
return deepMap(serializeError(input), handler, path, seen)
10+
}
11+
// allows for non-node js environments, sush as workers
12+
if (typeof Buffer !== 'undefined' && input instanceof Buffer) {
13+
return `[unable to log instanceof buffer]`
14+
}
15+
if (input instanceof Uint8Array) {
16+
return `[unable to log instanceof Uint8Array]`
17+
}
18+
19+
if (Array.isArray(input)) {
20+
const result = []
21+
for (let i = 0; i < input.length; i++) {
22+
const element = input[i]
23+
const elementPath = [...path, i]
24+
if (element instanceof Object) {
25+
if (!seen.has(element)) { // avoid getting stuck in circular reference
26+
seen.add(element)
27+
result.push(deepMap(handler(element, elementPath), handler, elementPath, seen))
28+
}
29+
} else {
30+
result.push(handler(element, elementPath))
31+
}
32+
}
33+
return result
34+
}
35+
36+
if (input === null) {
37+
return null
38+
} else if (typeof input === 'object' || typeof input === 'function') {
39+
const result = {}
40+
41+
for (const propertyName of Object.getOwnPropertyNames(input)) {
42+
// skip logging internal properties
43+
if (propertyName.startsWith('_')) {
44+
continue
45+
}
46+
47+
try {
48+
const property = input[propertyName]
49+
const propertyPath = [...path, propertyName]
50+
if (property instanceof Object) {
51+
if (!seen.has(property)) { // avoid getting stuck in circular reference
52+
seen.add(property)
53+
result[propertyName] = deepMap(
54+
handler(property, propertyPath), handler, propertyPath, seen
55+
)
56+
}
57+
} else {
58+
result[propertyName] = handler(property, propertyPath)
59+
}
60+
} catch (err) {
61+
// a getter may throw an error
62+
result[propertyName] = `[error getting value: ${err.message}]`
63+
}
64+
}
65+
return result
66+
}
67+
68+
return handler(input, path)
69+
}
70+
71+
module.exports = { deepMap }
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/** takes an error object and serializes it to a plan object */
2+
function serializeError (input) {
3+
if (!(input instanceof Error)) {
4+
if (typeof input === 'string') {
5+
const error = new Error(`attempted to serialize a non-error, string String, "${input}"`)
6+
return serializeError(error)
7+
}
8+
const error = new Error(`attempted to serialize a non-error, ${typeof input} ${input?.constructor?.name}`)
9+
return serializeError(error)
10+
}
11+
// different error objects store status code differently
12+
// AxiosError uses `status`, other services use `statusCode`
13+
const statusCode = input.statusCode ?? input.status
14+
// CAUTION: what we serialize here gets add to the size of logs
15+
return {
16+
errorType: input.errorType ?? input.constructor.name,
17+
...(input.message ? { message: input.message } : {}),
18+
...(input.stack ? { stack: input.stack } : {}),
19+
// think of this as error code
20+
...(input.code ? { code: input.code } : {}),
21+
// think of this as http status code
22+
...(statusCode ? { statusCode } : {}),
23+
}
24+
}
25+
26+
module.exports = {
27+
serializeError,
28+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
const matchers = require('./matchers')
2+
const { redactUrlPassword } = require('./utils')
3+
4+
const REPLACE = '***'
5+
6+
const redact = (value) => {
7+
if (typeof value !== 'string' || !value) {
8+
return value
9+
}
10+
return redactUrlPassword(value, REPLACE)
11+
.replace(matchers.NPM_SECRET.pattern, `npm_${REPLACE}`)
12+
.replace(matchers.UUID.pattern, REPLACE)
13+
}
14+
15+
// split on \s|= similar to how nopt parses options
16+
const splitAndRedact = (str) => {
17+
// stateful regex, don't move out of this scope
18+
const splitChars = /[\s=]/g
19+
20+
let match = null
21+
let result = ''
22+
let index = 0
23+
while (match = splitChars.exec(str)) {
24+
result += redact(str.slice(index, match.index)) + match[0]
25+
index = splitChars.lastIndex
26+
}
27+
28+
return result + redact(str.slice(index))
29+
}
30+
31+
// replaces auth info in an array of arguments or in a strings
32+
const redactLog = (arg) => {
33+
if (typeof arg === 'string') {
34+
return splitAndRedact(arg)
35+
} else if (Array.isArray(arg)) {
36+
return arg.map((a) => typeof a === 'string' ? splitAndRedact(a) : a)
37+
}
38+
return arg
39+
}
40+
41+
module.exports = {
42+
redact,
43+
redactLog,
44+
}
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
const TYPE_REGEX = 'regex'
2+
const TYPE_URL = 'url'
3+
const TYPE_PATH = 'path'
4+
5+
const NPM_SECRET = {
6+
type: TYPE_REGEX,
7+
pattern: /\b(npms?_)[a-zA-Z0-9]{36,48}\b/gi,
8+
replacement: `[REDACTED_NPM_SECRET]`,
9+
}
10+
11+
const AUTH_HEADER = {
12+
type: TYPE_REGEX,
13+
pattern: /\b(Basic\s+|Bearer\s+)[\w+=\-.]+\b/gi,
14+
replacement: `[REDACTED_AUTH_HEADER]`,
15+
}
16+
17+
const JSON_WEB_TOKEN = {
18+
type: TYPE_REGEX,
19+
pattern: /\b[A-Za-z0-9-_]{10,}(?!\.\d+\.)\.[A-Za-z0-9-_]{3,}\.[A-Za-z0-9-_]{20,}\b/gi,
20+
replacement: `[REDACTED_JSON_WEB_TOKEN]`,
21+
}
22+
23+
const UUID = {
24+
type: TYPE_REGEX,
25+
pattern: /\b[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\b/gi,
26+
replacement: `[REDACTED_UUID]`,
27+
}
28+
29+
const URL_MATCHER = {
30+
type: TYPE_REGEX,
31+
pattern: /(?:https?|ftp):\/\/[^\s/"$.?#].[^\s"]*/gi,
32+
replacement: '[REDACTED_URL]',
33+
}
34+
35+
const DEEP_HEADER_AUTHORIZATION = {
36+
type: TYPE_PATH,
37+
predicate: ({ path }) => path.endsWith('.headers.authorization'),
38+
replacement: '[REDACTED_HEADER_AUTHORIZATION]',
39+
}
40+
41+
const DEEP_HEADER_SET_COOKIE = {
42+
type: TYPE_PATH,
43+
predicate: ({ path }) => path.endsWith('.headers.set-cookie'),
44+
replacement: '[REDACTED_HEADER_SET_COOKIE]',
45+
}
46+
47+
const DEEP_HEADER_COOKIE = {
48+
type: TYPE_PATH,
49+
predicate: ({ path }) => path.endsWith('.headers.cookie'),
50+
replacement: '[REDACTED_HEADER_COOKIE]',
51+
}
52+
53+
const REWRITE_REQUEST = {
54+
type: TYPE_PATH,
55+
predicate: ({ path }) => path.endsWith('.request'),
56+
replacement: (input) => ({
57+
method: input?.method,
58+
path: input?.path,
59+
headers: input?.headers,
60+
url: input?.url,
61+
}),
62+
}
63+
64+
const REWRITE_RESPONSE = {
65+
type: TYPE_PATH,
66+
predicate: ({ path }) => path.endsWith('.response'),
67+
replacement: (input) => ({
68+
data: input?.data,
69+
status: input?.status,
70+
headers: input?.headers,
71+
}),
72+
}
73+
74+
module.exports = {
75+
TYPE_REGEX,
76+
TYPE_URL,
77+
TYPE_PATH,
78+
NPM_SECRET,
79+
AUTH_HEADER,
80+
JSON_WEB_TOKEN,
81+
UUID,
82+
URL_MATCHER,
83+
DEEP_HEADER_AUTHORIZATION,
84+
DEEP_HEADER_SET_COOKIE,
85+
DEEP_HEADER_COOKIE,
86+
REWRITE_REQUEST,
87+
REWRITE_RESPONSE,
88+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
const {
2+
AUTH_HEADER,
3+
JSON_WEB_TOKEN,
4+
NPM_SECRET,
5+
DEEP_HEADER_AUTHORIZATION,
6+
DEEP_HEADER_SET_COOKIE,
7+
REWRITE_REQUEST,
8+
REWRITE_RESPONSE,
9+
DEEP_HEADER_COOKIE,
10+
} = require('./matchers')
11+
12+
const {
13+
redactUrlMatcher,
14+
redactUrlPasswordMatcher,
15+
redactMatchers,
16+
} = require('./utils')
17+
18+
const { serializeError } = require('./error')
19+
20+
const { deepMap } = require('./deep-map')
21+
22+
const _redact = redactMatchers(
23+
NPM_SECRET,
24+
AUTH_HEADER,
25+
JSON_WEB_TOKEN,
26+
DEEP_HEADER_AUTHORIZATION,
27+
DEEP_HEADER_SET_COOKIE,
28+
DEEP_HEADER_COOKIE,
29+
REWRITE_REQUEST,
30+
REWRITE_RESPONSE,
31+
redactUrlMatcher(
32+
redactUrlPasswordMatcher()
33+
)
34+
)
35+
36+
const redact = (input) => deepMap(input, (value, path) => _redact(value, { path }))
37+
38+
/** takes an error returns new error keeping some custom properties */
39+
function redactError (input) {
40+
const { message, ...data } = serializeError(input)
41+
const output = new Error(redact(message))
42+
return Object.assign(output, redact(data))
43+
}
44+
45+
/** runs a function within try / catch and throws error wrapped in redactError */
46+
function redactThrow (func) {
47+
if (typeof func !== 'function') {
48+
throw new Error('redactThrow expects a function')
49+
}
50+
return async (...args) => {
51+
try {
52+
return await func(...args)
53+
} catch (error) {
54+
throw redactError(error)
55+
}
56+
}
57+
}
58+
59+
module.exports = { redact, redactError, redactThrow }

0 commit comments

Comments
 (0)