Upload via GUI (452 Dateien)
This commit is contained in:
@@ -81,3 +81,88 @@ function update_http_headers(): array
|
||||
[$token] = update_token_info();
|
||||
return $token !== '' ? ['Authorization: token ' . $token] : [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gehört diese Datei aus dem Update-Paket nicht auf die Installation? Plugins, Uploads, Backups und App-Dateien gehören dem System, die Plugin-Webseite
|
||||
* und Entwickler-Ordner gehören nicht auf Kunden-Installationen. Ausnahme: Das Handbuch (docs/DeskHub-Handbuch.pdf) kommt mit jedem Update (Adminportal → Hilfe).
|
||||
*/
|
||||
function update_path_is_skipped(string $relNorm): bool
|
||||
{
|
||||
// Die Konfiguration gehört der Installation: nichts aus config/ wird je überschrieben oder neu angelegt (auch nicht bei anderer Groß-/Kleinschreibung)
|
||||
if (preg_match('#^(\./)*config(/|$)#i', $relNorm) || preg_match('#(^|/)(\.env|config\.php)$#i', $relNorm) && !str_contains($relNorm, '/')) return true;
|
||||
if ($relNorm === 'docs/DeskHub-Handbuch.pdf' || $relNorm === 'tools/fix-permissions.sh') return false;
|
||||
return (bool) (preg_match('#^(plugins|uploads|backups|app_downloads)/#', $relNorm)
|
||||
|| preg_match('#^(plugin-webseite|tools|tests|docs|desktop|mobile|theme-packages|vorschaubilder|\.gitea|\.github)/#', $relNorm));
|
||||
}
|
||||
|
||||
|
||||
// ─── Updates von der Plugin-Webseite ─────────────────────────────────────────
|
||||
|
||||
/**
|
||||
* Adresse der Update-Schnittstelle auf der offiziellen Plugin-Webseite (app-release.php neben dem Katalog) oder '' ohne offiziellen Katalog.
|
||||
* Der Zugangsschlüssel wird nur an diesen Server geschickt (catalog_access_headers).
|
||||
*/
|
||||
function update_publisher_endpoint(array $query): string
|
||||
{
|
||||
$base = function_exists('catalog_defaults') ? (string) (catalog_defaults()['plugins_url'] ?? '') : '';
|
||||
$parts = parse_url($base);
|
||||
if (!$parts || ($parts['scheme'] ?? '') !== 'https' || empty($parts['host'])) return '';
|
||||
$path = rtrim(str_replace('\\', '/', dirname((string) ($parts['path'] ?? '/'))), '/');
|
||||
return 'https://' . $parts['host'] . (isset($parts['port']) ? ':' . (int) $parts['port'] : '') . $path . '/app-release.php?' . http_build_query(['platform' => 'server'] + $query);
|
||||
}
|
||||
|
||||
/**
|
||||
* Die auf der Plugin-Webseite veröffentlichten System-Updates, neueste zuerst. Leer, wenn die Seite nicht antwortet oder nichts
|
||||
* veröffentlicht ist (dann greift die Ausweichquelle). Jeder Eintrag hat dieselben Felder wie ein Gitea-Release (tag_name, published_at, body)
|
||||
* plus sha256, size, signature und source = 'publisher'.
|
||||
*
|
||||
* @return list<array<string,mixed>>
|
||||
*/
|
||||
function update_publisher_releases(): array
|
||||
{
|
||||
static $cache = null;
|
||||
if ($cache !== null && !isset($GLOBALS['deskhub_http_get'])) return $cache;
|
||||
$url = update_publisher_endpoint(['list' => 1]);
|
||||
$out = [];
|
||||
if ($url !== '') {
|
||||
[$status, $body] = plugin_http_get($url, 1048576, 8);
|
||||
$data = $status === 200 && is_string($body) ? json_decode($body, true) : null;
|
||||
foreach ((array) ($data['releases'] ?? []) as $r) {
|
||||
$v = (string) ($r['version'] ?? '');
|
||||
if (!is_array($r) || !preg_match('/^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?$/', $v) || !preg_match('/^[0-9a-f]{64}$/i', (string) ($r['sha256'] ?? ''))) continue;
|
||||
$out[] = ['tag_name' => $v, 'published_at' => (string) ($r['created_at'] ?? ''), 'body' => (string) ($r['notes'] ?? ''), 'sha256' => strtolower((string) $r['sha256']),
|
||||
'size' => (int) ($r['size'] ?? 0), 'signature' => (string) ($r['signature'] ?? ''), 'source' => 'publisher'];
|
||||
}
|
||||
usort($out, fn($a, $b) => version_compare($b['tag_name'], $a['tag_name']));
|
||||
}
|
||||
return $cache = $out;
|
||||
}
|
||||
|
||||
/** Ein Eintrag aus update_publisher_releases() zu einem Versions-Tag (mit oder ohne „v“) oder null. */
|
||||
function update_publisher_find(string $tag): ?array
|
||||
{
|
||||
$v = ltrim(trim($tag), 'vV');
|
||||
foreach (update_publisher_releases() as $r) if ($r['tag_name'] === $v) return $r;
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lädt das Paket einer Version von der Plugin-Webseite und prüft Prüfsumme und (bei eingebautem Herausgeber-Schlüssel) Signatur.
|
||||
*
|
||||
* @return array{0:?string,1:?string} [Pfad zur ZIP-Datei, Fehlertext]; bei Fehler ist die Datei schon gelöscht
|
||||
*/
|
||||
function update_publisher_fetch(array $release): array
|
||||
{
|
||||
$url = update_publisher_endpoint(['version' => $release['tag_name'], 'download' => 1]);
|
||||
if ($url === '') return [null, 'Die Plugin-Webseite ist nicht eingetragen.'];
|
||||
[$status, $body, $err] = plugin_http_get($url, 300 * 1048576, 180);
|
||||
if ($status !== 200 || !is_string($body)) return [null, 'Download von der Plugin-Webseite fehlgeschlagen' . ($err ? ': ' . $err : " (HTTP $status).")];
|
||||
if (!hash_equals((string) $release['sha256'], hash('sha256', $body))) return [null, 'Die Prüfsumme des Pakets stimmt nicht. Es wird nicht installiert.'];
|
||||
$tmp = tempnam(sys_get_temp_dir(), 'dh_') . '.zip';
|
||||
file_put_contents($tmp, $body);
|
||||
if (update_signature_required()) {
|
||||
$problem = update_verify_package((string) $release['tag_name'], $tmp, (string) $release['signature']);
|
||||
if ($problem !== null) { @unlink($tmp); return [null, $problem]; }
|
||||
}
|
||||
return [$tmp, null];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user