-
Notifications
You must be signed in to change notification settings - Fork 138
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
fix: seek subdomain correctly #888
Conversation
Size Change: +2.2 kB (0%) Total Size: 734 kB
ℹ️ View Unchanged
|
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.
Feels like something that needs tests.... can we test it or is it so browser specific that we would essentially be mocking out the whole logic?
const mockDocumentDotCookie = { | ||
value_: '', | ||
|
||
get cookie() { | ||
return this.value_ | ||
}, | ||
|
||
set cookie(value) { | ||
//needs to refuse known public suffixes, like a browser would | ||
// value arrives like dmn_chk_1699961248575=1;domain=.uk | ||
const domain = value.split('domain=') | ||
if (['.uk', '.com', '.au', '.com.au', '.co.uk'].includes(domain[1])) return | ||
this.value_ += value + ';' | ||
}, | ||
} |
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.
@benjackwhite I couldn't get testcafe to test this. But I was having to attach the function to the window and then have testcafe eval it and who knows why it wasn't working.
Sometimes it wasn't present, others it returned the empty string, I think even sometimes it worked, but it was horrible.
So instead I have a fake cookie jar to test the logic with.
And then in the actual code...
if (!matchedSubDomain) { | ||
const originalMatch = originalCookieDomainFn(hostname) | ||
if (originalMatch !== matchedSubDomain) { | ||
logger.info('Warning: cookie subdomain discovery mismatch', originalMatch, matchedSubDomain) | ||
} | ||
matchedSubDomain = originalMatch | ||
} |
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.
... if the new mechanism returns no match we fall back to the original.
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.
The other alternative I guess is to let people configure their subdomain.
And if that's present we use it without looking at location. Then folk that it's working for do nothing, everyone else has to configure it. That's yucky but safer
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.
Still somewhat worried about this code but its more of a gut feeling than anything I can actually see wrong with it :D
Let's try it
if (!matchedSubDomain) { | ||
const originalMatch = originalCookieDomainFn(hostname) | ||
if (originalMatch !== matchedSubDomain) { | ||
logger.info('Warning: cookie subdomain discovery mismatch', originalMatch, matchedSubDomain) | ||
} | ||
matchedSubDomain = originalMatch | ||
} |
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.
Still somewhat worried about this code but its more of a gut feeling than anything I can actually see wrong with it :D
Let's try it
We relied on a regex for detecting subdomain in order to choose what cookie domain to set for PostHog storage.
This worked fine for
example.com
orwww.example.com
but it didn't work forexample.co.uk
orexample.com.au
because it would grab the first two parts and so try to set on the public suffixco.uk
orcom.au
A lot of suggested solutions on line involve keeping a list of public suffixes, or making DNS lookups to validate values which wouldn't fit here.
But... browsers reject cookies set on public suffixes - despite not offering an API to directly check if something is a public suffix.
So, we can split the current hostname up and then progressively try to set a cookie until the browser accepts it.
For
a.long.domain.someone.is.using.com.au
we would check:.au
rejected by browser.com.au
rejected by browser.using.com.au
accepted by browserWe call this method a lot and the browser can't maintain in-memory variables and navigate between sub-domains, so I also cache the result
I manually tested the code in the developer console of firefox, chrome, and safari