Files
goclaw/internal/http/browser_cookies_payload.go
2026-05-24 11:27:02 +07:00

114 lines
3.2 KiB
Go

package http
import (
"net/http"
"net/url"
"strings"
"time"
"github.com/nextlevelbuilder/goclaw/internal/store"
)
type browserCookieSyncRequest struct {
AgentID string `json:"agent_id"`
Agent string `json:"agent,omitempty"`
Source string `json:"source,omitempty"`
Cookies []browserCookieSyncPayload `json:"cookies"`
}
type browserCookieSyncPayload struct {
Domain string `json:"domain"`
Name string `json:"name"`
Path string `json:"path"`
Value string `json:"value"`
URL string `json:"url,omitempty"`
Secure bool `json:"secure"`
HTTPOnly bool `json:"httpOnly"`
HTTPOnlySnake bool `json:"http_only"`
SameSite string `json:"sameSite"`
SameSiteSnake string `json:"same_site"`
ExpiresAt *time.Time `json:"expiresAt"`
ExpiresAtSnake *time.Time `json:"expires_at"`
ExpirationDate *float64 `json:"expirationDate"`
ExpirationDateSnake *float64 `json:"expiration_date"`
}
type browserCookieMetadata struct {
Domain string `json:"domain"`
Name string `json:"name"`
Path string `json:"path"`
Secure bool `json:"secure"`
HTTPOnly bool `json:"httpOnly"`
SameSite string `json:"sameSite,omitempty"`
ExpiresAt *time.Time `json:"expiresAt,omitempty"`
Source string `json:"source,omitempty"`
UpdatedAt time.Time `json:"updatedAt"`
}
func (p browserCookieSyncPayload) toStoreCookie(source string) (store.BrowserCookie, error) {
domain := strings.TrimSpace(p.Domain)
if domain == "" && p.URL != "" {
u, err := url.Parse(p.URL)
if err != nil {
return store.BrowserCookie{}, errBrowserCookieInvalidURL
}
domain = u.Hostname()
}
if len(p.Value) > maxBrowserCookieValueBytes {
return store.BrowserCookie{}, errBrowserCookieValueTooLarge
}
c := store.NormalizeBrowserCookie(store.BrowserCookie{
Domain: domain,
Name: p.Name,
Path: p.Path,
Value: p.Value,
Secure: p.Secure,
HTTPOnly: p.HTTPOnly || p.HTTPOnlySnake,
SameSite: firstBrowserCookieNonEmpty(p.SameSite, p.SameSiteSnake),
ExpiresAt: firstTime(p.ExpiresAt, p.ExpiresAtSnake, timeFromUnixSeconds(p.ExpirationDate), timeFromUnixSeconds(p.ExpirationDateSnake)),
Source: source,
})
if err := store.ValidateBrowserCookie(c); err != nil {
return store.BrowserCookie{}, err
}
return c, nil
}
func browserCookieFilterFromQuery(r *http.Request) store.BrowserCookieFilter {
q := r.URL.Query()
return store.BrowserCookieFilter{
Domain: q.Get("domain"),
Name: q.Get("name"),
Path: q.Get("path"),
}
}
func firstBrowserCookieNonEmpty(values ...string) string {
for _, v := range values {
if strings.TrimSpace(v) != "" {
return strings.TrimSpace(v)
}
}
return ""
}
func firstTime(values ...*time.Time) *time.Time {
for _, v := range values {
if v != nil {
t := v.UTC()
return &t
}
}
return nil
}
func timeFromUnixSeconds(v *float64) *time.Time {
if v == nil {
return nil
}
sec := int64(*v)
nsec := int64((*v - float64(sec)) * 1e9)
t := time.Unix(sec, nsec).UTC()
return &t
}