feat(sub): make external subscription fetch User-Agent configurable (#6613)

* feat(sub): make external subscription fetch User-Agent configurable

Some providers reject fetches that do not send a known client User-Agent.
Expose externalSubUserAgent as a panel setting (default v2rayNG/1.8.5)
and use it when fetching client external subscription URLs.

Fixes #6383

* ci: retrigger frontend after npm registry maintenance

The frontend job failed solely on `npm audit` while registry.npmjs.org
returned 503 (Service Under Maintenance). Lint, typecheck, vitest, vite
build, and storybook all passed. Local `npm audit --omit=dev
--audit-level=high` now reports 0 vulnerabilities.

* fix(sub): fall back to the default UA when the DB is not initialised

externalSubUserAgent read the setting through SettingService.getSetting,
which calls Model() on database.GetDB() and panics on a nil *gorm.DB.
The fetch path's other DB read, service.ExternalSubscriptionHwid, already
treats a nil DB as unreachable and sends no header; the new UA lookup
did not, so any fetch before InitDB panicked instead of sending the
historical v2rayNG/1.8.5.

Production initialises the DB before the sub server starts, but the
internal/sub fetch tests run without one: under make test-go's
-shuffle=on, whenever one of them ran before the first InitDB test the
panic aborted the whole package. Reproduced deterministically with
go test -run '^TestDoFetchSubscriptionLinks_RejectsOversizedBody$'.

---------

Co-authored-by: mrchatam <mrchatam@users.noreply.github.com>
Co-authored-by: MHSanaei <ho3ein.sanaei@gmail.com>
This commit is contained in:
mrchatam
2026-09-27 01:06:33 +03:30
committed by GitHub
parent 9672249edb
commit bd9ccde1f4
26 changed files with 161 additions and 1 deletions
+2
View File
@@ -1395,6 +1395,8 @@
"subDomainDesc": "The domain name for the subscription service. (leave blank to listen on all domains and IPs). Also used as the fallback domain for the displayed subscription link when \"Reverse Proxy URI\" is empty — set \"Reverse Proxy URI\" if the panel and the subscription are reached through different domains (e.g. behind a reverse proxy).",
"subUpdates": "Update Intervals",
"subUpdatesDesc": "The update intervals of the subscription URL in the client apps. (unit: hour)",
"externalSubUserAgent": "External subscription User-Agent",
"externalSubUserAgentDesc": "User-Agent header sent when the panel fetches a client external subscription URL. Leave blank to use the default (v2rayNG/1.8.5). Some providers reject unknown clients.",
"subEncrypt": "Encode",
"subEncryptDesc": "The returned content of subscription service will be Base64 encoded.",
"subURI": "Reverse Proxy URI",