From 517ea76a9c2593383d5ac367408f87d7043fa6f6 Mon Sep 17 00:00:00 2001 From: Jay Hemnani <193022578+jayhemnani9910@users.noreply.github.com> Date: Tue, 20 Oct 2026 02:45:00 +0530 Subject: [PATCH] fix: send the API key expiration email again after a renewal (#1847) Co-authored-by: Elias Schneider --- backend/internal/apikey/expiry_job_test.go | 44 ++++++++++++++++++++++ backend/internal/apikey/service.go | 2 + 2 files changed, 46 insertions(+) diff --git a/backend/internal/apikey/expiry_job_test.go b/backend/internal/apikey/expiry_job_test.go index 281fa59f..cd12e339 100644 --- a/backend/internal/apikey/expiry_job_test.go +++ b/backend/internal/apikey/expiry_job_test.go @@ -100,3 +100,47 @@ func TestAPIKeyExpiryCronJobNotifiesAndMarksExpiringKeys(t *testing.T) { require.NoError(t, db.First(&laterKey, "id = ?", laterKey.ID).Error) require.False(t, laterKey.ExpirationEmailSent) } + +func TestAPIKeyExpiryCronJobNotifiesAgainAfterRenewal(t *testing.T) { + db := testutils.NewDatabaseForTest(t) + userEmail := "renewal@example.com" + user := model.User{ + Username: "renewal-user", + Email: &userEmail, + FirstName: "Renewal", + LastName: "User", + DisplayName: "Renewal User", + } + require.NoError(t, db.Create(&user).Error) + + // The key already expired, and its owner was notified before that + renewedKey := ApiKey{ + Name: "Renewed", + Key: "renewed-hash", + ExpiresAt: datatype.DateTime(time.Now().Add(-time.Hour)), + ExpirationEmailSent: true, + UserID: user.ID, + } + require.NoError(t, db.Create(&renewedKey).Error) + + service, err := newService(t.Context(), db, "") + require.NoError(t, err) + + renewed, _, err := service.RenewApiKey(t.Context(), user.ID, renewedKey.ID, time.Now().Add(3*24*time.Hour)) + require.NoError(t, err) + require.False(t, renewed.ExpirationEmailSent) + + sender := &expiryJobTestSender{} + job := &expiryJob{ + service: service, + appConfig: expiryJobTestConfig{config: &appconfig.AppConfigModel{ + EmailApiKeyExpirationEnabled: "true", + }}, + email: sender, + } + require.NoError(t, job.checkAndNotifyExpiringAPIKeys(t.Context())) + require.Equal(t, []string{"Renewed"}, sender.keyNames) + + require.NoError(t, db.First(&renewedKey, "id = ?", renewedKey.ID).Error) + require.True(t, renewedKey.ExpirationEmailSent) +} diff --git a/backend/internal/apikey/service.go b/backend/internal/apikey/service.go index e44d857f..c3de9289 100644 --- a/backend/internal/apikey/service.go +++ b/backend/internal/apikey/service.go @@ -123,6 +123,8 @@ func (s *Service) RenewApiKey(ctx context.Context, userID, apiKeyID string, expi apiKey.Key = utils.CreateSha256Hash(token) apiKey.ExpiresAt = datatype.DateTime(expiration) + // The renewed key expires again, so its owner should be notified again + apiKey.ExpirationEmailSent = false err = tx.WithContext(ctx).Save(&apiKey).Error if err != nil {