fix(launcher): bootstrap release state and signed manifest

This commit is contained in:
Comely
2026-07-10 02:38:04 -07:00
parent 9d632f3323
commit bec05cdbc8
13 changed files with 150 additions and 10 deletions
+2
View File
@@ -5,6 +5,8 @@ set(_common_sources
FileHelper.cpp
ConfigHelper.h
ConfigHelper.cpp
InitialStatePolicy.h
ManifestBootstrapPolicy.h
PolicyHelper.h
PolicyHelper.cpp
LocalStateHelper.h
+14 -2
View File
@@ -1,4 +1,5 @@
#include "ConfigHelper.h"
#include "InitialStatePolicy.h"
#include <QCoreApplication>
#include <QDebug>
@@ -583,9 +584,20 @@ bool ConfigHelper::initializeStateDefaults()
for (const QString& key : mutableKeys())
{
if (!m_initialState.contains(key))
continue;
const QString storageKey = stateStorageKey(key);
if (!settings.contains(storageKey) && m_initialState.contains(key))
settings.setValue(storageKey, m_initialState.value(key).toString());
const bool storedValueExists = settings.contains(storageKey);
const QString storedValue = storedValueExists
? settings.value(storageKey).toString()
: QString();
const QString initialValue = m_initialState.value(key).toString();
if (UpdateClient::shouldApplyInitialStateValue(
key, storedValueExists, storedValue, initialValue))
{
settings.setValue(storageKey, initialValue);
}
}
settings.sync();
+19
View File
@@ -0,0 +1,19 @@
#pragma once
#include <QString>
namespace UpdateClient
{
inline bool shouldApplyInitialStateValue(const QString& key,
bool storedValueExists,
const QString& storedValue,
const QString& initialValue)
{
if (!storedValueExists)
return true;
return key == QStringLiteral("license_key")
&& storedValue.trimmed().isEmpty()
&& !initialValue.trimmed().isEmpty();
}
}
+12 -1
View File
@@ -19,6 +19,11 @@ IntegrityHelper::IntegrityHelper(const QString& installDir)
QString IntegrityHelper::errorString() const { return m_error; }
bool IntegrityHelper::isManifestCacheMissing() const
{
return m_manifestCacheMissing;
}
bool IntegrityHelper::safeRelativePath(const QString& path) const
{
const QString clean = QDir::cleanPath(QDir::fromNativeSeparators(path));
@@ -82,14 +87,20 @@ bool IntegrityHelper::verifyInstalledVersion(const QString& appId, const QString
const QString& version)
{
m_error.clear();
m_manifestCacheMissing = false;
QString cachePath = QDir(ConfigHelper::instance().updateRoot()).filePath(
"manifest_cache/manifest_" + version + ".json");
const QString legacyCachePath = QDir(m_installDir).filePath(
"update/manifest_cache/manifest_" + version + ".json");
if (!QFile::exists(cachePath))
cachePath = legacyCachePath;
if (!QFile::exists(cachePath)) {
m_manifestCacheMissing = true;
m_error = "signed manifest cache missing for " + version;
return false;
}
QFile cache(cachePath);
if (!cache.open(QIODevice::ReadOnly)) { m_error = "signed manifest cache missing for " + version; return false; }
if (!cache.open(QIODevice::ReadOnly)) { m_error = "cannot read signed manifest cache for " + version; return false; }
QJsonParseError wrapperError;
const QJsonDocument wrapperDoc = QJsonDocument::fromJson(cache.readAll(), &wrapperError);
if (wrapperError.error != QJsonParseError::NoError || !wrapperDoc.isObject()) {
+2
View File
@@ -7,6 +7,7 @@ public:
explicit IntegrityHelper(const QString& installDir);
bool verifyInstalledVersion(const QString& appId, const QString& channel,
const QString& version);
bool isManifestCacheMissing() const;
QString errorString() const;
private:
@@ -17,4 +18,5 @@ private:
QString m_installDir;
QString m_error;
bool m_manifestCacheMissing = false;
};
+24
View File
@@ -0,0 +1,24 @@
#pragma once
namespace UpdateClient
{
enum class ManifestBootstrapAction
{
None,
FetchCurrentManifest,
CurrentVersionNotPublished
};
inline ManifestBootstrapAction manifestBootstrapAction(
bool manifestCacheMissing,
bool networkAvailable,
bool updateAvailable,
int serverVersionId)
{
if (!manifestCacheMissing || !networkAvailable || updateAvailable)
return ManifestBootstrapAction::None;
if (serverVersionId <= 0)
return ManifestBootstrapAction::CurrentVersionNotPublished;
return ManifestBootstrapAction::FetchCurrentManifest;
}
}