fix cookie -- not working
This commit is contained in:
@@ -4,10 +4,7 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"hash/crc32"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"path"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
@@ -21,6 +18,14 @@ type AnonymousSessionInitializer interface {
|
||||
NewAnonymous(ctx context.Context, req *http.Request, cookieName string) (*pscookie.SessionContext, error)
|
||||
}
|
||||
|
||||
type SessionExpiryRefresher interface {
|
||||
RefreshExpiry(ctx context.Context, session *pscookie.SessionContext) error
|
||||
}
|
||||
|
||||
type SessionCookieNameResolver interface {
|
||||
ResolveCookieName(ctx context.Context, req *http.Request) (string, error)
|
||||
}
|
||||
|
||||
type LanguageResolver interface {
|
||||
ResolveLanguageID(ctx context.Context, req *http.Request, fallback int64) int64
|
||||
}
|
||||
@@ -31,11 +36,22 @@ type ProductRouteMatcher interface {
|
||||
|
||||
func Session(cfg psconfig.Config, codec pscookie.Codec, initializer AnonymousSessionInitializer, languageResolver LanguageResolver, matcher ProductRouteMatcher) echo.MiddlewareFunc {
|
||||
ownership := cfg.ParseRouteOwnership()
|
||||
expiryRefresher, _ := initializer.(SessionExpiryRefresher)
|
||||
cookieNameResolver, _ := initializer.(SessionCookieNameResolver)
|
||||
|
||||
return func(next echo.HandlerFunc) echo.HandlerFunc {
|
||||
return func(c echo.Context) error {
|
||||
ownedRoute := ownsProductRoute(ownership.ProductPrefixes, c.Request().URL.Path, matcher)
|
||||
configuredCookieName := cfg.DeriveCookieName(requestCookieHost(c.Request()))
|
||||
if cookieNameResolver != nil {
|
||||
resolvedCookieName, err := cookieNameResolver.ResolveCookieName(c.Request().Context(), c.Request())
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, fmt.Sprintf("prestashop cookie name resolution failed: %v", err))
|
||||
}
|
||||
if strings.TrimSpace(resolvedCookieName) != "" {
|
||||
configuredCookieName = resolvedCookieName
|
||||
}
|
||||
}
|
||||
cookieName, rawCookie := findPrestaShopCookie(c.Request(), configuredCookieName)
|
||||
if cookieName == "" {
|
||||
cookieName = configuredCookieName
|
||||
@@ -66,12 +82,17 @@ func Session(cfg psconfig.Config, codec pscookie.Codec, initializer AnonymousSes
|
||||
applyRequestMarket(session, requestMarketSelection(c.Request()))
|
||||
}
|
||||
if ownedRoute && shouldSetSessionCookie(rawCookie, session) {
|
||||
if expiryRefresher != nil {
|
||||
if err := expiryRefresher.RefreshExpiry(c.Request().Context(), session); err != nil {
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, fmt.Sprintf("prestashop session expiry refresh failed: %v", err))
|
||||
}
|
||||
}
|
||||
encoded, err := codec.Encode(session)
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, "prestashop cookie encode failed")
|
||||
}
|
||||
session.RawCookie = encoded
|
||||
setPrestaShopCookie(c.Request(), c.Response(), ownership.ProductPrefixes, cookieName, encoded)
|
||||
setPrestaShopCookie(c.Request(), c.Response(), session, cookieName, encoded)
|
||||
if redirectURL, ok := clearMarketSelectionURL(c.Request()); ok {
|
||||
return c.Redirect(http.StatusSeeOther, redirectURL)
|
||||
}
|
||||
@@ -213,19 +234,18 @@ func applyRequestMarket(session *pscookie.SessionContext, selection marketSelect
|
||||
|
||||
session.CurrencyID = int64Ptr(selection.CurrencyID)
|
||||
session.Values["iso_code_country"] = selection.CountryISO
|
||||
if selection.CountryID > 0 {
|
||||
session.Values["id_country"] = strconv.FormatInt(selection.CountryID, 10)
|
||||
session.OrderedKeys = ensureOrderedKey(session.OrderedKeys, "id_country", 5)
|
||||
}
|
||||
session.Values["id_currency"] = strconv.FormatInt(selection.CurrencyID, 10)
|
||||
delete(session.Values, "id_country")
|
||||
session.OrderedKeys = ensureOrderedKey(session.OrderedKeys, "iso_code_country", 4)
|
||||
session.OrderedKeys = ensureOrderedKey(session.OrderedKeys, "id_currency", 6)
|
||||
session.OrderedKeys = removeOrderedKey(session.OrderedKeys, "id_country")
|
||||
session.OrderedKeys = ensureOrderedKey(session.OrderedKeys, "id_currency", 5)
|
||||
|
||||
if !session.IsLoggedIn {
|
||||
if checksum := anonymousSessionChecksum(session, sessionLanguageID(session)); checksum != "" {
|
||||
session.Values["checksum"] = checksum
|
||||
session.OrderedKeys = ensureOrderedKey(session.OrderedKeys, "checksum", len(session.OrderedKeys))
|
||||
}
|
||||
trimAnonymousCookieValues(session)
|
||||
session.OrderedKeys = ensureOrderedKey(session.OrderedKeys, "id_guest", 6)
|
||||
session.OrderedKeys = ensureOrderedKey(session.OrderedKeys, "id_connections", 7)
|
||||
session.OrderedKeys = removeOrderedKey(session.OrderedKeys, "checksum")
|
||||
session.OrderedKeys = ensureOrderedKey(session.OrderedKeys, "checksum", len(session.OrderedKeys))
|
||||
}
|
||||
|
||||
session.Plaintext = ""
|
||||
@@ -284,6 +304,46 @@ func ensureOrderedKey(keys []string, key string, index int) []string {
|
||||
return keys
|
||||
}
|
||||
|
||||
func removeOrderedKey(keys []string, key string) []string {
|
||||
for i, existing := range keys {
|
||||
if existing == key {
|
||||
return append(keys[:i], keys[i+1:]...)
|
||||
}
|
||||
}
|
||||
return keys
|
||||
}
|
||||
|
||||
func trimAnonymousCookieValues(session *pscookie.SessionContext) {
|
||||
if session == nil || session.Values == nil {
|
||||
return
|
||||
}
|
||||
|
||||
allowed := map[string]struct{}{
|
||||
"date_add": {},
|
||||
"id_lang": {},
|
||||
"id_language": {},
|
||||
"iso_code_country": {},
|
||||
"id_currency": {},
|
||||
"id_guest": {},
|
||||
"id_connections": {},
|
||||
"checksum": {},
|
||||
}
|
||||
|
||||
for key := range session.Values {
|
||||
if _, ok := allowed[key]; !ok {
|
||||
delete(session.Values, key)
|
||||
}
|
||||
}
|
||||
|
||||
filtered := make([]string, 0, len(session.OrderedKeys))
|
||||
for _, key := range session.OrderedKeys {
|
||||
if _, ok := allowed[key]; ok {
|
||||
filtered = append(filtered, key)
|
||||
}
|
||||
}
|
||||
session.OrderedKeys = filtered
|
||||
}
|
||||
|
||||
func int64Ptr(value int64) *int64 {
|
||||
if value == 0 {
|
||||
return nil
|
||||
@@ -353,53 +413,17 @@ func clearMarketSelectionURL(req *http.Request) (string, bool) {
|
||||
return cleanPath, true
|
||||
}
|
||||
|
||||
func setPrestaShopCookie(req *http.Request, res *echo.Response, ownedPrefixes []string, name, value string) {
|
||||
http.SetCookie(res.Writer, &http.Cookie{
|
||||
Name: name,
|
||||
Value: value,
|
||||
Path: requestCookiePath(req.URL.Path, ownedPrefixes),
|
||||
Domain: requestCookieDomain(req),
|
||||
Secure: requestCookieSecure(req),
|
||||
HttpOnly: true,
|
||||
SameSite: http.SameSiteLaxMode,
|
||||
})
|
||||
}
|
||||
|
||||
func requestCookiePath(requestPath string, ownedPrefixes []string) string {
|
||||
for _, prefix := range ownedPrefixes {
|
||||
if prefix == "" || !strings.HasPrefix(requestPath, prefix) {
|
||||
continue
|
||||
}
|
||||
base := path.Clean(strings.TrimSuffix(prefix, "/"))
|
||||
if base == "." || base == "/" {
|
||||
return "/"
|
||||
}
|
||||
parent := path.Dir(base)
|
||||
if parent == "." {
|
||||
return "/"
|
||||
}
|
||||
if !strings.HasSuffix(parent, "/") {
|
||||
parent += "/"
|
||||
}
|
||||
return parent
|
||||
func setPrestaShopCookie(req *http.Request, res *echo.Response, session *pscookie.SessionContext, name, value string) {
|
||||
maxAge := 1
|
||||
if session != nil && session.ExpiresAt != nil {
|
||||
maxAge = int(session.ExpiresAt.UTC().Unix())
|
||||
}
|
||||
|
||||
return "/"
|
||||
}
|
||||
|
||||
func requestCookieDomain(req *http.Request) string {
|
||||
host := requestCookieHost(req)
|
||||
if host == "" {
|
||||
return ""
|
||||
header := fmt.Sprintf("%s=%s; path=/; max-age=%d; HttpOnly; SameSite=Lax", name, value, maxAge)
|
||||
if requestCookieSecure(req) {
|
||||
header += "; Secure"
|
||||
}
|
||||
if parsed, err := url.Parse("http://" + host); err == nil {
|
||||
host = parsed.Hostname()
|
||||
}
|
||||
host = strings.TrimSpace(strings.TrimPrefix(host, "."))
|
||||
if host == "" || strings.EqualFold(host, "localhost") || net.ParseIP(host) != nil {
|
||||
return ""
|
||||
}
|
||||
return host
|
||||
res.Header().Add(echo.HeaderSetCookie, header)
|
||||
}
|
||||
|
||||
func requestCookieHost(req *http.Request) string {
|
||||
|
||||
Reference in New Issue
Block a user