@@ -590,9 +590,6 @@ export class HttpServer {
590590 this . heart . beat ( )
591591 const route = this . parseUrl ( request )
592592 const write = ( payload : HttpResponse ) : void => {
593- const host = request . headers . host || ""
594- const idx = host . indexOf ( ":" )
595- const domain = idx !== - 1 ? host . substring ( 0 , idx ) : host
596593 response . writeHead ( payload . redirect ? HttpCode . Redirect : payload . code || HttpCode . Ok , {
597594 "Content-Type" : payload . mime || getMediaMime ( payload . filePath ) ,
598595 ...( payload . redirect ? { Location : this . constructRedirect ( request , route , payload as RedirectResponse ) } : { } ) ,
@@ -603,7 +600,7 @@ export class HttpServer {
603600 "Set-Cookie" : [
604601 `${ payload . cookie . key } =${ payload . cookie . value } ` ,
605602 `Path=${ normalize ( payload . cookie . path || "/" , true ) } ` ,
606- domain ? `Domain= ${ this . getCookieDomain ( domain ) } ` : undefined ,
603+ this . getCookieDomain ( request . headers . host || "" ) ,
607604 // "HttpOnly",
608605 "SameSite=lax" ,
609606 ]
@@ -822,20 +819,39 @@ export class HttpServer {
822819 }
823820
824821 /**
825- * Get the domain that should be used for setting a cookie. This will allow
826- * the user to authenticate only once. This will return the highest level
822+ * Get the value that should be used for setting a cookie domain . This will
823+ * allow the user to authenticate only once. This will use the highest level
827824 * domain (e.g. `coder.com` over `test.coder.com` if both are specified).
828825 */
829- private getCookieDomain ( host : string ) : string {
830- let current : string | undefined
826+ private getCookieDomain ( host : string ) : string | undefined {
827+ const idx = host . lastIndexOf ( ":" )
828+ host = idx !== - 1 ? host . substring ( 0 , idx ) : host
829+ if (
830+ // Might be blank/missing, so there's nothing more to do.
831+ ! host ||
832+ // IP addresses can't have subdomains so there's no value in setting the
833+ // domain for them. Assume anything with a : is ipv6 (valid domain name
834+ // characters are alphanumeric or dashes).
835+ host . includes ( ":" ) ||
836+ // Assume anything entirely numbers and dots is ipv4 (currently tlds
837+ // cannot be entirely numbers).
838+ ! / [ ^ 0 - 9 . ] / . test ( host ) ||
839+ // localhost subdomains don't seem to work at all (browser bug?).
840+ host . endsWith ( ".localhost" ) ||
841+ // It might be localhost (or an IP, see above) if it's a proxy and it
842+ // isn't setting the host header to match the access domain.
843+ host === "localhost"
844+ ) {
845+ return undefined
846+ }
847+
831848 this . proxyDomains . forEach ( ( domain ) => {
832- if ( host . endsWith ( domain ) && ( ! current || domain . length < current . length ) ) {
833- current = domain
849+ if ( host . endsWith ( domain ) && domain . length < host . length ) {
850+ host = domain
834851 }
835852 } )
836- // Setting the domain to localhost doesn't seem to work for subdomains (for
837- // example dev.localhost).
838- return current && current !== "localhost" ? current : host
853+
854+ return host ? `Domain=${ host } ` : undefined
839855 }
840856
841857 /**
0 commit comments