Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions AISKU/Tests/Unit/src/AISKUSize.Tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ function _checkSize(checkType: string, maxSize: number, size: number, isNightly:
}

export class AISKUSizeCheck extends AITestClass {
private readonly MAX_RAW_SIZE = 147;
private readonly MAX_BUNDLE_SIZE = 147;
private readonly MAX_RAW_SIZE = 148;
private readonly MAX_BUNDLE_SIZE = 148;
private readonly MAX_RAW_DEFLATE_SIZE = 59;
private readonly MAX_BUNDLE_DEFLATE_SIZE = 59;
private readonly rawFilePath = "../dist/es5/applicationinsights-web.min.js";
Expand Down
6 changes: 3 additions & 3 deletions AISKULight/Tests/Unit/src/AISKULightSize.Tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,9 @@ function _checkSize(checkType: string, maxSize: number, size: number, isNightly:

export class AISKULightSizeCheck extends AITestClass {
private readonly MAX_RAW_SIZE = 93;
private readonly MAX_BUNDLE_SIZE = 93;
private readonly MAX_RAW_DEFLATE_SIZE = 38;
private readonly MAX_BUNDLE_DEFLATE_SIZE = 38;
private readonly MAX_BUNDLE_SIZE = 94;
private readonly MAX_RAW_DEFLATE_SIZE = 39;
private readonly MAX_BUNDLE_DEFLATE_SIZE = 39;
private readonly rawFilePath = "../dist/es5/applicationinsights-web-basic.min.js";
private readonly currentVer = "3.3.9";
private readonly prodFilePath = `../browser/es5/aib.${this.currentVer[0]}.min.js`;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ import {
IExceptionConfig, IInstrumentCallDetails, IPlugin, IProcessTelemetryContext, IProcessTelemetryUnloadContext,
ITelemetryInitializerHandler, ITelemetryItem, ITelemetryPluginChain, ITelemetryUnloadState, InstrumentEvent,
TelemetryInitializerFunction, _eInternalMessageId, arrForEach, cfgDfBoolean, cfgDfMerge, cfgDfSet, cfgDfString, cfgDfValidate,
createProcessTelemetryContext, createUniqueNamespace, dumpObj, eLoggingSeverity, eventOff, eventOn, findAllScripts, generateW3CId,
getDocument, getExceptionName, getHistory, getLocation, getWindow, hasHistory, hasWindow, isFunction, isNullOrUndefined, isString,
isUndefined, mergeEvtNamespace, onConfigChange, safeGetCookieMgr, strUndefined, throwError
createProcessTelemetryContext, createUniqueNamespace, dumpObj, eLoggingSeverity, eventOff, eventOn, fieldRedaction, findAllScripts,
generateW3CId, getDocument, getExceptionName, getHistory, getLocation, getWindow, hasHistory, hasWindow, isFunction, isNullOrUndefined,
isString, isUndefined, mergeEvtNamespace, onConfigChange, safeGetCookieMgr, strUndefined, throwError
} from "@microsoft/applicationinsights-core-js";
import { PropertiesPlugin } from "@microsoft/applicationinsights-properties-js";
import { isArray, isError, objDeepFreeze, objDefine, scheduleTimeout, strIndexOf } from "@nevware21/ts-utils";
Expand Down Expand Up @@ -264,6 +264,9 @@ export class AnalyticsPlugin extends BaseTelemetryPlugin implements IAppInsights
_self.trackPageView = (pageView?: IPageViewTelemetry, customProperties?: ICustomProperties) => {
try {
let inPv = pageView || {};
if (_self.core && _self.core.config) {
inPv.uri = fieldRedaction(inPv.uri, _self.core.config);
}
_pageViewManager.trackPageView(inPv, {...inPv.properties, ...inPv.measurements, ...customProperties});

if (_autoTrackPageVisitTime) {
Expand All @@ -289,6 +292,9 @@ export class AnalyticsPlugin extends BaseTelemetryPlugin implements IAppInsights
if (doc) {
pageView.refUri = pageView.refUri === undefined ? doc.referrer : pageView.refUri;
}
if (_self.core && _self.core.config) {
pageView.refUri = fieldRedaction(pageView.refUri, _self.core.config);
}
if (isNullOrUndefined(pageView.startTime)) {
// calculate the start time manually
let duration = ((properties || pageView.properties || {}).duration || 0);
Expand Down Expand Up @@ -385,7 +391,9 @@ export class AnalyticsPlugin extends BaseTelemetryPlugin implements IAppInsights
let loc = getLocation();
url = loc && loc.href || "";
}

if (_self.core && _self.core.config) {
url = fieldRedaction(url, _self.core.config);
}
_pageTracking.stop(name, url, properties, measurement);

if (_autoTrackPageVisitTime) {
Expand Down Expand Up @@ -801,7 +809,9 @@ export class AnalyticsPlugin extends BaseTelemetryPlugin implements IAppInsights
} else {
_currUri = locn && locn.href || "";
}

if (_self.core && _self.core.config) {
_currUri = fieldRedaction(_currUri, _self.core.config);
}
if (_enableAutoRouteTracking) {
let distributedTraceCtx = _getDistributedTraceCtx();
if (distributedTraceCtx) {
Expand Down Expand Up @@ -912,6 +922,9 @@ export class AnalyticsPlugin extends BaseTelemetryPlugin implements IAppInsights
// array with max length of 2 that store current url and previous url for SPA page route change trackPageview use.
let location = getLocation(true);
_prevUri = location && location.href || "";
if (_self.core && _self.core.config) {
_prevUri = fieldRedaction(_prevUri, _self.core.config);
}
_currUri = null;
_evtNamespace = null;
_extConfig = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
} from "@microsoft/applicationinsights-common";
import {
IAppInsightsCore, IDiagnosticLogger, IProcessTelemetryUnloadContext, ITelemetryUnloadState, _eInternalMessageId, _throwInternal,
arrForEach, dumpObj, eLoggingSeverity, getDocument, getExceptionName, getLocation, isNullOrUndefined
arrForEach, dumpObj, eLoggingSeverity, fieldRedaction, getDocument, getExceptionName, getLocation, isNullOrUndefined
} from "@microsoft/applicationinsights-core-js";
import { ITimerHandler, getPerformance, isUndefined, isWebWorker, scheduleTimeout } from "@nevware21/ts-utils";
import { PageViewPerformanceManager } from "./PageViewPerformanceManager";
Expand Down Expand Up @@ -96,7 +96,9 @@ export class PageViewManager {
let location = getLocation();
uri = pageView.uri = location && location.href || "";
}

if (core && core.config){
uri = pageView.uri = fieldRedaction(pageView.uri, core.config);
}
if (!firstPageViewSent){
let perf = getPerformance();
// Access the performance timing object
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
* @copyright Microsoft 2020
*/

import { getDocument, getLocation, getWindow, hasDocument, isFunction } from "@microsoft/applicationinsights-core-js";
import {
IConfiguration, fieldRedaction, getDocument, getLocation, getWindow, hasDocument, isFunction
} from "@microsoft/applicationinsights-core-js";
import { scheduleTimeout } from "@nevware21/ts-utils";
import { IClickAnalyticsConfiguration, IOverrideValues } from "./Interfaces/Datamodel";
import { findClosestAnchor, isValueAssigned } from "./common/Utils";
Expand Down Expand Up @@ -126,7 +128,7 @@ export function getPageName(config: IClickAnalyticsConfiguration, overrideValues
* @param location - window.location or document.location
* @returns Flag indicating if an element is market PII.
*/
export function sanitizeUrl(config: IClickAnalyticsConfiguration, location: Location): string {
export function sanitizeUrl(config: IClickAnalyticsConfiguration, location: Location, rootConfig?: IConfiguration): string {
if (!location) {
return null;
}
Expand All @@ -141,7 +143,7 @@ export function sanitizeUrl(config: IClickAnalyticsConfiguration, location: Loca
if (!!config.urlCollectQuery) { // false by default
url += (isValueAssigned(location.search)? location.search : "");
}

url = fieldRedaction(url, rootConfig);
return url;
}

Expand Down
8 changes: 6 additions & 2 deletions extensions/applicationinsights-dependencies-js/src/ajax.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ import {
BaseTelemetryPlugin, IAppInsightsCore, IConfigDefaults, IConfiguration, ICustomProperties, IDistributedTraceContext,
IInstrumentCallDetails, IInstrumentHooksCallbacks, IPlugin, IProcessTelemetryContext, ITelemetryItem, ITelemetryPluginChain,
InstrumentFunc, InstrumentProto, _eInternalMessageId, _throwInternal, arrForEach, createProcessTelemetryContext, createUniqueNamespace,
dumpObj, eLoggingSeverity, eventOn, generateW3CId, getExceptionName, getGlobal, getIEVersion, getLocation, getPerformance, isFunction,
isNullOrUndefined, isString, isXhrSupported, mergeEvtNamespace, onConfigChange, strPrototype, strTrim
dumpObj, eLoggingSeverity, eventOn, fieldRedaction, generateW3CId, getExceptionName, getGlobal, getIEVersion, getLocation,
getPerformance, isFunction, isNullOrUndefined, isString, isXhrSupported, mergeEvtNamespace, onConfigChange, strPrototype, strTrim
} from "@microsoft/applicationinsights-core-js";
import { isWebWorker, objFreeze, scheduleTimeout, strIndexOf, strSplit, strSubstr } from "@nevware21/ts-utils";
import { DependencyInitializerFunction, IDependencyInitializerDetails, IDependencyInitializerHandler } from "./DependencyInitializer";
Expand Down Expand Up @@ -1193,6 +1193,10 @@ export class AjaxMonitor extends BaseTelemetryPlugin implements IDependenciesPlu
}
}

if (_self.core && _self.core.config) {
requestUrl = fieldRedaction(requestUrl, _self.core.config);
}

ajaxData.requestUrl = requestUrl;

let method = "GET";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ function _checkSize(checkType: string, maxSize: number, size: number, isNightly:
}

export class PropertiesExtensionSizeCheck extends AITestClass {
private readonly MAX_DEFLATE_SIZE = 18;
private readonly MAX_DEFLATE_SIZE = 19;
private readonly rawFilePath = "../dist/es5/applicationinsights-properties-js.min.js";
// Automatically updated by version scripts
private readonly currentVer = "3.3.9";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Licensed under the MIT License.

import { ITelemetryTrace, ITraceState, dataSanitizeString } from "@microsoft/applicationinsights-common";
import { IDiagnosticLogger, generateW3CId, getLocation } from "@microsoft/applicationinsights-core-js";
import { IConfiguration, IDiagnosticLogger, fieldRedaction, generateW3CId, getLocation } from "@microsoft/applicationinsights-core-js";

export class TelemetryTrace implements ITelemetryTrace {

Expand All @@ -12,13 +12,16 @@ export class TelemetryTrace implements ITelemetryTrace {
public traceFlags: number;
public name: string;

constructor(id?: string, parentId?: string, name?: string, logger?: IDiagnosticLogger) {
constructor(id?: string, parentId?: string, name?: string, logger?: IDiagnosticLogger, config?: IConfiguration) {
const _self = this;
_self.traceID = id || generateW3CId();
_self.parentID = parentId;
let location = getLocation();
if (!name && location && location.pathname) {
name = location.pathname;
if (config) {
name = fieldRedaction(name, config);
}
}

_self.name = dataSanitizeString(logger, name);
Expand Down
2 changes: 1 addition & 1 deletion shared/1ds-core-js/src/Index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export {
objForEachKey, strStartsWith, strEndsWith, strContains, strTrim, isDate, isArray, isError, isString, isNumber, isBoolean,
toISOString, arrForEach, arrIndexOf, arrMap, arrReduce, objKeys, objDefineAccessors, dateNow, getExceptionName, throwError,
setValue, getSetValue, isNotTruthy, isTruthy, proxyAssign, proxyFunctions, proxyFunctionAs, optimizeObject,
addEventHandler, newGuid, perfNow, newId, generateW3CId, safeGetLogger, objFreeze, objSeal,
addEventHandler, newGuid, perfNow, newId, generateW3CId, safeGetLogger, objFreeze, objSeal, fieldRedaction,
// EnvUtils
getGlobal, getGlobalInst, hasWindow, getWindow, hasDocument, getDocument, getCrypto, getMsCrypto,
hasNavigator, getNavigator, hasHistory, getHistory, getLocation, getPerformance, hasJSON, getJSON,
Expand Down
4 changes: 2 additions & 2 deletions shared/1ds-core-js/test/Unit/src/FileSizeCheckTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ function _checkSize(checkType: string, maxSize: number, size: number, isNightly:
}

export class FileSizeCheckTest extends AITestClass {
private readonly MAX_BUNDLE_SIZE = 69;
private readonly MAX_DEFLATE_SIZE = 29;
private readonly MAX_BUNDLE_SIZE = 70;
private readonly MAX_DEFLATE_SIZE = 30;
private readonly bundleFilePath = "../bundle/es5/ms.core.min.js";

public testInitialize() {
Expand Down
115 changes: 113 additions & 2 deletions shared/AppInsightsCommon/Tests/Unit/src/AppInsightsCommon.tests.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { strRepeat } from "@nevware21/ts-utils";
import { Assert, AITestClass } from "@microsoft/ai-test-framework";
import { DiagnosticLogger } from "@microsoft/applicationinsights-core-js";
import { dataSanitizeInput, dataSanitizeKey, dataSanitizeMessage, DataSanitizerValues, dataSanitizeString } from "../../../src/Telemetry/Common/DataSanitizer";
import { DiagnosticLogger, IConfiguration } from "@microsoft/applicationinsights-core-js";
import { dataSanitizeInput, dataSanitizeKey, dataSanitizeMessage, DataSanitizerValues, dataSanitizeString, dataSanitizeUrl } from "../../../src/Telemetry/Common/DataSanitizer";


export class ApplicationInsightsTests extends AITestClass {
Expand Down Expand Up @@ -293,5 +293,116 @@ export class ApplicationInsightsTests extends AITestClass {
loggerStub.restore();
}
});
this.testCase({
name: 'DataSanitizerTests: dataSanitizeUrl properly redacts credentials in URLs with config enabled',
test: () => {
// URLs with credentials
let config = {} as IConfiguration;
const urlWithCredentials = "https://username:password@example.com/path";
const expectedRedactedUrl = "https://REDACTED:REDACTED@example.com/path";

// Act & Assert
const result = dataSanitizeUrl(this.logger, urlWithCredentials, config);
Assert.equal(expectedRedactedUrl, result);
}
});
this.testCase({
name: 'DataSanitizerTests: dataSanitizeUrl properly redacts credentials in URLs with config disabled',
test: () => {
// URLs with credentials
let config = {redactUrls: false} as IConfiguration;
const urlWithCredentials = "https://username:password@example.com/path";

// Act & Assert
const result = dataSanitizeUrl(this.logger, urlWithCredentials, config);
Assert.equal(urlWithCredentials, result);
}
});
this.testCase({
name: 'DataSanitizerTests: dataSanitizeUrl handles invalid URLs',
test: () => {
// Invalid URL that will cause URL constructor to throw
const invalidUrl = 123545;

// Act & Assert
const result = dataSanitizeUrl(this.logger, invalidUrl);
Assert.equal(invalidUrl, result, "Invalid URLs should be returned unchanged");
}
});
this.testCase({
name: 'DataSanitizerTests: dataSanitizeUrl still enforces maximum length after redaction',
test: () => {
// Setup
let config = {} as IConfiguration;
const loggerStub = this.sandbox.stub(this.logger, "throwInternal");
const MAX_URL_LENGTH = DataSanitizerValues.MAX_URL_LENGTH;

// Create a very long URL with sensitive information
const longBaseUrl = "https://username:password@example.com/";
const longPathPart = strRepeat("a", MAX_URL_LENGTH);
const longUrl = longBaseUrl + longPathPart;

// Act
const result = dataSanitizeUrl(this.logger, longUrl, config);

// Assert
Assert.equal(MAX_URL_LENGTH, result.length, "URL should be truncated to maximum length");
Assert.equal(true, result.indexOf("REDACTED") > -1, "Redaction should happen before truncation");
Assert.ok(loggerStub.calledOnce, "Logger should be called once for oversized URL");

loggerStub.restore();
}
});
this.testCase({
name: 'DataSanitizerTests: dataSanitizeUrl handles null and undefined inputs',
test: () => {
// Act & Assert
const nullResult = dataSanitizeUrl(this.logger, null);
Assert.equal(null, nullResult, "Null input should return null");

const undefinedResult = dataSanitizeUrl(this.logger, undefined);
Assert.equal(undefined, undefinedResult, "Undefined input should return undefined");
}
});
this.testCase({
name: 'DataSanitizerTests: dataSanitizeUrl preserves URLs with no sensitive information',
test: () => {
// URL with no sensitive information
let config = {} as IConfiguration;
const safeUrl = "https://example.com/api?param1=value1&param2=value2";

// Act & Assert
const result = dataSanitizeUrl(this.logger, safeUrl, config);
Assert.equal(safeUrl, result, "URL with no sensitive info should remain unchanged");
}
});
this.testCase({
name: 'DataSanitizerTests: dataSanitizeUrl properly redacts sensitive query parameters',
test: () => {
// URLs with sensitive query parameters
let config = {} as IConfiguration;
const urlWithSensitiveParams = "https://example.com/api?Signature=secret&normal=value";
const expectedRedactedUrl = "https://example.com/api?Signature=REDACTED&normal=value";

// Act & Assert
const result = dataSanitizeUrl(this.logger, urlWithSensitiveParams, config);
Assert.equal(expectedRedactedUrl, result);
}
});
this.testCase({
name: 'DataSanitizerTests: dataSanitizeUrl properly redacts sensitive query parameters (default + custom)',
test: () => {
// URLs with sensitive query parameters
let config = {
redactQueryParams: ["authorize", "api_key", "password"]
} as IConfiguration;
const urlWithSensitiveParams = "https://example.com/api?Signature=secret&authorize=value";
const expectedRedactedUrl = "https://example.com/api?Signature=REDACTED&authorize=REDACTED";

// Act & Assert
const result = dataSanitizeUrl(this.logger, urlWithSensitiveParams, config);
Assert.equal(expectedRedactedUrl, result);
}
});
}
}
10 changes: 7 additions & 3 deletions shared/AppInsightsCommon/src/Telemetry/Common/DataSanitizer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@
// Licensed under the MIT License.

import {
IDiagnosticLogger, _eInternalMessageId, _throwInternal, eLoggingSeverity, getJSON, hasJSON, isObject, objForEachKey, strTrim
IConfiguration, IDiagnosticLogger, _eInternalMessageId, _throwInternal, eLoggingSeverity, fieldRedaction, getJSON, hasJSON, isObject,
objForEachKey, strTrim
} from "@microsoft/applicationinsights-core-js";
import { asString, strSubstr, strSubstring } from "@nevware21/ts-utils";
import { asString, isString, strSubstr, strSubstring } from "@nevware21/ts-utils";

export const enum DataSanitizerValues {
/**
Expand Down Expand Up @@ -98,7 +99,10 @@ export function dataSanitizeString(logger: IDiagnosticLogger, value: any, maxLen
return valueTrunc || value;
}

export function dataSanitizeUrl(logger: IDiagnosticLogger, url: any) {
export function dataSanitizeUrl(logger: IDiagnosticLogger, url: any, config?: IConfiguration) {
if (isString(url)) {
url = fieldRedaction(url, config);
}
return dataSanitizeInput(logger, url, DataSanitizerValues.MAX_URL_LENGTH, _eInternalMessageId.UrlTooLong);
}

Expand Down
Loading