package auth import ( "net/http" "time" ) // CookieName is the single httpOnly cookie that carries the JWT. const CookieName = "spsays_auth" // CookieOptions captures the per-environment knobs for the auth cookie. type CookieOptions struct { Domain string // empty in dev; ".prabhupadasays.org" in prod for subdomain sharing Secure bool // true in production (HTTPS-only) } // Set writes the JWT into a Secure, httpOnly, SameSite=Lax cookie. // SameSite=Lax + same-registrable-domain (prabhupadasays.org / api.prabhupadasays.org) // is enough for cross-subdomain auth without resorting to SameSite=None. func Set(w http.ResponseWriter, token string, expires time.Time, opts CookieOptions) { http.SetCookie(w, &http.Cookie{ Name: CookieName, Value: token, Path: "/", Domain: opts.Domain, Expires: expires, MaxAge: int(time.Until(expires).Seconds()), HttpOnly: true, Secure: opts.Secure, SameSite: http.SameSiteLaxMode, }) } // Clear overwrites the auth cookie with an immediately-expired one. func Clear(w http.ResponseWriter, opts CookieOptions) { http.SetCookie(w, &http.Cookie{ Name: CookieName, Value: "", Path: "/", Domain: opts.Domain, Expires: time.Unix(0, 0), MaxAge: -1, HttpOnly: true, Secure: opts.Secure, SameSite: http.SameSiteLaxMode, }) } // Read pulls the raw JWT out of the request cookie. Returns "" if missing. func Read(r *http.Request) string { c, err := r.Cookie(CookieName) if err != nil { return "" } return c.Value }