feat: dynamic cookie domains (#722)

* feat: dynamic cookie domains

Replaces #685

I was having weird testing issues when trying to merge #685, so I
rewrote it from scratch to be a lot more minimal.

* chore: spelling

Signed-off-by: Xe Iaso <me@xeiaso.net>

---------

Signed-off-by: Xe Iaso <me@xeiaso.net>
This commit is contained in:
Xe Iaso 2025-06-26 08:11:59 -04:00 committed by GitHub
parent 7cf6ac5de6
commit a1b7d2ccda
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 137 additions and 37 deletions

View file

@ -4,6 +4,7 @@ import (
"fmt"
"math/rand"
"net/http"
"regexp"
"slices"
"strings"
"time"
@ -15,21 +16,40 @@ import (
"github.com/TecharoHQ/anubis/web"
"github.com/a-h/templ"
"github.com/golang-jwt/jwt/v5"
"golang.org/x/net/publicsuffix"
)
func (s *Server) SetCookie(w http.ResponseWriter, name, value, path string) {
var domainMatchRegexp = regexp.MustCompile(`^((xn--)?[a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,}$`)
func (s *Server) SetCookie(w http.ResponseWriter, name, value, path, host string) {
var domain = s.opts.CookieDomain
if s.opts.CookieDynamicDomain && domainMatchRegexp.MatchString(host) {
if etld, err := publicsuffix.EffectiveTLDPlusOne(host); err == nil {
domain = etld
name = anubis.WithDomainCookieName + etld
}
}
http.SetCookie(w, &http.Cookie{
Name: name,
Value: value,
Expires: time.Now().Add(s.opts.CookieExpiration),
SameSite: http.SameSiteLaxMode,
Domain: s.opts.CookieDomain,
Domain: domain,
Partitioned: s.opts.CookiePartitioned,
Path: path,
})
}
func (s *Server) ClearCookie(w http.ResponseWriter, name, path string) {
func (s *Server) ClearCookie(w http.ResponseWriter, name, path, host string) {
var domain = s.opts.CookieDomain
if s.opts.CookieDynamicDomain && domainMatchRegexp.MatchString(host) {
if etld, err := publicsuffix.EffectiveTLDPlusOne(host); err == nil {
domain = etld
name = anubis.WithDomainCookieName + etld
}
}
http.SetCookie(w, &http.Cookie{
Name: name,
Value: "",
@ -37,7 +57,7 @@ func (s *Server) ClearCookie(w http.ResponseWriter, name, path string) {
Expires: time.Now().Add(-1 * time.Minute),
SameSite: http.SameSiteLaxMode,
Partitioned: s.opts.CookiePartitioned,
Domain: s.opts.CookieDomain,
Domain: domain,
Path: path,
})
}