@pratham.raval/browser-core 6.22.3 → 6.22.5
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/README.md +1 -1
- package/cjs/boot/displayAlreadyInitializedError.d.ts +1 -1
- package/cjs/boot/init.d.ts +1 -1
- package/cjs/browser/cookie.d.ts +10 -0
- package/cjs/browser/cookie.js +13 -0
- package/cjs/browser/cookie.js.map +1 -1
- package/cjs/domain/configuration/configuration.js +4 -4
- package/cjs/domain/configuration/configuration.js.map +1 -1
- package/cjs/domain/configuration/endpointBuilder.js +16 -24
- package/cjs/domain/configuration/endpointBuilder.js.map +1 -1
- package/cjs/domain/configuration/transportConfiguration.js +5 -15
- package/cjs/domain/configuration/transportConfiguration.js.map +1 -1
- package/cjs/domain/intakeSites.d.ts +1 -7
- package/cjs/domain/intakeSites.js +2 -8
- package/cjs/domain/intakeSites.js.map +1 -1
- package/cjs/domain/session/oldCookiesMigration.d.ts +1 -1
- package/cjs/domain/session/oldCookiesMigration.js +1 -1
- package/cjs/domain/session/sessionManager.d.ts +1 -0
- package/cjs/domain/session/sessionManager.js +24 -6
- package/cjs/domain/session/sessionManager.js.map +1 -1
- package/cjs/domain/session/sessionState.js +2 -8
- package/cjs/domain/session/sessionState.js.map +1 -1
- package/cjs/domain/session/sessionStore.d.ts +1 -1
- package/cjs/domain/session/sessionStore.js +5 -1
- package/cjs/domain/session/sessionStore.js.map +1 -1
- package/cjs/domain/session/storeStrategies/sessionInCookie.d.ts +5 -1
- package/cjs/domain/session/storeStrategies/sessionInCookie.js +52 -3
- package/cjs/domain/session/storeStrategies/sessionInCookie.js.map +1 -1
- package/cjs/domain/session/storeStrategies/sessionInLocalStorage.d.ts +2 -0
- package/cjs/domain/session/storeStrategies/sessionInLocalStorage.js +1 -0
- package/cjs/domain/session/storeStrategies/sessionInLocalStorage.js.map +1 -1
- package/cjs/domain/session/storeStrategies/sessionStoreStrategy.d.ts +1 -1
- package/cjs/domain/session/storeStrategies/sessionStoreStrategy.js +1 -1
- package/cjs/domain/synthetics/syntheticsWorkerValues.d.ts +6 -6
- package/cjs/domain/synthetics/syntheticsWorkerValues.js +6 -6
- package/cjs/domain/synthetics/syntheticsWorkerValues.js.map +1 -1
- package/cjs/domain/tags.js +6 -5
- package/cjs/domain/tags.js.map +1 -1
- package/cjs/domain/telemetry/telemetry.js +4 -5
- package/cjs/domain/telemetry/telemetry.js.map +1 -1
- package/cjs/domain/telemetry/telemetryEvent.types.d.ts +1 -1
- package/cjs/index.d.ts +1 -1
- package/cjs/index.js +3 -2
- package/cjs/index.js.map +1 -1
- package/cjs/tools/display.js +1 -1
- package/cjs/tools/display.js.map +1 -1
- package/cjs/tools/experimentalFeatures.d.ts +2 -1
- package/cjs/tools/experimentalFeatures.js +1 -0
- package/cjs/tools/experimentalFeatures.js.map +1 -1
- package/cjs/tools/utils/browserDetection.d.ts +2 -0
- package/cjs/tools/utils/browserDetection.js +20 -0
- package/cjs/tools/utils/browserDetection.js.map +1 -1
- package/cjs/tools/utils/stringUtils.d.ts +15 -0
- package/cjs/tools/utils/stringUtils.js +36 -0
- package/cjs/tools/utils/stringUtils.js.map +1 -1
- package/cjs/transport/httpRequest.d.ts +1 -0
- package/cjs/transport/httpRequest.js +26 -4
- package/cjs/transport/httpRequest.js.map +1 -1
- package/cjs/transport/index.d.ts +1 -1
- package/cjs/transport/index.js +2 -1
- package/cjs/transport/index.js.map +1 -1
- package/esm/boot/displayAlreadyInitializedError.d.ts +1 -1
- package/esm/boot/init.d.ts +1 -1
- package/esm/browser/cookie.d.ts +10 -0
- package/esm/browser/cookie.js +13 -1
- package/esm/browser/cookie.js.map +1 -1
- package/esm/domain/configuration/configuration.js +5 -5
- package/esm/domain/configuration/configuration.js.map +1 -1
- package/esm/domain/configuration/endpointBuilder.js +16 -24
- package/esm/domain/configuration/endpointBuilder.js.map +1 -1
- package/esm/domain/configuration/transportConfiguration.js +6 -16
- package/esm/domain/configuration/transportConfiguration.js.map +1 -1
- package/esm/domain/intakeSites.d.ts +1 -7
- package/esm/domain/intakeSites.js +1 -7
- package/esm/domain/intakeSites.js.map +1 -1
- package/esm/domain/session/oldCookiesMigration.d.ts +1 -1
- package/esm/domain/session/oldCookiesMigration.js +1 -1
- package/esm/domain/session/sessionManager.d.ts +1 -0
- package/esm/domain/session/sessionManager.js +25 -7
- package/esm/domain/session/sessionManager.js.map +1 -1
- package/esm/domain/session/sessionState.js +2 -8
- package/esm/domain/session/sessionState.js.map +1 -1
- package/esm/domain/session/sessionStore.d.ts +1 -1
- package/esm/domain/session/sessionStore.js +5 -1
- package/esm/domain/session/sessionStore.js.map +1 -1
- package/esm/domain/session/storeStrategies/sessionInCookie.d.ts +5 -1
- package/esm/domain/session/storeStrategies/sessionInCookie.js +53 -4
- package/esm/domain/session/storeStrategies/sessionInCookie.js.map +1 -1
- package/esm/domain/session/storeStrategies/sessionInLocalStorage.d.ts +2 -0
- package/esm/domain/session/storeStrategies/sessionInLocalStorage.js +1 -1
- package/esm/domain/session/storeStrategies/sessionInLocalStorage.js.map +1 -1
- package/esm/domain/session/storeStrategies/sessionStoreStrategy.d.ts +1 -1
- package/esm/domain/session/storeStrategies/sessionStoreStrategy.js +1 -1
- package/esm/domain/synthetics/syntheticsWorkerValues.d.ts +6 -6
- package/esm/domain/synthetics/syntheticsWorkerValues.js +6 -6
- package/esm/domain/synthetics/syntheticsWorkerValues.js.map +1 -1
- package/esm/domain/tags.js +6 -5
- package/esm/domain/tags.js.map +1 -1
- package/esm/domain/telemetry/telemetry.js +4 -5
- package/esm/domain/telemetry/telemetry.js.map +1 -1
- package/esm/domain/telemetry/telemetryEvent.types.d.ts +1 -1
- package/esm/index.d.ts +1 -1
- package/esm/index.js +1 -1
- package/esm/index.js.map +1 -1
- package/esm/tools/display.js +1 -1
- package/esm/tools/display.js.map +1 -1
- package/esm/tools/experimentalFeatures.d.ts +2 -1
- package/esm/tools/experimentalFeatures.js +1 -0
- package/esm/tools/experimentalFeatures.js.map +1 -1
- package/esm/tools/utils/browserDetection.d.ts +2 -0
- package/esm/tools/utils/browserDetection.js +18 -0
- package/esm/tools/utils/browserDetection.js.map +1 -1
- package/esm/tools/utils/stringUtils.d.ts +15 -0
- package/esm/tools/utils/stringUtils.js +35 -0
- package/esm/tools/utils/stringUtils.js.map +1 -1
- package/esm/transport/httpRequest.d.ts +1 -0
- package/esm/transport/httpRequest.js +25 -4
- package/esm/transport/httpRequest.js.map +1 -1
- package/esm/transport/index.d.ts +1 -1
- package/esm/transport/index.js +1 -1
- package/esm/transport/index.js.map +1 -1
- package/package.json +4 -6
- package/src/boot/displayAlreadyInitializedError.ts +1 -1
- package/src/boot/init.ts +1 -1
- package/src/browser/cookie.ts +19 -1
- package/src/domain/configuration/configuration.ts +4 -4
- package/src/domain/configuration/endpointBuilder.ts +17 -27
- package/src/domain/configuration/transportConfiguration.ts +6 -18
- package/src/domain/intakeSites.ts +2 -17
- package/src/domain/session/oldCookiesMigration.ts +1 -1
- package/src/domain/session/sessionManager.ts +28 -7
- package/src/domain/session/sessionState.ts +2 -7
- package/src/domain/session/sessionStore.ts +6 -2
- package/src/domain/session/storeStrategies/sessionInCookie.ts +66 -4
- package/src/domain/session/storeStrategies/sessionInLocalStorage.ts +1 -1
- package/src/domain/session/storeStrategies/sessionStoreStrategy.ts +1 -1
- package/src/domain/synthetics/syntheticsWorkerValues.ts +9 -9
- package/src/domain/tags.ts +6 -6
- package/src/domain/telemetry/telemetry.ts +5 -5
- package/src/domain/telemetry/telemetryEvent.types.ts +1 -1
- package/src/index.ts +1 -0
- package/src/tools/display.ts +1 -1
- package/src/tools/experimentalFeatures.ts +1 -0
- package/src/tools/utils/browserDetection.ts +26 -0
- package/src/tools/utils/stringUtils.ts +34 -0
- package/src/transport/httpRequest.ts +31 -5
- package/src/transport/index.ts +1 -1
|
@@ -46,6 +46,7 @@ export interface RetryInfo {
|
|
|
46
46
|
count: number;
|
|
47
47
|
lastFailureStatus: number;
|
|
48
48
|
}
|
|
49
|
+
export declare function setCurrentSite(site: string | undefined): void;
|
|
49
50
|
export declare function createHttpRequest<Body extends Payload = Payload>(endpointBuilders: EndpointBuilder[], bytesLimit: number, reportError: (error: RawError) => void): HttpRequest<Body>;
|
|
50
51
|
export declare function fetchKeepAliveStrategy(endpointBuilder: EndpointBuilder, bytesLimit: number, payload: Payload, onResponse?: (r: HttpResponse) => void): void;
|
|
51
52
|
export declare function fetchStrategy(endpointBuilder: EndpointBuilder, payload: Payload, onResponse?: (r: HttpResponse) => void): void;
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import { monitor, monitorError } from '../tools/monitor';
|
|
2
2
|
import { Observable } from '../tools/observable';
|
|
3
|
+
import { getDetailedBrowserName } from '../tools/utils/browserDetection';
|
|
3
4
|
import { newRetryState, sendWithRetryStrategy } from './sendWithRetryStrategy';
|
|
5
|
+
let currentSite;
|
|
6
|
+
export function setCurrentSite(site) {
|
|
7
|
+
currentSite = site;
|
|
8
|
+
}
|
|
4
9
|
export function createHttpRequest(endpointBuilders, bytesLimit, reportError) {
|
|
5
10
|
const observable = new Observable();
|
|
6
11
|
const retryState = newRetryState();
|
|
@@ -49,9 +54,15 @@ export function fetchKeepAliveStrategy(endpointBuilder, bytesLimit, payload, onR
|
|
|
49
54
|
const canUseKeepAlive = isKeepAliveSupported() && payload.bytesCount < bytesLimit;
|
|
50
55
|
if (canUseKeepAlive) {
|
|
51
56
|
const fetchUrl = endpointBuilder.build('fetch-keepalive', payload);
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
.
|
|
57
|
+
const headers = buildRequestHeaders(fetchUrl);
|
|
58
|
+
fetch(fetchUrl, { method: 'POST', body: payload.data, keepalive: true, mode: 'cors', headers })
|
|
59
|
+
.then(monitor((response) => {
|
|
60
|
+
onResponse === null || onResponse === void 0 ? void 0 : onResponse({ status: response.status, type: response.type });
|
|
61
|
+
}))
|
|
62
|
+
.catch(monitor((error) => {
|
|
63
|
+
fetchStrategy(endpointBuilder, payload, onResponse);
|
|
64
|
+
onResponse === null || onResponse === void 0 ? void 0 : onResponse({ status: 0 });
|
|
65
|
+
}));
|
|
55
66
|
}
|
|
56
67
|
else {
|
|
57
68
|
fetchStrategy(endpointBuilder, payload, onResponse);
|
|
@@ -59,7 +70,8 @@ export function fetchKeepAliveStrategy(endpointBuilder, bytesLimit, payload, onR
|
|
|
59
70
|
}
|
|
60
71
|
export function fetchStrategy(endpointBuilder, payload, onResponse) {
|
|
61
72
|
const fetchUrl = endpointBuilder.build('fetch', payload);
|
|
62
|
-
|
|
73
|
+
const headers = buildRequestHeaders(fetchUrl);
|
|
74
|
+
fetch(fetchUrl, { method: 'POST', body: payload.data, mode: 'cors', headers })
|
|
63
75
|
.then(monitor((response) => onResponse === null || onResponse === void 0 ? void 0 : onResponse({ status: response.status, type: response.type })))
|
|
64
76
|
.catch(monitor(() => onResponse === null || onResponse === void 0 ? void 0 : onResponse({ status: 0 })));
|
|
65
77
|
}
|
|
@@ -72,4 +84,13 @@ function isKeepAliveSupported() {
|
|
|
72
84
|
return false;
|
|
73
85
|
}
|
|
74
86
|
}
|
|
87
|
+
function buildRequestHeaders(url) {
|
|
88
|
+
const headers = {};
|
|
89
|
+
// dynamically match your RUM SDK endpoint host
|
|
90
|
+
// "site" comes from init() call, so this automatically adjusts
|
|
91
|
+
if (currentSite && url) {
|
|
92
|
+
headers['X-Browser-Name'] = getDetailedBrowserName();
|
|
93
|
+
}
|
|
94
|
+
return headers;
|
|
95
|
+
}
|
|
75
96
|
//# sourceMappingURL=httpRequest.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"httpRequest.js","sourceRoot":"","sources":["../../src/transport/httpRequest.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAExD,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAChD,OAAO,EAAE,aAAa,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAA;AA2D9E,MAAM,UAAU,iBAAiB,CAC/B,gBAAmC,EACnC,UAAkB,EAClB,WAAsC;IAEtC,MAAM,UAAU,GAAG,IAAI,UAAU,EAA0B,CAAA;IAC3D,MAAM,UAAU,GAAG,aAAa,EAAQ,CAAA;IAExC,OAAO;QACL,UAAU;QACV,IAAI,EAAE,CAAC,OAAa,EAAE,EAAE;YACtB,KAAK,MAAM,eAAe,IAAI,gBAAgB,EAAE,CAAC;gBAC/C,qBAAqB,CACnB,OAAO,EACP,UAAU,EACV,CAAC,OAAO,EAAE,UAAU,EAAE,EAAE,CAAC,sBAAsB,CAAC,eAAe,EAAE,UAAU,EAAE,OAAO,EAAE,UAAU,CAAC,EACjG,eAAe,CAAC,SAAS,EACzB,WAAW,EACX,UAAU,CACX,CAAA;YACH,CAAC;QACH,CAAC;QACD;;;WAGG;QACH,UAAU,EAAE,CAAC,OAAa,EAAE,EAAE;YAC5B,KAAK,MAAM,eAAe,IAAI,gBAAgB,EAAE,CAAC;gBAC/C,kBAAkB,CAAC,eAAe,EAAE,UAAU,EAAE,OAAO,CAAC,CAAA;YAC1D,CAAC;QACH,CAAC;KACF,CAAA;AACH,CAAC;AAED,SAAS,kBAAkB,CAAC,eAAgC,EAAE,UAAkB,EAAE,OAAgB;IAChG,MAAM,YAAY,GAAG,CAAC,CAAC,SAAS,CAAC,UAAU,IAAI,OAAO,CAAC,UAAU,GAAG,UAAU,CAAA;IAC9E,IAAI,YAAY,EAAE,CAAC;QACjB,IAAI,CAAC;YACH,MAAM,SAAS,GAAG,eAAe,CAAC,KAAK,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAA;YAC1D,MAAM,QAAQ,GAAG,SAAS,CAAC,UAAU,CAAC,SAAS,EAAE,OAAO,CAAC,IAAI,CAAC,CAAA;YAE9D,IAAI,QAAQ,EAAE,CAAC;gBACb,OAAM;YACR,CAAC;QACH,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,iBAAiB,CAAC,CAAC,CAAC,CAAA;QACtB,CAAC;IACH,CAAC;IAED,aAAa,CAAC,eAAe,EAAE,OAAO,CAAC,CAAA;AACzC,CAAC;AAED,IAAI,sBAAsB,GAAG,KAAK,CAAA;AAElC,SAAS,iBAAiB,CAAC,CAAU;IACnC,IAAI,CAAC,sBAAsB,EAAE,CAAC;QAC5B,sBAAsB,GAAG,IAAI,CAAA;QAC7B,YAAY,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;AACH,CAAC;AAED,MAAM,UAAU,sBAAsB,CACpC,eAAgC,EAChC,UAAkB,EAClB,OAAgB,EAChB,UAAsC;IAEtC,MAAM,eAAe,GAAG,oBAAoB,EAAE,IAAI,OAAO,CAAC,UAAU,GAAG,UAAU,CAAA;IAEjF,IAAI,eAAe,EAAE,CAAC;QACpB,MAAM,QAAQ,GAAG,eAAe,CAAC,KAAK,CAAC,iBAAiB,EAAE,OAAO,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"httpRequest.js","sourceRoot":"","sources":["../../src/transport/httpRequest.ts"],"names":[],"mappings":"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"}
|
package/esm/transport/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export type { BandwidthStats, HttpRequest, HttpRequestEvent, Payload, RetryInfo } from './httpRequest';
|
|
2
|
-
export { createHttpRequest } from './httpRequest';
|
|
2
|
+
export { createHttpRequest, setCurrentSite } from './httpRequest';
|
|
3
3
|
export type { BrowserWindowWithEventBridge, DatadogEventBridge } from './eventBridge';
|
|
4
4
|
export { canUseEventBridge, bridgeSupports, getEventBridge, BridgeCapability } from './eventBridge';
|
|
5
5
|
export { createBatch } from './batch';
|
package/esm/transport/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { createHttpRequest } from './httpRequest';
|
|
1
|
+
export { createHttpRequest, setCurrentSite } from './httpRequest';
|
|
2
2
|
export { canUseEventBridge, bridgeSupports, getEventBridge } from './eventBridge';
|
|
3
3
|
export { createBatch } from './batch';
|
|
4
4
|
export { createFlushController } from './flushController';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/transport/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/transport/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAEjE,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,cAAc,EAAoB,MAAM,eAAe,CAAA;AACnG,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AAErC,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pratham.raval/browser-core",
|
|
3
|
-
"version": "6.22.
|
|
3
|
+
"version": "6.22.5",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"main": "cjs/index.js",
|
|
6
6
|
"module": "esm/index.js",
|
|
@@ -13,11 +13,6 @@
|
|
|
13
13
|
"build:esm": "rm -rf esm && tsc -p tsconfig.esm.json && yarn replace-build-env esm",
|
|
14
14
|
"replace-build-env": "node ../../scripts/build/replace-build-env.ts"
|
|
15
15
|
},
|
|
16
|
-
"repository": {
|
|
17
|
-
"type": "git",
|
|
18
|
-
"url": "https://github.com/DataDog/browser-sdk.git",
|
|
19
|
-
"directory": "packages/core"
|
|
20
|
-
},
|
|
21
16
|
"devDependencies": {
|
|
22
17
|
"@types/pako": "2.0.4",
|
|
23
18
|
"pako": "2.1.0"
|
|
@@ -27,5 +22,8 @@
|
|
|
27
22
|
},
|
|
28
23
|
"publishConfig": {
|
|
29
24
|
"access": "public"
|
|
25
|
+
},
|
|
26
|
+
"dependencies": {
|
|
27
|
+
"ua-parser-js": "2.0.8"
|
|
30
28
|
}
|
|
31
29
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { InitConfiguration } from '../domain/configuration'
|
|
2
2
|
import { display } from '../tools/display'
|
|
3
3
|
|
|
4
|
-
export function displayAlreadyInitializedError(sdkName: '
|
|
4
|
+
export function displayAlreadyInitializedError(sdkName: 'MD_RUM' | 'MD_LOGS', initConfiguration: InitConfiguration) {
|
|
5
5
|
if (!initConfiguration.silentMultipleInit) {
|
|
6
6
|
display.error(`${sdkName} is already initialized.`)
|
|
7
7
|
}
|
package/src/boot/init.ts
CHANGED
|
@@ -12,7 +12,7 @@ export interface PublicApi {
|
|
|
12
12
|
version: string
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
|
-
* For CDN async setup: Early RUM API calls must be wrapped in the `window.
|
|
15
|
+
* For CDN async setup: Early RUM API calls must be wrapped in the `window.MD_RUM.onReady()` callback. This ensures the code only gets executed once the SDK is properly loaded.
|
|
16
16
|
*
|
|
17
17
|
* See [CDN async setup](https://docs.datadoghq.com/real_user_monitoring/browser/#cdn-async) for further information.
|
|
18
18
|
*/
|
package/src/browser/cookie.ts
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import { display } from '../tools/display'
|
|
2
2
|
import { ONE_MINUTE, ONE_SECOND } from '../tools/utils/timeUtils'
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
findAllCommaSeparatedValues,
|
|
5
|
+
findCommaSeparatedValue,
|
|
6
|
+
findCommaSeparatedValues,
|
|
7
|
+
generateUUID,
|
|
8
|
+
} from '../tools/utils/stringUtils'
|
|
4
9
|
import { buildUrl } from '../tools/utils/urlPolyfill'
|
|
5
10
|
|
|
6
11
|
export interface CookieOptions {
|
|
@@ -21,15 +26,28 @@ export function setCookie(name: string, value: string, expireDelay: number = 0,
|
|
|
21
26
|
document.cookie = `${name}=${value};${expires};path=/;samesite=${sameSite}${domain}${secure}${partitioned}`
|
|
22
27
|
}
|
|
23
28
|
|
|
29
|
+
/**
|
|
30
|
+
* Returns the value of the cookie with the given name
|
|
31
|
+
* If there are multiple cookies with the same name, returns the first one
|
|
32
|
+
*/
|
|
24
33
|
export function getCookie(name: string) {
|
|
25
34
|
return findCommaSeparatedValue(document.cookie, name)
|
|
26
35
|
}
|
|
27
36
|
|
|
37
|
+
/**
|
|
38
|
+
* Returns all the values of the cookies with the given name
|
|
39
|
+
*/
|
|
40
|
+
export function getCookies(name: string): string[] {
|
|
41
|
+
return findAllCommaSeparatedValues(document.cookie).get(name) || []
|
|
42
|
+
}
|
|
43
|
+
|
|
28
44
|
let initCookieParsed: Map<string, string> | undefined
|
|
29
45
|
|
|
30
46
|
/**
|
|
31
47
|
* Returns a cached value of the cookie. Use this during SDK initialization (and whenever possible)
|
|
32
48
|
* to avoid accessing document.cookie multiple times.
|
|
49
|
+
*
|
|
50
|
+
* ⚠️ If there are multiple cookies with the same name, returns the LAST one (unlike `getCookie()`)
|
|
33
51
|
*/
|
|
34
52
|
export function getInitCookie(name: string) {
|
|
35
53
|
if (!initCookieParsed) {
|
|
@@ -342,9 +342,9 @@ function isString(tag: unknown, tagName: string): tag is string | undefined | nu
|
|
|
342
342
|
return true
|
|
343
343
|
}
|
|
344
344
|
|
|
345
|
-
function
|
|
346
|
-
if (site && typeof site
|
|
347
|
-
display.error(
|
|
345
|
+
function isValidSite(site: unknown) {
|
|
346
|
+
if (site !== undefined && site !== null && typeof site !== 'string') {
|
|
347
|
+
display.error('Site must be a non-null string')
|
|
348
348
|
return false
|
|
349
349
|
}
|
|
350
350
|
return true
|
|
@@ -376,7 +376,7 @@ export function validateAndBuildConfiguration(
|
|
|
376
376
|
}
|
|
377
377
|
|
|
378
378
|
if (
|
|
379
|
-
!
|
|
379
|
+
!isValidSite(initConfiguration.site) ||
|
|
380
380
|
!isSampleRate(initConfiguration.sessionSampleRate, 'Session') ||
|
|
381
381
|
!isSampleRate(initConfiguration.telemetrySampleRate, 'Telemetry') ||
|
|
382
382
|
!isSampleRate(initConfiguration.telemetryConfigurationSampleRate, 'Telemetry Configuration') ||
|
|
@@ -2,7 +2,7 @@ import type { Payload } from '../../transport'
|
|
|
2
2
|
import { timeStampNow } from '../../tools/utils/timeUtils'
|
|
3
3
|
import { normalizeUrl } from '../../tools/utils/urlPolyfill'
|
|
4
4
|
import { generateUUID } from '../../tools/utils/stringUtils'
|
|
5
|
-
|
|
5
|
+
|
|
6
6
|
import type { InitConfiguration } from './configuration'
|
|
7
7
|
|
|
8
8
|
// replaced at build time
|
|
@@ -48,36 +48,26 @@ function createEndpointUrlWithParametersBuilder(
|
|
|
48
48
|
const proxy = initConfiguration.proxy
|
|
49
49
|
if (typeof proxy === 'string') {
|
|
50
50
|
const normalizedProxyUrl = normalizeUrl(proxy)
|
|
51
|
-
return (parameters) => `${normalizedProxyUrl}?
|
|
51
|
+
return (parameters) => `${normalizedProxyUrl}?mdforward=${encodeURIComponent(`${path}?${parameters}`)}`
|
|
52
52
|
}
|
|
53
53
|
if (typeof proxy === 'function') {
|
|
54
54
|
return (parameters) => proxy({ path, parameters })
|
|
55
55
|
}
|
|
56
56
|
const host = buildEndpointHost(trackType, initConfiguration)
|
|
57
|
-
return (parameters) => `https://${host}${path}?${parameters}`
|
|
57
|
+
// return (parameters) => `https://${host}${path}?${parameters}`
|
|
58
|
+
return (parameters) => `${host}${path}?${parameters}`
|
|
58
59
|
}
|
|
59
60
|
|
|
60
61
|
export function buildEndpointHost(
|
|
61
62
|
trackType: TrackType,
|
|
62
63
|
initConfiguration: InitConfiguration & { usePciIntake?: boolean }
|
|
63
64
|
) {
|
|
64
|
-
const { site =
|
|
65
|
-
|
|
66
|
-
if (trackType === 'logs' && initConfiguration.usePciIntake && site === INTAKE_SITE_US1) {
|
|
67
|
-
return PCI_INTAKE_HOST_US1
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
if (internalAnalyticsSubdomain && site === INTAKE_SITE_US1) {
|
|
71
|
-
return `${internalAnalyticsSubdomain}.${INTAKE_SITE_US1}`
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
if (site === INTAKE_SITE_FED_STAGING) {
|
|
75
|
-
return `http-intake.logs.${site}`
|
|
76
|
-
}
|
|
65
|
+
const { site = 'localhost' } = initConfiguration
|
|
77
66
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
67
|
+
// Use the site directly as the host
|
|
68
|
+
// If site includes a port, use it as-is
|
|
69
|
+
// If no port is specified, the default HTTPS port 443 will be used automatically
|
|
70
|
+
return site
|
|
81
71
|
}
|
|
82
72
|
|
|
83
73
|
/**
|
|
@@ -92,22 +82,22 @@ function buildEndpointParameters(
|
|
|
92
82
|
extraParameters: string[] = []
|
|
93
83
|
) {
|
|
94
84
|
const parameters = [
|
|
95
|
-
`
|
|
96
|
-
`
|
|
97
|
-
`
|
|
98
|
-
'
|
|
99
|
-
`
|
|
85
|
+
`mdsource=${source}`,
|
|
86
|
+
`md-api-key=${clientToken}`,
|
|
87
|
+
`md-evp-origin-version=${encodeURIComponent(__BUILD_ENV__SDK_VERSION__)}`,
|
|
88
|
+
'md-evp-origin=browser',
|
|
89
|
+
`md-request-id=${generateUUID()}`,
|
|
100
90
|
].concat(extraParameters)
|
|
101
91
|
|
|
102
92
|
if (encoding) {
|
|
103
|
-
parameters.push(`
|
|
93
|
+
parameters.push(`md-evp-encoding=${encoding}`)
|
|
104
94
|
}
|
|
105
95
|
|
|
106
96
|
if (trackType === 'rum') {
|
|
107
|
-
parameters.push(`batch_time=${timeStampNow()}`, `
|
|
97
|
+
parameters.push(`batch_time=${timeStampNow()}`, `_md.api=${api}`)
|
|
108
98
|
|
|
109
99
|
if (retry) {
|
|
110
|
-
parameters.push(`
|
|
100
|
+
parameters.push(`_md.retry_count=${retry.count}`, `_md.retry_after=${retry.lastFailureStatus}`)
|
|
111
101
|
}
|
|
112
102
|
}
|
|
113
103
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Site } from '../intakeSites'
|
|
2
|
-
import {
|
|
2
|
+
import { INTAKE_URL_PARAMETERS } from '../intakeSites'
|
|
3
3
|
import type { InitConfiguration } from './configuration'
|
|
4
4
|
import type { EndpointBuilder } from './endpointBuilder'
|
|
5
5
|
import { createEndpointBuilder } from './endpointBuilder'
|
|
@@ -22,7 +22,7 @@ export interface ReplicaConfiguration {
|
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
export function computeTransportConfiguration(initConfiguration: InitConfiguration): TransportConfiguration {
|
|
25
|
-
const site = initConfiguration.site ||
|
|
25
|
+
const site = initConfiguration.site || 'localhost'
|
|
26
26
|
const source = validateSource(initConfiguration.source)
|
|
27
27
|
|
|
28
28
|
const endpointBuilders = computeEndpointBuilders({ ...initConfiguration, site, source })
|
|
@@ -54,22 +54,10 @@ function computeEndpointBuilders(initConfiguration: InitConfiguration) {
|
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
function computeReplicaConfiguration(initConfiguration: InitConfiguration): ReplicaConfiguration | undefined {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
const replicaConfiguration: InitConfiguration = {
|
|
62
|
-
...initConfiguration,
|
|
63
|
-
site: INTAKE_SITE_US1,
|
|
64
|
-
clientToken: initConfiguration.replica.clientToken,
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
return {
|
|
68
|
-
logsEndpointBuilder: createEndpointBuilder(replicaConfiguration, 'logs'),
|
|
69
|
-
rumEndpointBuilder: createEndpointBuilder(replicaConfiguration, 'rum', [
|
|
70
|
-
`application.id=${initConfiguration.replica.applicationId}`,
|
|
71
|
-
]),
|
|
72
|
-
}
|
|
57
|
+
// Disable replica configuration for custom endpoints to avoid duplicate requests
|
|
58
|
+
// The replica feature was designed for Datadog's internal use and causes unwanted duplicates
|
|
59
|
+
// when using custom endpoints
|
|
60
|
+
return undefined
|
|
73
61
|
}
|
|
74
62
|
|
|
75
63
|
export function isIntakeUrl(url: string): boolean {
|
|
@@ -1,17 +1,2 @@
|
|
|
1
|
-
export type Site =
|
|
2
|
-
|
|
3
|
-
| 'us3.datadoghq.com'
|
|
4
|
-
| 'us5.datadoghq.com'
|
|
5
|
-
| 'datadoghq.eu'
|
|
6
|
-
| 'ddog-gov.com'
|
|
7
|
-
| 'ap1.datadoghq.com'
|
|
8
|
-
| 'ap2.datadoghq.com'
|
|
9
|
-
|
|
10
|
-
export const INTAKE_SITE_STAGING: Site = 'datad0g.com' as Site
|
|
11
|
-
export const INTAKE_SITE_FED_STAGING: Site = 'dd0g-gov.com' as Site
|
|
12
|
-
export const INTAKE_SITE_US1: Site = 'datadoghq.com'
|
|
13
|
-
export const INTAKE_SITE_EU1: Site = 'datadoghq.eu'
|
|
14
|
-
export const INTAKE_SITE_US1_FED: Site = 'ddog-gov.com'
|
|
15
|
-
|
|
16
|
-
export const PCI_INTAKE_HOST_US1 = 'pci.browser-intake-datadoghq.com'
|
|
17
|
-
export const INTAKE_URL_PARAMETERS = ['ddsource', 'dd-api-key', 'dd-request-id']
|
|
1
|
+
export type Site = string
|
|
2
|
+
export const INTAKE_URL_PARAMETERS = ['mdsource', 'md-api-key', 'md-request-id']
|
|
@@ -4,7 +4,7 @@ import { SESSION_STORE_KEY } from './storeStrategies/sessionStoreStrategy'
|
|
|
4
4
|
import type { SessionState } from './sessionState'
|
|
5
5
|
import { expandSessionState, isSessionStarted } from './sessionState'
|
|
6
6
|
|
|
7
|
-
export const OLD_SESSION_COOKIE_NAME = '
|
|
7
|
+
export const OLD_SESSION_COOKIE_NAME = '_md'
|
|
8
8
|
export const OLD_RUM_COOKIE_NAME = '_dd_r'
|
|
9
9
|
export const OLD_LOGS_COOKIE_NAME = '_dd_l'
|
|
10
10
|
|
|
@@ -14,12 +14,13 @@ import { getCurrentSite } from '../../browser/cookie'
|
|
|
14
14
|
import { ExperimentalFeature, isExperimentalFeatureEnabled } from '../../tools/experimentalFeatures'
|
|
15
15
|
import { findLast } from '../../tools/utils/polyfills'
|
|
16
16
|
import { monitorError } from '../../tools/monitor'
|
|
17
|
-
import { SESSION_NOT_TRACKED, SESSION_TIME_OUT_DELAY } from './sessionConstants'
|
|
17
|
+
import { SESSION_NOT_TRACKED, SESSION_TIME_OUT_DELAY, SessionPersistence } from './sessionConstants'
|
|
18
18
|
import { startSessionStore } from './sessionStore'
|
|
19
19
|
import type { SessionState } from './sessionState'
|
|
20
20
|
import { toSessionState } from './sessionState'
|
|
21
21
|
import { retrieveSessionCookie } from './storeStrategies/sessionInCookie'
|
|
22
22
|
import { SESSION_STORE_KEY } from './storeStrategies/sessionStoreStrategy'
|
|
23
|
+
import { retrieveSessionFromLocalStorage } from './storeStrategies/sessionInLocalStorage'
|
|
23
24
|
|
|
24
25
|
export interface SessionManager<TrackingType extends string> {
|
|
25
26
|
findSession: (
|
|
@@ -38,6 +39,7 @@ export interface SessionContext<TrackingType extends string> extends Context {
|
|
|
38
39
|
trackingType: TrackingType
|
|
39
40
|
isReplayForced: boolean
|
|
40
41
|
anonymousId: string | undefined
|
|
42
|
+
created: string | undefined
|
|
41
43
|
}
|
|
42
44
|
|
|
43
45
|
export const VISIBILITY_CHECK_DELAY = ONE_MINUTE
|
|
@@ -91,7 +93,7 @@ export function startSessionManager<TrackingType extends string>(
|
|
|
91
93
|
if (trackingConsentState.isGranted()) {
|
|
92
94
|
sessionStore.expandOrRenewSession()
|
|
93
95
|
} else {
|
|
94
|
-
sessionStore.expire()
|
|
96
|
+
sessionStore.expire(false)
|
|
95
97
|
}
|
|
96
98
|
})
|
|
97
99
|
|
|
@@ -107,13 +109,14 @@ export function startSessionManager<TrackingType extends string>(
|
|
|
107
109
|
const session = sessionStore.getSession()
|
|
108
110
|
|
|
109
111
|
if (!session) {
|
|
110
|
-
reportUnexpectedSessionState().catch(() => void 0) // Ignore errors
|
|
112
|
+
reportUnexpectedSessionState(configuration).catch(() => void 0) // Ignore errors
|
|
111
113
|
|
|
112
114
|
return {
|
|
113
115
|
id: 'invalid',
|
|
114
116
|
trackingType: SESSION_NOT_TRACKED as TrackingType,
|
|
115
117
|
isReplayForced: false,
|
|
116
118
|
anonymousId: undefined,
|
|
119
|
+
created: undefined,
|
|
117
120
|
}
|
|
118
121
|
}
|
|
119
122
|
|
|
@@ -122,6 +125,7 @@ export function startSessionManager<TrackingType extends string>(
|
|
|
122
125
|
trackingType: session[productKey] as TrackingType,
|
|
123
126
|
isReplayForced: !!session.forcedReplay,
|
|
124
127
|
anonymousId: session.anonymousId,
|
|
128
|
+
created: session.created,
|
|
125
129
|
}
|
|
126
130
|
}
|
|
127
131
|
|
|
@@ -172,16 +176,33 @@ function trackResume(configuration: Configuration, cb: () => void) {
|
|
|
172
176
|
stopCallbacks.push(stop)
|
|
173
177
|
}
|
|
174
178
|
|
|
175
|
-
async function reportUnexpectedSessionState() {
|
|
176
|
-
const
|
|
179
|
+
async function reportUnexpectedSessionState(configuration: Configuration) {
|
|
180
|
+
const sessionStoreStrategyType = configuration.sessionStoreStrategyType
|
|
181
|
+
if (!sessionStoreStrategyType) {
|
|
182
|
+
return
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
let rawSession
|
|
186
|
+
let cookieContext
|
|
187
|
+
|
|
188
|
+
if (sessionStoreStrategyType.type === SessionPersistence.COOKIE) {
|
|
189
|
+
rawSession = retrieveSessionCookie(sessionStoreStrategyType.cookieOptions)
|
|
190
|
+
|
|
191
|
+
cookieContext = {
|
|
192
|
+
cookie: await getSessionCookies(),
|
|
193
|
+
currentDomain: `${window.location.protocol}//${window.location.hostname}`,
|
|
194
|
+
}
|
|
195
|
+
} else {
|
|
196
|
+
rawSession = retrieveSessionFromLocalStorage()
|
|
197
|
+
}
|
|
177
198
|
// monitor-until: forever, could be handy to troubleshoot issues until session manager rework
|
|
178
199
|
addTelemetryDebug('Unexpected session state', {
|
|
200
|
+
sessionStoreStrategyType: sessionStoreStrategyType.type,
|
|
179
201
|
session: rawSession,
|
|
180
202
|
isSyntheticsTest: isSyntheticsTest(),
|
|
181
203
|
createdTimestamp: rawSession?.created,
|
|
182
204
|
expireTimestamp: rawSession?.expire,
|
|
183
|
-
|
|
184
|
-
currentDomain: `${window.location.protocol}//${window.location.hostname}`,
|
|
205
|
+
...cookieContext,
|
|
185
206
|
})
|
|
186
207
|
}
|
|
187
208
|
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { isEmptyObject } from '../../tools/utils/objectUtils'
|
|
2
2
|
import { objectEntries } from '../../tools/utils/polyfills'
|
|
3
3
|
import { dateNow } from '../../tools/utils/timeUtils'
|
|
4
|
-
import { generateUUID } from '../../tools/utils/stringUtils'
|
|
5
4
|
import type { Configuration } from '../configuration'
|
|
6
5
|
import { SESSION_EXPIRATION_DELAY, SESSION_TIME_OUT_DELAY } from './sessionConstants'
|
|
7
6
|
import { isValidSessionString, SESSION_ENTRY_REGEXP, SESSION_ENTRY_SEPARATOR } from './sessionStateValidation'
|
|
@@ -23,12 +22,8 @@ export function getExpiredSessionState(
|
|
|
23
22
|
const expiredSessionState: SessionState = {
|
|
24
23
|
isExpired: EXPIRED,
|
|
25
24
|
}
|
|
26
|
-
if (configuration.trackAnonymousUser) {
|
|
27
|
-
|
|
28
|
-
expiredSessionState.anonymousId = previousSessionState?.anonymousId
|
|
29
|
-
} else {
|
|
30
|
-
expiredSessionState.anonymousId = generateUUID()
|
|
31
|
-
}
|
|
25
|
+
if (configuration.trackAnonymousUser && previousSessionState?.anonymousId) {
|
|
26
|
+
expiredSessionState.anonymousId = previousSessionState?.anonymousId
|
|
32
27
|
}
|
|
33
28
|
return expiredSessionState
|
|
34
29
|
}
|
|
@@ -26,7 +26,7 @@ export interface SessionStore {
|
|
|
26
26
|
renewObservable: Observable<void>
|
|
27
27
|
expireObservable: Observable<void>
|
|
28
28
|
sessionStateUpdateObservable: Observable<{ previousState: SessionState; newState: SessionState }>
|
|
29
|
-
expire: () => void
|
|
29
|
+
expire: (hasConsent?: boolean) => void
|
|
30
30
|
stop: () => void
|
|
31
31
|
updateSessionState: (state: Partial<SessionState>) => void
|
|
32
32
|
}
|
|
@@ -170,6 +170,7 @@ export function startSessionStore<TrackingType extends string>(
|
|
|
170
170
|
{
|
|
171
171
|
process: (sessionState) => {
|
|
172
172
|
if (isSessionInNotStartedState(sessionState)) {
|
|
173
|
+
sessionState.anonymousId = generateUUID()
|
|
173
174
|
return getExpiredSessionState(sessionState, configuration)
|
|
174
175
|
}
|
|
175
176
|
},
|
|
@@ -231,8 +232,11 @@ export function startSessionStore<TrackingType extends string>(
|
|
|
231
232
|
expireObservable,
|
|
232
233
|
sessionStateUpdateObservable,
|
|
233
234
|
restartSession: startSession,
|
|
234
|
-
expire: () => {
|
|
235
|
+
expire: (hasConsent?: boolean) => {
|
|
235
236
|
cancelExpandOrRenewSession()
|
|
237
|
+
if (hasConsent === false && sessionCache) {
|
|
238
|
+
delete sessionCache.anonymousId
|
|
239
|
+
}
|
|
236
240
|
sessionStoreStrategy.expireSession(sessionCache)
|
|
237
241
|
synchronizeSession(getExpiredSessionState(sessionCache, configuration))
|
|
238
242
|
},
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import { isExperimentalFeatureEnabled, ExperimentalFeature } from '../../../tools/experimentalFeatures'
|
|
2
|
+
import { isEmptyObject } from '../../../tools/utils/objectUtils'
|
|
1
3
|
import { isChromium } from '../../../tools/utils/browserDetection'
|
|
2
4
|
import type { CookieOptions } from '../../../browser/cookie'
|
|
3
|
-
import { getCurrentSite, areCookiesAuthorized,
|
|
5
|
+
import { getCurrentSite, areCookiesAuthorized, getCookies, setCookie, getCookie } from '../../../browser/cookie'
|
|
4
6
|
import type { InitConfiguration, Configuration } from '../../configuration'
|
|
5
7
|
import { tryOldCookiesMigration } from '../oldCookiesMigration'
|
|
6
8
|
import {
|
|
@@ -14,6 +16,8 @@ import { toSessionString, toSessionState, getExpiredSessionState } from '../sess
|
|
|
14
16
|
import type { SessionStoreStrategy, SessionStoreStrategyType } from './sessionStoreStrategy'
|
|
15
17
|
import { SESSION_STORE_KEY } from './sessionStoreStrategy'
|
|
16
18
|
|
|
19
|
+
const SESSION_COOKIE_VERSION = 0
|
|
20
|
+
|
|
17
21
|
export function selectCookieStrategy(initConfiguration: InitConfiguration): SessionStoreStrategyType | undefined {
|
|
18
22
|
const cookieOptions = buildCookieOptions(initConfiguration)
|
|
19
23
|
return cookieOptions && areCookiesAuthorized(cookieOptions)
|
|
@@ -30,7 +34,7 @@ export function initCookieStrategy(configuration: Configuration, cookieOptions:
|
|
|
30
34
|
isLockEnabled: isChromium(),
|
|
31
35
|
persistSession: (sessionState: SessionState) =>
|
|
32
36
|
storeSessionCookie(cookieOptions, configuration, sessionState, SESSION_EXPIRATION_DELAY),
|
|
33
|
-
retrieveSession: retrieveSessionCookie,
|
|
37
|
+
retrieveSession: () => retrieveSessionCookie(cookieOptions),
|
|
34
38
|
expireSession: (sessionState: SessionState) =>
|
|
35
39
|
storeSessionCookie(
|
|
36
40
|
cookieOptions,
|
|
@@ -51,15 +55,34 @@ function storeSessionCookie(
|
|
|
51
55
|
sessionState: SessionState,
|
|
52
56
|
defaultTimeout: number
|
|
53
57
|
) {
|
|
58
|
+
let sessionStateString = toSessionString(sessionState)
|
|
59
|
+
|
|
60
|
+
if (isExperimentalFeatureEnabled(ExperimentalFeature.ENCODE_COOKIE_OPTIONS)) {
|
|
61
|
+
sessionStateString = toSessionString({
|
|
62
|
+
...sessionState,
|
|
63
|
+
// deleting a cookie is writing a new cookie with an empty value
|
|
64
|
+
// we don't want to store the cookie options in this case otherwise the cookie will not be deleted
|
|
65
|
+
...(!isEmptyObject(sessionState) ? { c: encodeCookieOptions(options) } : {}),
|
|
66
|
+
})
|
|
67
|
+
}
|
|
68
|
+
|
|
54
69
|
setCookie(
|
|
55
70
|
SESSION_STORE_KEY,
|
|
56
|
-
|
|
71
|
+
sessionStateString,
|
|
57
72
|
configuration.trackAnonymousUser ? SESSION_COOKIE_EXPIRATION_DELAY : defaultTimeout,
|
|
58
73
|
options
|
|
59
74
|
)
|
|
60
75
|
}
|
|
61
76
|
|
|
62
|
-
|
|
77
|
+
/**
|
|
78
|
+
* Retrieve the session state from the cookie that was set with the same cookie options
|
|
79
|
+
* If there is no match, return the first cookie, because that's how `getCookie()` works
|
|
80
|
+
*/
|
|
81
|
+
export function retrieveSessionCookie(cookieOptions: CookieOptions): SessionState {
|
|
82
|
+
if (isExperimentalFeatureEnabled(ExperimentalFeature.ENCODE_COOKIE_OPTIONS)) {
|
|
83
|
+
return retrieveSessionCookieFromEncodedCookie(cookieOptions)
|
|
84
|
+
}
|
|
85
|
+
|
|
63
86
|
const sessionString = getCookie(SESSION_STORE_KEY)
|
|
64
87
|
const sessionState = toSessionState(sessionString)
|
|
65
88
|
return sessionState
|
|
@@ -83,3 +106,42 @@ export function buildCookieOptions(initConfiguration: InitConfiguration): Cookie
|
|
|
83
106
|
|
|
84
107
|
return cookieOptions
|
|
85
108
|
}
|
|
109
|
+
|
|
110
|
+
function encodeCookieOptions(cookieOptions: CookieOptions): string {
|
|
111
|
+
const domainCount = cookieOptions.domain ? cookieOptions.domain.split('.').length - 1 : 0
|
|
112
|
+
|
|
113
|
+
/* eslint-disable no-bitwise */
|
|
114
|
+
let byte = 0
|
|
115
|
+
byte |= SESSION_COOKIE_VERSION << 5 // Store version in upper 3 bits
|
|
116
|
+
byte |= domainCount << 1 // Store domain count in next 4 bits
|
|
117
|
+
byte |= cookieOptions.crossSite ? 1 : 0 // Store useCrossSiteScripting in next bit
|
|
118
|
+
/* eslint-enable no-bitwise */
|
|
119
|
+
|
|
120
|
+
return byte.toString(16) // Convert to hex string
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Retrieve the session state from the cookie that was set with the same cookie options.
|
|
125
|
+
* If there is no match, fallback to the first cookie, (because that's how `getCookie()` works)
|
|
126
|
+
* and this allows to keep the current session id when we release this feature.
|
|
127
|
+
*/
|
|
128
|
+
function retrieveSessionCookieFromEncodedCookie(cookieOptions: CookieOptions): SessionState {
|
|
129
|
+
const cookies = getCookies(SESSION_STORE_KEY)
|
|
130
|
+
const opts = encodeCookieOptions(cookieOptions)
|
|
131
|
+
|
|
132
|
+
let sessionState: SessionState | undefined
|
|
133
|
+
|
|
134
|
+
// reverse the cookies so that if there is no match, the cookie returned is the first one
|
|
135
|
+
for (const cookie of cookies.reverse()) {
|
|
136
|
+
sessionState = toSessionState(cookie)
|
|
137
|
+
|
|
138
|
+
if (sessionState.c === opts) {
|
|
139
|
+
break
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// remove the cookie options from the session state as this is not part of the session state
|
|
144
|
+
delete sessionState?.c
|
|
145
|
+
|
|
146
|
+
return sessionState ?? {}
|
|
147
|
+
}
|
|
@@ -34,7 +34,7 @@ function persistInLocalStorage(sessionState: SessionState) {
|
|
|
34
34
|
localStorage.setItem(SESSION_STORE_KEY, toSessionString(sessionState))
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
function retrieveSessionFromLocalStorage(): SessionState {
|
|
37
|
+
export function retrieveSessionFromLocalStorage(): SessionState {
|
|
38
38
|
const sessionString = localStorage.getItem(SESSION_STORE_KEY)
|
|
39
39
|
return toSessionState(sessionString)
|
|
40
40
|
}
|
|
@@ -2,7 +2,7 @@ import type { CookieOptions } from '../../../browser/cookie'
|
|
|
2
2
|
import type { SessionPersistence } from '../sessionConstants'
|
|
3
3
|
import type { SessionState } from '../sessionState'
|
|
4
4
|
|
|
5
|
-
export const SESSION_STORE_KEY = '
|
|
5
|
+
export const SESSION_STORE_KEY = '_md_s'
|
|
6
6
|
|
|
7
7
|
export type SessionStoreStrategyType =
|
|
8
8
|
| { type: typeof SessionPersistence.COOKIE; cookieOptions: CookieOptions }
|