feat: add manual and automatic WARP IP rotation (#5099)

* feat: add manual and automatic WARP IP rotation

* fix: update generated api and frontend schemas

* fix(warp): validate rotation interval, fix auto-update timing, sync editor

- Validate the auto-update interval as an integer and store it via setInt;
  a non-integer value previously broke GetAllSetting for the whole panel.
- Seed warpLastUpdate when the interval is saved and when changing IP
  manually, so auto-update counts from "now" instead of epoch 0 and a
  manual rotation doesn't trigger an immediate scheduled one.
- Guard WarpIpJob: when lastUpdate is unset, establish a baseline and skip
  instead of rotating on the next tick.
- Log WARP license re-apply failures instead of swallowing them.
- After a manual "Change IP", sync the in-memory Xray editor with the keys
  the backend persisted so a later template save can't revert them; only
  toast success when the interval save actually succeeds.
- Add the WARP rotation UI strings to all 13 locales.
- Drop trailing whitespace introduced in entity.go and xray_setting.go.

---------

Co-authored-by: Rqzbeh <Rqzbeh@example.com>
Co-authored-by: Sanaei <ho3ein.sanaei@gmail.com>
This commit is contained in:
Rouzbeh†
2026-06-09 01:43:43 +02:00
committed by GitHub
parent be8bd4e22c
commit d9ccf157c3
27 changed files with 436 additions and 28 deletions
+5
View File
@@ -1455,6 +1455,11 @@
"outboundUpdated": "تم تحديث صادر NordVPN"
},
"warp": {
"changeIp": "تغيير الـ IP",
"changeIpSuccess": "تم تغيير عنوان IP الخاص بـ WARP بنجاح!",
"autoUpdateIp": "التحديث التلقائي لعنوان IP",
"intervalDays": "الفاصل الزمني (أيام)",
"intervalDesc": "0 للتعطيل. يغيّر عنوان IP تلقائيًا.",
"licenseError": "فشل تعيين رخصة WARP.",
"fetchFirst": "احصل على تكوين WARP أولاً.",
"createAccount": "إنشاء حساب WARP",
+5
View File
@@ -1456,6 +1456,11 @@
"outboundUpdated": "NordVPN outbound updated"
},
"warp": {
"changeIp": "Change IP",
"changeIpSuccess": "WARP IP changed successfully!",
"autoUpdateIp": "Auto Update IP Address",
"intervalDays": "Interval (Days)",
"intervalDesc": "0 to disable. Changes IP address automatically.",
"licenseError": "Failed to set WARP license.",
"fetchFirst": "Fetch the WARP config first.",
"createAccount": "Create WARP account",
+5
View File
@@ -1455,6 +1455,11 @@
"outboundUpdated": "Salida NordVPN actualizada"
},
"warp": {
"changeIp": "Cambiar IP",
"changeIpSuccess": "¡IP de WARP cambiada correctamente!",
"autoUpdateIp": "Actualizar IP automáticamente",
"intervalDays": "Intervalo (días)",
"intervalDesc": "0 para desactivar. Cambia la dirección IP automáticamente.",
"licenseError": "No se pudo establecer la licencia WARP.",
"fetchFirst": "Obtén primero la configuración WARP.",
"createAccount": "Crear cuenta WARP",
+5
View File
@@ -1455,6 +1455,11 @@
"outboundUpdated": "خروجی NordVPN به‌روزرسانی شد"
},
"warp": {
"changeIp": "تغییر IP",
"changeIpSuccess": "آدرس IP وارپ با موفقیت تغییر کرد!",
"autoUpdateIp": "به‌روزرسانی خودکار آدرس IP",
"intervalDays": "بازه (روز)",
"intervalDesc": "برای غیرفعال‌سازی ۰ بگذارید. آدرس IP را به‌صورت خودکار تغییر می‌دهد.",
"licenseError": "تنظیم لایسنس WARP ناموفق بود.",
"fetchFirst": "ابتدا پیکربندی WARP را دریافت کنید.",
"createAccount": "ایجاد حساب WARP",
+5
View File
@@ -1455,6 +1455,11 @@
"outboundUpdated": "Outbound NordVPN diperbarui"
},
"warp": {
"changeIp": "Ganti IP",
"changeIpSuccess": "IP WARP berhasil diganti!",
"autoUpdateIp": "Perbarui Alamat IP Otomatis",
"intervalDays": "Interval (Hari)",
"intervalDesc": "0 untuk menonaktifkan. Mengganti alamat IP secara otomatis.",
"licenseError": "Gagal mengatur lisensi WARP.",
"fetchFirst": "Ambil konfig WARP terlebih dahulu.",
"createAccount": "Buat akun WARP",
+5
View File
@@ -1455,6 +1455,11 @@
"outboundUpdated": "NordVPN アウトバウンドを更新しました"
},
"warp": {
"changeIp": "IP を変更",
"changeIpSuccess": "WARP の IP を変更しました!",
"autoUpdateIp": "IP アドレスの自動更新",
"intervalDays": "間隔(日)",
"intervalDesc": "0 で無効。IP アドレスを自動的に変更します。",
"licenseError": "WARP ライセンスの設定に失敗しました。",
"fetchFirst": "先に WARP 構成を取得してください。",
"createAccount": "WARP アカウントを作成",
+5
View File
@@ -1455,6 +1455,11 @@
"outboundUpdated": "Saída NordVPN atualizada"
},
"warp": {
"changeIp": "Alterar IP",
"changeIpSuccess": "IP do WARP alterado com sucesso!",
"autoUpdateIp": "Atualizar endereço IP automaticamente",
"intervalDays": "Intervalo (dias)",
"intervalDesc": "0 para desativar. Altera o endereço IP automaticamente.",
"licenseError": "Falha ao definir licença WARP.",
"fetchFirst": "Obtenha primeiro a configuração WARP.",
"createAccount": "Criar conta WARP",
+5
View File
@@ -1455,6 +1455,11 @@
"outboundUpdated": "Исходящий NordVPN обновлён"
},
"warp": {
"changeIp": "Сменить IP",
"changeIpSuccess": "IP-адрес WARP успешно изменён!",
"autoUpdateIp": "Автоматическое обновление IP-адреса",
"intervalDays": "Интервал (дни)",
"intervalDesc": "0 — отключить. Автоматически меняет IP-адрес.",
"licenseError": "Не удалось установить лицензию WARP.",
"fetchFirst": "Сначала получите WARP-конфиг.",
"createAccount": "Создать аккаунт WARP",
+5
View File
@@ -1454,6 +1454,11 @@
"outboundUpdated": "NordVPN giden bağlantı güncellendi."
},
"warp": {
"changeIp": "IP Değiştir",
"changeIpSuccess": "WARP IP adresi başarıyla değiştirildi!",
"autoUpdateIp": "IP Adresini Otomatik Güncelle",
"intervalDays": "Aralık (Gün)",
"intervalDesc": "Devre dışı bırakmak için 0. IP adresini otomatik olarak değiştirir.",
"licenseError": "WARP lisansı ayarlanamadı.",
"fetchFirst": "Önce WARP yapılandırmasını alın.",
"createAccount": "WARP Hesabı Oluştur",
+5
View File
@@ -1455,6 +1455,11 @@
"outboundUpdated": "Вихідний NordVPN оновлено"
},
"warp": {
"changeIp": "Змінити IP",
"changeIpSuccess": "IP-адресу WARP успішно змінено!",
"autoUpdateIp": "Автоматичне оновлення IP-адреси",
"intervalDays": "Інтервал (дні)",
"intervalDesc": "0 — вимкнути. Автоматично змінює IP-адресу.",
"licenseError": "Не вдалося встановити ліцензію WARP.",
"fetchFirst": "Спочатку отримайте WARP-конфіг.",
"createAccount": "Створити акаунт WARP",
+5
View File
@@ -1455,6 +1455,11 @@
"outboundUpdated": "Đã cập nhật outbound NordVPN"
},
"warp": {
"changeIp": "Đổi IP",
"changeIpSuccess": "Đã đổi IP WARP thành công!",
"autoUpdateIp": "Tự động cập nhật địa chỉ IP",
"intervalDays": "Khoảng thời gian (ngày)",
"intervalDesc": "0 để tắt. Tự động đổi địa chỉ IP.",
"licenseError": "Không thiết lập được giấy phép WARP.",
"fetchFirst": "Hãy lấy cấu hình WARP trước.",
"createAccount": "Tạo tài khoản WARP",
+5
View File
@@ -1455,6 +1455,11 @@
"outboundUpdated": "NordVPN 出站已更新"
},
"warp": {
"changeIp": "更换 IP",
"changeIpSuccess": "WARP IP 更换成功!",
"autoUpdateIp": "自动更新 IP 地址",
"intervalDays": "间隔(天)",
"intervalDesc": "设为 0 禁用。自动更换 IP 地址。",
"licenseError": "设置 WARP 许可证失败。",
"fetchFirst": "请先获取 WARP 配置。",
"createAccount": "创建 WARP 账户",
+5
View File
@@ -1455,6 +1455,11 @@
"outboundUpdated": "NordVPN 出站已更新"
},
"warp": {
"changeIp": "更換 IP",
"changeIpSuccess": "WARP IP 更換成功!",
"autoUpdateIp": "自動更新 IP 位址",
"intervalDays": "間隔(天)",
"intervalDesc": "設為 0 停用。自動更換 IP 位址。",
"licenseError": "設定 WARP 授權失敗。",
"fetchFirst": "請先取得 WARP 設定。",
"createAccount": "建立 WARP 帳號",