From 3a20930ead41f570198a57fed4f04c1dca239180 Mon Sep 17 00:00:00 2001 From: Zack Spear Date: Fri, 21 Mar 2025 14:05:17 -0700 Subject: [PATCH] feat: UnraidCheckExec for Check OS Updates via UPC dropdown (#1265) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Added `UnraidCheckExec.php` to separate concerns between UnraidCheck and ReplaceKey, allowing for JSON responses. - Updated `unraidcheck` script to parse query strings for compatibility with the new class. - Modified `webgui.ts` to call `UnraidCheckExec.php` instead of `UnraidCheck.php` for update checks. ## Summary by CodeRabbit - **New Features** - Updated the plugin installation process to ensure critical files remain protected during updates. - Introduced a dedicated update check component that now returns results in a JSON format. - Enhanced the web interface’s update check functionality with streamlined request parameters. - **Refactor** - Separated update checking responsibilities for improved logic clarity and overall reliability. - Updated the interface for the update check payload to enhance parameter handling. --- plugin/plugins/dynamix.unraid.net.plg | 2 + .../include/UnraidCheckExec.php | 68 +++++++++++++++++++ .../scripts/unraidcheck | 3 + web/composables/services/webgui.ts | 10 ++- 4 files changed, 80 insertions(+), 3 deletions(-) create mode 100644 plugin/source/dynamix.unraid.net/usr/local/emhttp/plugins/dynamix.plugin.manager/include/UnraidCheckExec.php diff --git a/plugin/plugins/dynamix.unraid.net.plg b/plugin/plugins/dynamix.unraid.net.plg index 72a9c4d69..3e2f5d349 100755 --- a/plugin/plugins/dynamix.unraid.net.plg +++ b/plugin/plugins/dynamix.unraid.net.plg @@ -392,6 +392,7 @@ if [ -f /tmp/restore-files-dynamix-unraid-net ]; then "/usr/local/emhttp/plugins/dynamix.plugin.manager/scripts/showchanges" "/usr/local/emhttp/plugins/dynamix.plugin.manager/scripts/unraidcheck" "/usr/local/emhttp/plugins/dynamix.plugin.manager/include/UnraidCheck.php" + "/usr/local/emhttp/plugins/dynamix.plugin.manager/include/UnraidCheckExec.php" "/usr/local/emhttp/plugins/dynamix.my.servers/Connect.page" "/usr/local/emhttp/plugins/dynamix.my.servers/MyServers.page" "/usr/local/emhttp/plugins/dynamix.my.servers/Registration.page" @@ -511,6 +512,7 @@ preserveFilesDirs=( "move:/usr/local/emhttp/plugins/dynamix.plugin.manager/Update.page:preventDowngrade" "move:/usr/local/emhttp/plugins/dynamix.plugin.manager/scripts/unraidcheck:preventDowngrade" "move:/usr/local/emhttp/plugins/dynamix.plugin.manager/include/UnraidCheck.php:preventDowngrade" + "move:/usr/local/emhttp/plugins/dynamix.plugin.manager/include/UnraidCheckExec.php:preventDowngrade" "move:/usr/local/emhttp/plugins/dynamix.my.servers/MyServers.page:skip" "move:/usr/local/emhttp/plugins/dynamix.my.servers/Connect.page:skip" "move:/usr/local/emhttp/plugins/dynamix.my.servers/Registration.page:preventDowngrade" diff --git a/plugin/source/dynamix.unraid.net/usr/local/emhttp/plugins/dynamix.plugin.manager/include/UnraidCheckExec.php b/plugin/source/dynamix.unraid.net/usr/local/emhttp/plugins/dynamix.plugin.manager/include/UnraidCheckExec.php new file mode 100644 index 000000000..7b2881cd2 --- /dev/null +++ b/plugin/source/dynamix.unraid.net/usr/local/emhttp/plugins/dynamix.plugin.manager/include/UnraidCheckExec.php @@ -0,0 +1,68 @@ + 'true', + ]; + + if (isset($_GET['altUrl'])) { + $url = filter_var($_GET['altUrl'], FILTER_VALIDATE_URL); + if ($url !== false) { + $host = parse_url($url, PHP_URL_HOST); + $scheme = parse_url($url, PHP_URL_SCHEME); + + if ($host && $scheme === 'https' && ( + $host === self::ALLOWED_DOMAIN || + str_ends_with($host, '.' . self::ALLOWED_DOMAIN) + )) { + $params['altUrl'] = $url; + } + } + } + + putenv('QUERY_STRING=' . http_build_query($params)); + } + + public function execute(): string + { + // Validate script with all necessary permissions + if (!is_file(self::SCRIPT_PATH) || + !is_readable(self::SCRIPT_PATH) || + !is_executable(self::SCRIPT_PATH)) { + throw new RuntimeException('Script not found or not executable'); + } + + $this->setupEnvironment(); + $output = []; + $command = escapeshellcmd(self::SCRIPT_PATH); + if (exec($command, $output) === false) { + throw new RuntimeException('Script execution failed'); + } + + return implode("\n", $output); + } +} + +// Usage +$checker = new UnraidCheckExec(); +echo $checker->execute(); diff --git a/plugin/source/dynamix.unraid.net/usr/local/emhttp/plugins/dynamix.plugin.manager/scripts/unraidcheck b/plugin/source/dynamix.unraid.net/usr/local/emhttp/plugins/dynamix.plugin.manager/scripts/unraidcheck index b1006b958..81cb3ea58 100755 --- a/plugin/source/dynamix.unraid.net/usr/local/emhttp/plugins/dynamix.plugin.manager/scripts/unraidcheck +++ b/plugin/source/dynamix.unraid.net/usr/local/emhttp/plugins/dynamix.plugin.manager/scripts/unraidcheck @@ -18,6 +18,9 @@ require_once "$docroot/plugins/dynamix/include/ReplaceKey.php"; $replaceKey = new ReplaceKey(); $replaceKey->check(); +// utilized by UnraidCheckExec.php to have UnraidCheck.php return a json response when this script is called directly +parse_str(getenv('QUERY_STRING') ?? '', $_GET); + require_once "$docroot/plugins/dynamix.plugin.manager/include/UnraidCheck.php"; $unraidOsCheck = new UnraidOsCheck(); $unraidOsCheck->checkForUpdate(); diff --git a/web/composables/services/webgui.ts b/web/composables/services/webgui.ts index 3fee75517..04bd48269 100644 --- a/web/composables/services/webgui.ts +++ b/web/composables/services/webgui.ts @@ -92,6 +92,11 @@ interface WebguiUnraidCheckPayload { version?: string; } +interface WebguiUnraidCheckExecPayload { + altUrl?: string; + json?: boolean; +} + interface WebguiUnraidCheckIgnoreResponse { updateOsIgnoredReleases: string[]; } @@ -99,8 +104,7 @@ interface WebguiUnraidCheckIgnoreResponse { export const WebguiCheckForUpdate = async (): Promise => { console.debug('[WebguiCheckForUpdate]'); try { - const params: WebguiUnraidCheckPayload = { - action: 'check', + const params: WebguiUnraidCheckExecPayload = { json: true, }; // conditionally add altUrl if OS_RELEASES.toString() is not 'https://releases.unraid.net/os' @@ -108,7 +112,7 @@ export const WebguiCheckForUpdate = async (): Promise {