Commit Graph

7816 Commits

Author SHA1 Message Date
Fringg c2b68e1afa fix: apply create-vs-update fix to all remaining tariff_purchase flows
Fixed 6 more locations in tariff_purchase.py that had the same broken
pattern (custom purchase, daily purchase, trial conversion, tariff
switch, daily switch, instant switch). All now use _should_create
based on multi-tariff mode instead of falling back to user UUID.
2026-04-15 13:24:07 +03:00
Fringg cea7260a85 fix: apply same create-vs-update fix to renewal and purchase flows
Same bug as the tariff purchase fix: in multi-tariff mode, new
subscriptions without remnawave_uuid incorrectly fell back to
user.remnawave_uuid and called update instead of create.

Fixed in subscription_renewal_service.py and purchase.py to use
the same _should_create pattern based on mode.
2026-04-15 13:17:35 +03:00
Fringg e3c0caabcf fix: create panel user instead of update for new subscriptions in multi-tariff mode
In multi-tariff mode, new subscriptions have remnawave_uuid=None.
The old logic fell back to user.remnawave_uuid (from a previous
subscription) and called update_remnawave_user(), which refused
to work because the NEW subscription had no UUID.

Now correctly: in multi-tariff mode, always CREATE if subscription
has no remnawave_uuid. In single-tariff mode, use user-level UUID.

Fixes: "subscription has no remnawave_uuid, cannot update panel"
2026-04-15 13:14:10 +03:00
Fringg aeaa4f8e0d fix: allow clearing all period discounts from promo groups
Empty period_discounts dict was normalized to None by the schema,
making it indistinguishable from "field absent" (don't update).
Now empty dict passes through to CRUD which correctly sets
period_discounts=None in DB, clearing all discounts.
2026-04-15 04:13:43 +03:00
Fringg e226ac8637 feat: add DISPLAY_NAME_RESTRICTION_ENABLED toggle
Allows disabling the display name restriction middleware via .env.
Users with special characters in their Telegram name (e.g. "@")
were blocked from using the bot entirely. Default: true (enabled).

Set DISPLAY_NAME_RESTRICTION_ENABLED=false to disable.
2026-04-15 04:03:18 +03:00
Fringg 85403da528 fix: use CABINET_URL for campaign web links instead of MINIAPP_CUSTOM_URL
Campaign web links were generated from MINIAPP_CUSTOM_URL which is often
empty, causing get_campaign_web_link() to return None. Admins and partners
could only share bot links for campaigns, not cabinet links.

Now prefers CABINET_URL (where the auth flow captures ?campaign= param),
falling back to MINIAPP_CUSTOM_URL for backwards compatibility. This is
consistent with how referral web links already use CABINET_URL.
2026-04-15 03:56:34 +03:00
Fringg bdd873382c fix: remove daily tariff fallback to smallest period discount
Daily tariffs (period_days=1) incorrectly inherited the discount
of the smallest configured period (e.g. 90 days -> 5%). This caused
daily prices to show discounts that were never intended for them.

Now daily tariffs only get a discount if explicitly configured for
period_days=1 in the promo group's period_discounts.
2026-04-15 03:39:52 +03:00
Fringg 9d750d9eb0 fix: format telegram_auth.py to use single quotes (ruff) 2026-04-15 03:34:49 +03:00
Gary Jarrel 87b83f59c6 fix(ci): read Docker image version from release-please manifest instead of hardcoding (#2859)
The x-release-please-version markers in workflow files were stuck at v3.7.0
since commit 5070bb34 removed them from extra-files (GitHub Actions returns
403 when release-please tries to modify .github/workflows/ via GITHUB_TOKEN).

Instead of hardcoding the version, read it from .release-please-manifest.json
at build time. This file is always kept in sync by release-please and does
not require workflow file write permissions.

---

Маркеры x-release-please-version в workflow-файлах застряли на v3.7.0
после коммита 5070bb34, который удалил их из extra-files (GitHub Actions
возвращает 403 при попытке release-please изменить .github/workflows/
через GITHUB_TOKEN).

Вместо хардкода версии теперь читаем её из .release-please-manifest.json
во время сборки. Этот файл всегда синхронизируется release-please и не
требует прав на запись в workflow-файлы.
2026-04-15 03:15:35 +03:00
Fringg 8ff6f99229 feat: add TELEGRAM_API_URL for custom Telegram Bot API server
Support custom Telegram Bot API server URL via TELEGRAM_API_URL env var.
Enables bot operation in regions where api.telegram.org is blocked
(Cloudflare Worker, self-hosted telegram-bot-api, nginx reverse proxy).
Uses native aiogram TelegramAPIServer.from_base(), works with PROXY_URL.
2026-04-15 03:12:59 +03:00
Dmitry V. Lunin 94da3c35b0 fix: use PROXY_URL for Telegram OIDC JWKS requests (#2866) 2026-04-15 03:08:06 +03:00
Dmitry V. Lunin d35a8bb74c fix: update subscription_crypto_link when syncing user from panel (#2867)
* fix: update subscription_crypto_link when syncing user from panel

* fix: update subscription_crypto_link when syncing user from panel
2026-04-15 03:07:07 +03:00
Egor c635d88764 Merge pull request #2878 from BEDOLAGA-DEV/main
w
2026-04-15 02:53:04 +03:00
c0mrade 5009703676 Merge pull request #2875 from BEDOLAGA-DEV/release-please--branches--main
chore(main): release 3.46.1
v3.46.1
2026-04-13 22:09:58 +03:00
github-actions[bot] e88a5989b6 chore(main): release 3.46.1 2026-04-13 19:07:27 +00:00
c0mrade 02747381dc Merge pull request #2874 from BEDOLAGA-DEV/dev
fix: cabinet_refresh_tokens migration + notification_settings jsonb
2026-04-13 22:06:53 +03:00
c0mrade e74fda954c fix: change notification_settings from json to jsonb for DISTINCT compatibility 2026-04-13 21:56:04 +03:00
c0mrade 8587f03f67 fix: add checkfirst guards to cabinet_refresh_tokens migration 2026-04-13 21:47:16 +03:00
c0mrade 4707cdf60c fix: add missing migration for cabinet_refresh_tokens table 2026-04-13 21:43:46 +03:00
c0mrade 0879b8b218 Merge pull request #2873 from BEDOLAGA-DEV/release-please--branches--main
chore(main): release 3.46.0
v3.46.0
2026-04-13 19:47:36 +03:00
github-actions[bot] 1d91382b8e chore(main): release 3.46.0 2026-04-13 16:37:54 +00:00
c0mrade 3768b18a39 Merge pull request #2872 from BEDOLAGA-DEV/dev
Bugfixes: campaign, tickets, NaloGO, devices, broadcasts, menu editor
2026-04-13 19:37:16 +03:00
c0mrade 1eeeb39779 fix: exclude users with active subscriptions from expired broadcast
In multi-subscription mode, a user with an expired trial AND an active
paid subscription was incorrectly included in expired broadcast targets.

Fixed in 3 places:
- get_target_users_count (SQL): added NOT EXISTS active sub subquery
- get_target_users 'expired' (Python): skip if has_active
- get_target_users 'expired_subscribers' (Python): same check
2026-04-13 19:21:52 +03:00
c0mrade 570af82dfd fix: raise MAX_BUTTONS_PER_ROW to 8 and allow tg:// deep links in menu editor
MAX_BUTTONS_PER_ROW was 3, causing Pydantic 422 when adding multiple
custom buttons to a row. Telegram allows up to 8 buttons per row.

Also added tg:// to URL_PATTERN so admins can use Telegram deep links
(tg://resolve, tg://user, etc.) in custom menu buttons. webapp mode
still requires https:// as enforced by existing validation.
2026-04-13 17:07:19 +03:00
c0mrade bc3893b934 fix: use MAX_DEVICES_LIMIT instead of hardcoded 10 for device buttons
Admin user device editor had hardcoded limit of 10 in text, validation,
and inline buttons. Now uses settings.MAX_DEVICES_LIMIT dynamically,
generating buttons 1..N in rows of 4. Falls back to text-only input
if limit exceeds Telegram's 100-button cap.
2026-04-13 14:42:16 +03:00
c0mrade 16d91638bc fix: enforce max_attempts limit in NaloGO receipt queue
The _max_attempts property existed but was never checked as a limit.
Receipts were retried indefinitely (55+ attempts observed in logs).
Now receipts exceeding max_attempts are removed from the queue.
2026-04-13 14:42:06 +03:00
c0mrade eb18b3a0f9 fix: handle TelegramBadRequest when deleting old ticket notifications
Messages older than 48 hours cannot be deleted via Telegram API.
Now falls back to editing the message text instead of crashing.
2026-04-13 14:41:59 +03:00
c0mrade a8e2b62f4b feat: save campaign_slug during standalone email registration
Campaign slug was lost during email registration flow — it was only
sent at verification time from localStorage, which is empty if the
user opens the verification link in a different browser/webview.

Now campaign_slug is accepted in the registration request, saved to
user.pending_campaign_slug, and used as fallback during email
verification. Also processed immediately for auto-verified test emails.
2026-04-13 14:41:49 +03:00
c0mrade fb8d2b3ee4 fix: upsert refresh tokens (ON CONFLICT) + periodic cleanup of expired/revoked tokens 2026-04-10 18:08:27 +03:00
c0mrade 2321667ecb fix: add TRAFFIC_WARNING_ALERT and LOW_BALANCE_ALERT localization keys to all locales 2026-04-10 17:58:04 +03:00
c0mrade 113304b212 style: remove unused import (ruff fix) 2026-04-10 16:47:41 +03:00
c0mrade 0300044b00 feat: add category field to broadcast API schemas and routes 2026-04-10 16:10:13 +03:00
c0mrade 931abfe7a5 feat: add broadcast category (system/news/promo) + filter recipients by user prefs 2026-04-10 16:05:43 +03:00
c0mrade 1d96f80f60 feat: add traffic % warning check using user's threshold preference 2026-04-10 15:59:32 +03:00
c0mrade 4e50419171 feat: implement low balance alert + respect user notification preferences
- Add _check_low_balance_alerts to monitoring service
- Notify users with autopay when balance drops below their threshold
- Uses notification_prefs helper for per-user settings
2026-04-10 15:43:32 +03:00
c0mrade 7208a52c94 feat: respect user traffic_warning notification preference in webhook handler 2026-04-10 15:37:33 +03:00
c0mrade 63fdfe4a42 feat: respect user subscription_expiry notification preferences 2026-04-10 15:37:00 +03:00
c0mrade e0e2edf816 feat: add user notification preferences helper utility 2026-04-10 15:35:30 +03:00
c0mrade 522a8779d6 style: fix ruff format for all sync-related changes 2026-04-10 15:13:59 +03:00
c0mrade be32010d63 fix: trial activation fallback to trial-eligible servers when tariff has no squads (BUG-12) + fix misleading button text 2026-04-10 15:04:38 +03:00
c0mrade 7e920fa30f fix: add retry queue to all remaining RemnaWave error handlers 2026-04-10 14:22:10 +03:00
c0mrade 1b376baeca fix: add retry queue to cabinet subscription operation RemnaWave errors 2026-04-10 11:56:48 +03:00
c0mrade 91a756a33e fix: add retry queue to payment webhook and renewal service RemnaWave errors 2026-04-10 11:56:24 +03:00
c0mrade 970dc549df fix: add retry queue to classic mode bot purchase handler 2026-04-10 11:40:20 +03:00
c0mrade 65120f0bad fix: add retry queue to daily subscription service RemnaWave errors 2026-04-10 11:39:39 +03:00
c0mrade 9cb559ff39 fix: enqueue retry on RemnaWave API failure in all purchase flows (BUG-2, BUG-10)
Add remnawave_retry_queue.enqueue() calls in all 10 purchase error handlers
where RemnaWave API failure was caught and swallowed without scheduling a retry:
- cabinet purchase.py: purchase_tariff() and activate_trial() (2 places)
- subscription_purchase_service.py: miniapp purchase flow (1 place)
- tariff_purchase.py: custom, standard, daily, renewal, switch, daily-switch,
  and instant-switch flows (7 places)
2026-04-10 11:04:02 +03:00
c0mrade 8f1882f24c feat: start RemnaWave retry queue on app startup 2026-04-10 10:48:14 +03:00
c0mrade 8542a39305 fix: always sync squads in auto-purchase renewal (BUG-4) 2026-04-10 10:48:01 +03:00
c0mrade 646ac4cfa1 fix: match tariff_id when creating subscriptions from panel sync (BUG-11) 2026-04-10 10:41:50 +03:00
c0mrade abdf296767 feat: add RemnaWave retry queue for failed API calls (BUG-2, BUG-10) 2026-04-10 10:41:49 +03:00