@microsoft/applicationinsights-core-js
Version:
Microsoft Application Insights Core Javascript SDK
393 lines • 18.5 kB
JavaScript
/*
* Application Insights JavaScript SDK - Core, 3.3.6
* Copyright (c) Microsoft and contributors. All rights reserved.
*/
var _a, _b;
import { arrForEach, arrIndexOf, dumpObj, getDocument, getLazy, getNavigator, isArray, isFunction, isNullOrUndefined, isString, isTruthy, isUndefined, objForEachKey, strEndsWith, strIndexOf, strLeft, strSubstring, strTrim, utcNow } from "@nevware21/ts-utils";
import { cfgDfMerge } from "../Config/ConfigDefaultHelpers";
import { createDynamicConfig, onConfigChange } from "../Config/DynamicConfig";
import { _DYN_ENABLED, _DYN_LENGTH, _DYN_LOGGER, _DYN_SPLIT, _DYN_USER_AGENT } from "../__DynamicConstants";
import { _throwInternal } from "./DiagnosticLogger";
import { getLocation, isIE } from "./EnvUtils";
import { getExceptionName, isNotNullOrUndefined, setValue, strContains } from "./HelperFuncs";
import { STR_DOMAIN, STR_EMPTY, STR_PATH, UNDEFINED_VALUE } from "./InternalConstants";
var strToGMTString = "toGMTString";
var strToUTCString = "toUTCString";
var strCookie = "cookie";
var strExpires = "expires";
var strIsCookieUseDisabled = "isCookieUseDisabled";
var strDisableCookiesUsage = "disableCookiesUsage";
var strConfigCookieMgr = "_ckMgr";
var _supportsCookies = null;
var _allowUaSameSite = null;
var _parsedCookieValue = null;
var _doc;
var _cookieCache = {};
var _globalCookieConfig = {};
// // `isCookieUseDisabled` is deprecated, so explicitly casting as a key of IConfiguration to avoid typing error
// // when both isCookieUseDisabled and disableCookiesUsage are used disableCookiesUsage will take precedent, which is
// // why its listed first
/**
* Set the supported dynamic config values as undefined (or an empty object) so that
* any listeners will be informed of any changes.
* Explicitly NOT including the deprecated `isCookieUseDisabled` as we don't want to support
* the v1 deprecated field as dynamic for updates
*/
var rootDefaultConfig = (_a = {
cookieCfg: cfgDfMerge((_b = {},
_b[STR_DOMAIN] = { fb: "cookieDomain", dfVal: isNotNullOrUndefined },
_b.path = { fb: "cookiePath", dfVal: isNotNullOrUndefined },
_b.enabled = UNDEFINED_VALUE,
_b.ignoreCookies = UNDEFINED_VALUE,
_b.blockedCookies = UNDEFINED_VALUE,
_b)),
cookieDomain: UNDEFINED_VALUE,
cookiePath: UNDEFINED_VALUE
},
_a[strDisableCookiesUsage] = UNDEFINED_VALUE,
_a);
function _getDoc() {
!_doc && (_doc = getLazy(function () { return getDocument(); }));
}
/**
* @ignore
* DO NOT USE or export from the module, this is exposed as public to support backward compatibility of previous static utility methods only.
* If you want to manager cookies either use the ICookieMgr available from the core instance via getCookieMgr() or create
* your own instance of the CookieMgr and use that.
* Using this directly for enabling / disabling cookie handling will not only affect your usage but EVERY user of cookies.
* Example, if you are using a shared component that is also using Application Insights you will affect their cookie handling.
* @param logger - The DiagnosticLogger to use for reporting errors.
*/
function _gblCookieMgr(config, logger) {
// Stash the global instance against the BaseCookieMgr class
var inst = createCookieMgr[strConfigCookieMgr] || _globalCookieConfig[strConfigCookieMgr];
if (!inst) {
// Note: not using the getSetValue() helper as that would require always creating a temporary cookieMgr
// that ultimately is never used
inst = createCookieMgr[strConfigCookieMgr] = createCookieMgr(config, logger);
_globalCookieConfig[strConfigCookieMgr] = inst;
}
return inst;
}
function _isMgrEnabled(cookieMgr) {
if (cookieMgr) {
return cookieMgr.isEnabled();
}
return true;
}
function _isIgnoredCookie(cookieMgrCfg, name) {
if (name && cookieMgrCfg && isArray(cookieMgrCfg.ignoreCookies)) {
return arrIndexOf(cookieMgrCfg.ignoreCookies, name) !== -1;
}
return false;
}
function _isBlockedCookie(cookieMgrCfg, name) {
if (name && cookieMgrCfg && isArray(cookieMgrCfg.blockedCookies)) {
if (arrIndexOf(cookieMgrCfg.blockedCookies, name) !== -1) {
return true;
}
}
return _isIgnoredCookie(cookieMgrCfg, name);
}
function _isCfgEnabled(rootConfig, cookieMgrConfig) {
var isCfgEnabled = cookieMgrConfig[_DYN_ENABLED /* @min:%2eenabled */];
if (isNullOrUndefined(isCfgEnabled)) {
// Set the enabled from the provided setting or the legacy root values
var cookieEnabled = void 0;
// This field is deprecated and dynamic updates will not be fully supported
if (!isUndefined(rootConfig[strIsCookieUseDisabled])) {
cookieEnabled = !rootConfig[strIsCookieUseDisabled];
}
// If this value is defined it takes precedent over the above
if (!isUndefined(rootConfig[strDisableCookiesUsage])) {
cookieEnabled = !rootConfig[strDisableCookiesUsage];
}
// Not setting the cookieMgrConfig.enabled as that will update (set) the global dynamic config
// So future "updates" then may not be as expected
isCfgEnabled = cookieEnabled;
}
return isCfgEnabled;
}
/**
* Helper to return the ICookieMgr from the core (if not null/undefined) or a default implementation
* associated with the configuration or a legacy default.
* @param core - The AppInsightsCore instance to get the cookie manager from
* @param config - The config to use if the core is not available
* @returns
*/
export function safeGetCookieMgr(core, config) {
var cookieMgr;
if (core) {
// Always returns an instance
cookieMgr = core.getCookieMgr();
}
else if (config) {
var cookieCfg = config.cookieCfg;
if (cookieCfg && cookieCfg[strConfigCookieMgr]) {
cookieMgr = cookieCfg[strConfigCookieMgr];
}
else {
cookieMgr = createCookieMgr(config);
}
}
if (!cookieMgr) {
// Get or initialize the default global (legacy) cookie manager if we couldn't find one
cookieMgr = _gblCookieMgr(config, (core || {})[_DYN_LOGGER /* @min:%2elogger */]);
}
return cookieMgr;
}
export function createCookieMgr(rootConfig, logger) {
var cookieMgrConfig;
var _path;
var _domain;
var unloadHandler;
// Explicitly checking against false, so that setting to undefined will === true
var _enabled;
var _getCookieFn;
var _setCookieFn;
var _delCookieFn;
// Make sure the root config is dynamic as it may be the global config
rootConfig = createDynamicConfig(rootConfig || _globalCookieConfig, null, logger).cfg;
// Will get recalled if the referenced configuration is changed
unloadHandler = onConfigChange(rootConfig, function (details) {
// Make sure the root config has all of the the defaults to the root config to ensure they are dynamic
details.setDf(details.cfg, rootDefaultConfig);
// Create and apply the defaults to the cookieCfg element
cookieMgrConfig = details.ref(details.cfg, "cookieCfg"); // details.setDf(details.cfg.cookieCfg, defaultConfig);
_path = cookieMgrConfig[STR_PATH /* @min:%2epath */] || "/";
_domain = cookieMgrConfig[STR_DOMAIN /* @min:%2edomain */];
// Explicitly checking against false, so that setting to undefined will === true
_enabled = _isCfgEnabled(rootConfig, cookieMgrConfig) !== false;
_getCookieFn = cookieMgrConfig.getCookie || _getCookieValue;
_setCookieFn = cookieMgrConfig.setCookie || _setCookieValue;
_delCookieFn = cookieMgrConfig.delCookie || _setCookieValue;
}, logger);
var cookieMgr = {
isEnabled: function () {
var enabled = _isCfgEnabled(rootConfig, cookieMgrConfig) !== false && _enabled && areCookiesSupported(logger);
// Using an indirect lookup for any global cookie manager to support tree shaking for SDK's
// that don't use the "applicationinsights-core" version of the default cookie function
var gblManager = _globalCookieConfig[strConfigCookieMgr];
if (enabled && gblManager && cookieMgr !== gblManager) {
// Make sure the GlobalCookie Manager instance (if not this instance) is also enabled.
// As the global (deprecated) functions may have been called (for backward compatibility)
enabled = _isMgrEnabled(gblManager);
}
return enabled;
},
setEnabled: function (value) {
// Explicitly checking against false, so that setting to undefined will === true
_enabled = value !== false;
cookieMgrConfig[_DYN_ENABLED /* @min:%2eenabled */] = value;
},
set: function (name, value, maxAgeSec, domain, path) {
var result = false;
if (_isMgrEnabled(cookieMgr) && !_isBlockedCookie(cookieMgrConfig, name)) {
var values = {};
var theValue = strTrim(value || STR_EMPTY);
var idx = strIndexOf(theValue, ";");
if (idx !== -1) {
theValue = strTrim(strLeft(value, idx));
values = _extractParts(strSubstring(value, idx + 1));
}
// Only update domain if not already present (isUndefined) and the value is truthy (not null, undefined or empty string)
setValue(values, STR_DOMAIN, domain || _domain, isTruthy, isUndefined);
if (!isNullOrUndefined(maxAgeSec)) {
var _isIE = isIE();
if (isUndefined(values[strExpires])) {
var nowMs = utcNow();
// Only add expires if not already present
var expireMs = nowMs + (maxAgeSec * 1000);
// Sanity check, if zero or -ve then ignore
if (expireMs > 0) {
var expiry = new Date();
expiry.setTime(expireMs);
setValue(values, strExpires, _formatDate(expiry, !_isIE ? strToUTCString : strToGMTString) || _formatDate(expiry, _isIE ? strToGMTString : strToUTCString) || STR_EMPTY, isTruthy);
}
}
if (!_isIE) {
// Only replace if not already present
setValue(values, "max-age", STR_EMPTY + maxAgeSec, null, isUndefined);
}
}
var location_1 = getLocation();
if (location_1 && location_1.protocol === "https:") {
setValue(values, "secure", null, null, isUndefined);
// Only set same site if not also secure
if (_allowUaSameSite === null) {
_allowUaSameSite = !uaDisallowsSameSiteNone((getNavigator() || {})[_DYN_USER_AGENT /* @min:%2euserAgent */]);
}
if (_allowUaSameSite) {
setValue(values, "SameSite", "None", null, isUndefined);
}
}
setValue(values, STR_PATH, path || _path, null, isUndefined);
//let setCookieFn = cookieMgrConfig.setCookie || _setCookieValue;
_setCookieFn(name, _formatCookieValue(theValue, values));
result = true;
}
return result;
},
get: function (name) {
var value = STR_EMPTY;
if (_isMgrEnabled(cookieMgr) && !_isIgnoredCookie(cookieMgrConfig, name)) {
value = _getCookieFn(name);
}
return value;
},
del: function (name, path) {
var result = false;
if (_isMgrEnabled(cookieMgr)) {
// Only remove the cookie if the manager and cookie support has not been disabled
result = cookieMgr.purge(name, path);
}
return result;
},
purge: function (name, path) {
var _a;
var result = false;
if (areCookiesSupported(logger)) {
// Setting the expiration date in the past immediately removes the cookie
var values = (_a = {},
_a[STR_PATH] = path ? path : "/",
_a[strExpires] = "Thu, 01 Jan 1970 00:00:01 GMT",
_a);
if (!isIE()) {
// Set max age to expire now
values["max-age"] = "0";
}
// let delCookie = cookieMgrConfig.delCookie || _setCookieValue;
_delCookieFn(name, _formatCookieValue(STR_EMPTY, values));
result = true;
}
return result;
},
unload: function (isAsync) {
unloadHandler && unloadHandler.rm();
unloadHandler = null;
}
};
// Associated this cookie manager with the config
cookieMgr[strConfigCookieMgr] = cookieMgr;
return cookieMgr;
}
/*
* Helper method to tell if document.cookie object is supported by the runtime
*/
export function areCookiesSupported(logger) {
if (_supportsCookies === null) {
_supportsCookies = false;
!_doc && _getDoc();
try {
var doc = _doc.v || {};
_supportsCookies = doc[strCookie] !== undefined;
}
catch (e) {
_throwInternal(logger, 2 /* eLoggingSeverity.WARNING */, 68 /* _eInternalMessageId.CannotAccessCookie */, "Cannot access document.cookie - " + getExceptionName(e), { exception: dumpObj(e) });
}
}
return _supportsCookies;
}
function _extractParts(theValue) {
var values = {};
if (theValue && theValue[_DYN_LENGTH /* @min:%2elength */]) {
var parts = strTrim(theValue)[_DYN_SPLIT /* @min:%2esplit */](";");
arrForEach(parts, function (thePart) {
thePart = strTrim(thePart || STR_EMPTY);
if (thePart) {
var idx = strIndexOf(thePart, "=");
if (idx === -1) {
values[thePart] = null;
}
else {
values[strTrim(strLeft(thePart, idx))] = strTrim(strSubstring(thePart, idx + 1));
}
}
});
}
return values;
}
function _formatDate(theDate, func) {
if (isFunction(theDate[func])) {
return theDate[func]();
}
return null;
}
function _formatCookieValue(value, values) {
var cookieValue = value || STR_EMPTY;
objForEachKey(values, function (name, theValue) {
cookieValue += "; " + name + (!isNullOrUndefined(theValue) ? "=" + theValue : STR_EMPTY);
});
return cookieValue;
}
function _getCookieValue(name) {
var cookieValue = STR_EMPTY;
!_doc && _getDoc();
if (_doc.v) {
var theCookie = _doc.v[strCookie] || STR_EMPTY;
if (_parsedCookieValue !== theCookie) {
_cookieCache = _extractParts(theCookie);
_parsedCookieValue = theCookie;
}
cookieValue = strTrim(_cookieCache[name] || STR_EMPTY);
}
return cookieValue;
}
function _setCookieValue(name, cookieValue) {
!_doc && _getDoc();
if (_doc.v) {
_doc.v[strCookie] = name + "=" + cookieValue;
}
}
export function uaDisallowsSameSiteNone(userAgent) {
if (!isString(userAgent)) {
return false;
}
// Cover all iOS based browsers here. This includes:
// - Safari on iOS 12 for iPhone, iPod Touch, iPad
// - WkWebview on iOS 12 for iPhone, iPod Touch, iPad
// - Chrome on iOS 12 for iPhone, iPod Touch, iPad
// All of which are broken by SameSite=None, because they use the iOS networking stack
if (strContains(userAgent, "CPU iPhone OS 12") || strContains(userAgent, "iPad; CPU OS 12")) {
return true;
}
// Cover Mac OS X based browsers that use the Mac OS networking stack. This includes:
// - Safari on Mac OS X
// This does not include:
// - Internal browser on Mac OS X
// - Chrome on Mac OS X
// - Chromium on Mac OS X
// Because they do not use the Mac OS networking stack.
if (strContains(userAgent, "Macintosh; Intel Mac OS X 10_14") && strContains(userAgent, "Version/") && strContains(userAgent, "Safari")) {
return true;
}
// Cover Mac OS X internal browsers that use the Mac OS networking stack. This includes:
// - Internal browser on Mac OS X
// This does not include:
// - Safari on Mac OS X
// - Chrome on Mac OS X
// - Chromium on Mac OS X
// Because they do not use the Mac OS networking stack.
if (strContains(userAgent, "Macintosh; Intel Mac OS X 10_14") && strEndsWith(userAgent, "AppleWebKit/605.1.15 (KHTML, like Gecko)")) {
return true;
}
// Cover Chrome 50-69, because some versions are broken by SameSite=None, and none in this range require it.
// Note: this covers some pre-Chromium Edge versions, but pre-Chromim Edge does not require SameSite=None, so this is fine.
// Note: this regex applies to Windows, Mac OS X, and Linux, deliberately.
if (strContains(userAgent, "Chrome/5") || strContains(userAgent, "Chrome/6")) {
return true;
}
// Unreal Engine runs Chromium 59, but does not advertise as Chrome until 4.23. Treat versions of Unreal
// that don't specify their Chrome version as lacking support for SameSite=None.
if (strContains(userAgent, "UnrealEngine") && !strContains(userAgent, "Chrome")) {
return true;
}
// UCBrowser < 12.13.2 ignores Set-Cookie headers with SameSite=None
// NB: this rule isn't complete - you need regex to make a complete rule.
// See: https://www.chromium.org/updates/same-site/incompatible-clients
if (strContains(userAgent, "UCBrowser/12") || strContains(userAgent, "UCBrowser/11")) {
return true;
}
return false;
}
//# sourceMappingURL=CookieMgr.js.map