diff --git a/backend/pkg/sessions/api/web/handlers.go b/backend/pkg/sessions/api/web/handlers.go index 4ca3fec32..af509d8f6 100644 --- a/backend/pkg/sessions/api/web/handlers.go +++ b/backend/pkg/sessions/api/web/handlers.go @@ -135,11 +135,6 @@ func (e *handlersImpl) startSessionHandlerWeb(w http.ResponseWriter, r *http.Req // Add tracker version to context r = r.WithContext(context.WithValue(r.Context(), "tracker", req.TrackerVersion)) - if err := validateTrackerVersion(req.TrackerVersion); err != nil { - e.log.Error(r.Context(), "unsupported tracker version: %s, err: %s", req.TrackerVersion, err) - e.responser.ResponseWithError(e.log, r.Context(), w, http.StatusUpgradeRequired, errors.New("please upgrade the tracker version"), startTime, r.URL.Path, bodySize) - return - } // Handler's logic if req.ProjectKey == nil { @@ -162,6 +157,13 @@ func (e *handlersImpl) startSessionHandlerWeb(w http.ResponseWriter, r *http.Req // Add projectID to context r = r.WithContext(context.WithValue(r.Context(), "projectID", fmt.Sprintf("%d", p.ProjectID))) + // Validate tracker version + if err := validateTrackerVersion(req.TrackerVersion); err != nil { + e.log.Error(r.Context(), "unsupported tracker version: %s, err: %s", req.TrackerVersion, err) + e.responser.ResponseWithError(e.log, r.Context(), w, http.StatusUpgradeRequired, errors.New("please upgrade the tracker version"), startTime, r.URL.Path, bodySize) + return + } + // Check if the project supports mobile sessions if !p.IsWeb() { e.responser.ResponseWithError(e.log, r.Context(), w, http.StatusForbidden, errors.New("project doesn't support web sessions"), startTime, r.URL.Path, bodySize) diff --git a/frontend/app/components/Client/Integrations/ProfilerDoc/ProfilerDoc.tsx b/frontend/app/components/Client/Integrations/ProfilerDoc/ProfilerDoc.tsx index eb6013a7c..6b0f5b930 100644 --- a/frontend/app/components/Client/Integrations/ProfilerDoc/ProfilerDoc.tsx +++ b/frontend/app/components/Client/Integrations/ProfilerDoc/ProfilerDoc.tsx @@ -16,10 +16,10 @@ function ProfilerDoc() { ? sites.find((site) => site.id === siteId)?.projectKey : sites[0]?.projectKey; - const usage = `import OpenReplay from '@openreplay/tracker'; + const usage = `import { tracker } from '@openreplay/tracker'; import trackerProfiler from '@openreplay/tracker-profiler'; //... -const tracker = new OpenReplay({ +tracker.configure({ projectKey: '${projectKey}' }); tracker.start() @@ -29,10 +29,12 @@ export const profiler = tracker.use(trackerProfiler()); const fn = profiler('call_name')(() => { //... }, thisArg); // thisArg is optional`; - const usageCjs = `import OpenReplay from '@openreplay/tracker/cjs'; + const usageCjs = `import { tracker } from '@openreplay/tracker/cjs'; +// alternatively you can use dynamic import without /cjs suffix to prevent issues with window scope + import trackerProfiler from '@openreplay/tracker-profiler/cjs'; //... -const tracker = new OpenReplay({ +tracker.configure({ projectKey: '${projectKey}' }); //... diff --git a/frontend/app/components/Client/Integrations/Tracker/AssistDoc/AssistNpm.tsx b/frontend/app/components/Client/Integrations/Tracker/AssistDoc/AssistNpm.tsx index 30893ba95..a333441b9 100644 --- a/frontend/app/components/Client/Integrations/Tracker/AssistDoc/AssistNpm.tsx +++ b/frontend/app/components/Client/Integrations/Tracker/AssistDoc/AssistNpm.tsx @@ -7,17 +7,19 @@ import { useTranslation } from 'react-i18next'; function AssistNpm(props) { const { t } = useTranslation(); - const usage = `import OpenReplay from '@openreplay/tracker'; + const usage = `import { tracker } from '@openreplay/tracker'; import trackerAssist from '@openreplay/tracker-assist'; -const tracker = new OpenReplay({ +tracker.configure({ projectKey: '${props.projectKey}', }); tracker.start() tracker.use(trackerAssist(options)); // check the list of available options below`; - const usageCjs = `import OpenReplay from '@openreplay/tracker/cjs'; + const usageCjs = `import { tracker } from '@openreplay/tracker/cjs'; +// alternatively you can use dynamic import without /cjs suffix to prevent issues with window scope import trackerAssist from '@openreplay/tracker-assist/cjs'; -const tracker = new OpenReplay({ + +tracker.configure({ projectKey: '${props.projectKey}' }); const trackerAssist = tracker.use(trackerAssist(options)); // check the list of available options below diff --git a/frontend/app/components/Client/Integrations/Tracker/GraphQLDoc/GraphQLDoc.tsx b/frontend/app/components/Client/Integrations/Tracker/GraphQLDoc/GraphQLDoc.tsx index dd704b0bf..85e6d68c0 100644 --- a/frontend/app/components/Client/Integrations/Tracker/GraphQLDoc/GraphQLDoc.tsx +++ b/frontend/app/components/Client/Integrations/Tracker/GraphQLDoc/GraphQLDoc.tsx @@ -14,19 +14,20 @@ function GraphQLDoc() { const projectKey = siteId ? sites.find((site) => site.id === siteId)?.projectKey : sites[0]?.projectKey; - const usage = `import OpenReplay from '@openreplay/tracker'; + const usage = `import { tracker } from '@openreplay/tracker'; import trackerGraphQL from '@openreplay/tracker-graphql'; //... -const tracker = new OpenReplay({ +tracker.configure({ projectKey: '${projectKey}' }); tracker.start() //... export const recordGraphQL = tracker.use(trackerGraphQL());`; - const usageCjs = `import OpenReplay from '@openreplay/tracker/cjs'; + const usageCjs = `import { tracker } from '@openreplay/tracker/cjs'; +// alternatively you can use dynamic import without /cjs suffix to prevent issues with window scope import trackerGraphQL from '@openreplay/tracker-graphql/cjs'; //... -const tracker = new OpenReplay({ +tracker.configure({ projectKey: '${projectKey}' }); //... diff --git a/frontend/app/components/Client/Integrations/Tracker/MobxDoc/MobxDoc.tsx b/frontend/app/components/Client/Integrations/Tracker/MobxDoc/MobxDoc.tsx index e31a25b86..688f97824 100644 --- a/frontend/app/components/Client/Integrations/Tracker/MobxDoc/MobxDoc.tsx +++ b/frontend/app/components/Client/Integrations/Tracker/MobxDoc/MobxDoc.tsx @@ -15,20 +15,21 @@ function MobxDoc() { ? sites.find((site) => site.id === siteId)?.projectKey : sites[0]?.projectKey; - const mobxUsage = `import OpenReplay from '@openreplay/tracker'; + const mobxUsage = `import { tracker } from '@openreplay/tracker'; import trackerMobX from '@openreplay/tracker-mobx'; //... -const tracker = new OpenReplay({ +tracker.configure({ projectKey: '${projectKey}' }); tracker.use(trackerMobX()); // check list of available options below tracker.start(); `; - const mobxUsageCjs = `import OpenReplay from '@openreplay/tracker/cjs'; + const mobxUsageCjs = `import { tracker } from '@openreplay/tracker/cjs'; +// alternatively you can use dynamic import without /cjs suffix to prevent issues with window scope import trackerMobX from '@openreplay/tracker-mobx/cjs'; //... -const tracker = new OpenReplay({ +tracker.configure({ projectKey: '${projectKey}' }); tracker.use(trackerMobX()); // check list of available options below diff --git a/frontend/app/components/Client/Integrations/Tracker/NgRxDoc/NgRxDoc.tsx b/frontend/app/components/Client/Integrations/Tracker/NgRxDoc/NgRxDoc.tsx index d1401899f..8e52cdfa2 100644 --- a/frontend/app/components/Client/Integrations/Tracker/NgRxDoc/NgRxDoc.tsx +++ b/frontend/app/components/Client/Integrations/Tracker/NgRxDoc/NgRxDoc.tsx @@ -16,10 +16,10 @@ function NgRxDoc() { : sites[0]?.projectKey; const usage = `import { StoreModule } from '@ngrx/store'; import { reducers } from './reducers'; -import OpenReplay from '@openreplay/tracker'; +import { tracker } from '@openreplay/tracker'; import trackerNgRx from '@openreplay/tracker-ngrx'; //... -const tracker = new OpenReplay({ +tracker.configure({ projectKey: '${projectKey}' }); tracker.start() @@ -32,10 +32,11 @@ const metaReducers = [tracker.use(trackerNgRx())]; // check list of ava export class AppModule {}`; const usageCjs = `import { StoreModule } from '@ngrx/store'; import { reducers } from './reducers'; -import OpenReplay from '@openreplay/tracker/cjs'; +import { tracker } from '@openreplay/tracker/cjs'; +// alternatively you can use dynamic import without /cjs suffix to prevent issues with window scope import trackerNgRx from '@openreplay/tracker-ngrx/cjs'; //... -const tracker = new OpenReplay({ +tracker.configure({ projectKey: '${projectKey}' }); //... diff --git a/frontend/app/components/Client/Integrations/Tracker/PiniaDoc/PiniaDoc.tsx b/frontend/app/components/Client/Integrations/Tracker/PiniaDoc/PiniaDoc.tsx index 8c18077f2..c9ac2e9f9 100644 --- a/frontend/app/components/Client/Integrations/Tracker/PiniaDoc/PiniaDoc.tsx +++ b/frontend/app/components/Client/Integrations/Tracker/PiniaDoc/PiniaDoc.tsx @@ -17,10 +17,10 @@ function PiniaDoc() { ? sites.find((site) => site.id === siteId)?.projectKey : sites[0]?.projectKey; const usage = `import Vuex from 'vuex' -import OpenReplay from '@openreplay/tracker'; +import { tracker } from '@openreplay/tracker'; import trackerVuex from '@openreplay/tracker-vuex'; //... -const tracker = new OpenReplay({ +tracker.configure({ projectKey: '${projectKey}' }); tracker.start() diff --git a/frontend/app/components/Client/Integrations/Tracker/ReduxDoc/ReduxDoc.tsx b/frontend/app/components/Client/Integrations/Tracker/ReduxDoc/ReduxDoc.tsx index 35c2ad37a..216bf6605 100644 --- a/frontend/app/components/Client/Integrations/Tracker/ReduxDoc/ReduxDoc.tsx +++ b/frontend/app/components/Client/Integrations/Tracker/ReduxDoc/ReduxDoc.tsx @@ -16,10 +16,10 @@ function ReduxDoc() { : sites[0]?.projectKey; const usage = `import { applyMiddleware, createStore } from 'redux'; -import OpenReplay from '@openreplay/tracker'; +import { tracker } from '@openreplay/tracker'; import trackerRedux from '@openreplay/tracker-redux'; //... -const tracker = new OpenReplay({ +tracker.configure({ projectKey: '${projectKey}' }); tracker.start() @@ -29,10 +29,11 @@ const store = createStore( applyMiddleware(tracker.use(trackerRedux())) // check list of available options below );`; const usageCjs = `import { applyMiddleware, createStore } from 'redux'; -import OpenReplay from '@openreplay/tracker/cjs'; +import { tracker } from '@openreplay/tracker/cjs'; +// alternatively you can use dynamic import without /cjs suffix to prevent issues with window scope import trackerRedux from '@openreplay/tracker-redux/cjs'; //... -const tracker = new OpenReplay({ +tracker.configure({ projectKey: '${projectKey}' }); //... diff --git a/frontend/app/components/Client/Integrations/Tracker/VueDoc/VueDoc.tsx b/frontend/app/components/Client/Integrations/Tracker/VueDoc/VueDoc.tsx index b32e9f1f4..133f17c89 100644 --- a/frontend/app/components/Client/Integrations/Tracker/VueDoc/VueDoc.tsx +++ b/frontend/app/components/Client/Integrations/Tracker/VueDoc/VueDoc.tsx @@ -16,10 +16,10 @@ function VueDoc() { : sites[0]?.projectKey; const usage = `import Vuex from 'vuex' -import OpenReplay from '@openreplay/tracker'; +import { tracker } from '@openreplay/tracker'; import trackerVuex from '@openreplay/tracker-vuex'; //... -const tracker = new OpenReplay({ +tracker.configure({ projectKey: '${projectKey}' }); tracker.start() @@ -29,10 +29,11 @@ const store = new Vuex.Store({ plugins: [tracker.use(trackerVuex())] // check list of available options below });`; const usageCjs = `import Vuex from 'vuex' -import OpenReplay from '@openreplay/tracker/cjs'; +import { tracker } from '@openreplay/tracker/cjs'; +// alternatively you can use dynamic import without /cjs suffix to prevent issues with window scope import trackerVuex from '@openreplay/tracker-vuex/cjs'; //... -const tracker = new OpenReplay({ +tracker.configure({ projectKey: '${projectKey}' }); //... diff --git a/frontend/app/components/Client/Integrations/Tracker/ZustandDoc/ZustandDoc.tsx b/frontend/app/components/Client/Integrations/Tracker/ZustandDoc/ZustandDoc.tsx index b25f40dd6..75e51afaf 100644 --- a/frontend/app/components/Client/Integrations/Tracker/ZustandDoc/ZustandDoc.tsx +++ b/frontend/app/components/Client/Integrations/Tracker/ZustandDoc/ZustandDoc.tsx @@ -16,11 +16,10 @@ function ZustandDoc(props) { : sites[0]?.projectKey; const usage = `import create from "zustand"; -import Tracker from '@openreplay/tracker'; +import { tracker } from '@openreplay/tracker'; import trackerZustand, { StateLogger } from '@openreplay/tracker-zustand'; - -const tracker = new Tracker({ +tracker.configure({ projectKey: ${projectKey}, }); @@ -43,11 +42,12 @@ const useBearStore = create( ) `; const usageCjs = `import create from "zustand"; -import Tracker from '@openreplay/tracker/cjs'; +import { tracker } from '@openreplay/tracker/cjs'; +// alternatively you can use dynamic import without /cjs suffix to prevent issues with window scope import trackerZustand, { StateLogger } from '@openreplay/tracker-zustand/cjs'; -const tracker = new Tracker({ +tracker.configure({ projectKey: ${projectKey}, }); diff --git a/frontend/app/components/Onboarding/components/OnboardingTabs/InstallDocs/InstallDocs.js b/frontend/app/components/Onboarding/components/OnboardingTabs/InstallDocs/InstallDocs.js index c9dc3c245..724d95eea 100644 --- a/frontend/app/components/Onboarding/components/OnboardingTabs/InstallDocs/InstallDocs.js +++ b/frontend/app/components/Onboarding/components/OnboardingTabs/InstallDocs/InstallDocs.js @@ -7,16 +7,17 @@ import stl from './installDocs.module.css'; import { useTranslation } from 'react-i18next'; const installationCommand = 'npm i @openreplay/tracker'; -const usageCode = `import Tracker from '@openreplay/tracker'; +const usageCode = `import { tracker } from '@openreplay/tracker'; -const tracker = new Tracker({ +tracker.configure({ projectKey: "PROJECT_KEY", ingestPoint: "https://${window.location.hostname}/ingest", }); tracker.start()`; -const usageCodeSST = `import Tracker from '@openreplay/tracker/cjs'; +const usageCodeSST = `import { tracker } from '@openreplay/tracker/cjs'; +// alternatively you can use dynamic import without /cjs suffix to prevent issues with window scope -const tracker = new Tracker({ +tracker.configure({ projectKey: "PROJECT_KEY", ingestPoint: "https://${window.location.hostname}/ingest", }); diff --git a/frontend/app/components/shared/TrackingCodeModal/InstallDocs/InstallDocs.js b/frontend/app/components/shared/TrackingCodeModal/InstallDocs/InstallDocs.js index b9f400d4e..526382406 100644 --- a/frontend/app/components/shared/TrackingCodeModal/InstallDocs/InstallDocs.js +++ b/frontend/app/components/shared/TrackingCodeModal/InstallDocs/InstallDocs.js @@ -5,17 +5,18 @@ import stl from './installDocs.module.css'; import { useTranslation } from 'react-i18next'; const installationCommand = 'npm i @openreplay/tracker'; -const usageCode = `import Tracker from '@openreplay/tracker'; +const usageCode = `import { tracker } from '@openreplay/tracker'; -const tracker = new Tracker({ +tracker.configure({ projectKey: "PROJECT_KEY", ingestPoint: "https://${window.location.hostname}/ingest", }); tracker.start()`; -const usageCodeSST = `import Tracker from '@openreplay/tracker/cjs'; +const usageCodeSST = `import { tracker } from '@openreplay/tracker/cjs'; +// alternatively you can use dynamic import without /cjs suffix to prevent issues with window scope -const tracker = new Tracker({ +tracker.configure({ projectKey: "PROJECT_KEY", ingestPoint: "https://${window.location.hostname}/ingest", }); diff --git a/tracker/tracker-assist/.yarn/install-state.gz b/tracker/tracker-assist/.yarn/install-state.gz index a6fe4294c..9ef26268b 100644 Binary files a/tracker/tracker-assist/.yarn/install-state.gz and b/tracker/tracker-assist/.yarn/install-state.gz differ diff --git a/tracker/tracker/.yarn/install-state.gz b/tracker/tracker/.yarn/install-state.gz index 195bd0d89..c1f9dd9b8 100644 Binary files a/tracker/tracker/.yarn/install-state.gz and b/tracker/tracker/.yarn/install-state.gz differ diff --git a/tracker/tracker/CHANGELOG.md b/tracker/tracker/CHANGELOG.md index ef8e97fd4..50166be88 100644 --- a/tracker/tracker/CHANGELOG.md +++ b/tracker/tracker/CHANGELOG.md @@ -1,3 +1,7 @@ +## 16.0.2 + +- fix attributeSender key generation to prevent calling native methods on objects + ## 16.0.1 - drop computing ts digits diff --git a/tracker/tracker/package.json b/tracker/tracker/package.json index ea0fbec48..13eab0724 100644 --- a/tracker/tracker/package.json +++ b/tracker/tracker/package.json @@ -1,7 +1,7 @@ { "name": "@openreplay/tracker", "description": "The OpenReplay tracker main package", - "version": "16.0.1", + "version": "16.0.2", "keywords": [ "logging", "replay" diff --git a/tracker/tracker/src/main/modules/attributeSender.ts b/tracker/tracker/src/main/modules/attributeSender.ts index 200de919b..70f7cff43 100644 --- a/tracker/tracker/src/main/modules/attributeSender.ts +++ b/tracker/tracker/src/main/modules/attributeSender.ts @@ -15,7 +15,9 @@ export class StringDictionary { getKey = (str: string): [number, boolean] => { let isNew = false - if (!this.backDict[str]) { + // avoiding potential native object properties + const safeKey = `__${str}` + if (!this.backDict[safeKey]) { isNew = true // shaving the first 2 digits of the timestamp (since they are irrelevant for next millennia) const shavedTs = Date.now() % 10 ** (13 - 2) @@ -26,10 +28,10 @@ export class StringDictionary { } else { this.lastSuffix = 1 } - this.backDict[str] = id + this.backDict[safeKey] = id this.lastTs = shavedTs } - return [this.backDict[str], isNew] + return [this.backDict[safeKey], isNew] } }