refactor: introduce reqctx pkg for request context

This commit is contained in:
2025-12-04 00:48:43 +00:00
parent 57167d5715
commit 539b15dcb7
4 changed files with 29 additions and 19 deletions

View File

@@ -5,6 +5,7 @@ import (
"github.com/get-drexa/drexa/internal/auth" "github.com/get-drexa/drexa/internal/auth"
"github.com/get-drexa/drexa/internal/httperr" "github.com/get-drexa/drexa/internal/httperr"
"github.com/get-drexa/drexa/internal/reqctx"
"github.com/get-drexa/drexa/internal/user" "github.com/get-drexa/drexa/internal/user"
"github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2"
"github.com/google/uuid" "github.com/google/uuid"
@@ -54,17 +55,14 @@ func (h *HTTPHandler) RegisterRoutes(api fiber.Router) fiber.Router {
} }
func (h *HTTPHandler) accountMiddleware(c *fiber.Ctx) error { func (h *HTTPHandler) accountMiddleware(c *fiber.Ctx) error {
user, err := auth.AuthenticatedUser(c) u := reqctx.AuthenticatedUser(c).(*user.User)
if err != nil {
return c.SendStatus(fiber.StatusUnauthorized)
}
accountID, err := uuid.Parse(c.Params("accountID")) accountID, err := uuid.Parse(c.Params("accountID"))
if err != nil { if err != nil {
return c.SendStatus(fiber.StatusNotFound) return c.SendStatus(fiber.StatusNotFound)
} }
account, err := h.accountService.AccountByID(c.Context(), h.db, user.ID, accountID) account, err := h.accountService.AccountByID(c.Context(), h.db, u.ID, accountID)
if err != nil { if err != nil {
if errors.Is(err, ErrAccountNotFound) { if errors.Is(err, ErrAccountNotFound) {
return c.SendStatus(fiber.StatusNotFound) return c.SendStatus(fiber.StatusNotFound)

View File

@@ -5,7 +5,6 @@ import (
"fmt" "fmt"
) )
var ErrUnauthenticatedRequest = errors.New("unauthenticated request")
var ErrInvalidRefreshToken = errors.New("invalid refresh token") var ErrInvalidRefreshToken = errors.New("invalid refresh token")
var ErrRefreshTokenExpired = errors.New("refresh token expired") var ErrRefreshTokenExpired = errors.New("refresh token expired")
var ErrRefreshTokenReused = errors.New("refresh token reused") var ErrRefreshTokenReused = errors.New("refresh token reused")

View File

@@ -7,15 +7,14 @@ import (
"time" "time"
"github.com/get-drexa/drexa/internal/httperr" "github.com/get-drexa/drexa/internal/httperr"
"github.com/get-drexa/drexa/internal/reqctx"
"github.com/get-drexa/drexa/internal/user" "github.com/get-drexa/drexa/internal/user"
"github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2"
"github.com/uptrace/bun" "github.com/uptrace/bun"
) )
const authenticatedUserKey = "authenticatedUser"
// NewAuthMiddleware creates a middleware that authenticates requests via Bearer token or cookies. // NewAuthMiddleware creates a middleware that authenticates requests via Bearer token or cookies.
// To obtain the authenticated user in subsequent handlers, see AuthenticatedUser. // To obtain the authenticated user in subsequent handlers, see reqctx.AuthenticatedUser.
func NewAuthMiddleware(s *Service, db *bun.DB, cookieConfig CookieConfig) fiber.Handler { func NewAuthMiddleware(s *Service, db *bun.DB, cookieConfig CookieConfig) fiber.Handler {
return func(c *fiber.Ctx) error { return func(c *fiber.Ctx) error {
var at string var at string
@@ -59,7 +58,7 @@ func NewAuthMiddleware(s *Service, db *bun.DB, cookieConfig CookieConfig) fiber.
return httperr.Internal(err) return httperr.Internal(err)
} }
c.Locals(authenticatedUserKey, authResult.User) reqctx.SetAuthenticatedUser(c, authResult.User)
// if cookie based auth and access token is about to expire (within 5 minutes), // if cookie based auth and access token is about to expire (within 5 minutes),
// attempt to refresh the access token. if there is any error, ignore it and let the request continue. // attempt to refresh the access token. if there is any error, ignore it and let the request continue.
@@ -81,12 +80,3 @@ func NewAuthMiddleware(s *Service, db *bun.DB, cookieConfig CookieConfig) fiber.
return c.Next() return c.Next()
} }
} }
// AuthenticatedUser returns the authenticated user from the given fiber context.
// Returns ErrUnauthenticatedRequest if not authenticated.
func AuthenticatedUser(c *fiber.Ctx) (*user.User, error) {
if u, ok := c.Locals(authenticatedUserKey).(*user.User); ok {
return u, nil
}
return nil, ErrUnauthenticatedRequest
}

View File

@@ -0,0 +1,23 @@
package reqctx
import (
"errors"
"github.com/gofiber/fiber/v2"
)
const authenticatedUserKey = "authenticatedUser"
var ErrUnauthenticatedRequest = errors.New("unauthenticated request")
// AuthenticatedUser returns the authenticated user from the given fiber context.
// Returns ErrUnauthenticatedRequest if not authenticated.
// The caller must type assert the returned value to the appropriate user type.
func AuthenticatedUser(c *fiber.Ctx) any {
return c.Locals(authenticatedUserKey)
}
// SetAuthenticatedUser sets the authenticated user in the fiber context.
func SetAuthenticatedUser(c *fiber.Ctx, user interface{}) {
c.Locals(authenticatedUserKey, user)
}