@vtex/api
Version:
VTEX I/O API client
95 lines (94 loc) • 3.44 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.cloneAndSanitizeHeaders = exports.getTraceInfo = exports.INTERESTING_HEADERS = void 0;
const node_error_report_1 = require("@vtex/node-error-report");
/**
* Headers that are interesting for tracing and debugging purposes
*/
exports.INTERESTING_HEADERS = [
// Request/Response Identification & Routing
'x-request-id',
'x-correlation-id',
'x-trace-id',
'x-span-id',
'x-forwarded-for',
'x-real-ip',
'host',
'referer',
// Content & Encoding
'content-type',
'content-length',
'content-encoding',
'accept',
'accept-encoding',
'accept-language',
// Caching & Performance
'cache-control',
'etag',
'if-none-match',
'expires',
'last-modified',
// Client Information
'user-agent',
'x-forwarded-proto',
'x-forwarded-host',
'x-forwarded-port',
// VTEX/E-commerce Specific (x-vtex-* headers are handled automatically)
'x-router-cache',
'x-powered-by-vtex-cache',
'jaeger-debug-id',
// API & Service Headers
'x-api-version',
'x-service-name',
'x-timeout',
'retry-after',
// Security (will be sanitized)
'authorization',
'cookie',
];
// Create the set once for performance
const INTERESTING_HEADERS_SET = new Set(exports.INTERESTING_HEADERS.map(h => h.toLowerCase()));
function getTraceInfo(span) {
var _a, _b;
const spanContext = span === null || span === void 0 ? void 0 : span.context();
return {
isSampled: (_b = (_a = spanContext === null || spanContext === void 0 ? void 0 : spanContext.isSampled) === null || _a === void 0 ? void 0 : _a.call(spanContext)) !== null && _b !== void 0 ? _b : false,
traceId: spanContext === null || spanContext === void 0 ? void 0 : spanContext.toTraceId(),
};
}
exports.getTraceInfo = getTraceInfo;
/**
* Do a shallow copy of a headers object and redacts sensitive information.
* Only includes headers that are in the INTERESTING_HEADERS whitelist.
*
* @param headersObj The headers object
* @param resultFieldsPrefix The prefix that will be added to each field on the result object
*/
const cloneAndSanitizeHeaders = (headersObj, resultFieldsPrefix = '') => {
const ret = {};
const entries = Object.entries(headersObj);
for (const [key, val] of entries) {
const lowerKey = key.toLowerCase();
// Only include headers that are in our whitelist or start with x-vtex-
if (!INTERESTING_HEADERS_SET.has(lowerKey) && !lowerKey.startsWith('x-vtex-')) {
continue;
}
// Most of the time val is a string, but there are some cases, for example when we do a axios interceptor,
// that a header field can contain an object, for example:
// ```
// "common": {
// "Accept": "application/json, text/plain, */*"
// },
// "delete": { },
// "get": { },
// "head": { },
// "post": {
// "Content-Type": "application/x-www-form-urlencoded"
// },
// ```
// In those corner cases we probably won't have a sensitive string as key, so we don't treat them here
ret[`${resultFieldsPrefix}${key}`] = node_error_report_1.authFields.includes(key) ? (0, node_error_report_1.sanitizeAuth)(val) : val;
}
return ret;
};
exports.cloneAndSanitizeHeaders = cloneAndSanitizeHeaders;