mirror of
https://github.com/onsonr/sonr.git
synced 2025-03-10 21:09:11 +00:00
91 lines
2.1 KiB
Go
91 lines
2.1 KiB
Go
package ctx
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"net/http"
|
|
"time"
|
|
|
|
"github.com/gorilla/sessions"
|
|
"github.com/labstack/echo/v4"
|
|
"github.com/segmentio/ksuid"
|
|
)
|
|
|
|
var store sessions.Store
|
|
|
|
type ctxKeySessionID struct{}
|
|
|
|
// SessionMiddleware establishes a Session Cookie.
|
|
func SessionMiddleware(next echo.HandlerFunc) echo.HandlerFunc {
|
|
store = sessions.NewCookieStore([]byte("SESSION_KEY"))
|
|
return func(c echo.Context) error {
|
|
ctx := c.Request().Context()
|
|
|
|
// Attempt to read the session ID from the "session" cookie
|
|
sessionID, err := readSessionIDFromCookie(c)
|
|
if err != nil {
|
|
// Generate a new KSUID if the session cookie is missing or invalid
|
|
sessionID = ksuid.New().String()
|
|
// Write the new session ID to the "session" cookie
|
|
err = writeSessionIDToCookie(c, sessionID)
|
|
if err != nil {
|
|
return c.JSON(
|
|
http.StatusInternalServerError,
|
|
map[string]string{"error": "Failed to set session cookie"},
|
|
)
|
|
}
|
|
}
|
|
|
|
// Inject the session ID into the context
|
|
ctx = context.WithValue(ctx, ctxKeySessionID{}, sessionID)
|
|
// Update the request with the new context
|
|
c.SetRequest(c.Request().WithContext(ctx))
|
|
|
|
return next(c)
|
|
}
|
|
}
|
|
|
|
func defaultSession(id string, s *sessions.Session) *session {
|
|
return &session{
|
|
session: s,
|
|
id: id,
|
|
origin: "",
|
|
address: "",
|
|
chainID: "",
|
|
}
|
|
}
|
|
|
|
func getSessionID(ctx context.Context) (string, error) {
|
|
sessionID, ok := ctx.Value(ctxKeySessionID{}).(string)
|
|
if !ok || sessionID == "" {
|
|
return "", errors.New("session ID not found in context")
|
|
}
|
|
return sessionID, nil
|
|
}
|
|
|
|
func readSessionIDFromCookie(c echo.Context) (string, error) {
|
|
cookie, err := c.Cookie("session")
|
|
if err != nil {
|
|
// Cookie not found or other error
|
|
return "", err
|
|
}
|
|
if cookie == nil || cookie.Value == "" {
|
|
// Cookie is empty
|
|
return "", http.ErrNoCookie
|
|
}
|
|
return cookie.Value, nil
|
|
}
|
|
|
|
func writeSessionIDToCookie(c echo.Context, sessionID string) error {
|
|
cookie := &http.Cookie{
|
|
Name: "session",
|
|
Value: sessionID,
|
|
Expires: time.Now().Add(24 * time.Hour),
|
|
HttpOnly: true,
|
|
Path: "/",
|
|
// Add Secure and SameSite attributes as needed
|
|
}
|
|
c.SetCookie(cookie)
|
|
return nil
|
|
}
|