Skip to content
This repository was archived by the owner on Sep 30, 2024. It is now read-only.

Commit 9de3bed

Browse files
authored
[Backport 5.2] web/tracking: extract user and session tracking from EventLogger (#57884) (#58029)
`EventLogger` is currently a very overloaded mechanism that handles all sorts of tracking mechanisms and cookie configurations on top of event logging. This change extracts user tracking (anonymous user ID, cohorts, and device ID) and session tracking (URL stuff) from `EventLogger` into separate, isolated classes. Functionally everything should be the same, but streamlined significantly. Most importantly, this unblocks us so that we can use these mechanisms for introducing a client implementation for the [new telemetry framework](https://docs.sourcegraph.com/dev/background-information/telemetry) while preserving existing behaviour. This only changes `client/web` - it seems this is copy-pasted into several places, we can work on centralizing them all later. Part of https://github.com/sourcegraph/sourcegraph/issues/56920 Enables https://github.com/sourcegraph/sourcegraph/pull/57939 `sg start dotcom`, then: ``` select * from event_logs where source = 'WEB' order by timestamp desc limit 3; ``` (cherry picked from commit f79aa36)
1 parent 4b2ef0c commit 9de3bed

File tree

9 files changed

+310
-277
lines changed

9 files changed

+310
-277
lines changed

client/web/BUILD.bazel

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1698,8 +1698,11 @@ ts_project(
16981698
"src/tour/data/index.tsx",
16991699
"src/tour/hooks.ts",
17001700
"src/tracking/TelemetricLink.tsx",
1701+
"src/tracking/cookies.ts",
17011702
"src/tracking/eventLogger.ts",
17021703
"src/tracking/services/serverAdminWrapper.tsx",
1704+
"src/tracking/sessionTracker.ts",
1705+
"src/tracking/userTracker.ts",
17031706
"src/tracking/util.ts",
17041707
"src/types/fzy.js/index.d.ts",
17051708
"src/user/area/UserArea.tsx",
@@ -2007,6 +2010,7 @@ ts_project(
20072010
"src/team/area/testContext.mock.ts",
20082011
"src/tour/components/Tour/Tour.test.tsx",
20092012
"src/tour/components/Tour/useTour.test.tsx",
2013+
"src/tracking/userTracker.test.ts",
20102014
"src/tracking/util.test.ts",
20112015
"src/user/index.test.ts",
20122016
"src/user/settings/auth/ExternalAccount.test.tsx",

client/web/src/auth/SignUpForm.tsx

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import React, { useCallback, useMemo, useState } from 'react'
22

33
import { mdiBitbucket, mdiGithub, mdiGitlab } from '@mdi/js'
44
import classNames from 'classnames'
5-
import cookies from 'js-cookie'
65
import { type Observable, of } from 'rxjs'
76
import { fromFetch } from 'rxjs/fetch'
87
import { catchError, switchMap } from 'rxjs/operators'
@@ -17,7 +16,7 @@ import { Link, Icon, Label, Text, Button, AnchorLink, LoaderInput, ErrorAlert }
1716

1817
import { LoaderButton } from '../components/LoaderButton'
1918
import type { AuthProvider, SourcegraphContext } from '../jscontext'
20-
import { ANONYMOUS_USER_ID_KEY, eventLogger, FIRST_SOURCE_URL_KEY, LAST_SOURCE_URL_KEY } from '../tracking/eventLogger'
19+
import { eventLogger } from '../tracking/eventLogger'
2120
import { validatePassword, getPasswordRequirements } from '../util/security'
2221

2322
import { OrDivider } from './OrDivider'
@@ -110,9 +109,9 @@ export const SignUpForm: React.FunctionComponent<React.PropsWithChildren<SignUpF
110109
email: emailState.value,
111110
username: usernameState.value,
112111
password: passwordState.value,
113-
anonymousUserId: cookies.get(ANONYMOUS_USER_ID_KEY),
114-
firstSourceUrl: cookies.get(FIRST_SOURCE_URL_KEY),
115-
lastSourceUrl: cookies.get(LAST_SOURCE_URL_KEY),
112+
anonymousUserId: eventLogger.user.anonymousUserID,
113+
firstSourceUrl: eventLogger.session.getFirstSourceURL(),
114+
lastSourceUrl: eventLogger.session.getLastSourceURL(),
116115
}).catch(error => {
117116
setError(asError(error))
118117
setLoading(false)

client/web/src/tracking/cookies.ts

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import cookies, { type CookieAttributes } from 'js-cookie'
2+
3+
/**
4+
* Cookies is a simple interface over real cookies from 'js-cookie'.
5+
*/
6+
export interface Cookies {
7+
/**
8+
* Read cookie
9+
*/
10+
get(name: string): string | undefined
11+
/**
12+
* Create a cookie
13+
*/
14+
set(name: string, value: string, options?: CookieAttributes): string | undefined
15+
}
16+
17+
/**
18+
* Alias for 'js-cookie' default implementation, behind the Cookies interface.
19+
*/
20+
export function defaultCookies(): Cookies {
21+
return cookies
22+
}
23+
24+
export const userCookieSettings: CookieAttributes = {
25+
// 365 days expiry, but renewed on activity.
26+
expires: 365,
27+
// Enforce HTTPS
28+
secure: true,
29+
// We only read the cookie with JS so we don't need to send it cross-site nor on initial page requests.
30+
// However, we do need it on page redirects when users sign up via OAuth, hence using the Lax policy.
31+
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite
32+
sameSite: 'Lax',
33+
// Specify the Domain attribute to ensure subdomains (about.sourcegraph.com) can receive this cookie.
34+
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#define_where_cookies_are_sent
35+
domain: location.hostname,
36+
}
37+
38+
export const deviceSessionCookieSettings: CookieAttributes = {
39+
// ~30 minutes expiry, but renewed on activity.
40+
expires: 0.0208,
41+
// Enforce HTTPS
42+
secure: true,
43+
// We only read the cookie with JS so we don't need to send it cross-site nor on initial page requests.
44+
// However, we do need it on page redirects when users sign up via OAuth, hence using the Lax policy.
45+
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite
46+
sameSite: 'Lax',
47+
// Specify the Domain attribute to ensure subdomains (about.sourcegraph.com) can receive this cookie.
48+
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#define_where_cookies_are_sent
49+
domain: location.hostname,
50+
}

0 commit comments

Comments
 (0)