Prepare release

This commit is contained in:
Divarion_D
2026-09-23 14:22:56 +03:00
parent f4a5fd6513
commit aa207c9a39
10 changed files with 169 additions and 122 deletions
+22 -52
View File
@@ -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."
]
}
+2
View File
@@ -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:
+35 -37
View File
@@ -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` |
+23 -27
View File
@@ -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` |Определения констант состояния, контексты начальной загрузки|
+76
View File
@@ -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 не требует
> ответственность за неправильное использование или незаконное развертывание.
+1 -1
View File
@@ -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;
+1 -1
View File
@@ -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.
*/
+1 -1
View File
@@ -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
+5 -3
View File
@@ -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;
+3
View File
@@ -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