@corbado/observe 1.12.1 → 1.14.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/CHANGELOG.md +12 -0
- package/dist/analysis/index.mjs +2 -0
- package/dist/analysis/plugins/event-time.mjs +18 -0
- package/dist/analysis/plugins/fixed-source-path.mjs +47 -0
- package/dist/analysis/readers/page.mjs +4 -0
- package/dist/analysis/tracker-core.mjs +15 -1
- package/dist/analysis/version.mjs +1 -1
- package/dist/cdn/script.global.js +1 -1
- package/dist/index.d.mts +70 -2
- package/dist/index.d.ts +70 -2
- package/dist/index.js +2 -2
- package/dist/index.mjs +2 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @corbado/observe
|
|
2
2
|
|
|
3
|
+
## 1.14.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 8f563e2: New tracker plugin `eventTime(stamp)` for `initCore`: every tracked event is dated by the integration's clock, `stamp(explicitTimestamp)`, instead of `explicitTimestamp ?? Date.now()`, also for SDK methods that take no timestamp (`flowStarted`, `flowFinished`, decisions, an operation's `subflow_started`). For integrations that replay host signals late (e.g. from a host-side event buffer). A clock that throws or returns a non-finite number falls back to the SDK's own dating; telemetry and low events keep their capture time. `init()` / `CorbadoTracker` are unchanged.
|
|
8
|
+
|
|
9
|
+
## 1.13.0
|
|
10
|
+
|
|
11
|
+
### Minor Changes
|
|
12
|
+
|
|
13
|
+
- e0c70aa: New tracker plugin `fixedSourcePath(policy)` for `initCore`: the batch source path (`meta.trackingSourcePath`) comes from the integration's policy (e.g. `pageSourcePath(PAGES)` of `@corbado/autocapture`) instead of the server-driven `sourcePathQuery` config, so it can be declared in the integration's collection manifest. A failing policy sends the fully masked path. `init()` / `CorbadoTracker` are unchanged.
|
|
14
|
+
|
|
3
15
|
## 1.12.1
|
|
4
16
|
|
|
5
17
|
### Patch Changes
|
package/dist/analysis/index.mjs
CHANGED
|
@@ -11,6 +11,8 @@ export * from "./plugins/cookie-storage.mjs";
|
|
|
11
11
|
export * from "./plugins/cross-origin-session.mjs";
|
|
12
12
|
export * from "./plugins/raw-errors.mjs";
|
|
13
13
|
export * from "./plugins/probes.mjs";
|
|
14
|
+
export * from "./plugins/fixed-source-path.mjs";
|
|
15
|
+
export * from "./plugins/event-time.mjs";
|
|
14
16
|
export * from "./probe-lane.mjs";
|
|
15
17
|
export * from "./transport.mjs";
|
|
16
18
|
export * from "./queue.mjs";
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
// src/plugins/event-time.ts
|
|
2
|
+
function eventTime(stamp) {
|
|
3
|
+
if (typeof stamp !== "function") return {};
|
|
4
|
+
return {
|
|
5
|
+
// Guarded here, not in the tracker: the core only pays for the hook call.
|
|
6
|
+
eventTime: (explicitTimestamp) => {
|
|
7
|
+
try {
|
|
8
|
+
const stamped = stamp(explicitTimestamp);
|
|
9
|
+
return typeof stamped === "number" && Number.isFinite(stamped) ? stamped : void 0;
|
|
10
|
+
} catch {
|
|
11
|
+
return void 0;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
export {
|
|
17
|
+
eventTime
|
|
18
|
+
};
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
// src/plugins/fixed-source-path.ts
|
|
2
|
+
import { readLocationPath } from "../readers/page.mjs";
|
|
3
|
+
var MAX_SOURCE_PATH = 2048;
|
|
4
|
+
function maskedSourcePath(path) {
|
|
5
|
+
const segments = String(path ?? "").split("/").filter((segment) => segment !== "");
|
|
6
|
+
return segments.length === 0 ? "/" : "/" + segments.map(() => "*").join("/");
|
|
7
|
+
}
|
|
8
|
+
function fixedSourcePath(policy) {
|
|
9
|
+
if (typeof policy !== "function") return {};
|
|
10
|
+
return {
|
|
11
|
+
sourcePath: () => {
|
|
12
|
+
const { path, search } = readLocationPath({
|
|
13
|
+
key: "page:location.fixed-source-path",
|
|
14
|
+
title: "Page path and declared parameters",
|
|
15
|
+
accessNote: "location.pathname and location.search, reduced by the integration's declared page templates and parameters (trackingSourcePath); everything else is masked",
|
|
16
|
+
group: "Page",
|
|
17
|
+
origin: "observe-external",
|
|
18
|
+
fields: [
|
|
19
|
+
{
|
|
20
|
+
path: "url.path",
|
|
21
|
+
label: "Page path (declared parts only)",
|
|
22
|
+
category: "technical",
|
|
23
|
+
exposure: "partial",
|
|
24
|
+
transform: { note: "declared page templates and path parameters; other segments become '*'" }
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
path: "url.query",
|
|
28
|
+
label: "Page address parameters (declared ones only)",
|
|
29
|
+
category: "technical",
|
|
30
|
+
exposure: "redacted",
|
|
31
|
+
transform: { note: "declared parameters as their declared reduction; other values become '*'" }
|
|
32
|
+
}
|
|
33
|
+
]
|
|
34
|
+
});
|
|
35
|
+
try {
|
|
36
|
+
const out = policy(path, search);
|
|
37
|
+
return typeof out === "string" ? out.slice(0, MAX_SOURCE_PATH) : maskedSourcePath(path);
|
|
38
|
+
} catch {
|
|
39
|
+
return maskedSourcePath(path);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
export {
|
|
45
|
+
fixedSourcePath,
|
|
46
|
+
maskedSourcePath
|
|
47
|
+
};
|
|
@@ -21,6 +21,9 @@ function readSourcePath(_meta, mode, allow) {
|
|
|
21
21
|
const search = applySourcePathQuery(window.location.search, mode, allow);
|
|
22
22
|
return `${window.location.pathname}${search}`;
|
|
23
23
|
}
|
|
24
|
+
function readLocationPath(_meta) {
|
|
25
|
+
return { path: window.location.pathname, search: window.location.search };
|
|
26
|
+
}
|
|
24
27
|
function readCookieScope(_meta) {
|
|
25
28
|
return { hostname: window.location.hostname, https: window.location.protocol === "https:" };
|
|
26
29
|
}
|
|
@@ -29,6 +32,7 @@ export {
|
|
|
29
32
|
readCookieScope,
|
|
30
33
|
readDocumentComplete,
|
|
31
34
|
readDocumentHidden,
|
|
35
|
+
readLocationPath,
|
|
32
36
|
readPageUrl,
|
|
33
37
|
readSourcePath
|
|
34
38
|
};
|
|
@@ -132,6 +132,8 @@ var CorbadoTrackerCore = class _CorbadoTrackerCore {
|
|
|
132
132
|
this.eachPlugin(installed, (plugin) => {
|
|
133
133
|
if (plugin.session) this.bridge = plugin.session(this) || this.bridge;
|
|
134
134
|
if (plugin.rawErrors) this.rawErrors = plugin.rawErrors;
|
|
135
|
+
if (typeof plugin.sourcePath === "function") this.fixedSourcePath = plugin.sourcePath;
|
|
136
|
+
if (plugin.eventTime) this.eventClock = plugin.eventTime;
|
|
135
137
|
});
|
|
136
138
|
if (options.fixedDataConfig?.crossOriginSession && !this.bridge) {
|
|
137
139
|
this.logger.warn("fixedDataConfig.crossOriginSession is ignored without the crossOriginSession() plugin");
|
|
@@ -270,6 +272,10 @@ var CorbadoTrackerCore = class _CorbadoTrackerCore {
|
|
|
270
272
|
bridge;
|
|
271
273
|
/** Raw-error serializer of a plugin; undefined = operation step errors drop `rawError`. */
|
|
272
274
|
rawErrors;
|
|
275
|
+
/** Fixed source path of a plugin; undefined = the server-driven `sourcePathQuery` policy. */
|
|
276
|
+
fixedSourcePath;
|
|
277
|
+
/** Event clock of a plugin (never throws); undefined or an undefined result = `explicitTimestamp ?? Date.now()`. */
|
|
278
|
+
eventClock;
|
|
273
279
|
/** @internal Shared passive page observation and per-operation context registration. */
|
|
274
280
|
getWindowObserver() {
|
|
275
281
|
return this.windowObserver ??= new SharedWindowObserver(
|
|
@@ -719,6 +725,14 @@ var CorbadoTrackerCore = class _CorbadoTrackerCore {
|
|
|
719
725
|
if (typeof window === "undefined") {
|
|
720
726
|
return void 0;
|
|
721
727
|
}
|
|
728
|
+
if (this.fixedSourcePath) {
|
|
729
|
+
try {
|
|
730
|
+
const path = this.fixedSourcePath();
|
|
731
|
+
return typeof path === "string" ? path : void 0;
|
|
732
|
+
} catch {
|
|
733
|
+
return void 0;
|
|
734
|
+
}
|
|
735
|
+
}
|
|
722
736
|
return readSourcePath(
|
|
723
737
|
{
|
|
724
738
|
key: "page:location.source-path",
|
|
@@ -880,7 +894,7 @@ var CorbadoTrackerCore = class _CorbadoTrackerCore {
|
|
|
880
894
|
if (name === AuthEventName.FlowFinished || name === AuthEventName.FlowAutoFinished || name === AuthEventName.FlowReset) {
|
|
881
895
|
this.windowObserver?.flushInputs();
|
|
882
896
|
}
|
|
883
|
-
const timestamp = explicitTimestamp ?? Date.now();
|
|
897
|
+
const timestamp = this.eventClock?.(explicitTimestamp) ?? explicitTimestamp ?? Date.now();
|
|
884
898
|
const capturedId = capture?.id ?? uuidv7();
|
|
885
899
|
const capturedSessionId = capture?.sessionId ?? this.sessionId;
|
|
886
900
|
const nextSeq = this.nextSeq();
|