chore(topup): harden direct-open guard and admin toggle defenses

Post-review nits:
* AdminPaymentMethodEdit.tsx: `config.open_url_direct ?? false` when seeding
  state — defends against stale backend rendering (e.g. cache invalidation
  race before migration applies)
* Same file: aria-label now uses the localized `admin.paymentMethods.openUrlDirect`
  translation key instead of hardcoded English
* TopUpAmount.tsx: case-insensitive guard for Telegram deep-link URLs —
  `https://t.me/`, `http://t.me/`, and `tg://` all match regardless of provider
  casing quirks. Lowercase normalization done once before the comparisons.
This commit is contained in:
Fringg
2026-05-13 11:13:33 +03:00
parent aa8bfc9d08
commit 5493c25e5f
2 changed files with 11 additions and 3 deletions

View File

@@ -80,7 +80,8 @@ export default function AdminPaymentMethodEdit() {
setFirstTopupFilter(config.first_topup_filter);
setPromoGroupFilterMode(config.promo_group_filter_mode);
setSelectedPromoGroupIds(config.allowed_promo_group_ids);
setOpenUrlDirect(config.open_url_direct);
// ?? false — защита от stale-config (backend ещё не пришёл с миграцией)
setOpenUrlDirect(config.open_url_direct ?? false);
}
}, [config]);
@@ -236,7 +237,7 @@ export default function AdminPaymentMethodEdit() {
className={`relative h-6 w-11 shrink-0 rounded-full transition-colors ${
openUrlDirect ? 'bg-accent-500' : 'bg-dark-600'
}`}
aria-label="Toggle open URL directly"
aria-label={t('admin.paymentMethods.openUrlDirect', 'Open payment page directly')}
>
<span
className={`absolute top-1 h-4 w-4 rounded-full bg-white transition-transform ${

View File

@@ -279,7 +279,14 @@ export default function TopUpAmount() {
// handler (openInvoice / openTelegramLink в setPaymentUrl-ветке).
// Stars уже отбит раньше через starsPaymentMutation, здесь — защита
// на случай CryptoBot и других Telegram-deep-link провайдеров.
if (method?.open_url_direct && !redirectUrl.startsWith('https://t.me/')) {
// toLowerCase для устойчивости к редким провайдерам, которые могут вернуть
// URL в нестандартном регистре. Также покрываем tg:// scheme на всякий случай.
const lowerUrl = redirectUrl.toLowerCase();
const isTelegramDeepLink =
lowerUrl.startsWith('https://t.me/') ||
lowerUrl.startsWith('http://t.me/') ||
lowerUrl.startsWith('tg://');
if (method?.open_url_direct && !isTelegramDeepLink) {
window.location.href = redirectUrl;
return;
}