-
Notifications
You must be signed in to change notification settings - Fork 225
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 <[email protected]>
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 <[email protected]>
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_cookie
server setting and implement IP address fallback for abuse detection when cookies are not available.Key Changes
New Analytics Cookie Server Setting
analytics_cookie
server setting: Administrators can now control whether analytics cookies are enabled through the admin settings panelanalytics_cookie
is disabled, no analytics cookies are set or read across the applicationAnonymous User ID System
getAnonymousID
function (packages/next/lib/user-id.ts
): Centralized logic to get anonymous user ID with intelligent fallback:analytics_cookie
server setting is enabled)isValidAnonymousID
functionEnhanced Abuse Protection
packages/server/jupyter/abuse.ts
,packages/server/llm/abuse.ts
):anonymous_id
parameter (from cookie or IP) instead ofanalytics_cookie
isValidAnonymousID
API Endpoint Updates
packages/next/pages/api/v2/jupyter/execute.ts
): UsesgetAnonymousID
for consistent anonymous trackingpackages/next/pages/api/v2/llm/evaluate.ts
): UsesgetAnonymousID
for consistent anonymous trackingEnhanced Validation and Testing
isValidAnonID
toisValidAnonymousID
(packages/util/misc.ts
): Improved naming consistencypackages/util/misc.test.ts
): Tests for IPv4, IPv6, UUIDs, and edge casesisValidAnonymousID
across the codebaseBackend Analytics System
Enhanced analytics script (
packages/hub/analytics-script.ts
):analytics_cookie
server setting is enabledImproved analytics handler (
packages/hub/analytics.ts
):analytics_cookie
server setting is enabledPrivacy and Compliance Benefits
analytics_cookie
server setting allows administrators to disable analytics cookies entirelyanalytics_cookie
setting is disabled, no analytics cookies are set or readImplementation Notes
analytics_cookie
server setting controls cookie behavior across the entire application🤖 Generated with Claude Code