@multiplayer-app/session-recorder-common 0.0.3 → 0.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -100,6 +100,9 @@ exports.SessionRecorderHttpInstrumentationHooksNode = {
100
100
  else {
101
101
  responseBody = responseBuffer.toString('utf-8');
102
102
  }
103
+ if (responseBody.length) {
104
+ responseBody = JSON.parse(JSON.stringify(responseBody));
105
+ }
103
106
  if (!skipResponseBodyModification) {
104
107
  if (traceId.startsWith(constants_node_1.MULTIPLAYER_TRACE_DEBUG_PREFIX)
105
108
  && _options.isMaskBodyEnabled) {
@@ -121,14 +124,14 @@ exports.SessionRecorderHttpInstrumentationHooksNode = {
121
124
  const headers = (options.isMaskHeadersEnabled
122
125
  ? _options.maskHeaders(_response.getHeaders(), span)
123
126
  : _response.getHeaders()) || {};
124
- let _headers = {};
127
+ // Deep copy headers to prevent mutation of original object
128
+ const _headers = JSON.parse(JSON.stringify(headers));
125
129
  if (_options.headersToInclude) {
130
+ const filteredHeaders = {};
126
131
  for (const headerName of _options.headersToInclude) {
127
- _headers[headerName] = headers[headerName];
132
+ filteredHeaders[headerName] = _headers[headerName];
128
133
  }
129
- }
130
- else {
131
- _headers = JSON.parse(JSON.stringify(headers));
134
+ Object.assign(_headers, filteredHeaders);
132
135
  }
133
136
  if ((_a = _options.headersToExclude) === null || _a === void 0 ? void 0 : _a.length) {
134
137
  for (const headerName of _options.headersToExclude) {
@@ -163,14 +166,14 @@ exports.SessionRecorderHttpInstrumentationHooksNode = {
163
166
  const headers = (_options.isMaskHeadersEnabled
164
167
  ? _options.maskHeaders(_request.headers, span)
165
168
  : _request.headers) || {};
166
- let _headers = {};
169
+ // Deep copy headers to prevent mutation of original object
170
+ const _headers = JSON.parse(JSON.stringify(headers));
167
171
  if (_options.headersToInclude) {
172
+ const filteredHeaders = {};
168
173
  for (const headerName of _options.headersToInclude) {
169
- _headers[headerName] = headers[headerName];
174
+ filteredHeaders[headerName] = _headers[headerName];
170
175
  }
171
- }
172
- else {
173
- _headers = JSON.parse(JSON.stringify(headers));
176
+ Object.assign(_headers, filteredHeaders);
174
177
  }
175
178
  if ((_a = _options.headersToExclude) === null || _a === void 0 ? void 0 : _a.length) {
176
179
  for (const headerName of _options.headersToExclude) {
@@ -196,6 +199,7 @@ exports.SessionRecorderHttpInstrumentationHooksNode = {
196
199
  let requestBody = body;
197
200
  if (!requestBody)
198
201
  return;
202
+ requestBody = JSON.parse(JSON.stringify(requestBody));
199
203
  if (traceId.startsWith(constants_node_1.MULTIPLAYER_TRACE_DEBUG_PREFIX)
200
204
  && _options.isMaskBodyEnabled) {
201
205
  requestBody = _options.maskBody(requestBody, span);
@@ -1 +1 @@
1
- {"version":3,"file":"SessionRecorderHttpInstrumentationHooksNode.js","sourceRoot":"","sources":["../../src/SessionRecorderHttpInstrumentationHooksNode.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n IncomingMessage,\n ServerResponse,\n ClientRequest,\n} from 'http'\nimport * as zlib from 'zlib'\nimport type { Span } from '@opentelemetry/api'\nimport {\n ATTR_MULTIPLAYER_HTTP_REQUEST_BODY,\n ATTR_MULTIPLAYER_HTTP_REQUEST_HEADERS,\n ATTR_MULTIPLAYER_HTTP_RESPONSE_BODY,\n ATTR_MULTIPLAYER_HTTP_RESPONSE_HEADERS,\n MULTIPLAYER_MAX_HTTP_REQUEST_RESPONSE_SIZE,\n ATTR_MULTIPLAYER_HTTP_RESPONSE_BODY_ENCODING,\n MULTIPLAYER_TRACE_DEBUG_PREFIX,\n MULTIPLAYER_TRACE_DOC_PREFIX\n} from './constants.node'\nimport {\n mask,\n schemify,\n isGzip,\n} from './sdk'\nimport {\n sensitiveFields,\n sensitiveHeaders\n} from './sdk/mask'\n\ninterface HttpResponseHookOptions {\n maxPayloadSizeBytes?: number\n schemifyDocSpanPayload?: boolean\n uncompressPayload?: boolean\n\n captureHeaders?: boolean\n captureBody?: boolean\n\n isMaskBodyEnabled?: boolean\n isMaskHeadersEnabled?: boolean\n\n maskBody?: (arg: any, span: Span) => any\n maskHeaders?: (arg: any, span: Span) => any\n\n maskBodyFieldsList?: string[]\n maskHeadersList?: string[]\n\n headersToInclude?: string[]\n headersToExclude?: string[]\n}\n\ninterface HttpRequestHookOptions {\n maxPayloadSizeBytes?: number\n schemifyDocSpanPayload?: boolean\n\n captureHeaders?: boolean\n captureBody?: boolean\n\n isMaskBodyEnabled?: boolean\n isMaskHeadersEnabled?: boolean\n\n maskBody?: (arg: any, span: Span) => any\n maskHeaders?: (arg: any, span: Span) => any\n\n maskBodyFieldsList?: string[]\n maskHeadersList?: string[]\n\n headersToInclude?: string[]\n headersToExclude?: string[]\n}\n\nconst setDefaultOptions = (\n options: HttpResponseHookOptions | HttpResponseHookOptions\n): Omit<HttpResponseHookOptions & HttpResponseHookOptions, 'maskBody' | 'maskHeaders'>\n & {\n maskBody: (arg: any, span: Span) => any\n maskHeaders: (arg: any, span: Span) => any\n captureHeaders: boolean,\n captureBody: boolean,\n isMaskBodyEnabled: boolean\n isMaskHeadersEnabled: boolean\n schemifyDocSpanPayload: boolean,\n uncompressPayload: boolean,\n maxPayloadSizeBytes: number\n } => {\n options.captureHeaders = 'captureHeaders' in options\n ? options.captureHeaders\n : true\n options.captureBody = 'captureBody' in options\n ? options.captureBody\n : true\n options.isMaskBodyEnabled = 'isMaskBodyEnabled' in options\n ? options.isMaskBodyEnabled\n : true\n options.isMaskHeadersEnabled = 'isMaskHeadersEnabled' in options\n ? options.isMaskHeadersEnabled\n : true\n options.schemifyDocSpanPayload = 'schemifyDocSpanPayload' in options\n ? options.schemifyDocSpanPayload\n : false\n options.uncompressPayload = 'uncompressPayload' in options\n ? options.uncompressPayload\n : true\n options.maskBody = options.maskBody || mask([\n ...(\n Array.isArray(options.maskBodyFieldsList)\n ? options.maskBodyFieldsList\n : sensitiveFields\n ),\n ...(\n Array.isArray(options.maskHeadersList)\n ? options.maskHeadersList\n : sensitiveHeaders\n ),\n ])\n options.maskHeaders = options.maskHeaders || mask([\n ...(\n Array.isArray(options.maskBodyFieldsList)\n ? options.maskBodyFieldsList\n : sensitiveFields\n ),\n ...(\n Array.isArray(options.maskHeadersList)\n ? options.maskHeadersList\n : sensitiveHeaders\n ),\n ])\n options.maxPayloadSizeBytes = options.maxPayloadSizeBytes || MULTIPLAYER_MAX_HTTP_REQUEST_RESPONSE_SIZE\n\n return options as Omit<HttpResponseHookOptions & HttpResponseHookOptions, 'maskBody' | 'maskHeaders'>\n & {\n maskBody: (arg: any, span: Span) => any\n maskHeaders: (arg: any, span: Span) => any\n captureHeaders: boolean,\n captureBody: boolean,\n isMaskBodyEnabled: boolean,\n isMaskHeadersEnabled: boolean,\n schemifyDocSpanPayload: boolean,\n uncompressPayload: boolean,\n maxPayloadSizeBytes: number\n }\n}\n\nexport const SessionRecorderHttpInstrumentationHooksNode = {\n responseHook: (options: HttpResponseHookOptions = {}) =>\n (span: Span, response: IncomingMessage | ServerResponse) => {\n try {\n const _options = setDefaultOptions(options)\n\n if (!_options.captureBody && !_options.captureHeaders) {\n return\n }\n\n const _response = response as ServerResponse\n const traceId = span.spanContext().traceId\n\n if (_response.setHeader) {\n _response.setHeader('X-Trace-Id', traceId)\n }\n\n const [oldWrite, oldEnd] = [_response.write, _response.end]\n\n const chunks: Buffer[] = [];\n\n if (_options.captureBody) {\n (_response.write as unknown) = function (...restArgs: any[]) {\n chunks.push(Buffer.from(restArgs[0]))\n // eslint-disable-next-line\n // @ts-ignore\n oldWrite.apply(_response, restArgs)\n }\n }\n\n // eslint-disable-next-line\n // @ts-ignore\n _response.end = async function (...restArgs) {\n if (_options.captureBody && restArgs[0]) {\n chunks.push(Buffer.from(restArgs[0]))\n }\n\n const responseBuffer = Buffer.concat(chunks)\n\n if (\n _options.captureBody\n && responseBuffer.byteLength > 0\n && responseBuffer.byteLength < _options.maxPayloadSizeBytes\n ) {\n let responseBody: string\n let skipResponseBodyModification = false\n\n if (isGzip(responseBuffer)) {\n if (_options.uncompressPayload) {\n const dezippedBuffer = await new Promise((resolve) => zlib\n .gunzip(responseBuffer, function (err, dezipped) {\n if (err) {\n return resolve(Buffer.from(''))\n } else {\n return resolve(dezipped)\n }\n })) as Buffer\n responseBody = dezippedBuffer.toString('utf-8')\n } else {\n span.setAttribute(\n ATTR_MULTIPLAYER_HTTP_RESPONSE_BODY_ENCODING,\n 'gzip',\n )\n\n skipResponseBodyModification = true\n responseBody = responseBuffer.toString('hex')\n }\n } else {\n responseBody = responseBuffer.toString('utf-8')\n }\n\n if (!skipResponseBodyModification) {\n if (\n traceId.startsWith(MULTIPLAYER_TRACE_DEBUG_PREFIX)\n && _options.isMaskBodyEnabled\n ) {\n responseBody = _options.maskBody(responseBody, span)\n } else if (\n traceId.startsWith(MULTIPLAYER_TRACE_DOC_PREFIX)\n && _options.schemifyDocSpanPayload\n ) {\n responseBody = schemify(responseBody)\n } else if (typeof responseBody !== 'string') {\n responseBody = JSON.stringify(responseBody)\n }\n }\n\n if (responseBody.length) {\n span.setAttribute(\n ATTR_MULTIPLAYER_HTTP_RESPONSE_BODY,\n responseBody,\n )\n }\n }\n\n if (_options.captureHeaders) {\n const headers = (options.isMaskHeadersEnabled\n ? _options.maskHeaders(_response.getHeaders(), span)\n : _response.getHeaders()) || {}\n\n let _headers: any = {}\n\n\n if (_options.headersToInclude) {\n for (const headerName of _options.headersToInclude) {\n _headers[headerName] = headers[headerName]\n }\n } else {\n _headers = JSON.parse(JSON.stringify(headers))\n }\n\n if (_options.headersToExclude?.length) {\n for (const headerName of _options.headersToExclude) {\n delete _headers[headerName]\n }\n }\n\n const stringifiedHeaders = JSON.stringify(_headers)\n\n if (stringifiedHeaders?.length) {\n span.setAttribute(\n ATTR_MULTIPLAYER_HTTP_RESPONSE_HEADERS,\n stringifiedHeaders,\n )\n }\n }\n\n // eslint-disable-next-line\n // @ts-ignore\n return oldEnd.apply(_response, restArgs)\n }\n } catch (error) {\n // eslint-disable-next-line\n console.error('An error occured in multiplayer otlp http responseHook', error)\n }\n },\n requestHook: (options: HttpRequestHookOptions = {}) =>\n (span: Span, request: ClientRequest | IncomingMessage) => {\n try {\n const _options = setDefaultOptions(options)\n\n if (!_options.captureBody && !_options.captureHeaders) {\n return\n }\n\n const traceId = span.spanContext().traceId\n const _request = request as IncomingMessage\n\n if (_options.captureHeaders) {\n const headers = (_options.isMaskHeadersEnabled\n ? _options.maskHeaders(_request.headers, span)\n : _request.headers) || {}\n let _headers: any = {}\n\n if (_options.headersToInclude) {\n for (const headerName of _options.headersToInclude) {\n _headers[headerName] = headers[headerName]\n }\n } else {\n _headers = JSON.parse(JSON.stringify(headers))\n }\n\n if (_options.headersToExclude?.length) {\n for (const headerName of _options.headersToExclude) {\n delete _headers[headerName]\n }\n }\n\n span.setAttribute(\n ATTR_MULTIPLAYER_HTTP_REQUEST_HEADERS,\n JSON.stringify(_headers),\n )\n }\n\n const contentType = _request?.headers?.['content-type']\n if (\n _options.captureBody\n && contentType?.includes('application/json')\n ) {\n let body = ''\n _request.on('data', (chunk) => {\n body += chunk\n })\n _request.on('end', () => {\n try {\n const requestBodySizeBytes = Buffer.byteLength(body, 'utf8')\n\n if (\n requestBodySizeBytes === 0\n || requestBodySizeBytes > _options.maxPayloadSizeBytes\n ) {\n return\n }\n\n let requestBody = body\n if (!requestBody) return\n\n if (\n traceId.startsWith(MULTIPLAYER_TRACE_DEBUG_PREFIX)\n && _options.isMaskBodyEnabled\n ) {\n requestBody = _options.maskBody(requestBody, span)\n } else if (\n traceId.startsWith(MULTIPLAYER_TRACE_DOC_PREFIX)\n && _options.schemifyDocSpanPayload\n ) {\n requestBody = schemify(requestBody)\n } else if (typeof requestBody !== 'string') {\n requestBody = JSON.stringify(requestBody)\n }\n\n if (requestBody?.length) {\n span.setAttribute(\n ATTR_MULTIPLAYER_HTTP_REQUEST_BODY,\n requestBody,\n )\n }\n } catch (err) {\n // eslint-disable-next-line\n console.error('[MULTIPLAYER-HTTP-REQ-HOOK] An error occured in multiplayer otlp http requestHook', err)\n }\n })\n }\n\n } catch (error) {\n // eslint-disable-next-line\n console.error('An error occured in multiplayer otlp http requestHook', error)\n }\n },\n}\n"]}
1
+ {"version":3,"file":"SessionRecorderHttpInstrumentationHooksNode.js","sourceRoot":"","sources":["../../src/SessionRecorderHttpInstrumentationHooksNode.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n IncomingMessage,\n ServerResponse,\n ClientRequest,\n} from 'http'\nimport * as zlib from 'zlib'\nimport type { Span } from '@opentelemetry/api'\nimport {\n ATTR_MULTIPLAYER_HTTP_REQUEST_BODY,\n ATTR_MULTIPLAYER_HTTP_REQUEST_HEADERS,\n ATTR_MULTIPLAYER_HTTP_RESPONSE_BODY,\n ATTR_MULTIPLAYER_HTTP_RESPONSE_HEADERS,\n MULTIPLAYER_MAX_HTTP_REQUEST_RESPONSE_SIZE,\n ATTR_MULTIPLAYER_HTTP_RESPONSE_BODY_ENCODING,\n MULTIPLAYER_TRACE_DEBUG_PREFIX,\n MULTIPLAYER_TRACE_DOC_PREFIX\n} from './constants.node'\nimport {\n mask,\n schemify,\n isGzip,\n} from './sdk'\nimport {\n sensitiveFields,\n sensitiveHeaders\n} from './sdk/mask'\n\ninterface HttpResponseHookOptions {\n maxPayloadSizeBytes?: number\n schemifyDocSpanPayload?: boolean\n uncompressPayload?: boolean\n\n captureHeaders?: boolean\n captureBody?: boolean\n\n isMaskBodyEnabled?: boolean\n isMaskHeadersEnabled?: boolean\n\n maskBody?: (arg: any, span: Span) => any\n maskHeaders?: (arg: any, span: Span) => any\n\n maskBodyFieldsList?: string[]\n maskHeadersList?: string[]\n\n headersToInclude?: string[]\n headersToExclude?: string[]\n}\n\ninterface HttpRequestHookOptions {\n maxPayloadSizeBytes?: number\n schemifyDocSpanPayload?: boolean\n\n captureHeaders?: boolean\n captureBody?: boolean\n\n isMaskBodyEnabled?: boolean\n isMaskHeadersEnabled?: boolean\n\n maskBody?: (arg: any, span: Span) => any\n maskHeaders?: (arg: any, span: Span) => any\n\n maskBodyFieldsList?: string[]\n maskHeadersList?: string[]\n\n headersToInclude?: string[]\n headersToExclude?: string[]\n}\n\nconst setDefaultOptions = (\n options: HttpResponseHookOptions | HttpResponseHookOptions\n): Omit<HttpResponseHookOptions & HttpResponseHookOptions, 'maskBody' | 'maskHeaders'>\n & {\n maskBody: (arg: any, span: Span) => any\n maskHeaders: (arg: any, span: Span) => any\n captureHeaders: boolean,\n captureBody: boolean,\n isMaskBodyEnabled: boolean\n isMaskHeadersEnabled: boolean\n schemifyDocSpanPayload: boolean,\n uncompressPayload: boolean,\n maxPayloadSizeBytes: number\n } => {\n options.captureHeaders = 'captureHeaders' in options\n ? options.captureHeaders\n : true\n options.captureBody = 'captureBody' in options\n ? options.captureBody\n : true\n options.isMaskBodyEnabled = 'isMaskBodyEnabled' in options\n ? options.isMaskBodyEnabled\n : true\n options.isMaskHeadersEnabled = 'isMaskHeadersEnabled' in options\n ? options.isMaskHeadersEnabled\n : true\n options.schemifyDocSpanPayload = 'schemifyDocSpanPayload' in options\n ? options.schemifyDocSpanPayload\n : false\n options.uncompressPayload = 'uncompressPayload' in options\n ? options.uncompressPayload\n : true\n options.maskBody = options.maskBody || mask([\n ...(\n Array.isArray(options.maskBodyFieldsList)\n ? options.maskBodyFieldsList\n : sensitiveFields\n ),\n ...(\n Array.isArray(options.maskHeadersList)\n ? options.maskHeadersList\n : sensitiveHeaders\n ),\n ])\n options.maskHeaders = options.maskHeaders || mask([\n ...(\n Array.isArray(options.maskBodyFieldsList)\n ? options.maskBodyFieldsList\n : sensitiveFields\n ),\n ...(\n Array.isArray(options.maskHeadersList)\n ? options.maskHeadersList\n : sensitiveHeaders\n ),\n ])\n options.maxPayloadSizeBytes = options.maxPayloadSizeBytes || MULTIPLAYER_MAX_HTTP_REQUEST_RESPONSE_SIZE\n\n return options as Omit<HttpResponseHookOptions & HttpResponseHookOptions, 'maskBody' | 'maskHeaders'>\n & {\n maskBody: (arg: any, span: Span) => any\n maskHeaders: (arg: any, span: Span) => any\n captureHeaders: boolean,\n captureBody: boolean,\n isMaskBodyEnabled: boolean,\n isMaskHeadersEnabled: boolean,\n schemifyDocSpanPayload: boolean,\n uncompressPayload: boolean,\n maxPayloadSizeBytes: number\n }\n}\n\nexport const SessionRecorderHttpInstrumentationHooksNode = {\n responseHook: (options: HttpResponseHookOptions = {}) =>\n (span: Span, response: IncomingMessage | ServerResponse) => {\n try {\n const _options = setDefaultOptions(options)\n\n if (!_options.captureBody && !_options.captureHeaders) {\n return\n }\n\n const _response = response as ServerResponse\n const traceId = span.spanContext().traceId\n\n if (_response.setHeader) {\n _response.setHeader('X-Trace-Id', traceId)\n }\n\n const [oldWrite, oldEnd] = [_response.write, _response.end]\n\n const chunks: Buffer[] = [];\n\n if (_options.captureBody) {\n (_response.write as unknown) = function (...restArgs: any[]) {\n chunks.push(Buffer.from(restArgs[0]))\n // eslint-disable-next-line\n // @ts-ignore\n oldWrite.apply(_response, restArgs)\n }\n }\n\n // eslint-disable-next-line\n // @ts-ignore\n _response.end = async function (...restArgs) {\n if (_options.captureBody && restArgs[0]) {\n chunks.push(Buffer.from(restArgs[0]))\n }\n\n const responseBuffer = Buffer.concat(chunks)\n\n if (\n _options.captureBody\n && responseBuffer.byteLength > 0\n && responseBuffer.byteLength < _options.maxPayloadSizeBytes\n ) {\n let responseBody: string\n let skipResponseBodyModification = false\n\n if (isGzip(responseBuffer)) {\n if (_options.uncompressPayload) {\n const dezippedBuffer = await new Promise((resolve) => zlib\n .gunzip(responseBuffer, function (err, dezipped) {\n if (err) {\n return resolve(Buffer.from(''))\n } else {\n return resolve(dezipped)\n }\n })) as Buffer\n responseBody = dezippedBuffer.toString('utf-8')\n } else {\n span.setAttribute(\n ATTR_MULTIPLAYER_HTTP_RESPONSE_BODY_ENCODING,\n 'gzip',\n )\n\n skipResponseBodyModification = true\n responseBody = responseBuffer.toString('hex')\n }\n } else {\n responseBody = responseBuffer.toString('utf-8')\n }\n\n if (responseBody.length) {\n responseBody = JSON.parse(JSON.stringify(responseBody))\n }\n\n if (!skipResponseBodyModification) {\n if (\n traceId.startsWith(MULTIPLAYER_TRACE_DEBUG_PREFIX)\n && _options.isMaskBodyEnabled\n ) {\n responseBody = _options.maskBody(responseBody, span)\n } else if (\n traceId.startsWith(MULTIPLAYER_TRACE_DOC_PREFIX)\n && _options.schemifyDocSpanPayload\n ) {\n responseBody = schemify(responseBody)\n } else if (typeof responseBody !== 'string') {\n responseBody = JSON.stringify(responseBody)\n }\n }\n\n if (responseBody.length) {\n span.setAttribute(\n ATTR_MULTIPLAYER_HTTP_RESPONSE_BODY,\n responseBody,\n )\n }\n }\n\n if (_options.captureHeaders) {\n const headers = (options.isMaskHeadersEnabled\n ? _options.maskHeaders(_response.getHeaders(), span)\n : _response.getHeaders()) || {}\n\n // Deep copy headers to prevent mutation of original object\n const _headers = JSON.parse(JSON.stringify(headers))\n\n if (_options.headersToInclude) {\n const filteredHeaders: any = {}\n for (const headerName of _options.headersToInclude) {\n filteredHeaders[headerName] = _headers[headerName]\n }\n Object.assign(_headers, filteredHeaders)\n }\n\n if (_options.headersToExclude?.length) {\n for (const headerName of _options.headersToExclude) {\n delete _headers[headerName]\n }\n }\n\n const stringifiedHeaders = JSON.stringify(_headers)\n\n if (stringifiedHeaders?.length) {\n span.setAttribute(\n ATTR_MULTIPLAYER_HTTP_RESPONSE_HEADERS,\n stringifiedHeaders,\n )\n }\n }\n\n // eslint-disable-next-line\n // @ts-ignore\n return oldEnd.apply(_response, restArgs)\n }\n } catch (error) {\n // eslint-disable-next-line\n console.error('An error occured in multiplayer otlp http responseHook', error)\n }\n },\n requestHook: (options: HttpRequestHookOptions = {}) =>\n (span: Span, request: ClientRequest | IncomingMessage) => {\n try {\n const _options = setDefaultOptions(options)\n\n if (!_options.captureBody && !_options.captureHeaders) {\n return\n }\n\n const traceId = span.spanContext().traceId\n const _request = request as IncomingMessage\n\n if (_options.captureHeaders) {\n const headers = (_options.isMaskHeadersEnabled\n ? _options.maskHeaders(_request.headers, span)\n : _request.headers) || {}\n // Deep copy headers to prevent mutation of original object\n const _headers = JSON.parse(JSON.stringify(headers))\n\n if (_options.headersToInclude) {\n const filteredHeaders: any = {}\n for (const headerName of _options.headersToInclude) {\n filteredHeaders[headerName] = _headers[headerName]\n }\n Object.assign(_headers, filteredHeaders)\n }\n\n if (_options.headersToExclude?.length) {\n for (const headerName of _options.headersToExclude) {\n delete _headers[headerName]\n }\n }\n\n span.setAttribute(\n ATTR_MULTIPLAYER_HTTP_REQUEST_HEADERS,\n JSON.stringify(_headers),\n )\n }\n\n const contentType = _request?.headers?.['content-type']\n if (\n _options.captureBody\n && contentType?.includes('application/json')\n ) {\n let body = ''\n _request.on('data', (chunk) => {\n body += chunk\n })\n _request.on('end', () => {\n try {\n const requestBodySizeBytes = Buffer.byteLength(body, 'utf8')\n\n if (\n requestBodySizeBytes === 0\n || requestBodySizeBytes > _options.maxPayloadSizeBytes\n ) {\n return\n }\n\n let requestBody = body\n if (!requestBody) return\n\n requestBody = JSON.parse(JSON.stringify(requestBody))\n\n if (\n traceId.startsWith(MULTIPLAYER_TRACE_DEBUG_PREFIX)\n && _options.isMaskBodyEnabled\n ) {\n requestBody = _options.maskBody(requestBody, span)\n } else if (\n traceId.startsWith(MULTIPLAYER_TRACE_DOC_PREFIX)\n && _options.schemifyDocSpanPayload\n ) {\n requestBody = schemify(requestBody)\n } else if (typeof requestBody !== 'string') {\n requestBody = JSON.stringify(requestBody)\n }\n\n if (requestBody?.length) {\n span.setAttribute(\n ATTR_MULTIPLAYER_HTTP_REQUEST_BODY,\n requestBody,\n )\n }\n } catch (err) {\n // eslint-disable-next-line\n console.error('[MULTIPLAYER-HTTP-REQ-HOOK] An error occured in multiplayer otlp http requestHook', err)\n }\n })\n }\n\n } catch (error) {\n // eslint-disable-next-line\n console.error('An error occured in multiplayer otlp http requestHook', error)\n }\n },\n}\n"]}
@@ -1,6 +1,6 @@
1
1
  import type { Span } from '@opentelemetry/api';
2
2
  export declare const sensitiveFields: string[];
3
3
  export declare const sensitiveHeaders: string[];
4
- declare const _default: (keysToMask?: string[]) => (value: any, span: Span) => any;
4
+ declare const _default: (keysToMask?: string[]) => (value: any, span?: Span) => any;
5
5
  export default _default;
6
6
  //# sourceMappingURL=mask.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"mask.d.ts","sourceRoot":"","sources":["../../../src/sdk/mask.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAA;AAI9C,eAAO,MAAM,eAAe,EAAE,MAAM,EAoEnC,CAAA;AAED,eAAO,MAAM,gBAAgB,EAAE,MAAM,EAKpC,CAAA;yBA+De,aAAY,MAAM,EAAO,MAAM,OAAO,GAAG,EAAE,MAAM,IAAI,KAAG,GAAG;AAA3E,wBAkBC"}
1
+ {"version":3,"file":"mask.d.ts","sourceRoot":"","sources":["../../../src/sdk/mask.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAA;AAI9C,eAAO,MAAM,eAAe,EAAE,MAAM,EAoEnC,CAAA;AAED,eAAO,MAAM,gBAAgB,EAAE,MAAM,EAKpC,CAAA;yBA+De,aAAY,MAAM,EAAO,MAAM,OAAO,GAAG,EAAE,OAAO,IAAI,KAAG,GAAG;AAA5E,wBAkBC"}
@@ -1 +1 @@
1
- {"version":3,"file":"mask.js","sourceRoot":"","sources":["../../../src/sdk/mask.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Span } from '@opentelemetry/api'\nimport { MASK_PLACEHOLDER } from '../constants.base'\n\nconst MAX_DEPTH = 8\nexport const sensitiveFields: string[] = [\n 'password',\n 'pass',\n 'passwd',\n 'pwd',\n 'token',\n 'access_token',\n 'accessToken',\n 'refresh_token',\n 'refreshToken',\n 'secret',\n 'api_key',\n 'apiKey',\n 'authorization',\n 'auth_token',\n 'authToken',\n 'jwt',\n 'session_id',\n 'sessionId',\n 'sessionToken',\n 'client_secret',\n 'clientSecret',\n 'private_key',\n 'privateKey',\n 'public_key',\n 'publicKey',\n 'key',\n 'encryption_key',\n 'encryptionKey',\n 'credit_card',\n 'creditCard',\n 'card_number',\n 'cardNumber',\n 'cvv',\n 'cvc',\n 'ssn',\n 'sin',\n 'pin',\n 'security_code',\n 'securityCode',\n 'bank_account',\n 'bankAccount',\n 'iban',\n 'swift',\n 'bic',\n 'routing_number',\n 'routingNumber',\n 'license_key',\n 'licenseKey',\n 'otp',\n 'mfa_code',\n 'mfaCode',\n 'phone_number',\n 'phoneNumber',\n 'email',\n 'address',\n 'dob',\n 'tax_id',\n 'taxId',\n 'passport_number',\n 'passportNumber',\n 'driver_license',\n 'driverLicense',\n\n 'set-cookie',\n 'cookie',\n 'authorization',\n 'proxyAuthorization',\n]\n\nexport const sensitiveHeaders: string[] = [\n 'set-cookie',\n 'cookie',\n 'authorization',\n 'proxyAuthorization',\n]\n\nconst maskAll = (value: any, depth = 0) => {\n const type = typeof value\n const isObject = type === 'object'\n let isArray = false\n\n if (Array.isArray(value)) {\n isArray = true\n }\n\n if (depth > MAX_DEPTH && (isObject || isArray)) {\n return undefined\n }\n\n if (isArray) {\n return value.map((val: any) => maskAll(val, depth + 1), value)\n }\n\n if (isObject) {\n for (const key in value) {\n value[key] = maskAll(value[key], depth + 1)\n }\n\n return value\n }\n\n if (type === 'string') {\n return MASK_PLACEHOLDER\n }\n\n return value\n}\n\nconst maskSelected = (value: any, keysToMask: string[]): any => {\n const type = typeof value\n const isObject = type === 'object'\n\n const _keysToMask = new Set(keysToMask)\n\n if (Array.isArray(value)) {\n return value.map((val: any) => maskSelected(val, keysToMask), value)\n }\n\n if (isObject) {\n for (const key in value) {\n if (_keysToMask.has(key)) {\n value[key] = MASK_PLACEHOLDER\n } else {\n value[key] = maskSelected(value[key],keysToMask)\n }\n }\n\n return value\n }\n\n if (type === 'string') {\n return value\n }\n\n return value\n}\n\nexport default (keysToMask: string[] = []) => (value: any, span: Span): any => {\n let payloadJson\n try {\n payloadJson = JSON.parse(value)\n } catch {\n payloadJson = value\n }\n let maskedData\n if (keysToMask.length) {\n maskedData = maskSelected(payloadJson, keysToMask)\n } else {\n maskedData = maskAll(payloadJson)\n }\n if (typeof maskedData !== 'string') {\n maskedData = JSON.stringify(maskedData)\n }\n\n return maskedData\n}\n"]}
1
+ {"version":3,"file":"mask.js","sourceRoot":"","sources":["../../../src/sdk/mask.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Span } from '@opentelemetry/api'\nimport { MASK_PLACEHOLDER } from '../constants.base'\n\nconst MAX_DEPTH = 8\nexport const sensitiveFields: string[] = [\n 'password',\n 'pass',\n 'passwd',\n 'pwd',\n 'token',\n 'access_token',\n 'accessToken',\n 'refresh_token',\n 'refreshToken',\n 'secret',\n 'api_key',\n 'apiKey',\n 'authorization',\n 'auth_token',\n 'authToken',\n 'jwt',\n 'session_id',\n 'sessionId',\n 'sessionToken',\n 'client_secret',\n 'clientSecret',\n 'private_key',\n 'privateKey',\n 'public_key',\n 'publicKey',\n 'key',\n 'encryption_key',\n 'encryptionKey',\n 'credit_card',\n 'creditCard',\n 'card_number',\n 'cardNumber',\n 'cvv',\n 'cvc',\n 'ssn',\n 'sin',\n 'pin',\n 'security_code',\n 'securityCode',\n 'bank_account',\n 'bankAccount',\n 'iban',\n 'swift',\n 'bic',\n 'routing_number',\n 'routingNumber',\n 'license_key',\n 'licenseKey',\n 'otp',\n 'mfa_code',\n 'mfaCode',\n 'phone_number',\n 'phoneNumber',\n 'email',\n 'address',\n 'dob',\n 'tax_id',\n 'taxId',\n 'passport_number',\n 'passportNumber',\n 'driver_license',\n 'driverLicense',\n\n 'set-cookie',\n 'cookie',\n 'authorization',\n 'proxyAuthorization',\n]\n\nexport const sensitiveHeaders: string[] = [\n 'set-cookie',\n 'cookie',\n 'authorization',\n 'proxyAuthorization',\n]\n\nconst maskAll = (value: any, depth = 0) => {\n const type = typeof value\n const isObject = type === 'object'\n let isArray = false\n\n if (Array.isArray(value)) {\n isArray = true\n }\n\n if (depth > MAX_DEPTH && (isObject || isArray)) {\n return undefined\n }\n\n if (isArray) {\n return value.map((val: any) => maskAll(val, depth + 1), value)\n }\n\n if (isObject) {\n for (const key in value) {\n value[key] = maskAll(value[key], depth + 1)\n }\n\n return value\n }\n\n if (type === 'string') {\n return MASK_PLACEHOLDER\n }\n\n return value\n}\n\nconst maskSelected = (value: any, keysToMask: string[]): any => {\n const type = typeof value\n const isObject = type === 'object'\n\n const _keysToMask = new Set(keysToMask)\n\n if (Array.isArray(value)) {\n return value.map((val: any) => maskSelected(val, keysToMask), value)\n }\n\n if (isObject) {\n for (const key in value) {\n if (_keysToMask.has(key)) {\n value[key] = MASK_PLACEHOLDER\n } else {\n value[key] = maskSelected(value[key], keysToMask)\n }\n }\n\n return value\n }\n\n if (type === 'string') {\n return value\n }\n\n return value\n}\n\nexport default (keysToMask: string[] = []) => (value: any, span?: Span): any => {\n let payloadJson\n try {\n payloadJson = JSON.parse(value)\n } catch {\n payloadJson = value\n }\n let maskedData\n if (keysToMask.length) {\n maskedData = maskSelected(payloadJson, keysToMask)\n } else {\n maskedData = maskAll(payloadJson)\n }\n if (typeof maskedData !== 'string') {\n maskedData = JSON.stringify(maskedData)\n }\n\n return maskedData\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@multiplayer-app/session-recorder-common",
3
- "version": "0.0.3",
3
+ "version": "0.0.8",
4
4
  "description": "Multiplayer Fullstack Session Recorder - opentelemetry",
5
5
  "author": {
6
6
  "name": "Multiplayer Software, Inc.",
@@ -30,7 +30,7 @@
30
30
  "lint": "eslint src/**/*.ts --config ../../.eslintrc",
31
31
  "preversion": "npm run lint",
32
32
  "postversion:skip": "git push && git push --tags",
33
- "build": "tsc --build tsconfig.json tsconfig.esm.json tsconfig.esnext.json",
33
+ "build": "rm -rf dist tsconfig.tsbuildinfo && tsc --build tsconfig.json tsconfig.esm.json tsconfig.esnext.json",
34
34
  "prepublishOnly": "npm run build"
35
35
  },
36
36
  "peerDependencies": {
@@ -209,6 +209,10 @@ export const SessionRecorderHttpInstrumentationHooksNode = {
209
209
  responseBody = responseBuffer.toString('utf-8')
210
210
  }
211
211
 
212
+ if (responseBody.length) {
213
+ responseBody = JSON.parse(JSON.stringify(responseBody))
214
+ }
215
+
212
216
  if (!skipResponseBodyModification) {
213
217
  if (
214
218
  traceId.startsWith(MULTIPLAYER_TRACE_DEBUG_PREFIX)
@@ -238,15 +242,15 @@ export const SessionRecorderHttpInstrumentationHooksNode = {
238
242
  ? _options.maskHeaders(_response.getHeaders(), span)
239
243
  : _response.getHeaders()) || {}
240
244
 
241
- let _headers: any = {}
242
-
245
+ // Deep copy headers to prevent mutation of original object
246
+ const _headers = JSON.parse(JSON.stringify(headers))
243
247
 
244
248
  if (_options.headersToInclude) {
249
+ const filteredHeaders: any = {}
245
250
  for (const headerName of _options.headersToInclude) {
246
- _headers[headerName] = headers[headerName]
251
+ filteredHeaders[headerName] = _headers[headerName]
247
252
  }
248
- } else {
249
- _headers = JSON.parse(JSON.stringify(headers))
253
+ Object.assign(_headers, filteredHeaders)
250
254
  }
251
255
 
252
256
  if (_options.headersToExclude?.length) {
@@ -290,14 +294,15 @@ export const SessionRecorderHttpInstrumentationHooksNode = {
290
294
  const headers = (_options.isMaskHeadersEnabled
291
295
  ? _options.maskHeaders(_request.headers, span)
292
296
  : _request.headers) || {}
293
- let _headers: any = {}
297
+ // Deep copy headers to prevent mutation of original object
298
+ const _headers = JSON.parse(JSON.stringify(headers))
294
299
 
295
300
  if (_options.headersToInclude) {
301
+ const filteredHeaders: any = {}
296
302
  for (const headerName of _options.headersToInclude) {
297
- _headers[headerName] = headers[headerName]
303
+ filteredHeaders[headerName] = _headers[headerName]
298
304
  }
299
- } else {
300
- _headers = JSON.parse(JSON.stringify(headers))
305
+ Object.assign(_headers, filteredHeaders)
301
306
  }
302
307
 
303
308
  if (_options.headersToExclude?.length) {
@@ -335,6 +340,8 @@ export const SessionRecorderHttpInstrumentationHooksNode = {
335
340
  let requestBody = body
336
341
  if (!requestBody) return
337
342
 
343
+ requestBody = JSON.parse(JSON.stringify(requestBody))
344
+
338
345
  if (
339
346
  traceId.startsWith(MULTIPLAYER_TRACE_DEBUG_PREFIX)
340
347
  && _options.isMaskBodyEnabled
package/src/sdk/mask.ts CHANGED
@@ -126,7 +126,7 @@ const maskSelected = (value: any, keysToMask: string[]): any => {
126
126
  if (_keysToMask.has(key)) {
127
127
  value[key] = MASK_PLACEHOLDER
128
128
  } else {
129
- value[key] = maskSelected(value[key],keysToMask)
129
+ value[key] = maskSelected(value[key], keysToMask)
130
130
  }
131
131
  }
132
132
 
@@ -140,7 +140,7 @@ const maskSelected = (value: any, keysToMask: string[]): any => {
140
140
  return value
141
141
  }
142
142
 
143
- export default (keysToMask: string[] = []) => (value: any, span: Span): any => {
143
+ export default (keysToMask: string[] = []) => (value: any, span?: Span): any => {
144
144
  let payloadJson
145
145
  try {
146
146
  payloadJson = JSON.parse(value)