commit 050ae0756f75da6590184e1b2fbfb1ca353126e7
parent 35ed37cd0383836418975052c2d3427ce7040d26
Author: n0tr1v <n0tr1v@protonmail.com>
Date: Sat, 30 Dec 2023 12:47:34 -0500
draft rate limiter
Diffstat:
1 file changed, 20 insertions(+), 4 deletions(-)
diff --git a/pkg/web/middlewares/middlewares.go b/pkg/web/middlewares/middlewares.go
@@ -274,7 +274,24 @@ func SetUserMiddleware(next echo.HandlerFunc) echo.HandlerFunc {
}
}
-var lastSeenCache = cache.NewWithKey[database.UserID, struct{}](time.Second, time.Minute)
+type RateLimit[K comparable] struct {
+ cache *cache.Cache[K, struct{}]
+}
+
+func NewRateLimit[K comparable](defaultExpiration time.Duration) *RateLimit[K] {
+ return &RateLimit[K]{
+ cache: cache.NewWithKey[K, struct{}](defaultExpiration, time.Minute),
+ }
+}
+
+func (l *RateLimit[K]) Clb(k K, clb func()) {
+ if !l.cache.Has(k) {
+ clb()
+ l.cache.SetD(k, struct{}{})
+ }
+}
+
+var lastSeenRL = NewRateLimit[database.UserID](time.Second)
// IsAuthMiddleware will ensure user is authenticated.
// - Find user from context
@@ -298,11 +315,10 @@ func IsAuthMiddleware(next echo.HandlerFunc) echo.HandlerFunc {
c.Response().Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
- if !lastSeenCache.Has(user.ID) {
+ lastSeenRL.Clb(user.ID, func() {
now := time.Now()
db.DB().Exec("UPDATE users SET last_seen_at = ?, updated_at = ? WHERE id = ?", now, now, int64(user.ID))
- lastSeenCache.SetD(user.ID, struct{}{})
- }
+ })
// Prevent clickjacking by setting the header on every logged in page
if !strings.Contains(c.Path(), "/chess/:key/form") &&