Skip to content

Commit df31e7b

Browse files
committed
hub/analytics: configure if cookie is set or not
1 parent 77a530b commit df31e7b

File tree

10 files changed

+50
-42
lines changed

10 files changed

+50
-42
lines changed

src/.claude/settings.local.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,10 @@
99
"Bash(tsc --noEmit)",
1010
"Bash(git fetch:*)",
1111
"Bash(git merge:*)",
12-
"Bash(prettier -w:*)"
12+
"Bash(prettier -w:*)",
13+
"Bash(git push:*)",
14+
"Bash(gh pr view:*)"
1315
],
1416
"deny": []
1517
}
16-
}
18+
}

src/CLAUDE.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,15 +34,15 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
3434

3535
### Package-Specific Commands
3636

37-
- `cd packages/[package] && pnpm tsc` - TypeScript compilation for a specific package
37+
- `cd packages/[package] && pnpm build` - Build and compile a specific package
3838
- `cd packages/[package] && pnpm test` - Run tests for a specific package
3939
- `cd packages/[package] && pnpm build` - Build a specific package
4040
- **IMPORTANT**: When modifying packages like `util` that other packages depend on, you must run `pnpm build` in the dependency package before typechecking dependent packages
4141

4242
### Development
4343

4444
- After code changes, run `pretter -w [filename]` to ensure consistent styling
45-
- After TypeScript or `*.tsx` changes, run `pnpm tsc` in the relevant package directory
45+
- After TypeScript or `*.tsx` changes, run `pnpm build` in the relevant package directory
4646

4747
## Architecture Overview
4848

@@ -120,14 +120,14 @@ CoCalc is organized as a monorepo with key packages:
120120

121121
### Development Workflow
122122

123-
1. Changes to TypeScript require compilation (`pnpm tsc` in relevant package)
123+
1. Changes to TypeScript require compilation (`pnpm build` in relevant package)
124124
2. Database must be running before starting hub
125125
3. Hub coordinates all services and should be restarted after changes
126126
4. Use `pnpm clean && pnpm build-dev` when switching branches or after major changes
127127

128128
# Workflow
129129

130-
- Be sure to typecheck when you're done making a series of code changes
130+
- Be sure to build when you're done making a series of code changes
131131
- Prefer running single tests, and not the whole test suite, for performance
132132

133133
## Git Workflow

src/packages/frontend/account/settings/email-address-setting.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ export const EmailAddressSetting = ({
7373
return;
7474
}
7575
try {
76-
// anonymouse users will get the "welcome" email
76+
// anonymous users will get the "welcome" email
7777
await webapp_client.account_client.send_verification_email(!is_anonymous);
7878
} catch (error) {
7979
const err_msg = `Problem sending welcome email: ${error}`;

src/packages/frontend/user-tracking.ts

Lines changed: 10 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,19 @@
77
// client code doesn't have to import webapp_client everywhere, and we can
88
// completely change this if we want.
99

10-
import { query, server_time } from "./frame-editors/generic/client";
10+
import { redux } from "@cocalc/frontend/app-framework";
11+
import {
12+
query,
13+
server_time,
14+
} from "@cocalc/frontend/frame-editors/generic/client";
15+
import { get_cookie } from "@cocalc/frontend/misc";
16+
import { webapp_client } from "@cocalc/frontend/webapp-client";
1117
import { uuid } from "@cocalc/util/misc";
12-
import { redux } from "./app-framework";
1318
import { version } from "@cocalc/util/smc-version";
14-
import { get_cookie } from "./misc";
15-
import { webapp_client } from "./webapp-client";
1619

17-
import { ANALYTICS_COOKIE_NAME, ANALYTICS_ENABLED } from "@cocalc/util/consts";
20+
import { ANALYTICS_COOKIE_NAME } from "@cocalc/util/consts";
1821

1922
export async function log(eventName: string, payload: any): Promise<void> {
20-
if (!ANALYTICS_ENABLED) {
21-
return;
22-
}
23-
2423
const central_log = {
2524
id: uuid(),
2625
event: `webapp-${eventName}`,
@@ -32,12 +31,9 @@ export async function log(eventName: string, payload: any): Promise<void> {
3231
},
3332
time: server_time(),
3433
};
34+
3535
try {
36-
await query({
37-
query: {
38-
central_log,
39-
},
40-
});
36+
await query({ query: { central_log } });
4137
} catch (err) {
4238
console.warn("WARNING: Failed to write log event -- ", central_log);
4339
}
@@ -49,10 +45,6 @@ export default async function track(
4945
event: string,
5046
value: object,
5147
): Promise<void> {
52-
if (!ANALYTICS_ENABLED) {
53-
return;
54-
}
55-
5648
// Replace all dashes with underscores in the event argument for consistency
5749
event = event.replace(/-/g, "_");
5850

src/packages/hub/analytics.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import { is_valid_uuid_string, uuid } from "@cocalc/util/misc";
2222
import { pii_retention_to_future } from "@cocalc/database/postgres/pii";
2323
import { get_server_settings } from "@cocalc/database/postgres/server-settings";
2424
import type { PostgreSQL } from "@cocalc/database/postgres/types";
25-
import { ANALYTICS_COOKIE_NAME, ANALYTICS_ENABLED } from "@cocalc/util/consts";
25+
import { ANALYTICS_COOKIE_NAME } from "@cocalc/util/consts";
2626

2727
import { getLogger } from "./logger";
2828

@@ -243,6 +243,7 @@ export async function initAnalytics(
243243
const DNS = settings.dns;
244244
const dns_parsed = parseDomain(DNS);
245245
const pii_retention = settings.pii_retention;
246+
const analytics_enabled = settings.analytics_cookie;
246247

247248
if (
248249
dns_parsed.type !== ParseResultType.Listed &&
@@ -288,17 +289,17 @@ export async function initAnalytics(
288289
`/analytics.js GET analytics_cookie='${req.cookies[ANALYTICS_COOKIE_NAME]}'`,
289290
);
290291

291-
if (!req.cookies[ANALYTICS_COOKIE_NAME] && ANALYTICS_ENABLED) {
292+
if (!req.cookies[ANALYTICS_COOKIE_NAME] && analytics_enabled) {
292293
// No analytics cookie is set and cookies are enabled, so we set one.
293-
// When ANALYTICS_ENABLED is false, we skip setting cookies to enable
294+
// When analytics_enabled is false, we skip setting cookies to enable
294295
// cookieless tracking for better privacy.
295296
setAnalyticsCookie(res /* DNS */);
296297
}
297298

298299
// Return NOOP if DNS is invalid, or if cookies are enabled and already exist
299300
if (
300301
dns_parsed.type !== ParseResultType.Listed ||
301-
(ANALYTICS_ENABLED && req.cookies[ANALYTICS_COOKIE_NAME])
302+
(analytics_enabled && req.cookies[ANALYTICS_COOKIE_NAME])
302303
) {
303304
// cache for 6 hours -- max-age has unit seconds
304305
res.header(
@@ -320,7 +321,7 @@ export async function initAnalytics(
320321
res.write(`var NAME = '${ANALYTICS_COOKIE_NAME}';\n`);
321322
res.write(`var ID = '${uuid()}';\n`);
322323
res.write(`var DOMAIN = '${DOMAIN}';\n`);
323-
res.write(`var ANALYTICS_ENABLED = ${ANALYTICS_ENABLED};\n`);
324+
res.write(`var ANALYTICS_ENABLED = ${analytics_enabled};\n`);
324325
// BASE_PATH
325326
if (req.query.fqd === "false") {
326327
res.write(`var PREFIX = '${base_path}';\n`);

src/packages/next/pages/api/v2/jupyter/execute.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,16 @@ The OUTPUT is:
2020
- a list of messages that describe the output of the last code execution.
2121
2222
*/
23+
import type { Request, Response } from "express";
24+
2325
import { execute } from "@cocalc/server/jupyter/execute";
2426
import getAccountId from "lib/account/get-account";
2527
import getParams from "lib/api/get-params";
2628

27-
import { ANALYTICS_COOKIE_NAME, ANALYTICS_ENABLED } from "@cocalc/util/consts";
29+
import { ANALYTICS_COOKIE_NAME } from "@cocalc/util/consts";
30+
import { getServerSettings } from "@cocalc/database/settings/server-settings";
2831

29-
export default async function handle(req, res) {
32+
export default async function handle(req: Request, res: Response) {
3033
try {
3134
const result = await doIt(req);
3235
res.json({ ...result, success: true });
@@ -36,11 +39,12 @@ export default async function handle(req, res) {
3639
}
3740
}
3841

39-
async function doIt(req) {
42+
async function doIt(req: Request) {
4043
const { input, kernel, history, tag, noCache, hash, project_id, path } =
4144
getParams(req);
4245
const account_id = await getAccountId(req);
43-
const analytics_cookie = ANALYTICS_ENABLED
46+
const { analytics_cookie: analytics_enabled } = await getServerSettings();
47+
const analytics_cookie = analytics_enabled
4448
? req.cookies[ANALYTICS_COOKIE_NAME]
4549
: undefined;
4650
return await execute({

src/packages/next/pages/api/v2/llm/evaluate.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
// This is the new endpoint for querying any LLM
22
// Previously, this has been in openai/chatgpt
33

4+
import type { Request, Response } from "express";
5+
6+
import { getServerSettings } from "@cocalc/database/settings/server-settings";
47
import { evaluate } from "@cocalc/server/llm/index";
5-
import { ANALYTICS_COOKIE_NAME, ANALYTICS_ENABLED } from "@cocalc/util/consts";
8+
import { ANALYTICS_COOKIE_NAME } from "@cocalc/util/consts";
69
import getAccountId from "lib/account/get-account";
710
import getParams from "lib/api/get-params";
811

9-
export default async function handle(req, res) {
12+
export default async function handle(req: Request, res: Response) {
1013
try {
1114
const result = await doIt(req);
1215
res.json({ ...result, success: true });
@@ -16,10 +19,11 @@ export default async function handle(req, res) {
1619
}
1720
}
1821

19-
async function doIt(req) {
22+
async function doIt(req: Request) {
2023
const { input, system, history, model, tag } = getParams(req);
2124
const account_id = await getAccountId(req);
22-
const analytics_cookie = ANALYTICS_ENABLED
25+
const { analytics_cookie: analytics_enabled } = await getServerSettings();
26+
const analytics_cookie = analytics_enabled
2327
? req.cookies[ANALYTICS_COOKIE_NAME]
2428
: undefined;
2529
return {

src/packages/util/consts/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,4 @@ export { DUMMY_SECRET } from "./project";
1313

1414
export { SERVER_SETTINGS_ENV_PREFIX } from "./server_settings";
1515

16-
export { ANALYTICS_COOKIE_NAME, ANALYTICS_ENABLED } from "./tracking";
16+
export { ANALYTICS_COOKIE_NAME } from "./tracking";

src/packages/util/consts/tracking.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,3 @@
55

66
// Cookie name for analytics tracking
77
export const ANALYTICS_COOKIE_NAME = "CC_ANA";
8-
9-
// Global flag to disable analytics tracking
10-
export const ANALYTICS_ENABLED: boolean = false;

src/packages/util/db-schema/site-settings-extras.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,7 @@ function custom_llm_display(value: string): string {
184184

185185
export type SiteSettingsExtrasKeys =
186186
| "pii_retention"
187+
| "analytics_cookie"
187188
| "conat_heading"
188189
| "conat_password"
189190
| "stripe_heading"
@@ -405,6 +406,13 @@ export const EXTRAS: SettingsExtras = {
405406
to_val: pii_retention_parse,
406407
to_display: pii_retention_display,
407408
},
409+
analytics_cookie: {
410+
name: "Analytics Cookie",
411+
desc: "Tag browser sessions visiting a website via an analytics.js script with a cookie",
412+
default: "no",
413+
valid: only_booleans,
414+
to_val: to_bool,
415+
},
408416
stripe_heading: {
409417
// this is consmetic, otherwise it looks weird.
410418
name: "Stripe Keys",

0 commit comments

Comments
 (0)