UNPKG

@vtex/api

Version:
95 lines (94 loc) 3.44 kB
"use strict"; 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;