* 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>
RegWarp now stores config.client_id from the Cloudflare registration, and WarpModal sources the reserved bytes from the live config response (falling back to stored creds). Previously reservedFor read an always-missing client_id, producing an empty reserved array.
The license update was always failing because the Cloudflare response has
no `success` field — the check rejected every successful PUT. On real
errors (e.g. "Too many connected devices."), the toast leaked the raw URL
+ JSON body. Now the WARP API's error envelope is parsed into a clean
message and shown inline next to the Update button.
Backend:
- check HTTP status on every Cloudflare API call so error bodies don't
get parsed as success
- replace unchecked type assertions with comma-ok form (no more panics
when Cloudflare returns an error response)
- return real errors when license/id/token fields are missing instead
of swallowing the failure
- guard SetWarpLicense against an empty errors array
- 15s timeout on the shared http.Client
- build all request bodies and persisted state with json.Marshal
- bump API path to v0a4005 and CF-Client-Version to a-6.30-3596 to
match the current Cloudflare WARP client
Frontend (warp_modal.html):
- remove stray </a-form-item> closing tag
- declare config/peer with const and null-check before dereferencing
- guard addOutbound/resetOutbound against missing warpOutbound
- rename getResolved -> getReserved (the array it builds is "reserved")
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>