fix: address audit findings for websearch, email verification, and pricing

- Fix websearch provider failover: proxy error from provider-specific proxy
  now continues to next provider instead of aborting the entire loop
- Fix SMTP failure locking users out: send email first, then write cache
  and increment rate counter
- Fix notify email cache key case sensitivity: normalize to lowercase
- Add OriginalPrice validation to validatePlanPatch and validatePlanRequired
- Add empty scope validation for channel pricing rules (group_ids/account_ids)
- Add platform color to account search dropdown in channel pricing rules
This commit is contained in:
erio
2026-04-13 23:35:59 +08:00
parent 1b7c295199
commit 74f8a30f86
7 changed files with 103 additions and 26 deletions

View File

@@ -291,6 +291,12 @@ func (s *UserService) SendNotifyEmailCode(ctx context.Context, userID int64, ema
return fmt.Errorf("generate code: %w", err)
}
// Send email first — if SMTP fails, don't write cache or increment counters,
// so the user is not locked out by cooldown/rate-limit for a code they never received.
if err := s.sendNotifyVerifyEmail(ctx, emailService, email, code); err != nil {
return err
}
if err := saveNotifyVerifyCode(ctx, cache, email, code); err != nil {
return err
}
@@ -300,7 +306,7 @@ func (s *UserService) SendNotifyEmailCode(ctx context.Context, userID int64, ema
slog.Error("failed to increment notify code user rate", "user_id", userID, "error", err)
}
return s.sendNotifyVerifyEmail(ctx, emailService, email, code)
return nil
}
// checkNotifyCodeRateLimit checks both email cooldown and user-level rate limit.