Skip to main content
Glama
config.js10.1 kB
var __assign = (this && this.__assign) || function () { __assign = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; var __read = (this && this.__read) || function (o, n) { var m = typeof Symbol === "function" && o[Symbol.iterator]; if (!m) return o; var i = m.call(o), r, ar = [], e; try { while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); } catch (error) { e = { error: error }; } finally { try { if (r && !r.done && (m = i["return"])) m.call(i); } finally { if (e) throw e.error; } } return ar; }; var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) { if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { if (ar || !(i in from)) { if (!ar) ar = Array.prototype.slice.call(from, 0, i); ar[i] = from[i]; } } return to.concat(ar || Array.prototype.slice.call(from)); }; import { isFunction, isNullish, isString, isUndefined } from '../../utils/type-utils'; import { convertToURL } from '../../utils/request-utils'; import { logger } from '../../utils/logger'; import { shouldCaptureValue } from '../../autocapture-utils'; import { each } from '../../utils'; var LOGGER_PREFIX = '[SessionRecording]'; var REDACTED = 'redacted'; export var defaultNetworkOptions = { initiatorTypes: [ 'audio', 'beacon', 'body', 'css', 'early-hint', 'embed', 'fetch', 'frame', 'iframe', 'icon', 'image', 'img', 'input', 'link', 'navigation', 'object', 'ping', 'script', 'track', 'video', 'xmlhttprequest', ], maskRequestFn: function (data) { return data; }, recordHeaders: false, recordBody: false, recordInitialRequests: false, recordPerformance: false, performanceEntryTypeToObserve: [ // 'event', // This is too noisy as it covers all browser events 'first-input', // 'mark', // Mark is used too liberally. We would need to filter for specific marks // 'measure', // Measure is used too liberally. We would need to filter for specific measures 'navigation', 'paint', 'resource', ], payloadSizeLimitBytes: 1000000, payloadHostDenyList: [ '.lr-ingest.io', '.ingest.sentry.io', '.clarity.ms', // NB no leading dot here 'analytics.google.com', ], }; var HEADER_DENY_LIST = [ 'authorization', 'x-forwarded-for', 'authorization', 'cookie', 'set-cookie', 'x-api-key', 'x-real-ip', 'remote-addr', 'forwarded', 'proxy-authorization', 'x-csrf-token', 'x-csrftoken', 'x-xsrf-token', ]; var PAYLOAD_CONTENT_DENY_LIST = [ 'password', 'secret', 'passwd', 'api_key', 'apikey', 'auth', 'credentials', 'mysql_pwd', 'privatekey', 'private_key', 'token', ]; // we always remove headers on the deny list because we never want to capture this sensitive data var removeAuthorizationHeader = function (data) { var headers = data.requestHeaders; if (!isNullish(headers)) { each(Object.keys(headers !== null && headers !== void 0 ? headers : {}), function (header) { if (HEADER_DENY_LIST.includes(header.toLowerCase())) { headers[header] = REDACTED; } }); } return data; }; var POSTHOG_PATHS_TO_IGNORE = ['/s/', '/e/', '/i/']; // want to ignore posthog paths when capturing requests, or we can get trapped in a loop // because calls to PostHog would be reported using a call to PostHog which would be reported.... var ignorePostHogPaths = function (data, apiHostConfig) { var _a; var url = convertToURL(data.name); // we need to account for api host config as e.g. pathname could be /ingest/s/ and we want to ignore that var replaceValue = apiHostConfig.indexOf('http') === 0 ? (_a = convertToURL(apiHostConfig)) === null || _a === void 0 ? void 0 : _a.pathname : apiHostConfig; if (replaceValue === '/') { replaceValue = ''; } var pathname = url === null || url === void 0 ? void 0 : url.pathname.replace(replaceValue || '', ''); if (url && pathname && POSTHOG_PATHS_TO_IGNORE.some(function (path) { return pathname.indexOf(path) === 0; })) { return undefined; } return data; }; function estimateBytes(payload) { return new Blob([payload]).size; } function enforcePayloadSizeLimit(payload, headers, limit, description) { if (isNullish(payload)) { return payload; } var requestContentLength = (headers === null || headers === void 0 ? void 0 : headers['content-length']) || estimateBytes(payload); if (isString(requestContentLength)) { requestContentLength = parseInt(requestContentLength); } if (requestContentLength > limit) { return LOGGER_PREFIX + " ".concat(description, " body too large to record (").concat(requestContentLength, " bytes)"); } return payload; } // people can have arbitrarily large payloads on their site, but we don't want to ingest them var limitPayloadSize = function (options) { var _a; // the smallest of 1MB or the specified limit if there is one var limit = Math.min(1000000, (_a = options.payloadSizeLimitBytes) !== null && _a !== void 0 ? _a : 1000000); return function (data) { if (data === null || data === void 0 ? void 0 : data.requestBody) { data.requestBody = enforcePayloadSizeLimit(data.requestBody, data.requestHeaders, limit, 'Request'); } if (data === null || data === void 0 ? void 0 : data.responseBody) { data.responseBody = enforcePayloadSizeLimit(data.responseBody, data.responseHeaders, limit, 'Response'); } return data; }; }; function scrubPayload(payload, label) { if (isNullish(payload)) { return payload; } var scrubbed = payload; if (!shouldCaptureValue(scrubbed, false)) { scrubbed = LOGGER_PREFIX + ' ' + label + ' body ' + REDACTED; } each(PAYLOAD_CONTENT_DENY_LIST, function (text) { if ((scrubbed === null || scrubbed === void 0 ? void 0 : scrubbed.length) && (scrubbed === null || scrubbed === void 0 ? void 0 : scrubbed.indexOf(text)) !== -1) { scrubbed = LOGGER_PREFIX + ' ' + label + ' body ' + REDACTED + ' as might contain: ' + text; } }); return scrubbed; } function scrubPayloads(capturedRequest) { if (isUndefined(capturedRequest)) { return undefined; } capturedRequest.requestBody = scrubPayload(capturedRequest.requestBody, 'Request'); capturedRequest.responseBody = scrubPayload(capturedRequest.responseBody, 'Response'); return capturedRequest; } /** * whether a maskRequestFn is provided or not, * we ensure that we remove the denied header from requests * we _never_ want to record that header by accident * if someone complains then we'll add an opt-in to let them override it */ export var buildNetworkRequestOptions = function (instanceConfig, remoteNetworkOptions) { var config = { payloadSizeLimitBytes: defaultNetworkOptions.payloadSizeLimitBytes, performanceEntryTypeToObserve: __spreadArray([], __read(defaultNetworkOptions.performanceEntryTypeToObserve), false), payloadHostDenyList: __spreadArray(__spreadArray([], __read((remoteNetworkOptions.payloadHostDenyList || [])), false), __read(defaultNetworkOptions.payloadHostDenyList), false), }; // client can always disable despite remote options var canRecordHeaders = instanceConfig.session_recording.recordHeaders === false ? false : remoteNetworkOptions.recordHeaders; var canRecordBody = instanceConfig.session_recording.recordBody === false ? false : remoteNetworkOptions.recordBody; var canRecordPerformance = instanceConfig.capture_performance === false ? false : remoteNetworkOptions.recordPerformance; var payloadLimiter = limitPayloadSize(config); var enforcedCleaningFn = function (d) { return payloadLimiter(ignorePostHogPaths(removeAuthorizationHeader(d), instanceConfig.api_host)); }; var hasDeprecatedMaskFunction = isFunction(instanceConfig.session_recording.maskNetworkRequestFn); if (hasDeprecatedMaskFunction && isFunction(instanceConfig.session_recording.maskCapturedNetworkRequestFn)) { logger.warn('Both `maskNetworkRequestFn` and `maskCapturedNetworkRequestFn` are defined. `maskNetworkRequestFn` will be ignored.'); } if (hasDeprecatedMaskFunction) { instanceConfig.session_recording.maskCapturedNetworkRequestFn = function (data) { var cleanedURL = instanceConfig.session_recording.maskNetworkRequestFn({ url: data.name }); return __assign(__assign({}, data), { name: cleanedURL === null || cleanedURL === void 0 ? void 0 : cleanedURL.url }); }; } config.maskRequestFn = isFunction(instanceConfig.session_recording.maskCapturedNetworkRequestFn) ? function (data) { var _a, _b, _c; var cleanedRequest = enforcedCleaningFn(data); return cleanedRequest ? ((_c = (_b = (_a = instanceConfig.session_recording).maskCapturedNetworkRequestFn) === null || _b === void 0 ? void 0 : _b.call(_a, cleanedRequest)) !== null && _c !== void 0 ? _c : undefined) : undefined; } : function (data) { return scrubPayloads(enforcedCleaningFn(data)); }; return __assign(__assign(__assign({}, defaultNetworkOptions), config), { recordHeaders: canRecordHeaders, recordBody: canRecordBody, recordPerformance: canRecordPerformance, recordInitialRequests: canRecordPerformance }); }; //# sourceMappingURL=config.js.map

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/sadiuysal/mem0-mcp-server-ts'

If you have feedback or need assistance with the MCP directory API, please join our Discord server