-
Couldn't load subscription status.
- Fork 228
hub/analytics: make analytics cookie optional #8452
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
4d411fd to
77a530b
Compare
fd335b0 to
df31e7b
Compare
- Add getAnonymousID function to get anonymous ID from cookie or IP - Support Cloudflare CF-Connecting-IP and X-Forwarded-For headers - Fall back to socket remote address if no cookie available - Update LLM and Jupyter APIs to use new anonymous ID logic - Rename isValidAnonID to isValidAnonymousID for consistency - Add comprehensive tests for isValidAnonymousID validation 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
src/packages/next/lib/user-id.ts
Outdated
| } | ||
|
|
||
| // Fall back to IP address - check headers in order of preference | ||
| const connectingIp = (req.headers["cf-connecting-ip"] || |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please refactor this with the code in packages/conat/core/server.ts --
The code could be put in packages/util/get-ip-address.ts
// See https://socket.io/how-to/get-the-ip-address-of-the-client
function getAddress(socket) {
const header = socket.handshake.headers["forwarded"];
if (header) {
for (const directive of header.split(",")[0].split(";")) {
if (directive.startsWith("for=")) {
return directive.substring(4);
}
}
}
let addr = socket.handshake.headers["x-forwarded-for"]?.split(",")?.[0];
if (addr) {
return addr;
}
for (const other of ["cf-connecting-ip", "fastly-client-ip"]) {
addr = socket.handshake.headers[other];
if (addr) {
return addr;
}
}
return socket.handshake.address;
}
(Also, concerns about the order of x-forwarded-for versus cf-connecting-ip...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I spent way too much time on this and this, but I think I got it. The more I looked into this and existing packages, the more edge cases popped up. Also, a widely used package has problems like not prioritizing cloudflare or not knowing how that forward header works. In any case, I wrapped it and wrote tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wow, that was pretty intense!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could in theory be a standalone library, which Andrey could also use in sagecellserver...
Summary
This PR implements optional analytics tracking in CoCalc, allowing the system to operate without analytics cookies for improved privacy compliance. The latest changes introduce a new
analytics_cookieserver setting and implement IP address fallback for abuse detection when cookies are not available.Key Changes
New Analytics Cookie Server Setting
analytics_cookieserver setting: Administrators can now control whether analytics cookies are enabled through the admin settings panelanalytics_cookieis disabled, no analytics cookies are set or read across the applicationAnonymous User ID System
getAnonymousIDfunction (packages/next/lib/user-id.ts): Centralized logic to get anonymous user ID with intelligent fallback:analytics_cookieserver setting is enabled)isValidAnonymousIDfunctionEnhanced Abuse Protection
packages/server/jupyter/abuse.ts,packages/server/llm/abuse.ts):anonymous_idparameter (from cookie or IP) instead ofanalytics_cookieisValidAnonymousIDAPI Endpoint Updates
packages/next/pages/api/v2/jupyter/execute.ts): UsesgetAnonymousIDfor consistent anonymous trackingpackages/next/pages/api/v2/llm/evaluate.ts): UsesgetAnonymousIDfor consistent anonymous trackingEnhanced Validation and Testing
isValidAnonIDtoisValidAnonymousID(packages/util/misc.ts): Improved naming consistencypackages/util/misc.test.ts): Tests for IPv4, IPv6, UUIDs, and edge casesisValidAnonymousIDacross the codebaseBackend Analytics System
Enhanced analytics script (
packages/hub/analytics-script.ts):analytics_cookieserver setting is enabledImproved analytics handler (
packages/hub/analytics.ts):analytics_cookieserver setting is enabledPrivacy and Compliance Benefits
analytics_cookieserver setting allows administrators to disable analytics cookies entirelyanalytics_cookiesetting is disabled, no analytics cookies are set or readImplementation Notes
analytics_cookieserver setting controls cookie behavior across the entire application🤖 Generated with Claude Code