@reservamos/browser-analytics 1.1.7-alpha.1 → 1.1.7
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 +2 -1
- package/dist/browser-analytics.cjs +3 -3
- package/dist/browser-analytics.cjs.map +1 -1
- package/dist/browser-analytics.esm.js +799 -765
- package/dist/browser-analytics.esm.js.map +1 -1
- package/dist/browser-analytics.iife.js +3 -3
- package/dist/browser-analytics.iife.js.map +1 -1
- package/package.json +3 -3
- package/src/services/botDetectionRelay.test.ts +58 -31
- package/src/services/botDetectionRelay.ts +13 -23
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@reservamos/browser-analytics",
|
|
3
|
-
"version": "1.1.7
|
|
3
|
+
"version": "1.1.7",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "git+https://github.com/reservamos/reservamos-browser-analytics.git"
|
|
@@ -74,6 +74,7 @@
|
|
|
74
74
|
"devDependencies": {
|
|
75
75
|
"@eslint/js": "^9.9.1",
|
|
76
76
|
"@ianvs/prettier-plugin-sort-imports": "^4.3.1",
|
|
77
|
+
"@reservamos/js-api-client": "6.28.0",
|
|
77
78
|
"@types/eslint__js": "^8.42.3",
|
|
78
79
|
"@types/jsdom": "^21.1.6",
|
|
79
80
|
"@types/mixpanel-browser": "^2.50.0",
|
|
@@ -93,7 +94,6 @@
|
|
|
93
94
|
"typescript-eslint": "^8.4.0",
|
|
94
95
|
"upgradeps": "^2.0.6",
|
|
95
96
|
"vite": "^5.0.12",
|
|
96
|
-
"vitest": "^1.2.1"
|
|
97
|
-
"@reservamos/js-api-client": "6.0.1"
|
|
97
|
+
"vitest": "^1.2.1"
|
|
98
98
|
}
|
|
99
99
|
}
|
|
@@ -1,13 +1,7 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
1
|
+
import coreApi from '@reservamos/js-api-client/core';
|
|
2
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
3
3
|
import botDetectionRelayService from './botDetectionRelay';
|
|
4
4
|
|
|
5
|
-
vi.mock('@/services/config', () => ({
|
|
6
|
-
default: {
|
|
7
|
-
getCoreAPIConfig: vi.fn(),
|
|
8
|
-
},
|
|
9
|
-
}));
|
|
10
|
-
|
|
11
5
|
const payload = {
|
|
12
6
|
requestId: 'request-123',
|
|
13
7
|
visitorId: 'visitor-123',
|
|
@@ -27,7 +21,13 @@ const coreApiConfig = {
|
|
|
27
21
|
describe('botDetectionRelayService', () => {
|
|
28
22
|
beforeEach(() => {
|
|
29
23
|
vi.unstubAllGlobals();
|
|
30
|
-
|
|
24
|
+
coreApi.setConfig(coreApiConfig);
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
afterEach(() => {
|
|
28
|
+
vi.useRealTimers();
|
|
29
|
+
vi.unstubAllGlobals();
|
|
30
|
+
vi.restoreAllMocks();
|
|
31
31
|
});
|
|
32
32
|
|
|
33
33
|
it('enables only the SDK-owned Bot Detection events', () => {
|
|
@@ -42,8 +42,8 @@ describe('botDetectionRelayService', () => {
|
|
|
42
42
|
).toBe(false);
|
|
43
43
|
});
|
|
44
44
|
|
|
45
|
-
it('
|
|
46
|
-
const fetchMock = vi.fn().mockResolvedValue({ ok: true });
|
|
45
|
+
it('sends an observation through the configured client', async () => {
|
|
46
|
+
const fetchMock = vi.fn().mockResolvedValue({ ok: true, status: 202 });
|
|
47
47
|
vi.stubGlobal('fetch', fetchMock);
|
|
48
48
|
|
|
49
49
|
await botDetectionRelayService.relay(payload);
|
|
@@ -55,32 +55,37 @@ describe('botDetectionRelayService', () => {
|
|
|
55
55
|
headers: {
|
|
56
56
|
'Content-Type': 'application/json',
|
|
57
57
|
'x-app-name': 'reservamos-web',
|
|
58
|
+
'Authorization': 'Bearer test-token',
|
|
58
59
|
},
|
|
59
|
-
body: JSON.stringify(
|
|
60
|
-
|
|
60
|
+
body: JSON.stringify({
|
|
61
|
+
requestId: payload.requestId,
|
|
62
|
+
visitorId: payload.visitorId,
|
|
63
|
+
distinctId: payload.distinctId,
|
|
64
|
+
eventName: 'Fingerprint Requested',
|
|
65
|
+
}),
|
|
66
|
+
signal: expect.any(AbortSignal),
|
|
61
67
|
},
|
|
62
68
|
);
|
|
63
69
|
});
|
|
64
70
|
|
|
65
|
-
it('omits
|
|
66
|
-
const fetchMock = vi.fn().mockResolvedValue({ ok: true });
|
|
71
|
+
it('omits distinctId when unavailable', async () => {
|
|
72
|
+
const fetchMock = vi.fn().mockResolvedValue({ ok: true, status: 202 });
|
|
67
73
|
vi.stubGlobal('fetch', fetchMock);
|
|
68
|
-
vi.mocked(configService.getCoreAPIConfig).mockReturnValue({
|
|
69
|
-
baseUrl: 'https://datalake-api-dev.reservamossaas.com/api',
|
|
70
|
-
defaultHeaders: {
|
|
71
|
-
Authorization: 'Bearer test-token',
|
|
72
|
-
Origin: 'https://example.com',
|
|
73
|
-
},
|
|
74
|
-
});
|
|
75
74
|
|
|
76
|
-
await botDetectionRelayService.relay(
|
|
75
|
+
await botDetectionRelayService.relay({
|
|
76
|
+
requestId: payload.requestId,
|
|
77
|
+
visitorId: payload.visitorId,
|
|
78
|
+
eventName: 'Search',
|
|
79
|
+
});
|
|
77
80
|
|
|
78
81
|
expect(fetchMock).toHaveBeenCalledWith(
|
|
79
|
-
|
|
82
|
+
expect.any(String),
|
|
80
83
|
expect.objectContaining({
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
+
body: JSON.stringify({
|
|
85
|
+
requestId: payload.requestId,
|
|
86
|
+
visitorId: payload.visitorId,
|
|
87
|
+
eventName: 'Fingerprint Requested',
|
|
88
|
+
}),
|
|
84
89
|
}),
|
|
85
90
|
);
|
|
86
91
|
});
|
|
@@ -97,7 +102,7 @@ describe('botDetectionRelayService', () => {
|
|
|
97
102
|
).resolves.toBeUndefined();
|
|
98
103
|
expect(consoleError).toHaveBeenCalledWith(
|
|
99
104
|
'Error relaying Fingerprint identification:',
|
|
100
|
-
|
|
105
|
+
{ httpStatus: null, reason: 'network_or_cors' },
|
|
101
106
|
);
|
|
102
107
|
|
|
103
108
|
consoleError.mockRestore();
|
|
@@ -117,11 +122,33 @@ describe('botDetectionRelayService', () => {
|
|
|
117
122
|
).resolves.toBeUndefined();
|
|
118
123
|
expect(consoleError).toHaveBeenCalledWith(
|
|
119
124
|
'Error relaying Fingerprint identification:',
|
|
120
|
-
|
|
121
|
-
message: 'Bot Detection relay failed with status 503',
|
|
122
|
-
}),
|
|
125
|
+
{ httpStatus: 503, reason: 'service_unavailable' },
|
|
123
126
|
);
|
|
124
127
|
|
|
125
128
|
consoleError.mockRestore();
|
|
126
129
|
});
|
|
130
|
+
|
|
131
|
+
it('contains client timeouts and reports a sanitized diagnostic', async () => {
|
|
132
|
+
vi.useFakeTimers();
|
|
133
|
+
const consoleError = vi
|
|
134
|
+
.spyOn(console, 'error')
|
|
135
|
+
.mockImplementation(() => undefined);
|
|
136
|
+
const fetchMock = vi.fn(
|
|
137
|
+
(_url: string, { signal }: { signal: AbortSignal }) =>
|
|
138
|
+
new Promise<Response>((_resolve, reject) => {
|
|
139
|
+
signal.addEventListener('abort', () => reject(new Error('Aborted')));
|
|
140
|
+
}),
|
|
141
|
+
);
|
|
142
|
+
vi.stubGlobal('fetch', fetchMock);
|
|
143
|
+
|
|
144
|
+
const attempt = botDetectionRelayService.relay(payload);
|
|
145
|
+
await vi.advanceTimersByTimeAsync(5000);
|
|
146
|
+
|
|
147
|
+
await expect(attempt).resolves.toBeUndefined();
|
|
148
|
+
expect(fetchMock).toHaveBeenCalledTimes(1);
|
|
149
|
+
expect(consoleError).toHaveBeenCalledWith(
|
|
150
|
+
'Error relaying Fingerprint identification:',
|
|
151
|
+
{ httpStatus: null, reason: 'timeout' },
|
|
152
|
+
);
|
|
153
|
+
});
|
|
127
154
|
});
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import type { BotDetectionRelayPayload } from '@/types/botDetection';
|
|
2
|
-
import
|
|
3
|
-
|
|
4
|
-
const BOT_DETECTION_RELAY_PATH = '/v1/fingerprint/bot-detection';
|
|
2
|
+
import coreApi from '@reservamos/js-api-client/core';
|
|
5
3
|
|
|
6
4
|
/**
|
|
7
5
|
* Events that require a fresh Fingerprint identification and Core API relay.
|
|
@@ -30,27 +28,19 @@ function isEnabledFor(eventName: string): boolean {
|
|
|
30
28
|
*/
|
|
31
29
|
async function relay(payload: BotDetectionRelayPayload): Promise<void> {
|
|
32
30
|
try {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
}
|
|
44
|
-
body: JSON.stringify(payload),
|
|
45
|
-
keepalive: true,
|
|
31
|
+
await coreApi.fingerprint.sendObservation({
|
|
32
|
+
requestId: payload.requestId,
|
|
33
|
+
visitorId: payload.visitorId,
|
|
34
|
+
distinctId: payload.distinctId,
|
|
35
|
+
onDiagnostic(diagnostic) {
|
|
36
|
+
if (diagnostic.reason !== 'http_accepted') {
|
|
37
|
+
console.error(
|
|
38
|
+
'Error relaying Fingerprint identification:',
|
|
39
|
+
diagnostic,
|
|
40
|
+
);
|
|
41
|
+
}
|
|
46
42
|
},
|
|
47
|
-
);
|
|
48
|
-
|
|
49
|
-
if (!response.ok) {
|
|
50
|
-
throw new Error(
|
|
51
|
-
`Bot Detection relay failed with status ${response.status}`,
|
|
52
|
-
);
|
|
53
|
-
}
|
|
43
|
+
});
|
|
54
44
|
} catch (error) {
|
|
55
45
|
console.error('Error relaying Fingerprint identification:', error);
|
|
56
46
|
}
|