mirror of
https://github.com/Vateron-Media/XC_VM.git
synced 2026-09-25 04:01:55 +02:00
Prepare release
This commit is contained in:
+22
-52
@@ -1,56 +1,26 @@
|
||||
{
|
||||
"version": "2.5.2",
|
||||
"version": "2.5.3",
|
||||
"changes": [
|
||||
"Added the new Player v2 web application with SPA frontend assets, styles, scripts and vendored libraries.",
|
||||
"Added Player v2 access-code authentication, scope wiring, stream and subtitle token generation, and Active Code login.",
|
||||
"Hardened Player v2 against IDOR and XSS vulnerabilities and added proper escaping for catalog poster URLs and category emoji.",
|
||||
"Restored player resize authorization and changed channel ACL handling to fail closed when authorization cannot be validated.",
|
||||
"Expanded the Smart Activation Codes system with the complete code lifecycle and integration into admin, reseller, line and MAG workflows.",
|
||||
"Added Category Templates with admin/reseller management and custom_data application.",
|
||||
"Integrated category-template custom_data into Active Codes and restricted applyToAll operations according to template visibility.",
|
||||
"Improved Active Code tables, localization, voucher-detail rendering, package/bouquet handling and reseller portal integration.",
|
||||
"Fixed device-locked activation codes so they can only be used by their assigned device and only one concurrent request can activate a code.",
|
||||
"Fixed Active Code information disclosure that could reveal the MAC address bound to a locked code.",
|
||||
"Added a unique per-install OPENSSL_EXTRA secret for installation-specific cryptographic operations.",
|
||||
"Added tamper-proof stream tokens using AES-256-GCM with per-panel configuration.",
|
||||
"Hardened authentication with constant-time shared-secret and HMAC comparisons, fresh admin/reseller sessions and improved session cookies.",
|
||||
"Restored login flood protection and improved access-control handling.",
|
||||
"Hardened image resizing against SSRF and DNS rebinding, including vetted IP handling and TLS verification for outbound requests.",
|
||||
"Removed credentialed reflected-Origin CORS behavior from the Player API.",
|
||||
"Fixed reseller API authentication caused by operator-precedence issues.",
|
||||
"Replaced the monolithic XC_Bootstrap flow with an injectable BootKernel pipeline.",
|
||||
"Added PSR-4 ConstantsInitializer and ErrorResponder components and consolidated legacy bootstrap prelude shims.",
|
||||
"Routed Web API database initialization through shared bootstrap stages and removed redundant streaming-path includes.",
|
||||
"Added bootstrap tests covering stage skip paths, side effects and initialization behavior.",
|
||||
"Centralized STATUS_* initialization and improved bootstrap documentation.",
|
||||
"Moved frequently edited release constants to top-of-file define() declarations.",
|
||||
"Added a dedicated Rector refactoring infrastructure with configuration, documentation and Make targets.",
|
||||
"Applied reviewed Rector transformations across core, streaming, Public Controllers and Ministra code.",
|
||||
"Performed multiple refactoring and convergence passes to simplify control flow, remove dead code and improve maintainability.",
|
||||
"Decomposed RadioService processing and mass-edit logic into smaller tested helpers.",
|
||||
"Converted inline XcVm fully-qualified references to PSR-4 imports.",
|
||||
"Reworked database access to use DatabaseAware::db() instead of threading the global database object through call chains.",
|
||||
"Expanded strict typing and corrected nullable parameter and PID handling across multiple components.",
|
||||
"Restored security guards and include paths affected by unsafe automated refactoring.",
|
||||
"Adopted K&R and tab formatting and expanded parameter type-hint requirements across the codebase.",
|
||||
"Resolved PHPCS and PHPStan issues introduced during the refactoring process and updated the PHPStan dependency.",
|
||||
"Added a dual-backend SQLite and MariaDB test database and improved test-environment guards.",
|
||||
"Expanded core test coverage for database, cache, authorization, brute-force protection, settings, HTTP requests, update channels and module registries.",
|
||||
"Added tests for ChannelService mass-edit and ordering behavior.",
|
||||
"Moved phpunit.phar into tests/ and updated test references.",
|
||||
"Added per-panel Responsive Tables configuration and profile appearance/customizer options.",
|
||||
"Added bouquet sort controls for moving entries up, down, to the top or to the bottom.",
|
||||
"Restored Users navigation tabs and fixed multiple new UI navigation and form submission issues.",
|
||||
"Fixed stream creation without an icon, deletion of unpaired MAG/Enigma2 devices and missing Streams page Resources data.",
|
||||
"Fixed CPU resource reporting so stream resource information is populated correctly and retained.",
|
||||
"Added MediaAnalyzedEvent dispatch after successful VOD analysis.",
|
||||
"Fixed VOD Range workers being terminated during concurrent requests.",
|
||||
"Exposed bouquet ID, name and order in bouquet listing output.",
|
||||
"Added FileCache safeguards and static deletion helpers.",
|
||||
"Pinned database connections to utf8mb4 and restored nullable database-host support for CLI boot.",
|
||||
"Fixed transactional database operations so Errors trigger rollback as well as Exceptions.",
|
||||
"Fixed simultaneous on-demand viewer requests so a stopped stream is started only once.",
|
||||
"Fixed live connection filtering and additional authentication, process-management and null-safety edge cases.",
|
||||
"Updated bootstrap and contributor documentation and removed obsolete references to the old prelude architecture."
|
||||
"Expanded the reseller dashboard with media panels for recently added streams, movies and episodes, live connections, expiring lines and a geographic connection map.",
|
||||
"Added richer dashboard cards with contextual Tabler icons, live media counters, category badges, artwork fallbacks and active viewer indicators.",
|
||||
"Added reseller trial deep-links and a voucher balance dashboard card, while reorganizing the reseller sidebar into clearer sections.",
|
||||
"Introduced a complete licensing and activation UI with license status, self-service key entry, activation banners and documentation covering the activation model and transmitted data.",
|
||||
"Added licensing gates for load-balancer installation and fanout integration, plus per-build RELEASE_ID/XC_VM_BUILD_ID watermarking and attribution integrity protection.",
|
||||
"Implemented Encrypt Playlists support across Live and VOD streams.",
|
||||
"Hardened player API authentication, activation-code login, token handling, CORS, image-resize SSRF protections, DNS rebinding defenses and TLS trusted-server handling.",
|
||||
"Expanded Category Templates to Lines, MAG, Enigma2 devices and reseller vouchers, including inherited template visibility and voucher custom_data integration.",
|
||||
"Added fanout operational controls including live debug-category selection, daemon memory reporting, bulk node draining and improved Redis/fanout reliability.",
|
||||
"Improved player API stability and correctness for active connection counts, missing icons, null bouquets, VOD paging, ratings, short EPG limits and content scoping.",
|
||||
"Overhauled the ticket lifecycle and admin interactions, while simplifying many mass-delete, picker and DataTable workflows.",
|
||||
"Added RTL interface support with Arabic translation and made text direction strictly follow the active language.",
|
||||
"Consolidated the admin bootstrap, removed legacy session.php/functions.php dependencies, modernized module administration and continued migration away from procedural compatibility layers.",
|
||||
"Removed the final goto statements and continued the Rector modernization program with expanded rules, cache fixes and convergence cleanup.",
|
||||
"Expanded automated tests across admin, player API, playback, calendars, database backends, authorization, caching, settings, HTTP and module registries.",
|
||||
"Added dual-backend SQLite/MariaDB coverage and improved bootstrap and test harness behavior.",
|
||||
"Improved module lifecycle handling so disabled modules stay disabled after reinstall and lifecycle failures are contained safely.",
|
||||
"Enhanced sync-dev.sh for Docker deployment and fixed ownership handling for generated parent directories.",
|
||||
"Improved CLI build/version resolution, Composer dependencies, PHPCS configuration and general code-quality tooling.",
|
||||
"Fixed numerous stability issues involving Redis, fanout configuration, nullable data, controller crashes, streaming resources, admin forms and player API edge cases.",
|
||||
"Updated authentication, licensing and UI translation documentation."
|
||||
]
|
||||
}
|
||||
|
||||
@@ -14,6 +14,8 @@ info:
|
||||
```
|
||||
{protocol}://{host}:{port}/player_api?username={username}&password={password}&action={action}
|
||||
```
|
||||
The legacy XtreamCodes `/player_api.php?…` spelling and the path-style
|
||||
`/player_api/{username}/{password}[/{action}]` form hit the same handler.
|
||||
|
||||
## Media access (direct links)
|
||||
After authorization, media is served from:
|
||||
|
||||
@@ -20,11 +20,8 @@ git log --pretty=format:"- %s (%h)" "$PREV_TAG"..main > dist/changes.md
|
||||
|
||||
```json
|
||||
{
|
||||
"version": "X.Y.Z",
|
||||
"changes": [
|
||||
"Description of change 1",
|
||||
"Description of change 2"
|
||||
]
|
||||
"version": "X.Y.Z",
|
||||
"changes": ["Description of change 1", "Description of change 2"]
|
||||
}
|
||||
```
|
||||
|
||||
@@ -41,7 +38,10 @@ Before publishing, verify the build works:
|
||||
**Quality checks** (CI runs the same set on the tag — confirm it is green):
|
||||
|
||||
```bash
|
||||
make dev-tools && make phpstan && make cs && make gates
|
||||
make dev-tools
|
||||
make phpstan
|
||||
make cs
|
||||
make gates
|
||||
php tests/phpunit.phar -c tests/phpunit.xml.dist
|
||||
make dev-clean # remove the dev tools afterwards, restoring the prod-only vendor/
|
||||
```
|
||||
@@ -134,7 +134,6 @@ Edit the version constant, disable the phpMiniAdmin access flag, and clear its p
|
||||
> anyone who reaches the panel. This step is a security hardening gate — a release must never
|
||||
> go out with it on.
|
||||
|
||||
|
||||
```text
|
||||
src/Core/Config/ConstantsInitializer.php
|
||||
```
|
||||
@@ -178,12 +177,12 @@ make main
|
||||
|
||||
After building, `dist/` should contain:
|
||||
|
||||
| File | Description |
|
||||
| --- | --- |
|
||||
| `XC_VM.zip` | MAIN installer (install script + xc_vm.tar.gz) |
|
||||
| `xc_vm.tar.gz` | MAIN archive (install & update) |
|
||||
| `loadbalancer.tar.gz` | LB archive (install & update) |
|
||||
| `hashes.md5` | MD5 checksums |
|
||||
| File | Description |
|
||||
| --------------------- | ---------------------------------------------- |
|
||||
| `XC_VM.zip` | MAIN installer (install script + xc_vm.tar.gz) |
|
||||
| `xc_vm.tar.gz` | MAIN archive (install & update) |
|
||||
| `loadbalancer.tar.gz` | LB archive (install & update) |
|
||||
| `hashes.md5` | MD5 checksums |
|
||||
|
||||
> The same archive is used for both clean installation and updates.
|
||||
> The update script (`src/update`) filters out binary/config directories at runtime using the hardcoded `UPDATE_EXCLUDE_DIRS` list inside the Python script itself.
|
||||
@@ -233,7 +232,6 @@ After publishing, the workflow will automatically:
|
||||
> on the **same version** — LBs read MAIN's database and a schema/behaviour skew can break
|
||||
> streaming. Don't leave LBs a release behind.
|
||||
|
||||
|
||||
- [ ] Verify all 4 assets are attached to the release
|
||||
- [ ] Run `md5sum -c hashes.md5` on downloaded files
|
||||
- [ ] Check Telegram notification was sent
|
||||
@@ -251,7 +249,7 @@ After publishing, the workflow will automatically:
|
||||
a published one; clients pin to a tag.
|
||||
- **A bad release already reached servers** — operators can downgrade per-server from the panel
|
||||
(**Servers → Rollback Version**, see [Update Mechanism → Rollback](../administration/update-system.md#rollback-downgrade)); on MAIN a DB backup is taken automatically first. Migrations are
|
||||
forward-only, so prefer a roll-*forward* hotfix when the fix is small.
|
||||
forward-only, so prefer a roll-_forward_ hotfix when the fix is small.
|
||||
|
||||
---
|
||||
|
||||
@@ -261,32 +259,32 @@ Every `make` target used during release prep, in one place.
|
||||
|
||||
**Quality checks** — run `make dev-tools` first, `make dev-clean` when done:
|
||||
|
||||
| Command | Purpose |
|
||||
| --- | --- |
|
||||
| `make dev-tools` | Install dev tooling (PHPStan, phpcs) via `composer install` |
|
||||
| `make phpstan` | Static analysis (also catches syntax errors) |
|
||||
| `make phpstan-baseline` | Regenerate the PHPStan baseline |
|
||||
| `make cs` | Code-style check — import/namespace hygiene (phpcs + Slevomat) |
|
||||
| `make cs-fix` | Apply code-style fixes in place |
|
||||
| `make gates` | PSR-4 regression gates (procedural-use, LB-archive, vendor-prod-only) |
|
||||
| `make dev-clean` | Remove the dev tools again, restoring the production-only `vendor/` |
|
||||
| `php tests/phpunit.phar -c tests/phpunit.xml.dist` | Unit tests |
|
||||
| Command | Purpose |
|
||||
| -------------------------------------------------- | --------------------------------------------------------------------- |
|
||||
| `make dev-tools` | Install dev tooling (PHPStan, phpcs) via `composer install` |
|
||||
| `make phpstan` | Static analysis (also catches syntax errors) |
|
||||
| `make phpstan-baseline` | Regenerate the PHPStan baseline |
|
||||
| `make cs` | Code-style check — import/namespace hygiene (phpcs + Slevomat) |
|
||||
| `make cs-fix` | Apply code-style fixes in place |
|
||||
| `make gates` | PSR-4 regression gates (procedural-use, LB-archive, vendor-prod-only) |
|
||||
| `make dev-clean` | Remove the dev tools again, restoring the production-only `vendor/` |
|
||||
| `php tests/phpunit.phar -c tests/phpunit.xml.dist` | Unit tests |
|
||||
|
||||
**Release prep & build:**
|
||||
|
||||
| Command | Purpose |
|
||||
| --- | --- |
|
||||
| `make generate_deleted_files` | Regenerate `src/migrations/deleted_files.txt` |
|
||||
| `make new` | Wipe + recreate `dist/` — run ONCE at the start (step 1), before writing `dist/changes.md`; never again before building |
|
||||
| `make lb` | Build the LoadBalancer archive into `dist/` |
|
||||
| `make main` | Build the MAIN archive into `dist/` |
|
||||
| `bash tools/test-install/test_release.sh` | Docker install test of the built release |
|
||||
| Command | Purpose |
|
||||
| ----------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
|
||||
| `make generate_deleted_files` | Regenerate `src/migrations/deleted_files.txt` |
|
||||
| `make new` | Wipe + recreate `dist/` — run ONCE at the start (step 1), before writing `dist/changes.md`; never again before building |
|
||||
| `make lb` | Build the LoadBalancer archive into `dist/` |
|
||||
| `make main` | Build the MAIN archive into `dist/` |
|
||||
| `bash tools/test-install/test_release.sh` | Docker install test of the built release |
|
||||
|
||||
**Documentation** (English source in `docs/en`; `docs/ru` is generated + committed):
|
||||
|
||||
| Command | Purpose |
|
||||
| --- | --- |
|
||||
| `make docs-venv` | One-time: local venv (build + translation deps) |
|
||||
| Command | Purpose |
|
||||
| --------------------- | ------------------------------------------------------ |
|
||||
| `make docs-venv` | One-time: local venv (build + translation deps) |
|
||||
| `make docs-translate` | Regenerate `docs/ru` from `docs/en` (before a release) |
|
||||
| `make docs-build` | Strict MkDocs build into `./build/site` (what CI runs) |
|
||||
| `make docs-serve` | Live docs preview at `http://127.0.0.1:8000` |
|
||||
| `make docs-build` | Strict MkDocs build into `./build/site` (what CI runs) |
|
||||
| `make docs-serve` | Live docs preview at `http://127.0.0.1:8000` |
|
||||
|
||||
@@ -64,12 +64,12 @@ $_SESSION['verify'] = md5($rUserInfo['username'] . '||' . $rCrypt); // Verificat
|
||||
|
||||
### `Authenticator::resellerLogin(array $data): array`
|
||||
|
||||
Способ входа в систему реселлера. Структура, идентичная `login()`, с этими различиями:
|
||||
Метод входа в систему торгового посредника. Структура идентична `login()` с этими отличиями:
|
||||
|
||||
- Повторная проверка всегда проверяется, когда она включена (параметр обхода отсутствует).
|
||||
- Для проверки разрешений требуется `is_reseller` вместо `is_admin`.
|
||||
- Возвращает `STATUS_NOT_RESELLER`, если у пользователя нет разрешения торгового посредника.
|
||||
- Логи входа в систему записываются с типом `RESELLER` вместо `ADMIN`.
|
||||
- Журналы входа в систему записываются с типом `RESELLER` вместо `ADMIN`.
|
||||
|
||||
Значения сеанса, записанные в зависимости от успеха:
|
||||
|
||||
@@ -91,7 +91,7 @@ $_SESSION['rverify'] = md5($rUserInfo['username'] . '||' . $rCrypt); // Verific
|
||||
| `STATUS_DISABLED` |5|Учетная запись отключена|
|
||||
| `STATUS_NOT_ADMIN` |6|У пользователя нет прав администратора|
|
||||
| `STATUS_INVALID_CAPTCHA` |12|Не удалось выполнить проверку reCAPTCHA|
|
||||
| `STATUS_INVALID_CODE` |13|Несоответствие кода доступа и группы|
|
||||
| `STATUS_INVALID_CODE` |13|Несоответствие кода доступа/ группы|
|
||||
| `STATUS_NOT_RESELLER` |35|У пользователя нет разрешения торгового посредника|
|
||||
|
||||
### Хэширование паролей
|
||||
@@ -100,13 +100,13 @@ $_SESSION['rverify'] = md5($rUserInfo['username'] . '||' . $rCrypt); // Verific
|
||||
Authenticator::hashPassword(string $password, ?string $salt = null, int $rounds = 20000): string
|
||||
```
|
||||
|
||||
Использует `crypt()` с SHA-512 (`$6$`). Используется формат `$6$rounds=20000$<salt>$`, где `<salt>` - это 16 шестнадцатеричных символов, полученных из `openssl_random_pseudo_bytes(16)`. Пароли повторно хэшируются при каждом успешном входе в систему, что приводит к перераспределению ресурсов.
|
||||
Использует `crypt()` с SHA-512 (`$6$`). Формат salt равен `$6$rounds=20000$<salt>$`, где `<salt>` - это 16 шестнадцатеричных символов, полученных из `openssl_random_pseudo_bytes(16)`. Пароли повторно хэшируются при каждом успешном входе в систему, что приводит к замене значения salt.
|
||||
|
||||
```php
|
||||
Authenticator::checkPassword(string $password, string $storedHash): bool
|
||||
```
|
||||
|
||||
Проверяет открытый текстовый пароль на соответствие сохраненному хэшу, используя `crypt($password, $storedHash)`, с безопасным по времени сравнением с помощью `hash_equals()`. Сохраненный хэш содержит алгоритм, раунды и соль, поэтому `crypt()` воспроизводит правильный хэш для сравнения.
|
||||
Проверяет пароль в виде открытого текста на соответствие сохраненному хэшу, используя `crypt($password, $storedHash)`, с возможностью сравнения по времени с помощью `hash_equals()`. Сохраненный хэш содержит алгоритм, раунды и соль, поэтому `crypt()` воспроизводит правильный хэш для сравнения.
|
||||
|
||||
---
|
||||
|
||||
@@ -127,7 +127,7 @@ Authenticator::checkPassword(string $password, string $storedHash): bool
|
||||
5. **Проверка, включенная пользователем** -- `enabled == 0` возвращает `CLIENT_DISABLED`.
|
||||
6. **Список разрешенных IP-адресов** -- Если для пользователя задано значение `allowed_ips`, IP-адрес клиента должен совпадать (решается с помощью `gethostbyname`).
|
||||
7. **Ограничение по стране** - Два режима:
|
||||
- Для каждого пользователя: если задано значение `forced_country`, а не `ALL`, страна GeoIP должна совпадать.
|
||||
- Для каждого пользователя: если задано значение `forced_country`, а не `ALL`, то страна GeoIP должна совпадать.
|
||||
- Глобальный: если нет переопределения для каждого пользователя, устанавливается глобальный параметр `allow_countries` (если только он не содержит `ALL`).
|
||||
8. **Проверка агента пользователя** -- Если для пользователя задано значение `allowed_ua`, то пользовательский агент HTTP должен соответствовать.
|
||||
9. флаг **Проверка интернет-провайдера** -- `isp_violate` отклоняет соединение.
|
||||
@@ -165,20 +165,18 @@ $_SESSION['pverify'] = md5($rUserInfo['username'] . '||' . $rUserInfo['password'
|
||||
|
||||
### Проверка сеанса администратора
|
||||
|
||||
Файл: `src/Public/Views/admin/functions.php`
|
||||
Точка входа: `AdminScopeBootstrap::hydrateAdminContext()` (`src/Infrastructure/Bootstrap/AdminScopeBootstrap.php`). Он запускается по пути администратора фронт-контроллера (через `boot()`) и вызывается непосредственно сценариями просмотра `$noBootstrapPages` (`login`, `setup`, `database`, `logout`, `player`, `post`) — заменяя прежний `admin/functions.php` include.
|
||||
|
||||
Если установлено значение `$_SESSION['hash']`, при каждой загрузке страницы выполняются следующие проверки:
|
||||
Когда установлено значение `$_SESSION['hash']`, он определяет пользователя (`UserRepository::getRegisteredUserById($_SESSION['hash'])`) и права доступа (`AuthRepository::getPermissions()`), а затем проверяет целостность сеанса с помощью `SessionManager::adminSessionValid($rUserInfo, $rPermissions, $rSettings)`:
|
||||
|
||||
1. **Поиск пользователя** -- `UserRepository::getRegisteredUserById($_SESSION['hash'])`. Если пользователь больше не существует, сеанс завершается.
|
||||
2. **Проверка прав доступа** -- `AuthRepository::getPermissions()` должен возвращать допустимый набор с `is_admin == true`.
|
||||
3. **Проверка IP-адреса** - Сравнивает текущий IP-адрес с `$_SESSION['ip']`:
|
||||
1. **Пользователь и администратор** - существует строка пользователя и разрешения, и задано значение `is_admin`.
|
||||
2. **Проверка IP-адреса** - Сравнивает текущий IP-адрес с `$_SESSION['ip']`:
|
||||
- Если параметр `ip_subnet_match` включен: сравниваются только первые три октета (например, `192.168.1.*` соответствует `192.168.1.*`).
|
||||
- Если параметр `ip_subnet_match` отключен: требуется точное совпадение IP-адресов.
|
||||
- Если IP-адрес не совпадает и включена настройка `ip_logout`, сеанс завершается.
|
||||
- Если IP-адрес не совпадает и `ip_logout` отключен, `$_SESSION['ip']` автоматически обновляется до нового IP-адреса.
|
||||
4. **Проверить проверку хэша Verify** -- `$_SESSION['verify']` должно быть равно `md5($rUserInfo['username'] . '||' . $rUserInfo['password'])`. Это гарантирует, что сеанс будет аннулирован в случае изменения пароля.
|
||||
- IP-адрес применяется только тогда, когда включено значение `ip_logout`; в противном случае допускается изменение IP-адреса (и в пути HTML значение `$_SESSION['ip']` обновляется до нового значения).
|
||||
3. **Проверить проверку хэша Verify** -- `$_SESSION['verify']` должно быть равно `md5($rUserInfo['username'] . '||' . $rUserInfo['password'])`. Это гарантирует, что сеанс будет аннулирован в случае изменения пароля.
|
||||
|
||||
Если какая-либо проверка завершается неудачей, сеанс очищается с помощью `SessionManager::clearContext('admin')`, и пользователь перенаправляется на индексную страницу.
|
||||
Если проверка завершается неудачно, сеанс очищается с помощью `SessionManager::clearContext('admin')`, и пользователь перенаправляется на индексную страницу. Конечная точка admin JSON DataTables (`Public\Controllers\Admin\TableController`) выполняет ту же проверку `SessionManager::adminSessionValid()` в своей ветви сеанса, но вместо перенаправления выдает JSON.
|
||||
|
||||
### Проверка сеанса работы с реселлером
|
||||
|
||||
@@ -193,11 +191,9 @@ $_SESSION['pverify'] = md5($rUserInfo['username'] . '||' . $rUserInfo['password'
|
||||
|
||||
Соответствие IP-подсети и поведение при выходе из системы по IP-адресу такое же, как у администратора.
|
||||
|
||||
### Тайм-аут сеанса администрирования
|
||||
### Жизненный цикл сеанса администратора
|
||||
|
||||
Файл: `src/Public/Views/admin/session.php`
|
||||
|
||||
Для сеансов администрирования выполняется отдельная проверка времени ожидания сеанса. Если заданы значения `$_SESSION['hash']` и `$_SESSION['last_activity']`, а с момента `last_activity` прошло более 60 минут, то сеансовые ключи (`hash`, `ip`, `code`, `verify`, `last_activity`) не заданы. При каждом действительном запросе обновляется `$_SESSION['last_activity']`, и сессия закрывается для записи.
|
||||
Запуск сеанса и 60-минутный тайм-аут бездействия выполняются в `AdminScopeBootstrap::bootSession()` (путь к интерфейсу контроллера), а для устаревших сценариев просмотра — в `SessionManager::start('admin')` + `requireAuth()`, которые заменили прежний параметр `admin/session.php`. Если заданы значения `$_SESSION['hash']` и `$_SESSION['last_activity']`, а с момента `last_activity` прошло более 60 минут, ключи сеанса (`hash`, `ip`, `code`, `verify`, `last_activity`) не заданы. При каждом действительном запросе обновляется `$_SESSION['last_activity']`, и сеанс закрывается для записи. Конечная точка опроса AJAX-сессии (`{"result": true/false}`) обслуживается `Public\Controllers\Admin\SessionController` (маршрут `session`).
|
||||
|
||||
### Проверка сеанса игрока
|
||||
|
||||
@@ -209,7 +205,7 @@ $_SESSION['pverify'] = md5($rUserInfo['username'] . '||' . $rUserInfo['password'
|
||||
|
||||
Файл: `src/Core/Auth/SessionManager.php`
|
||||
|
||||
Унифицированный сеансовый API, который абстрагирует различные имена сеансовых ключей в разных контекстах. Предназначен для замены устаревших файлов `admin/session.php` и `reseller/session.php`.
|
||||
Унифицированный сеансовый API, который абстрагирует различные имена сеансовых ключей в разных контекстах. Он заменяет устаревший admin `session.php` / `functions.php` includes (теперь удален); области реселлеров и игроков загружаются с помощью своих собственных классов `*ScopeBootstrap`.
|
||||
|
||||
### Контекстная ключевая карта
|
||||
|
||||
@@ -231,7 +227,7 @@ $_SESSION['pverify'] = md5($rUserInfo['username'] . '||' . $rUserInfo['password'
|
||||
|
||||
**`requireAuth(?string $loginUrl = null): void`**
|
||||
|
||||
Проверяет наличие аутентифицированного сеанса. Если запрос направлен напрямую на `session.php`, возвращает ответ в формате JSON `{"result": true/false}` (используется для опроса сеанса AJAX). В противном случае перенаправляет не прошедших проверку пользователей на страницу входа в систему. В случае успеха вызывает `touch()` для обновления временной метки действия.
|
||||
Перенаправляет пользователей, не прошедших проверку подлинности, на страницу входа в систему; в случае успеха вызывает `touch()` для обновления временной метки активности. Опрос выделенного сеанса AJAX теперь выполняется с помощью `SessionController` (маршрут `session`), а не с помощью этого метода.
|
||||
|
||||
**`isAuthenticated(): bool`**
|
||||
|
||||
@@ -267,7 +263,7 @@ $_SESSION['pverify'] = md5($rUserInfo['username'] . '||' . $rUserInfo['password'
|
||||
|
||||
**`getContext(): ?string`**
|
||||
|
||||
Возвращает текущую контекстную строку (`'admin'`, `'reseller'`, `'player'`) или `null`, если она не задана.
|
||||
Возвращает текущую строку контекста (`'admin'`, `'reseller'`, `'player'`) или `null`, если она не задана.
|
||||
|
||||
### Поведение по истечении времени ожидания
|
||||
|
||||
@@ -312,7 +308,7 @@ $_SESSION['pverify'] = md5($rUserInfo['username'] . '||' . $rUserInfo['password'
|
||||
|
||||
### `truncateAttempts(array $attempts, int $frequency, bool $list = false): array`
|
||||
|
||||
Отфильтровывает просроченные попытки из массива отслеживания. Если значение `$list` равно `true`, массив обрабатывается как индексированный (для `checkAuthFlood`); в противном случае как ассоциативный, с ключом по термину (для `checkBruteforce`).
|
||||
Отфильтровывает просроченные попытки из массива отслеживания. Если значение `$list` равно `true`, массив обрабатывается как индексированный (для `checkAuthFlood`); в противном случае как ассоциативный с ключом по термину (для `checkBruteforce`).
|
||||
|
||||
### Блокирующий механизм
|
||||
|
||||
@@ -410,9 +406,9 @@ VALUES($type, $codeId, $userId, $status, $ip, $timestamp);
|
||||
|
||||
Файл: `src/Core/Auth/PageAuthorization.php`
|
||||
|
||||
Управление доступом на уровне страницы. Определяет, разрешают ли групповые разрешения текущего пользователя доступ к определенной странице панели администратора или торгового посредника.
|
||||
Управление доступом на уровне страницы. Определяет, разрешают ли групповые права текущего пользователя доступ к определенной странице панели администратора или торгового посредника.
|
||||
|
||||
- `PageAuthorization::checkResellerPermissions($page)` - сопоставляет названия страниц с флагами требуемых разрешений и возвращает, разрешен ли доступ.
|
||||
- `PageAuthorization::checkResellerPermissions($page)` -- сопоставляет названия страниц с флагами требуемых разрешений и возвращает, разрешен ли доступ.
|
||||
|
||||
---
|
||||
|
||||
@@ -426,8 +422,8 @@ VALUES($type, $codeId, $userId, $status, $ip, $timestamp);
|
||||
| `src/Core/Auth/Authorization.php` |Проверки авторизации на уровне объекта|
|
||||
| `src/Core/Auth/PageAuthorization.php` |Управление доступом на уровне страницы|
|
||||
| `src/Public/Controllers/Player/PlayerLoginController.php` |Процесс входа игрока в систему с проверкой безопасности|
|
||||
| `src/Public/Views/admin/functions.php` |Проверка сеанса администратора при каждой загрузке страницы|
|
||||
| `src/Public/Views/admin/session.php` |Тайм-аут сеанса администратора и проверка сеанса AJAX|
|
||||
| `src/Infrastructure/Bootstrap/AdminScopeBootstrap.php` |Загрузка администратора: жизненный цикл сеанса, `$rUserInfo`/`$rPermissions`, защита целостности|
|
||||
| `src/Public/Controllers/Admin/SessionController.php` |Опрос сессии администратора AJAX (маршрут `session`)|
|
||||
| `src/Infrastructure/Bootstrap/reseller_functions.php` |Проверка сеанса реселлера при каждой загрузке страницы|
|
||||
| `src/Domain/User/UserRepository.php` |Поиск учетных данных (`getAuthUserByCredentials`)|
|
||||
| `src/bootstrap.php` |Определения констант состояния, контексты начальной загрузки|
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
# Лицензирование и активация
|
||||
|
||||
XC_VM находится под **бесплатный и с открытым исходным кодом** общей публичной лицензией **GNU Affero
|
||||
версия 3.0 (AGPL-3.0)**. На этой странице полностью раскрывается порядок лицензирования панели,
|
||||
проверка авторства и активация работают — включая именно то, что отправляет панель
|
||||
на сервер лицензирования и когда. Здесь нет ничего скрытого.
|
||||
|
||||
## Модель двойного лицензирования
|
||||
|
||||
|Вы сохраняете уведомление об авторстве|Вы удаляете атрибуцию (белую метку)|
|
||||
| ------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
|**AGPL-3.0 — бесплатно.** Все работает, включая узлы балансировки нагрузки. Нет активации, нет контакта с сервером.|**Требуется активация.** Для запуска подсистемы балансировки нагрузки / узлов кластера необходим бесплатный ключ активации, привязанный к компьютеру. Панель по-прежнему работает локально на одном сервере без ключа.|
|
||||
|
||||
Сохраняя _"Vateron Media · AGPL-3.0"_ кредит (явно как AGPL-3.0 **§7(b)**
|
||||
требуются разрешения) - это все, что требуется для развертывания в сообществе. Путь активации
|
||||
существует только для операторов, которые удаляют эту атрибуцию — это точка, в которой
|
||||
Vateron Media, как единственный правообладатель, предлагает отдельное соглашение, а не
|
||||
чем AGPL.
|
||||
|
||||
!!! примечание "Ключи для активации предоставляются бесплатно"
|
||||
Ключи выдаются **свободный** в режиме самообслуживания, по одному на каждый компьютер (HWID). Они не являются
|
||||
продано. Их целью является подотчетность — доступная для отзыва информация о том, кто управляет
|
||||
ребрендированная копия — не монетизация.
|
||||
|
||||
## Атрибуция -проверка целостности (AGPL §7b)
|
||||
|
||||
По каждому запросу комиссия проверяет, что уведомление о его присвоении все еще присутствует в
|
||||
нижний колонтитул. Если он был удален, то **пользовательский интерфейс управления** (администратор /реселлер / игрок)
|
||||
показывает уведомление `ATTRIBUTION_REMOVED` до тех пор, пока оно не будет восстановлено. Проверка завершена.
|
||||
**обратимый и неразрушающий**: данные не изменяются, интерфейс командной строки продолжает работать, и
|
||||
восстановление уведомления разблокирует панель при следующем запросе. **Потоковая передача для конечного пользователя
|
||||
эта проверка не влияет на**.
|
||||
|
||||
## Какие ворота активации
|
||||
|
||||
Для установки **белая этикетка** (атрибуция удалена) без действительного ключа:
|
||||
|
||||
- **Не удается подготовить узлы балансировщика нагрузки / кластера** — скомпилированное ядро
|
||||
отказывается предоставить удаленному узлу доступ к базе данных панели.
|
||||
- **Оперативная доставка большой емкости (демон разветвления) отключена**, таким образом, доставка
|
||||
возвращается к устаревшему способу. Панель с одним сервером остается доступной.
|
||||
|
||||
Установка **сообщество** (атрибуция не изменена) никогда не закрывается и никогда не связывается с
|
||||
сервер лицензирования.
|
||||
|
||||
## Как активировать
|
||||
|
||||
1. Найдите свой **ВИД**, указанный в **Настройки → Информация** и на баннере панели мониторинга.
|
||||
(`XC_VM::install_id()`).
|
||||
2. Отправьте его на странице активации и получите ключ, привязанный к этому HWID.
|
||||
3. Введите ключ в панели управления (баннер активации панели управления). Панель подтвердит его
|
||||
**не в сети** по открытому ключу, скомпилированному в расширении — обратный переход невозможен.
|
||||
требуется для того, чтобы начать им пользоваться.
|
||||
|
||||
## Данные, которые отправляет панель, — полное раскрытие
|
||||
|
||||
A **установка сообществом (авторство не изменено) ничего не отправляет** — он никогда не связывается с
|
||||
сервер лицензирования.
|
||||
|
||||
A **установка белой этикетки** устанавливает связь с сервером лицензирования
|
||||
(`https://www.xcvm.tech`)
|
||||
|
||||
**То, что никогда не отправлялось:** нет потоковых данных, нет данных о зрителе/подписчике, нет учетной записи
|
||||
учетные данные, нет содержимого базы данных, нет содержимого файла. Удаленная команда отсутствует
|
||||
канал — сервер никогда не приказывает панели что-либо делать; она только
|
||||
считывает подписанный вердикт _valid / revoked_ для своего собственного ключа.
|
||||
|
||||
## Происхождение
|
||||
|
||||
Каждой сборке присваивается уникальный идентификатор (`XC_VM_BUILD_ID`), поэтому утечка или
|
||||
переименованную копию можно проследить до сборки, из которой она была создана.
|
||||
|
||||
---
|
||||
|
||||
> ❗️ Вы несете единоличную ответственность за то, как используется XC_VM. Vateron Media не требует
|
||||
> ответственность за неправильное использование или незаконное развертывание.
|
||||
@@ -240,7 +240,7 @@ http {
|
||||
fastcgi_param XC_API $1;
|
||||
}
|
||||
|
||||
location ~ ^/(player_api|enigma2|xplugin|epg|playlist)\.php$ {
|
||||
location ~ ^/(player_api|enigma2|xplugin|epg|playlist)(?:\.php)?$ {
|
||||
limit_req zone=one burst=8;
|
||||
include limit_queue.conf;
|
||||
fastcgi_index index.php;
|
||||
|
||||
@@ -271,8 +271,8 @@ class XcvmCoreCommand implements CommandInterface {
|
||||
return (is_string($rBody) && $rCode >= 200 && $rCode < 300) ? $rBody : null;
|
||||
}
|
||||
|
||||
/** Download a URL to a file (following redirects). */
|
||||
/**
|
||||
* Download a URL to a file (following redirects).
|
||||
* Fetch $rUrl to $rDest. A transient failure is reported, not retried — the
|
||||
* command is idempotent, so re-running it is the recovery.
|
||||
*/
|
||||
|
||||
@@ -11,7 +11,7 @@ use RuntimeException;
|
||||
defined('DB_ACCESS_ENABLED') || define('DB_ACCESS_ENABLED', false);
|
||||
defined('DB_ACCESS_PWD') || define('DB_ACCESS_PWD', '');
|
||||
defined('DEV_MODE') || define('DEV_MODE', false);
|
||||
defined('XC_VM_VERSION') || define('XC_VM_VERSION', '2.5.2');
|
||||
defined('XC_VM_VERSION') || define('XC_VM_VERSION', '2.5.3');
|
||||
// Per-build watermark stamped into the deploy root by `make main` (see the
|
||||
// Makefile stamp_release_id target). A source/dev checkout is never stamped, so
|
||||
// runtime and the licence activation call report 'dev'. Unique per build, so a
|
||||
|
||||
@@ -107,7 +107,7 @@ http {
|
||||
rewrite ^ /api/playlist last;
|
||||
}
|
||||
|
||||
location = /panel_api.php {
|
||||
location ~ ^/panel_api(?:\.php)?$ {
|
||||
rewrite ^ /api/player_api last;
|
||||
}
|
||||
|
||||
@@ -304,8 +304,10 @@ http {
|
||||
fastcgi_param XC_API $1;
|
||||
}
|
||||
|
||||
# ─── Streaming API → Front Controller (legacy *.php) ──────
|
||||
location ~ ^/(player_api|enigma2|xplugin|epg|playlist|active_code)\.php$ {
|
||||
# ─── Streaming API → Front Controller (.php optional) ───
|
||||
# Clients send both the XtreamCodes legacy /player_api.php?… and
|
||||
# the bare /player_api?… — the suffix is optional so neither 404s.
|
||||
location ~ ^/(player_api|enigma2|xplugin|epg|playlist|active_code)(?:\.php)?$ {
|
||||
limit_req zone=one burst=8;
|
||||
include limit_queue.conf;
|
||||
fastcgi_index index.php;
|
||||
|
||||
@@ -18,8 +18,11 @@ Modules/ministra_85a7d/MinistraModule.php
|
||||
Modules/ministra_85a7d/PortalHandler.php
|
||||
Modules/ministra_85a7d/PortalHelpers.php
|
||||
Modules/ministra_85a7d/module.json
|
||||
Public/Controllers/Reseller/TableController.php
|
||||
Public/Views/admin/api.php
|
||||
Public/Views/admin/functions.php
|
||||
Public/Views/admin/modals.php
|
||||
Public/Views/admin/session.php
|
||||
Public/Views/layouts/reseller/modals.php
|
||||
Public/Views/reseller/topbar.php
|
||||
Public/assets/admin/css/app.css
|
||||
|
||||
Reference in New Issue
Block a user