@cloudcare/browser-core 1.1.2 → 1.2.0
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.
- package/cjs/{cookie.js → browser/cookie.js} +6 -37
- package/cjs/browser/fetchObservable.js +91 -0
- package/cjs/browser/xhrObservable.js +118 -0
- package/cjs/configuration/configuration.js +70 -0
- package/cjs/configuration/transportConfiguration.js +64 -0
- package/cjs/console/consoleObservable.js +84 -0
- package/cjs/dataMap.js +26 -21
- package/cjs/error/trackRuntimeError.js +27 -0
- package/cjs/helper/catchUserErrors.js +20 -0
- package/cjs/helper/contextHistory.js +134 -0
- package/cjs/helper/createEventRateLimiter.js +47 -0
- package/cjs/helper/deviceInfo.js +8 -25
- package/cjs/helper/display.js +31 -0
- package/cjs/helper/enums.js +28 -2
- package/cjs/helper/errorTools.js +63 -2
- package/cjs/helper/instrumentMethod.js +93 -0
- package/cjs/helper/lifeCycle.js +5 -3
- package/cjs/helper/observable.js +40 -2
- package/cjs/helper/tools.js +217 -11
- package/cjs/index.js +153 -23
- package/cjs/init.js +17 -27
- package/cjs/report/reportObservable.js +112 -0
- package/cjs/session/sessionConstants.js +13 -0
- package/cjs/session/sessionCookieStore.js +188 -0
- package/cjs/session/sessionManagement.js +96 -0
- package/cjs/session/sessionStore.js +150 -0
- package/cjs/synthetics/syntheticsWorkerValues.js +32 -0
- package/cjs/synthetics/usr.js +32 -0
- package/cjs/tracekit/computeStackTrace.js +73 -563
- package/cjs/tracekit/index.js +3 -15
- package/cjs/tracekit/tracekit.js +113 -0
- package/cjs/transport/batch.js +332 -0
- package/cjs/transport/httpRequest.js +112 -0
- package/cjs/transport/index.js +29 -0
- package/cjs/transport/sendWithRetryStrategy.js +177 -0
- package/cjs/transport/startBatchWithReplica.js +24 -0
- package/esm/{cookie.js → browser/cookie.js} +4 -35
- package/esm/browser/fetchObservable.js +77 -0
- package/esm/browser/xhrObservable.js +106 -0
- package/esm/configuration/configuration.js +55 -0
- package/esm/configuration/transportConfiguration.js +54 -0
- package/esm/console/consoleObservable.js +70 -0
- package/esm/dataMap.js +26 -21
- package/esm/error/trackRuntimeError.js +16 -0
- package/esm/helper/catchUserErrors.js +12 -0
- package/esm/helper/contextHistory.js +106 -0
- package/esm/helper/createEventRateLimiter.js +38 -0
- package/esm/helper/deviceInfo.js +6 -25
- package/esm/helper/display.js +21 -0
- package/esm/helper/enums.js +25 -1
- package/esm/helper/errorTools.js +58 -3
- package/esm/helper/instrumentMethod.js +81 -0
- package/esm/helper/lifeCycle.js +5 -3
- package/esm/helper/observable.js +39 -3
- package/esm/helper/tools.js +173 -3
- package/esm/index.js +17 -7
- package/esm/init.js +17 -22
- package/esm/report/reportObservable.js +98 -0
- package/esm/session/sessionConstants.js +3 -0
- package/esm/session/sessionCookieStore.js +168 -0
- package/esm/session/sessionManagement.js +78 -0
- package/esm/session/sessionStore.js +139 -0
- package/esm/synthetics/syntheticsWorkerValues.js +15 -0
- package/esm/synthetics/usr.js +18 -0
- package/esm/tracekit/computeStackTrace.js +73 -557
- package/esm/tracekit/index.js +1 -1
- package/esm/tracekit/tracekit.js +103 -0
- package/esm/transport/batch.js +316 -0
- package/esm/transport/httpRequest.js +104 -0
- package/esm/transport/index.js +3 -0
- package/esm/transport/sendWithRetryStrategy.js +165 -0
- package/esm/transport/startBatchWithReplica.js +15 -0
- package/package.json +2 -2
- package/src/.DS_Store +0 -0
- package/src/{cookie.js → browser/cookie.js} +6 -34
- package/src/browser/fetchObservable.js +86 -0
- package/src/browser/xhrObservable.js +102 -0
- package/src/configuration/configuration.js +61 -0
- package/src/configuration/transportConfiguration.js +42 -0
- package/src/console/consoleObservable.js +65 -0
- package/src/dataMap.js +26 -21
- package/src/error/trackRuntimeError.js +19 -0
- package/src/helper/catchUserErrors.js +12 -0
- package/src/helper/contextHistory.js +85 -0
- package/src/helper/createEventRateLimiter.js +37 -0
- package/src/helper/deviceInfo.js +5 -51
- package/src/helper/display.js +21 -0
- package/src/helper/enums.js +38 -14
- package/src/helper/errorTools.js +76 -12
- package/src/helper/instrumentMethod.js +97 -0
- package/src/helper/lifeCycle.js +5 -3
- package/src/helper/observable.js +33 -2
- package/src/helper/tools.js +159 -5
- package/src/index.js +18 -7
- package/src/init.js +17 -18
- package/src/report/reportObservable.js +113 -0
- package/src/session/sessionConstants.js +3 -0
- package/src/session/sessionCookieStore.js +159 -0
- package/src/session/sessionManagement.js +89 -0
- package/src/session/sessionStore.js +139 -0
- package/src/synthetics/syntheticsWorkerValues.js +22 -0
- package/src/synthetics/usr.js +18 -0
- package/src/tracekit/computeStackTrace.js +75 -551
- package/src/tracekit/index.js +1 -1
- package/src/tracekit/tracekit.js +100 -0
- package/src/transport/batch.js +289 -0
- package/src/transport/httpRequest.js +109 -0
- package/src/transport/index.js +3 -0
- package/src/transport/sendWithRetryStrategy.js +186 -0
- package/src/transport/startBatchWithReplica.js +26 -0
- package/cjs/configuration.js +0 -184
- package/cjs/errorCollection.js +0 -167
- package/cjs/fetchProxy.js +0 -162
- package/cjs/helper/errorFilter.js +0 -47
- package/cjs/sessionManagement.js +0 -221
- package/cjs/tracekit/report.js +0 -289
- package/cjs/transport.js +0 -373
- package/cjs/xhrProxy.js +0 -122
- package/esm/configuration.js +0 -167
- package/esm/errorCollection.js +0 -141
- package/esm/fetchProxy.js +0 -116
- package/esm/helper/errorFilter.js +0 -38
- package/esm/sessionManagement.js +0 -195
- package/esm/tracekit/report.js +0 -273
- package/esm/transport.js +0 -357
- package/esm/xhrProxy.js +0 -110
- package/src/configuration.js +0 -156
- package/src/errorCollection.js +0 -170
- package/src/fetchProxy.js +0 -109
- package/src/helper/errorFilter.js +0 -38
- package/src/sessionManagement.js +0 -224
- package/src/tracekit/report.js +0 -284
- package/src/transport.js +0 -380
- package/src/xhrProxy.js +0 -106
package/src/helper/tools.js
CHANGED
|
@@ -178,6 +178,63 @@ export var map = function (arr, fn, self) {
|
|
|
178
178
|
}
|
|
179
179
|
return ret
|
|
180
180
|
}
|
|
181
|
+
export var some = function(arr, fn, self) {
|
|
182
|
+
if (arr.some) {
|
|
183
|
+
return arr.some(fn)
|
|
184
|
+
}
|
|
185
|
+
var flag = false
|
|
186
|
+
for(var i = 0; i < arr.length; i++) {
|
|
187
|
+
if (!hasOwnProperty.call(arr, i)) {
|
|
188
|
+
continue
|
|
189
|
+
}
|
|
190
|
+
var val = arr[i]
|
|
191
|
+
if (fn.call(self, val, i, arr)) {
|
|
192
|
+
flag = true
|
|
193
|
+
break;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
return flag
|
|
197
|
+
}
|
|
198
|
+
export var every = function(arr, fn, self) {
|
|
199
|
+
if (arr.every) {
|
|
200
|
+
return arr.every(fn)
|
|
201
|
+
}
|
|
202
|
+
var flag = true
|
|
203
|
+
for(var i = 0; i < arr.length; i++) {
|
|
204
|
+
if (!hasOwnProperty.call(arr, i)) {
|
|
205
|
+
continue
|
|
206
|
+
}
|
|
207
|
+
var val = arr[i]
|
|
208
|
+
if (!fn.call(self, val, i, arr)) {
|
|
209
|
+
flag = false
|
|
210
|
+
break;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
return flag
|
|
214
|
+
}
|
|
215
|
+
export var matchList = function(list, value) {
|
|
216
|
+
return some(list, function(item) {return item === value || (item instanceof RegExp && item.test(value))})
|
|
217
|
+
}
|
|
218
|
+
// https://github.com/jquery/jquery/blob/a684e6ba836f7c553968d7d026ed7941e1a612d8/src/selector/escapeSelector.js
|
|
219
|
+
export var cssEscape = function(str) {
|
|
220
|
+
if (window.CSS && window.CSS.escape) {
|
|
221
|
+
return window.CSS.escape(str)
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
// eslint-disable-next-line no-control-regex
|
|
225
|
+
return str.replace(/([\0-\x1f\x7f]|^-?\d)|^-$|[^\x80-\uFFFF\w-]/g, function (ch, asCodePoint) {
|
|
226
|
+
if (asCodePoint) {
|
|
227
|
+
// U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER
|
|
228
|
+
if (ch === '\0') {
|
|
229
|
+
return '\uFFFD'
|
|
230
|
+
}
|
|
231
|
+
// Control characters and (dependent upon position) numbers get escaped as code points
|
|
232
|
+
return ch.slice(0, -1) + '\\' + ch.charCodeAt(ch.length - 1).toString(16) + ' '
|
|
233
|
+
}
|
|
234
|
+
// Other potentially-special ASCII characters get backslash-escaped
|
|
235
|
+
return '\\' + ch
|
|
236
|
+
})
|
|
237
|
+
}
|
|
181
238
|
export var inherit = function (subclass, superclass) {
|
|
182
239
|
var F = function () {}
|
|
183
240
|
F.prototype = superclass.prototype
|
|
@@ -654,6 +711,16 @@ export var urlParse = function (para) {
|
|
|
654
711
|
}
|
|
655
712
|
return new URLParser(para)
|
|
656
713
|
}
|
|
714
|
+
export function elementMatches(element, selector) {
|
|
715
|
+
if (element.matches) {
|
|
716
|
+
return element.matches(selector)
|
|
717
|
+
}
|
|
718
|
+
// IE11 support
|
|
719
|
+
if (element.msMatchesSelector) {
|
|
720
|
+
return element.msMatchesSelector(selector)
|
|
721
|
+
}
|
|
722
|
+
return false
|
|
723
|
+
}
|
|
657
724
|
export var addEvent = function () {
|
|
658
725
|
function fixEvent(event) {
|
|
659
726
|
if (event) {
|
|
@@ -1463,7 +1530,10 @@ export function noop() {}
|
|
|
1463
1530
|
export var ONE_SECOND = 1000
|
|
1464
1531
|
export var ONE_MINUTE = 60 * ONE_SECOND
|
|
1465
1532
|
export var ONE_HOUR = 60 * ONE_MINUTE
|
|
1466
|
-
export var
|
|
1533
|
+
export var ONE_DAY = 24 * ONE_HOUR
|
|
1534
|
+
export var ONE_YEAR = 365 * ONE_DAY
|
|
1535
|
+
export var ONE_KIBI_BYTE = 1024
|
|
1536
|
+
export var ONE_MEBI_BYTE = 1024 * ONE_KIBI_BYTE
|
|
1467
1537
|
/**
|
|
1468
1538
|
* Return true if the draw is successful
|
|
1469
1539
|
* @param threshold between 0 and 100
|
|
@@ -1504,7 +1574,7 @@ export function preferredNow() {
|
|
|
1504
1574
|
return relativeNow()
|
|
1505
1575
|
}
|
|
1506
1576
|
export function getTimestamp(relativeTime) {
|
|
1507
|
-
return Math.
|
|
1577
|
+
return Math.round(getNavigationStart() + relativeTime)
|
|
1508
1578
|
}
|
|
1509
1579
|
export function relativeNow() {
|
|
1510
1580
|
return performance.now()
|
|
@@ -1514,8 +1584,21 @@ export function clocksNow() {
|
|
|
1514
1584
|
return { relative: relativeNow(), timeStamp: timeStampNow() }
|
|
1515
1585
|
}
|
|
1516
1586
|
export function timeStampNow() {
|
|
1587
|
+
return dateNow()
|
|
1588
|
+
}
|
|
1589
|
+
|
|
1590
|
+
export function looksLikeRelativeTime(time) {
|
|
1591
|
+
return time < ONE_YEAR
|
|
1592
|
+
}
|
|
1593
|
+
export function dateNow() {
|
|
1594
|
+
// Do not use `Date.now` because sometimes websites are wrongly "polyfilling" it. For example, we
|
|
1595
|
+
// had some users using a very old version of `datejs`, which patched `Date.now` to return a Date
|
|
1596
|
+
// instance instead of a timestamp[1]. Those users are unlikely to fix this, so let's handle this
|
|
1597
|
+
// case ourselves.
|
|
1598
|
+
// [1]: https://github.com/datejs/Datejs/blob/97f5c7c58c5bc5accdab8aa7602b6ac56462d778/src/core-debug.js#L14-L16
|
|
1517
1599
|
return new Date().getTime()
|
|
1518
1600
|
}
|
|
1601
|
+
|
|
1519
1602
|
export function elapsed(start, end) {
|
|
1520
1603
|
return end - start
|
|
1521
1604
|
}
|
|
@@ -1530,7 +1613,20 @@ export function preferredTimeStamp(clocks) {
|
|
|
1530
1613
|
return getTimestamp(clocks.relative)
|
|
1531
1614
|
}
|
|
1532
1615
|
export function relativeToClocks(relative) {
|
|
1533
|
-
return { relative: relative, timeStamp:
|
|
1616
|
+
return { relative: relative, timeStamp: getCorrectedTimeStamp(relative) }
|
|
1617
|
+
}
|
|
1618
|
+
export function currentDrift() {
|
|
1619
|
+
// eslint-disable-next-line @typescript-eslint/restrict-plus-operands
|
|
1620
|
+
return Math.round(dateNow() - (getNavigationStart() + performance.now()))
|
|
1621
|
+
}
|
|
1622
|
+
|
|
1623
|
+
function getCorrectedTimeStamp(relativeTime) {
|
|
1624
|
+
var correctedOrigin = dateNow() - performance.now()
|
|
1625
|
+
// apply correction only for positive drift
|
|
1626
|
+
if (correctedOrigin > getNavigationStart()) {
|
|
1627
|
+
return Math.round(correctedOrigin + relativeTime)
|
|
1628
|
+
}
|
|
1629
|
+
return getTimestamp(relativeTime)
|
|
1534
1630
|
}
|
|
1535
1631
|
/**
|
|
1536
1632
|
* Navigation start slightly change on some rare cases
|
|
@@ -1643,7 +1739,25 @@ export function createContextManager() {
|
|
|
1643
1739
|
} else {
|
|
1644
1740
|
console.error('content 需要传递对象类型数据')
|
|
1645
1741
|
}
|
|
1646
|
-
|
|
1742
|
+
},
|
|
1743
|
+
getContext: function() {
|
|
1744
|
+
return deepClone(context)
|
|
1745
|
+
},
|
|
1746
|
+
|
|
1747
|
+
setContext: function(newContext) {
|
|
1748
|
+
context = deepClone(newContext)
|
|
1749
|
+
},
|
|
1750
|
+
|
|
1751
|
+
setContextProperty: function(key, property){
|
|
1752
|
+
context[key] = deepClone(property)
|
|
1753
|
+
},
|
|
1754
|
+
|
|
1755
|
+
removeContextProperty: function(key){
|
|
1756
|
+
delete context[key]
|
|
1757
|
+
},
|
|
1758
|
+
|
|
1759
|
+
clearContext: function(){
|
|
1760
|
+
context = {}
|
|
1647
1761
|
}
|
|
1648
1762
|
}
|
|
1649
1763
|
}
|
|
@@ -1656,7 +1770,32 @@ export function find(array, predicate) {
|
|
|
1656
1770
|
}
|
|
1657
1771
|
return undefined
|
|
1658
1772
|
}
|
|
1659
|
-
|
|
1773
|
+
export function arrayFrom(arrayLike) {
|
|
1774
|
+
if (Array.from) {
|
|
1775
|
+
return Array.from(arrayLike)
|
|
1776
|
+
}
|
|
1777
|
+
var array = []
|
|
1778
|
+
if (arrayLike instanceof Set) {
|
|
1779
|
+
arrayLike.forEach(function(item) { array.push(item) })
|
|
1780
|
+
} else {
|
|
1781
|
+
for (var i = 0; i < arrayLike.length; i++) {
|
|
1782
|
+
array.push(arrayLike[i])
|
|
1783
|
+
}
|
|
1784
|
+
}
|
|
1785
|
+
return array
|
|
1786
|
+
}
|
|
1787
|
+
export function findLast(
|
|
1788
|
+
array,
|
|
1789
|
+
predicate
|
|
1790
|
+
) {
|
|
1791
|
+
for (var i = array.length - 1; i >= 0; i -= 1) {
|
|
1792
|
+
var item = array[i]
|
|
1793
|
+
if (predicate(item, i, array)) {
|
|
1794
|
+
return item
|
|
1795
|
+
}
|
|
1796
|
+
}
|
|
1797
|
+
return undefined
|
|
1798
|
+
}
|
|
1660
1799
|
export function isPercentage(value) {
|
|
1661
1800
|
return isNumber(value) && value >= 0 && value <= 100
|
|
1662
1801
|
}
|
|
@@ -1665,6 +1804,14 @@ export function getLocationOrigin() {
|
|
|
1665
1804
|
return getLinkElementOrigin(window.location)
|
|
1666
1805
|
}
|
|
1667
1806
|
|
|
1807
|
+
export function isIE() {
|
|
1808
|
+
return Boolean(document.documentMode)
|
|
1809
|
+
}
|
|
1810
|
+
|
|
1811
|
+
export function isChromium() {
|
|
1812
|
+
return !!window.chrome || /HeadlessChrome/.test(window.navigator.userAgent)
|
|
1813
|
+
}
|
|
1814
|
+
|
|
1668
1815
|
/**
|
|
1669
1816
|
* IE fallback
|
|
1670
1817
|
* https://developer.mozilla.org/en-US/docs/Web/API/HTMLHyperlinkElementUtils/origin
|
|
@@ -1738,3 +1885,10 @@ export function escapeRowField(value) {
|
|
|
1738
1885
|
return value
|
|
1739
1886
|
}
|
|
1740
1887
|
}
|
|
1888
|
+
export function isNullUndefinedDefaultValue(data,defaultValue) {
|
|
1889
|
+
if (data !== null && data !== void 0) {
|
|
1890
|
+
return data
|
|
1891
|
+
} else {
|
|
1892
|
+
return defaultValue
|
|
1893
|
+
}
|
|
1894
|
+
}
|
package/src/index.js
CHANGED
|
@@ -1,22 +1,33 @@
|
|
|
1
1
|
export * from './helper/boundedBuffer'
|
|
2
|
+
export * from './helper/contextHistory'
|
|
2
3
|
export * from './helper/deviceInfo'
|
|
3
4
|
export * from './helper/enums'
|
|
4
|
-
export * from './helper/
|
|
5
|
+
export * from './helper/instrumentMethod'
|
|
5
6
|
export * from './helper/errorTools'
|
|
7
|
+
export * from './error/trackRuntimeError'
|
|
8
|
+
export * from './console/consoleObservable'
|
|
9
|
+
export * from './report/reportObservable'
|
|
10
|
+
export * from './helper/display'
|
|
6
11
|
export * from './helper/eventEmitter'
|
|
7
12
|
export * from './helper/lifeCycle'
|
|
8
13
|
export * from './helper/limitModification'
|
|
14
|
+
export * from './helper/createEventRateLimiter'
|
|
9
15
|
export * from './helper/observable'
|
|
10
16
|
export * from './helper/tools'
|
|
11
17
|
export * from './helper/urlPolyfill'
|
|
12
18
|
export * from './helper/mobileUtil'
|
|
13
19
|
export * from './tracekit'
|
|
14
|
-
export * from './configuration'
|
|
15
|
-
export * from './
|
|
20
|
+
export * from './configuration/configuration'
|
|
21
|
+
export * from './configuration/transportConfiguration'
|
|
22
|
+
export * from './browser/cookie'
|
|
23
|
+
export * from './browser/fetchObservable'
|
|
24
|
+
export * from './browser/xhrObservable'
|
|
16
25
|
export * from './dataMap'
|
|
17
|
-
export * from './errorCollection'
|
|
18
|
-
export * from './fetchProxy'
|
|
19
26
|
export * from './init'
|
|
20
|
-
export * from './sessionManagement'
|
|
27
|
+
export * from './session/sessionManagement'
|
|
28
|
+
export * from './session/sessionConstants'
|
|
29
|
+
export * from './session/sessionCookieStore'
|
|
30
|
+
export * from './session/sessionStore'
|
|
21
31
|
export * from './transport'
|
|
22
|
-
export * from './
|
|
32
|
+
export * from './synthetics/syntheticsWorkerValues'
|
|
33
|
+
|
package/src/init.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { extend, each } from './helper/tools'
|
|
2
|
-
import { areCookiesAuthorized } from './cookie'
|
|
3
2
|
export function makeGlobal(stub) {
|
|
4
3
|
var global = extend({}, stub, {
|
|
5
4
|
onReady: function (callback) {
|
|
@@ -63,22 +62,22 @@ export function getGlobalObject() {
|
|
|
63
62
|
}
|
|
64
63
|
return globalObject
|
|
65
64
|
}
|
|
66
|
-
export function checkCookiesAuthorized(options) {
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
}
|
|
65
|
+
// export function checkCookiesAuthorized(options) {
|
|
66
|
+
// if (!areCookiesAuthorized(options)) {
|
|
67
|
+
// console.warn('Cookies are not authorized, we will not send any data.')
|
|
68
|
+
// return false
|
|
69
|
+
// }
|
|
70
|
+
// return true
|
|
71
|
+
// }
|
|
73
72
|
|
|
74
|
-
export function checkIsNotLocalFile() {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
}
|
|
73
|
+
// export function checkIsNotLocalFile() {
|
|
74
|
+
// if (isLocalFile()) {
|
|
75
|
+
// console.error('Execution is not allowed in the current context.')
|
|
76
|
+
// return false
|
|
77
|
+
// }
|
|
78
|
+
// return true
|
|
79
|
+
// }
|
|
81
80
|
|
|
82
|
-
function isLocalFile() {
|
|
83
|
-
|
|
84
|
-
}
|
|
81
|
+
// function isLocalFile() {
|
|
82
|
+
// return window.location.protocol === 'file:'
|
|
83
|
+
// }
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { toStackTraceString } from '../helper/errorTools'
|
|
2
|
+
import { mergeObservables, Observable } from '../helper/observable'
|
|
3
|
+
import { includes, addEventListener, safeTruncate, filter, each } from '../helper/tools'
|
|
4
|
+
import { DOM_EVENT } from '../helper/enums'
|
|
5
|
+
export var RawReportType = {
|
|
6
|
+
intervention: 'intervention',
|
|
7
|
+
deprecation: 'deprecation',
|
|
8
|
+
cspViolation: 'csp_violation',
|
|
9
|
+
}
|
|
10
|
+
export function initReportObservable(apis) {
|
|
11
|
+
var observables = []
|
|
12
|
+
|
|
13
|
+
if (includes(apis, RawReportType.cspViolation)) {
|
|
14
|
+
observables.push(createCspViolationReportObservable())
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
var reportTypes = filter(apis, function(api) { return api !== RawReportType.cspViolation })
|
|
18
|
+
if (reportTypes.length) {
|
|
19
|
+
observables.push(createReportObservable(reportTypes))
|
|
20
|
+
}
|
|
21
|
+
return mergeObservables.apply(this, observables)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function createReportObservable(reportTypes) {
|
|
25
|
+
var observable = new Observable(function() {
|
|
26
|
+
if (!window.ReportingObserver) {
|
|
27
|
+
return
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
var handleReports = function(reports) {
|
|
31
|
+
each(reports, function(report) {
|
|
32
|
+
observable.notify(buildRawReportFromReport(report))
|
|
33
|
+
})
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
var observer = new window.ReportingObserver(handleReports, {
|
|
37
|
+
types: reportTypes,
|
|
38
|
+
buffered: true,
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
observer.observe()
|
|
42
|
+
return function() {
|
|
43
|
+
observer.disconnect()
|
|
44
|
+
}
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
return observable
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function createCspViolationReportObservable() {
|
|
51
|
+
var observable = new Observable(function() {
|
|
52
|
+
var handleCspViolation = function(event) {
|
|
53
|
+
observable.notify(buildRawReportFromCspViolation(event))
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
var _addEventListener = addEventListener(document, DOM_EVENT.SECURITY_POLICY_VIOLATION, handleCspViolation)
|
|
57
|
+
|
|
58
|
+
return _addEventListener.stop
|
|
59
|
+
})
|
|
60
|
+
return observable
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function buildRawReportFromReport(report) {
|
|
64
|
+
var body = report.body
|
|
65
|
+
var type = report.type
|
|
66
|
+
return {
|
|
67
|
+
type: type,
|
|
68
|
+
subtype: body.id,
|
|
69
|
+
message: type + ': ' + body.message,
|
|
70
|
+
stack: buildStack(body.id, body.message, body.sourceFile, body.lineNumber, body.columnNumber),
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function buildRawReportFromCspViolation(event) {
|
|
75
|
+
var type = RawReportType.cspViolation
|
|
76
|
+
var message = '\''+ event.blockedURI + '\' blocked by \'' + event.effectiveDirective + '\' directive'
|
|
77
|
+
return {
|
|
78
|
+
type: RawReportType.cspViolation,
|
|
79
|
+
subtype: event.effectiveDirective,
|
|
80
|
+
message: type + ': ' + message,
|
|
81
|
+
stack: buildStack(
|
|
82
|
+
event.effectiveDirective,
|
|
83
|
+
message + ' of the policy "'+ safeTruncate(event.originalPolicy, 100, '...') + '"',
|
|
84
|
+
event.sourceFile,
|
|
85
|
+
event.lineNumber,
|
|
86
|
+
event.columnNumber
|
|
87
|
+
),
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function buildStack(
|
|
92
|
+
name,
|
|
93
|
+
message,
|
|
94
|
+
sourceFile,
|
|
95
|
+
lineNumber,
|
|
96
|
+
columnNumber
|
|
97
|
+
){
|
|
98
|
+
return (
|
|
99
|
+
sourceFile &&
|
|
100
|
+
toStackTraceString({
|
|
101
|
+
name: name,
|
|
102
|
+
message: message,
|
|
103
|
+
stack: [
|
|
104
|
+
{
|
|
105
|
+
func: '?',
|
|
106
|
+
url: sourceFile,
|
|
107
|
+
line: lineNumber,
|
|
108
|
+
column: columnNumber,
|
|
109
|
+
},
|
|
110
|
+
],
|
|
111
|
+
})
|
|
112
|
+
)
|
|
113
|
+
}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import { getCookie, setCookie } from '../browser/cookie'
|
|
2
|
+
import { isChromium, dateNow, isEmptyObject, UUID, objectEntries,map, each, } from '../helper/tools'
|
|
3
|
+
import { SESSION_EXPIRATION_DELAY } from './sessionConstants'
|
|
4
|
+
|
|
5
|
+
var SESSION_ENTRY_REGEXP = /^([a-z]+)=([a-z0-9-]+)$/
|
|
6
|
+
var SESSION_ENTRY_SEPARATOR = '&'
|
|
7
|
+
|
|
8
|
+
export var SESSION_COOKIE_NAME = '_dataflux_s'
|
|
9
|
+
|
|
10
|
+
// arbitrary values
|
|
11
|
+
export var LOCK_RETRY_DELAY = 10
|
|
12
|
+
export var MAX_NUMBER_OF_LOCK_RETRIES = 100
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
var bufferedOperations= []
|
|
16
|
+
var ongoingOperations
|
|
17
|
+
|
|
18
|
+
export function withCookieLockAccess(operations, numberOfRetries) {
|
|
19
|
+
if (typeof numberOfRetries === 'undefined') {
|
|
20
|
+
numberOfRetries = 0
|
|
21
|
+
}
|
|
22
|
+
if (!ongoingOperations) {
|
|
23
|
+
ongoingOperations = operations
|
|
24
|
+
}
|
|
25
|
+
if (operations !== ongoingOperations) {
|
|
26
|
+
bufferedOperations.push(operations)
|
|
27
|
+
return
|
|
28
|
+
}
|
|
29
|
+
if (numberOfRetries >= MAX_NUMBER_OF_LOCK_RETRIES) {
|
|
30
|
+
next()
|
|
31
|
+
return
|
|
32
|
+
}
|
|
33
|
+
var currentLock
|
|
34
|
+
var currentSession = retrieveSession()
|
|
35
|
+
if (isCookieLockEnabled()) {
|
|
36
|
+
// if someone has lock, retry later
|
|
37
|
+
if (currentSession.lock) {
|
|
38
|
+
retryLater(operations, numberOfRetries)
|
|
39
|
+
return
|
|
40
|
+
}
|
|
41
|
+
// acquire lock
|
|
42
|
+
currentLock = UUID()
|
|
43
|
+
currentSession.lock = currentLock
|
|
44
|
+
setSession(currentSession, operations.options)
|
|
45
|
+
// if lock is not acquired, retry later
|
|
46
|
+
currentSession = retrieveSession()
|
|
47
|
+
if (currentSession.lock !== currentLock) {
|
|
48
|
+
retryLater(operations, numberOfRetries)
|
|
49
|
+
return
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
var processedSession = operations.process(currentSession)
|
|
53
|
+
if (isCookieLockEnabled()) {
|
|
54
|
+
// if lock corrupted after process, retry later
|
|
55
|
+
currentSession = retrieveSession()
|
|
56
|
+
if (currentSession.lock !== currentLock) {
|
|
57
|
+
retryLater(operations, numberOfRetries)
|
|
58
|
+
return
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
if (processedSession) {
|
|
62
|
+
persistSession(processedSession, operations.options)
|
|
63
|
+
}
|
|
64
|
+
if (isCookieLockEnabled()) {
|
|
65
|
+
// correctly handle lock around expiration would require to handle this case properly at several levels
|
|
66
|
+
// since we don't have evidence of lock issues around expiration, let's just not do the corruption check for it
|
|
67
|
+
if (!(processedSession && isExpiredState(processedSession))) {
|
|
68
|
+
// if lock corrupted after persist, retry later
|
|
69
|
+
currentSession = retrieveSession()
|
|
70
|
+
if (currentSession.lock !== currentLock) {
|
|
71
|
+
retryLater(operations, numberOfRetries)
|
|
72
|
+
return
|
|
73
|
+
}
|
|
74
|
+
delete currentSession.lock
|
|
75
|
+
setSession(currentSession, operations.options)
|
|
76
|
+
processedSession = currentSession
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
// call after even if session is not persisted in order to perform operations on
|
|
80
|
+
// up-to-date cookie value, the value could have been modified by another tab
|
|
81
|
+
if (operations.after) {
|
|
82
|
+
operations.after(processedSession || currentSession)
|
|
83
|
+
}
|
|
84
|
+
next()
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Cookie lock strategy allows mitigating issues due to concurrent access to cookie.
|
|
89
|
+
* This issue concerns only chromium browsers and enabling this on firefox increase cookie write failures.
|
|
90
|
+
*/
|
|
91
|
+
function isCookieLockEnabled() {
|
|
92
|
+
return isChromium()
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function retryLater(operations, currentNumberOfRetries) {
|
|
96
|
+
setTimeout(
|
|
97
|
+
function() {
|
|
98
|
+
withCookieLockAccess(operations, currentNumberOfRetries + 1)
|
|
99
|
+
},
|
|
100
|
+
LOCK_RETRY_DELAY
|
|
101
|
+
)
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function next() {
|
|
105
|
+
ongoingOperations = undefined
|
|
106
|
+
var nextOperations = bufferedOperations.shift()
|
|
107
|
+
if (nextOperations) {
|
|
108
|
+
withCookieLockAccess(nextOperations)
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export function persistSession(session, options) {
|
|
113
|
+
if (isExpiredState(session)) {
|
|
114
|
+
clearSession(options)
|
|
115
|
+
return
|
|
116
|
+
}
|
|
117
|
+
session.expire = String(dateNow() + SESSION_EXPIRATION_DELAY)
|
|
118
|
+
setSession(session, options)
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function setSession(session, options) {
|
|
122
|
+
setCookie(SESSION_COOKIE_NAME, toSessionString(session), SESSION_EXPIRATION_DELAY, options)
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export function toSessionString(session) {
|
|
126
|
+
return map(objectEntries(session), function(item) {
|
|
127
|
+
return item[0] + '=' + item[1]
|
|
128
|
+
}).join(SESSION_ENTRY_SEPARATOR)
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export function retrieveSession() {
|
|
132
|
+
var sessionString = getCookie(SESSION_COOKIE_NAME)
|
|
133
|
+
var session = {}
|
|
134
|
+
if (isValidSessionString(sessionString)) {
|
|
135
|
+
each(sessionString.split(SESSION_ENTRY_SEPARATOR), function(entry) {
|
|
136
|
+
var matches = SESSION_ENTRY_REGEXP.exec(entry)
|
|
137
|
+
if (matches !== null) {
|
|
138
|
+
var key = matches[1]
|
|
139
|
+
var value = matches[2]
|
|
140
|
+
session[key] = value
|
|
141
|
+
}
|
|
142
|
+
})
|
|
143
|
+
}
|
|
144
|
+
return session
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
function isValidSessionString(sessionString) {
|
|
148
|
+
return (
|
|
149
|
+
sessionString !== undefined &&
|
|
150
|
+
(sessionString.indexOf(SESSION_ENTRY_SEPARATOR) !== -1 || SESSION_ENTRY_REGEXP.test(sessionString))
|
|
151
|
+
)
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
function isExpiredState(session) {
|
|
155
|
+
return isEmptyObject(session)
|
|
156
|
+
}
|
|
157
|
+
function clearSession(options) {
|
|
158
|
+
setCookie(SESSION_COOKIE_NAME, '', 0, options)
|
|
159
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { relativeNow, clocksOrigin, ONE_MINUTE, each, addEventListeners, addEventListener } from '../helper/tools'
|
|
2
|
+
import { ContextHistory } from '../helper/contextHistory'
|
|
3
|
+
import { startSessionStore } from './sessionStore'
|
|
4
|
+
import { SESSION_TIME_OUT_DELAY } from './sessionConstants'
|
|
5
|
+
import { DOM_EVENT } from '../helper/enums'
|
|
6
|
+
|
|
7
|
+
export var VISIBILITY_CHECK_DELAY = ONE_MINUTE
|
|
8
|
+
var SESSION_CONTEXT_TIMEOUT_DELAY = SESSION_TIME_OUT_DELAY
|
|
9
|
+
var stopCallbacks = []
|
|
10
|
+
|
|
11
|
+
export var startSessionManager = function(
|
|
12
|
+
options,
|
|
13
|
+
productKey,
|
|
14
|
+
computeSessionState
|
|
15
|
+
) {
|
|
16
|
+
var sessionStore = startSessionStore(options, productKey, computeSessionState)
|
|
17
|
+
stopCallbacks.push(function() {
|
|
18
|
+
return sessionStore.stop()
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
var sessionContextHistory = new ContextHistory(SESSION_CONTEXT_TIMEOUT_DELAY)
|
|
22
|
+
stopCallbacks.push(function() {
|
|
23
|
+
return sessionContextHistory.stop()
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
sessionStore.renewObservable.subscribe(function(){
|
|
27
|
+
sessionContextHistory.add(buildSessionContext(), relativeNow())
|
|
28
|
+
})
|
|
29
|
+
sessionStore.expireObservable.subscribe(function() {
|
|
30
|
+
sessionContextHistory.closeActive(relativeNow())
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
sessionStore.expandOrRenewSession()
|
|
34
|
+
sessionContextHistory.add(buildSessionContext(), clocksOrigin().relative)
|
|
35
|
+
|
|
36
|
+
trackActivity(function() {
|
|
37
|
+
return sessionStore.expandOrRenewSession()
|
|
38
|
+
})
|
|
39
|
+
trackVisibility(function() {
|
|
40
|
+
return sessionStore.expandSession()
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
function buildSessionContext() {
|
|
44
|
+
return {
|
|
45
|
+
id: sessionStore.getSession().id,
|
|
46
|
+
trackingType: sessionStore.getSession()[productKey],
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return {
|
|
51
|
+
findActiveSession: function(startTime) {
|
|
52
|
+
return sessionContextHistory.find(startTime)
|
|
53
|
+
},
|
|
54
|
+
renewObservable: sessionStore.renewObservable,
|
|
55
|
+
expireObservable: sessionStore.expireObservable,
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export function stopSessionManager() {
|
|
60
|
+
each(stopCallbacks, function(e) {
|
|
61
|
+
return e()
|
|
62
|
+
})
|
|
63
|
+
stopCallbacks = []
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function trackActivity(expandOrRenewSession) {
|
|
67
|
+
var _addEventListeners = addEventListeners(
|
|
68
|
+
window,
|
|
69
|
+
[DOM_EVENT.CLICK,DOM_EVENT.TOUCH_START, DOM_EVENT.KEY_DOWN, DOM_EVENT.SCROLL],
|
|
70
|
+
expandOrRenewSession,
|
|
71
|
+
{ capture: true, passive: true }
|
|
72
|
+
)
|
|
73
|
+
stopCallbacks.push(_addEventListeners.stop)
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function trackVisibility(expandSession) {
|
|
77
|
+
var expandSessionWhenVisible = function() {
|
|
78
|
+
if (document.visibilityState === 'visible') {
|
|
79
|
+
expandSession()
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
var _addEventListener= addEventListener(document, DOM_EVENT.VISIBILITY_CHANGE, expandSessionWhenVisible)
|
|
83
|
+
stopCallbacks.push(_addEventListener.stop)
|
|
84
|
+
|
|
85
|
+
var visibilityCheckInterval = setInterval(expandSessionWhenVisible, VISIBILITY_CHECK_DELAY)
|
|
86
|
+
stopCallbacks.push(function() {
|
|
87
|
+
clearInterval(visibilityCheckInterval)
|
|
88
|
+
})
|
|
89
|
+
}
|