14 KiB
Регистрация изменений клиента F7cloud для работы с кастомным App Store
Все изменения внесены для совместимости с кастомным appstore без полагания на формат и поведение только официального store. Каждое изменение задокументировано для учёта и аудита.
1. lib/private/App/AppStore/Fetcher/AppFetcher.php
Цель: Исключить падение при отсутствии или неверном формате поля releases у приложения (кастомный appstore может отдавать не все поля).
Изменение: Перед циклом по $app['releases'] добавлена проверка: если у элемента массива приложений нет ключа releases или значение не является массивом, приложение пропускается (для него выставляется пустой элемент и выполняется continue).
Фрагмент кода (после изменения):
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'] устанавливается в [].
Фрагмент кода (после изменения):
// 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.
Фрагмент кода (после изменения):
} 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).
- OC_VersionString —
-
lib/private/legacy/OC_Defaults.php- defaultEntity, defaultName, defaultTitle и defaultProductName изменены с
'F7cloud'на'f7cloud'— название продукта в интерфейсе, заголовках и подвалах.
- defaultEntity, defaultName, defaultTitle и defaultProductName изменены с
Регистрация: 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).
- OC_Version установлен в
-
Приложения (
apps/*/appinfo/info.xml)- Во всех приложениях зависимости f7cloud приведены к диапазону 1.x:
min-version="1"иmax-version="2"(вместо min/max 28–34 или 32). - Так платформа 1.0.0 проходит проверку совместимости (1.0.0 ≥ 1 и 1.0.0 ≤ 2).
- Во всех приложениях зависимости f7cloud приведены к диапазону 1.x:
Регистрация: 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.