f7cloud_client/docs/CHANGELOG-APPSTORE.md
root 8b6a0139db f7cloud_client
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-17 22:59:26 +00:00

207 lines
14 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Регистрация изменений клиента F7cloud для работы с кастомным App Store
Все изменения внесены для совместимости с кастомным appstore без полагания на формат и поведение только официального store. Каждое изменение задокументировано для учёта и аудита.
---
## 1. `lib/private/App/AppStore/Fetcher/AppFetcher.php`
**Цель:** Исключить падение при отсутствии или неверном формате поля `releases` у приложения (кастомный appstore может отдавать не все поля).
**Изменение:** Перед циклом по `$app['releases']` добавлена проверка: если у элемента массива приложений нет ключа `releases` или значение не является массивом, приложение пропускается (для него выставляется пустой элемент и выполняется `continue`).
**Фрагмент кода (после изменения):**
```php
foreach ($response['data'] as $dataKey => $app) {
$releases = [];
// Skip apps without valid releases (e.g. custom appstore may omit or use different structure)
if (!isset($app['releases']) || !is_array($app['releases'])) {
$response['data'][$dataKey] = [];
continue;
}
// Filter all compatible releases
foreach ($app['releases'] as $release) {
```
**Регистрация:** изменение в методе `fetch()`, класс `OC\App\AppStore\Fetcher\AppFetcher`.
---
## 2. `lib/private/App/AppStore/Fetcher/Fetcher.php`
**Цель:** Корректно обрабатывать оба варианта ответа API appstore: массив приложений в корне JSON `[...]` и обёртку `{"data": [...]}`.
**Изменение:** В методе `fetch()` после установки `$responseJson['data']` из тела ответа добавлена нормализация: если декодированный JSON — массив с ключом `data` и значением-массивом, в `$responseJson['data']` подставляется этот внутренний массив; если декодированное значение не массив — `$responseJson['data']` устанавливается в `[]`.
**Фрагмент кода (после изменения):**
```php
// Normalize: support both root array [...] and wrapped {"data": [...]} from custom appstore
$decoded = $responseJson['data'];
if (is_array($decoded) && isset($decoded['data']) && is_array($decoded['data'])) {
$responseJson['data'] = $decoded['data'];
} elseif (!is_array($decoded)) {
$responseJson['data'] = [];
}
```
**Регистрация:** изменение в методе `fetch()`, класс `OC\App\AppStore\Fetcher\Fetcher`.
---
## 3. `lib/private/Installer.php`
**Цель:** При использовании кастомного appstore дать возможность указывать свои CA и CRL для проверки подписей приложений.
**Изменение:** В методе `downloadApp()` перед загрузкой корневого сертификата и CRL добавлена проверка: если в конфиге задан кастомный URL appstore (`appstoreurl` ≠ `https://apps.f7cloud.com/api/v1`) и заданы пути к файлам CA и CRL (`appstore_ca_path`, `appstore_crl_path`) и оба файла существуют, используются они; иначе — стандартные пути `resources/codesigning/root.crt` и `resources/codesigning/root.crl`.
**Новые параметры конфигурации (config.php):**
| Ключ | Тип | Описание |
|----------------------|--------|----------|
| `appstore_ca_path` | string | Абсолютный путь к файлу CA (PEM) для проверки сертификатов приложений из кастомного appstore. Учитывается только при кастомном `appstoreurl`. |
| `appstore_crl_path` | string | Абсолютный путь к файлу CRL для проверки отзыва сертификатов. Учитывается только при кастомном `appstoreurl`. |
Оба параметра должны быть заданы и указывать на существующие файлы, иначе используются встроенные CA/CRL.
**Регистрация:** изменение в методе `downloadApp()`, класс `OC\Installer`.
---
## 4. `core/Command/App/Install.php`
**Цель:** При ошибке установки приложения через `occ app:install` выводить полезную информацию, если сообщение исключения пустое.
**Изменение:** В блоке `catch (\Exception $e)` перед выводом сообщения проверяется, не пусто ли `$e->getMessage()` (в т.ч. строка `'0'`). Если пусто — в вывод подставляется строка вида `ИмяКласса in /path/to/file.php:NN`.
**Фрагмент кода (после изменения):**
```php
} catch (\Exception $e) {
$msg = $e->getMessage();
if ($msg === '' || $msg === '0') {
$msg = get_class($e) . ' in ' . $e->getFile() . ':' . $e->getLine();
}
$output->writeln('Error: ' . $msg);
return 1;
}
```
**Регистрация:** изменение в методе `execute()`, класс `OC\Core\Command\App\Install`.
---
## 5. URL appstore по умолчанию: `appstore.f7cloud.ru`
**Цель:** Использовать `https://appstore.f7cloud.ru/api/v1` как appstore по умолчанию, без прописывания в `config.php`.
**Изменения:**
- **`lib/private/App/AppStore/Fetcher/Fetcher.php`**
- Константа `APP_STORE_URL` изменена с `https://apps.f7cloud.com/api/v1` на `https://appstore.f7cloud.ru/api/v1`.
- В `getEndpoint()` fallback для `appstoreurl` заменён на `self::APP_STORE_URL` (вместо захардкоженной строки).
- **`lib/private/Installer.php`**
- Локальная переменная `$defaultAppStoreUrl` в `downloadApp()` изменена с `https://apps.f7cloud.com/api/v1` на `https://appstore.f7cloud.ru/api/v1` (используется для решения, применять ли кастомные CA/CRL).
**Регистрация:** константа и fallback в `OC\App\AppStore\Fetcher\Fetcher`; переменная в `OC\Installer::downloadApp()`.
Переопределить URL по-прежнему можно через `config.php`: `'appstoreurl' => 'https://...'`.
---
## 6. Брендинг версии: f7cloud 1.0.0
**Цель:** Отображать продукт как f7cloud 1.0.0 и сохранить совместимость проверок версий приложений (min/max-version).
**Изменения:**
- **`version.php`**
- **OC_VersionString** — `'f7cloud 1.0.0'` (отображается в интерфейсе и в `occ --version`).
- **$vendor** — `'f7cloud'`.
- **OC_Version** — `[1,0,0,0]` (числовая версия 1.0.0 на клиенте).
- В **OC_VersionCanBeUpgradedFrom** добавлен `'f7cloud' => array('1.0' => true)`.
- **`lib/private/legacy/OC_Defaults.php`**
- **defaultEntity**, **defaultName**, **defaultTitle** и **defaultProductName** изменены с `'F7cloud'` на `'f7cloud'` — название продукта в интерфейсе, заголовках и подвалах.
**Регистрация:** `version.php` (корень); класс `OC_Defaults` в `lib/private/legacy/OC_Defaults.php`.
Тема и `config.php` по-прежнему могут переопределять название продукта (например, через тему с методом `getProductName()`).
---
## 7. Отключение проверки сертификатов и подписей
**Цель:** Отключить проверку сертификатов и подписей для приложений и обновлений core, удалить сертификаты.
**Изменения:**
- **`lib/private/Installer.php`**
- Отключена проверка сертификата приложения (загрузка CA, проверка CRL, валидация подписи CA, проверка CN).
- Отключена проверка подписи скачанного архива приложения (`openssl_verify`).
- Приложения устанавливаются без проверки сертификатов и подписей.
- **`updater/index.php`**
- Метод `verifyIntegrity()` отключён — проверка подписи обновлений core не выполняется. Метод сразу возвращает управление.
- **`lib/private/IntegrityCheck/Checker.php`**
- Метод `verify()` отключён — проверка целостности кода (валидация сертификатов и подписей файлов) не выполняется. Метод возвращает пустой массив.
- **`resources/codesigning/`**
- Удалены файлы сертификатов: `root.crt`, `core.crt`, `root.crl`.
- Оставлены только license файлы (`.license`).
**Регистрация:** изменения в `OC\Installer::downloadApp()`, `Updater::verifyIntegrity()`, `OC\IntegrityCheck\Checker::verify()`; удаление файлов в `resources/codesigning/`.
**Внимание:** После этих изменений приложения и обновления устанавливаются без проверки подлинности. Используйте только доверенные источники.
---
## 8. Числовая версия 1.0.0 у клиента и приложений
**Цель:** Использовать числовую версию 1.0.0 на клиенте и привести все приложения к совместимости с 1.x.
**Изменения:**
- **`version.php`**
- **OC_Version** установлен в `array(1,0,0,0)` — числовая версия платформы 1.0.0 (для DependencyAnalyzer, AppFetcher, config).
- **Приложения (`apps/*/appinfo/info.xml`)**
- Во всех приложениях зависимости f7cloud приведены к диапазону 1.x:
`min-version="1"` и `max-version="2"` (вместо min/max 2834 или 32).
- Так платформа 1.0.0 проходит проверку совместимости (1.0.0 ≥ 1 и 1.0.0 ≤ 2).
**Регистрация:** `version.php`; все `appinfo/info.xml` с блоком `<dependencies><f7cloud .../></dependencies>`.
---
## Существующее поведение Fetcher (без изменений в этом реестре)
В `lib/private/App/AppStore/Fetcher/Fetcher.php` в методе `get()` уже присутствует:
- Обработка ошибок чтения кэша: при любой исключении при чтении/разборе файла кэша выполняется попытка получить новый файл и выполнить запрос к appstore (поведение как при отсутствии кэша).
- После успешного `putContent()` возвращаются данные из памяти (`$responseJson['data']`), а не из перечитанного файла, чтобы избежать проблем с только что записанным кэшем (например, в appdata).
Эти части кода в данном реестре не менялись и приведены только для полноты картины работы с кастомным appstore.
---
## Краткая сводка файлов
| Файл | Изменение |
|------|------------|
| `lib/private/App/AppStore/Fetcher/AppFetcher.php` | Защитная проверка `releases` перед циклом |
| `lib/private/App/AppStore/Fetcher/Fetcher.php` | Нормализация формата ответа; дефолтный URL appstore `appstore.f7cloud.ru` |
| `lib/private/Installer.php` | Опциональные CA/CRL для кастомного appstore; дефолтный URL appstore для проверки CA/CRL |
| `core/Command/App/Install.php` | Вывод класса и file:line при пустом сообщении исключения |
| `version.php` | Строка и числовая версия `f7cloud 1.0.0` (OC_Version [1,0,0,0]) |
| `apps/*/appinfo/info.xml` | Зависимости f7cloud: min-version="1" max-version="2" для совместимости с 1.0.0 |
| `lib/private/legacy/OC_Defaults.php` | Название продукта и entity/name/title: f7cloud |
| `lib/private/Installer.php` | Проверка сертификатов и подписей при установке приложений отключена |
| `updater/index.php` | Проверка сертификатов при обновлении core отключена |
| `lib/private/IntegrityCheck/Checker.php` | Проверка целостности кода (сертификаты) отключена |
| `resources/codesigning/` | Сертификаты удалены (оставлены только license файлы) |
Дата регистрации изменений: 2025-02-02.