diff --git a/aiogram/utils/auth_widget.py b/aiogram/utils/auth_widget.py index 4793f28c..7d596d5b 100644 --- a/aiogram/utils/auth_widget.py +++ b/aiogram/utils/auth_widget.py @@ -21,7 +21,7 @@ def check_signature(token: str, hash: str, **kwargs: Any) -> bool: check_string.encode("utf-8"), digestmod=hashlib.sha256, ).hexdigest() - return hmac_string == hash + return hmac.compare_digest(hmac_string, hash) def check_integrity(token: str, data: dict[str, Any]) -> bool: diff --git a/aiogram/utils/backoff.py b/aiogram/utils/backoff.py index 5fc1c2d2..afa9daed 100644 --- a/aiogram/utils/backoff.py +++ b/aiogram/utils/backoff.py @@ -65,7 +65,10 @@ class Backoff: await asyncio.sleep(next(self)) def _calculate_next(self, value: float) -> float: - return normalvariate(min(value * self.factor, self.max_delay), self.jitter) + return max( + self.min_delay, + normalvariate(min(value * self.factor, self.max_delay), self.jitter), + ) def __next__(self) -> float: self._current_delay = self._next_delay diff --git a/aiogram/utils/media_group.py b/aiogram/utils/media_group.py index 8a7eb53a..411a168d 100644 --- a/aiogram/utils/media_group.py +++ b/aiogram/utils/media_group.py @@ -351,6 +351,10 @@ class MediaGroupBuilder: :return: List of media objects. """ + if not self._media: + msg = "Media group must contain at least one media element" + raise ValueError(msg) + update_first_media: dict[str, Any] = {"caption": self.caption} if self.caption_entities is not None: update_first_media["caption_entities"] = self.caption_entities