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

14 KiB
Raw Blame History

Регистрация изменений клиента 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 (appstoreurlhttps://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).
  • 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.