diff --git a/havril/internal/api/handlers/oauth_handler.go b/havril/internal/api/handlers/oauth_handler.go index 08bb818..6f5a09f 100644 --- a/havril/internal/api/handlers/oauth_handler.go +++ b/havril/internal/api/handlers/oauth_handler.go @@ -1,6 +1,7 @@ package handlers import ( + "context" "crypto/rand" "crypto/sha256" "encoding/base64" @@ -29,8 +30,32 @@ type codeEntry struct { expiresAt time.Time } -func NewOAuthHandler(baseURL string, userRepo *user.Repository) *OAuthHandler { - return &OAuthHandler{baseURL: baseURL, userRepo: userRepo} +func NewOAuthHandler(ctx context.Context, baseURL string, userRepo *user.Repository) *OAuthHandler { + h := &OAuthHandler{baseURL: baseURL, userRepo: userRepo} + go h.cleanupExpiredCodes(ctx, 5*time.Minute) + return h +} + +func (h *OAuthHandler) cleanupExpiredCodes(ctx context.Context, interval time.Duration) { + ticker := time.NewTicker(interval) + defer ticker.Stop() + for { + select { + case <-ctx.Done(): + return + case <-ticker.C: + h.deleteExpiredCodes(time.Now()) + } + } +} + +func (h *OAuthHandler) deleteExpiredCodes(now time.Time) { + h.codes.Range(func(k, v any) bool { + if now.After(v.(*codeEntry).expiresAt) { + h.codes.Delete(k) + } + return true + }) } // Metadata handles GET /.well-known/oauth-authorization-server diff --git a/havril/main.go b/havril/main.go index dba69d8..74acebd 100644 --- a/havril/main.go +++ b/havril/main.go @@ -69,11 +69,13 @@ func main() { } goth.UseProviders(providers...) + ctx := context.Background() + // Dependency injection userRepo := user.NewRepository(db) userSvc := user.NewService(userRepo) authHandler := handlers.NewAuthHandler(userSvc) - oauthHandler := handlers.NewOAuthHandler(baseURL, userRepo) + oauthHandler := handlers.NewOAuthHandler(ctx, baseURL, userRepo) authMid := middleware.NewAuthMiddleware(userSvc) modelRepo := user.NewModelRepository(db) modelSvc := user.NewModelService(modelRepo) @@ -84,7 +86,7 @@ func main() { if err != nil { log.Fatalf("connect qdrant: %v", err) } - if err := store.EnsureCollection(context.Background(), qdrantHost, qdrantAPIKey); err != nil { + if err := store.EnsureCollection(ctx, qdrantHost, qdrantAPIKey); err != nil { log.Fatalf("failed to ensure qdrant collection: %v", err) } embedder, err := embedding.New(embedding.Config{