Files
sonr/pkg/gateway/internal/session/context.go
T

110 lines
2.5 KiB
Go
Raw Normal View History

2024-12-05 20:36:58 -05:00
package session
import (
"net/http"
2024-12-06 21:31:20 -05:00
"regexp"
"strings"
2024-12-05 20:36:58 -05:00
"github.com/labstack/echo/v4"
"github.com/onsonr/sonr/pkg/common"
2024-12-06 21:31:20 -05:00
"github.com/onsonr/sonr/pkg/gateway/internal/database"
"github.com/segmentio/ksuid"
"gorm.io/gorm"
2024-12-05 20:36:58 -05:00
)
2024-12-06 21:31:20 -05:00
// Get returns the HTTPContext from the echo context
func Get(c echo.Context) (*HTTPContext, error) {
2024-12-05 20:36:58 -05:00
ctx, ok := c.(*HTTPContext)
if !ok {
return nil, echo.NewHTTPError(http.StatusInternalServerError, "Session Context not found")
}
return ctx, nil
}
2024-12-06 21:31:20 -05:00
// HTTPContext is the context for HTTP endpoints.
type HTTPContext struct {
echo.Context
db *gorm.DB
sess *database.Session
}
// NewHTTPContext creates a new session context
func NewHTTPContext(c echo.Context, db *gorm.DB) *HTTPContext {
return &HTTPContext{
Context: c,
db: db,
}
2024-12-05 20:36:58 -05:00
}
2024-12-06 21:31:20 -05:00
// Session returns the current session
func (s *HTTPContext) Session() *database.Session {
return s.sess
2024-12-05 20:36:58 -05:00
}
2024-12-06 21:31:20 -05:00
// InitSession initializes or loads an existing session
func (s *HTTPContext) InitSession() error {
sessionID := s.getOrCreateSessionID()
// Try to load existing session
var sess database.Session
result := s.db.Where("id = ?", sessionID).First(&sess)
if result.Error != nil {
// Create new session if not found
bn, bv := extractBrowserInfo(s.Context)
sess = database.Session{
ID: sessionID,
BrowserName: bn,
BrowserVersion: bv,
}
if err := s.db.Create(&sess).Error; err != nil {
return err
}
}
s.sess = &sess
2024-12-05 20:36:58 -05:00
return nil
}
2024-12-06 21:31:20 -05:00
func (s *HTTPContext) getOrCreateSessionID() string {
if ok := common.CookieExists(s.Context, common.SessionID); !ok {
sessionID := ksuid.New().String()
common.WriteCookie(s.Context, common.SessionID, sessionID)
return sessionID
}
sessionID, err := common.ReadCookie(s.Context, common.SessionID)
if err != nil {
sessionID = ksuid.New().String()
common.WriteCookie(s.Context, common.SessionID, sessionID)
}
return sessionID
}
func extractBrowserInfo(c echo.Context) (string, string) {
userAgent := common.HeaderRead(c, common.UserAgent)
if userAgent == "" {
return "N/A", "-1"
}
var name, ver string
entries := strings.Split(strings.TrimSpace(userAgent), ",")
for _, entry := range entries {
entry = strings.TrimSpace(entry)
re := regexp.MustCompile(`"([^"]+)";v="([^"]+)"`)
matches := re.FindStringSubmatch(entry)
if len(matches) == 3 {
browserName := matches[1]
version := matches[2]
if browserName != common.BrowserNameUnknown.String() &&
browserName != common.BrowserNameChromium.String() {
name = browserName
ver = version
break
}
}
}
return name, ver
}