package middleware import ( "net/http" "time" "github.com/labstack/echo/v4" "github.com/labstack/echo/v4/middleware" "golang.org/x/time/rate" "github.com/treytartt/honeydue-api/internal/dto/responses" ) // AuthRateLimiter returns rate-limiting middleware tuned for authentication // endpoints. It uses Echo's built-in in-memory rate limiter keyed by client // IP address. // // Parameters: // - ratePerSecond: sustained request rate (e.g., 10/60.0 for ~10 per minute) // - burst: maximum burst size above the sustained rate func AuthRateLimiter(ratePerSecond rate.Limit, burst int) echo.MiddlewareFunc { store := middleware.NewRateLimiterMemoryStoreWithConfig( middleware.RateLimiterMemoryStoreConfig{ Rate: ratePerSecond, Burst: burst, ExpiresIn: 5 * time.Minute, }, ) return middleware.RateLimiterWithConfig(middleware.RateLimiterConfig{ Skipper: middleware.DefaultSkipper, IdentifierExtractor: func(c echo.Context) (string, error) { return c.RealIP(), nil }, Store: store, DenyHandler: func(c echo.Context, _ string, _ error) error { return c.JSON(http.StatusTooManyRequests, responses.ErrorResponse{ Error: "Too many requests. Please try again later.", }) }, ErrorHandler: func(c echo.Context, err error) error { return c.JSON(http.StatusForbidden, responses.ErrorResponse{ Error: "Unable to process request.", }) }, }) } // LoginRateLimiter returns rate-limiting middleware for login endpoints. // Allows 10 requests per minute with a burst of 5. func LoginRateLimiter() echo.MiddlewareFunc { // 10 requests per 60 seconds = ~0.167 req/s, burst 5 return AuthRateLimiter(rate.Limit(10.0/60.0), 5) } // RegistrationRateLimiter returns rate-limiting middleware for registration // endpoints. Allows 5 requests per minute with a burst of 3. func RegistrationRateLimiter() echo.MiddlewareFunc { // 5 requests per 60 seconds = ~0.083 req/s, burst 3 return AuthRateLimiter(rate.Limit(5.0/60.0), 3) } // PasswordResetRateLimiter returns rate-limiting middleware for password // reset endpoints. Allows 3 requests per minute with a burst of 2. func PasswordResetRateLimiter() echo.MiddlewareFunc { // 3 requests per 60 seconds = 0.05 req/s, burst 2 return AuthRateLimiter(rate.Limit(3.0/60.0), 2) }