Skip to content

Commit b80d048

Browse files
committedOct 2, 2024
deps: update @npmcli/redact@3.0.0
1 parent 81137fc commit b80d048

File tree

12 files changed

+544
-17
lines changed

12 files changed

+544
-17
lines changed
 

‎node_modules/.gitignore

+5
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,11 @@
194194
!/npm-pick-manifest
195195
!/npm-profile
196196
!/npm-registry-fetch
197+
!/npm-registry-fetch/node_modules/
198+
/npm-registry-fetch/node_modules/*
199+
!/npm-registry-fetch/node_modules/@npmcli/
200+
/npm-registry-fetch/node_modules/@npmcli/*
201+
!/npm-registry-fetch/node_modules/@npmcli/redact
197202
!/npm-user-validate
198203
!/p-map
199204
!/package-json-from-dist
+10-9
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@npmcli/redact",
3-
"version": "2.0.1",
3+
"version": "3.0.0",
44
"description": "Redact sensitive npm information from output",
55
"main": "lib/index.js",
66
"exports": {
@@ -10,12 +10,13 @@
1010
},
1111
"scripts": {
1212
"test": "tap",
13-
"lint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"",
13+
"lint": "npm run eslint",
1414
"postlint": "template-oss-check",
1515
"template-oss-apply": "template-oss-apply --force",
16-
"lintfix": "npm run lint -- --fix",
16+
"lintfix": "npm run eslint -- --fix",
1717
"snap": "tap",
18-
"posttest": "npm run lint"
18+
"posttest": "npm run lint",
19+
"eslint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\""
1920
},
2021
"keywords": [],
2122
"author": "GitHub Inc.",
@@ -26,11 +27,11 @@
2627
],
2728
"repository": {
2829
"type": "git",
29-
"url": "https://github.com/npm/redact.git"
30+
"url": "git+https://github.com/npm/redact.git"
3031
},
3132
"templateOSS": {
3233
"//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.",
33-
"version": "4.21.3",
34+
"version": "4.23.3",
3435
"publish": true
3536
},
3637
"tap": {
@@ -41,11 +42,11 @@
4142
"timeout": 120
4243
},
4344
"devDependencies": {
44-
"@npmcli/eslint-config": "^4.0.2",
45-
"@npmcli/template-oss": "4.21.3",
45+
"@npmcli/eslint-config": "^5.0.0",
46+
"@npmcli/template-oss": "4.23.3",
4647
"tap": "^16.3.10"
4748
},
4849
"engines": {
49-
"node": "^16.14.0 || >=18.0.0"
50+
"node": "^18.17.0 || >=20.5.0"
5051
}
5152
}
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.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
function filterError (input) {
2+
return {
3+
errorType: input.name,
4+
message: input.message,
5+
stack: input.stack,
6+
...(input.code ? { code: input.code } : {}),
7+
...(input.statusCode ? { statusCode: input.statusCode } : {}),
8+
}
9+
}
10+
11+
const deepMap = (input, handler = v => v, path = ['$'], seen = new Set([input])) => {
12+
// this is in an effort to maintain bole's error logging behavior
13+
if (path.join('.') === '$' && input instanceof Error) {
14+
return deepMap({ err: filterError(input) }, handler, path, seen)
15+
}
16+
if (input instanceof Error) {
17+
return deepMap(filterError(input), handler, path, seen)
18+
}
19+
if (input instanceof Buffer) {
20+
return `[unable to log instanceof buffer]`
21+
}
22+
if (input instanceof Uint8Array) {
23+
return `[unable to log instanceof Uint8Array]`
24+
}
25+
26+
if (Array.isArray(input)) {
27+
const result = []
28+
for (let i = 0; i < input.length; i++) {
29+
const element = input[i]
30+
const elementPath = [...path, i]
31+
if (element instanceof Object) {
32+
if (!seen.has(element)) { // avoid getting stuck in circular reference
33+
seen.add(element)
34+
result.push(deepMap(handler(element, elementPath), handler, elementPath, seen))
35+
}
36+
} else {
37+
result.push(handler(element, elementPath))
38+
}
39+
}
40+
return result
41+
}
42+
43+
if (input === null) {
44+
return null
45+
} else if (typeof input === 'object' || typeof input === 'function') {
46+
const result = {}
47+
48+
for (const propertyName of Object.getOwnPropertyNames(input)) {
49+
// skip logging internal properties
50+
if (propertyName.startsWith('_')) {
51+
continue
52+
}
53+
54+
try {
55+
const property = input[propertyName]
56+
const propertyPath = [...path, propertyName]
57+
if (property instanceof Object) {
58+
if (!seen.has(property)) { // avoid getting stuck in circular reference
59+
seen.add(property)
60+
result[propertyName] = deepMap(
61+
handler(property, propertyPath), handler, propertyPath, seen
62+
)
63+
}
64+
} else {
65+
result[propertyName] = handler(property, propertyPath)
66+
}
67+
} catch (err) {
68+
// a getter may throw an error
69+
result[propertyName] = `[error getting value: ${err.message}]`
70+
}
71+
}
72+
return result
73+
}
74+
75+
return handler(input, path)
76+
}
77+
78+
module.exports = { deepMap }
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+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
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 REWRITE_REQUEST = {
48+
type: TYPE_PATH,
49+
predicate: ({ path }) => path.endsWith('.request'),
50+
replacement: (input) => ({
51+
method: input?.method,
52+
path: input?.path,
53+
headers: input?.headers,
54+
url: input?.url,
55+
}),
56+
}
57+
58+
const REWRITE_RESPONSE = {
59+
type: TYPE_PATH,
60+
predicate: ({ path }) => path.endsWith('.response'),
61+
replacement: (input) => ({
62+
data: input?.data,
63+
status: input?.status,
64+
headers: input?.headers,
65+
}),
66+
}
67+
68+
module.exports = {
69+
TYPE_REGEX,
70+
TYPE_URL,
71+
TYPE_PATH,
72+
NPM_SECRET,
73+
AUTH_HEADER,
74+
JSON_WEB_TOKEN,
75+
UUID,
76+
URL_MATCHER,
77+
DEEP_HEADER_AUTHORIZATION,
78+
DEEP_HEADER_SET_COOKIE,
79+
REWRITE_REQUEST,
80+
REWRITE_RESPONSE,
81+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
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+
} = require('./matchers')
10+
11+
const {
12+
redactUrlMatcher,
13+
redactUrlPasswordMatcher,
14+
redactMatchers,
15+
} = require('./utils')
16+
17+
const { deepMap } = require('./deep-map')
18+
19+
const _redact = redactMatchers(
20+
NPM_SECRET,
21+
AUTH_HEADER,
22+
JSON_WEB_TOKEN,
23+
DEEP_HEADER_AUTHORIZATION,
24+
DEEP_HEADER_SET_COOKIE,
25+
REWRITE_REQUEST,
26+
REWRITE_RESPONSE,
27+
redactUrlMatcher(
28+
redactUrlPasswordMatcher()
29+
)
30+
)
31+
32+
const redact = (input) => deepMap(input, (value, path) => _redact(value, { path }))
33+
34+
module.exports = { redact }

‎node_modules/npm-registry-fetch/node_modules/@npmcli/redact/lib/utils.js

+202
Original file line numberDiff line numberDiff line change

‎node_modules/npm-registry-fetch/node_modules/@npmcli/redact/package.json

+51
Original file line numberDiff line numberDiff line change

‎package-lock.json

+16-6
Original file line numberDiff line numberDiff line change

‎package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@
5858
"@npmcli/map-workspaces": "^4.0.1",
5959
"@npmcli/package-json": "^6.0.1",
6060
"@npmcli/promise-spawn": "^8.0.1",
61-
"@npmcli/redact": "^2.0.1",
61+
"@npmcli/redact": "^3.0.0",
6262
"@npmcli/run-script": "^8.1.0",
6363
"@sigstore/tuf": "^2.3.4",
6464
"abbrev": "^2.0.0",

‎workspaces/arborist/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
"@npmcli/node-gyp": "^3.0.0",
1313
"@npmcli/package-json": "^6.0.1",
1414
"@npmcli/query": "^3.1.0",
15-
"@npmcli/redact": "^2.0.0",
15+
"@npmcli/redact": "^3.0.0",
1616
"@npmcli/run-script": "^8.1.0",
1717
"bin-links": "^4.0.4",
1818
"cacache": "^18.0.3",

0 commit comments

Comments
 (0)
Please sign in to comment.