Skip to content

Commit 5935a3b

Browse files
authored
feat: UnraidCheckExec for Check OS Updates via UPC dropdown (#1265)
- 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. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## 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. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
1 parent 2e85c74 commit 5935a3b

File tree

4 files changed

+80
-3
lines changed

4 files changed

+80
-3
lines changed

plugin/plugins/dynamix.unraid.net.plg

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,7 @@ if [ -f /tmp/restore-files-dynamix-unraid-net ]; then
392392
"/usr/local/emhttp/plugins/dynamix.plugin.manager/scripts/showchanges"
393393
"/usr/local/emhttp/plugins/dynamix.plugin.manager/scripts/unraidcheck"
394394
"/usr/local/emhttp/plugins/dynamix.plugin.manager/include/UnraidCheck.php"
395+
"/usr/local/emhttp/plugins/dynamix.plugin.manager/include/UnraidCheckExec.php"
395396
"/usr/local/emhttp/plugins/dynamix.my.servers/Connect.page"
396397
"/usr/local/emhttp/plugins/dynamix.my.servers/MyServers.page"
397398
"/usr/local/emhttp/plugins/dynamix.my.servers/Registration.page"
@@ -511,6 +512,7 @@ preserveFilesDirs=(
511512
"move:/usr/local/emhttp/plugins/dynamix.plugin.manager/Update.page:preventDowngrade"
512513
"move:/usr/local/emhttp/plugins/dynamix.plugin.manager/scripts/unraidcheck:preventDowngrade"
513514
"move:/usr/local/emhttp/plugins/dynamix.plugin.manager/include/UnraidCheck.php:preventDowngrade"
515+
"move:/usr/local/emhttp/plugins/dynamix.plugin.manager/include/UnraidCheckExec.php:preventDowngrade"
514516
"move:/usr/local/emhttp/plugins/dynamix.my.servers/MyServers.page:skip"
515517
"move:/usr/local/emhttp/plugins/dynamix.my.servers/Connect.page:skip"
516518
"move:/usr/local/emhttp/plugins/dynamix.my.servers/Registration.page:preventDowngrade"
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
<?php
2+
/**
3+
* This file exists to maintain separation of concerns between UnraidCheck and ReplaceKey.
4+
* Instead of combining both classes directly, we utilize the unraidcheck script which already
5+
* handles both operations in a simplified manner.
6+
*
7+
* It's called via the WebguiCheckForUpdate function in composables/services/webgui.ts of the web components.
8+
* Handles WebguiUnraidCheckExecPayload interface parameters:
9+
* - altUrl?: string
10+
* - json?: boolean
11+
*/
12+
class UnraidCheckExec
13+
{
14+
private const SCRIPT_PATH = '/usr/local/emhttp/plugins/dynamix.plugin.manager/scripts/unraidcheck';
15+
private const ALLOWED_DOMAIN = 'releases.unraid.net';
16+
17+
private function setupEnvironment(): void
18+
{
19+
header('Content-Type: application/json');
20+
header('X-Content-Type-Options: nosniff');
21+
header('X-Frame-Options: DENY');
22+
header('Content-Security-Policy: default-src \'none\'');
23+
24+
$params = [
25+
'json' => 'true',
26+
];
27+
28+
if (isset($_GET['altUrl'])) {
29+
$url = filter_var($_GET['altUrl'], FILTER_VALIDATE_URL);
30+
if ($url !== false) {
31+
$host = parse_url($url, PHP_URL_HOST);
32+
$scheme = parse_url($url, PHP_URL_SCHEME);
33+
34+
if ($host && $scheme === 'https' && (
35+
$host === self::ALLOWED_DOMAIN ||
36+
str_ends_with($host, '.' . self::ALLOWED_DOMAIN)
37+
)) {
38+
$params['altUrl'] = $url;
39+
}
40+
}
41+
}
42+
43+
putenv('QUERY_STRING=' . http_build_query($params));
44+
}
45+
46+
public function execute(): string
47+
{
48+
// Validate script with all necessary permissions
49+
if (!is_file(self::SCRIPT_PATH) ||
50+
!is_readable(self::SCRIPT_PATH) ||
51+
!is_executable(self::SCRIPT_PATH)) {
52+
throw new RuntimeException('Script not found or not executable');
53+
}
54+
55+
$this->setupEnvironment();
56+
$output = [];
57+
$command = escapeshellcmd(self::SCRIPT_PATH);
58+
if (exec($command, $output) === false) {
59+
throw new RuntimeException('Script execution failed');
60+
}
61+
62+
return implode("\n", $output);
63+
}
64+
}
65+
66+
// Usage
67+
$checker = new UnraidCheckExec();
68+
echo $checker->execute();

plugin/source/dynamix.unraid.net/usr/local/emhttp/plugins/dynamix.plugin.manager/scripts/unraidcheck

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ require_once "$docroot/plugins/dynamix/include/ReplaceKey.php";
1818
$replaceKey = new ReplaceKey();
1919
$replaceKey->check();
2020

21+
// utilized by UnraidCheckExec.php to have UnraidCheck.php return a json response when this script is called directly
22+
parse_str(getenv('QUERY_STRING') ?? '', $_GET);
23+
2124
require_once "$docroot/plugins/dynamix.plugin.manager/include/UnraidCheck.php";
2225
$unraidOsCheck = new UnraidOsCheck();
2326
$unraidOsCheck->checkForUpdate();

web/composables/services/webgui.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -92,23 +92,27 @@ interface WebguiUnraidCheckPayload {
9292
version?: string;
9393
}
9494

95+
interface WebguiUnraidCheckExecPayload {
96+
altUrl?: string;
97+
json?: boolean;
98+
}
99+
95100
interface WebguiUnraidCheckIgnoreResponse {
96101
updateOsIgnoredReleases: string[];
97102
}
98103

99104
export const WebguiCheckForUpdate = async (): Promise<ServerUpdateOsResponse | unknown> => {
100105
console.debug('[WebguiCheckForUpdate]');
101106
try {
102-
const params: WebguiUnraidCheckPayload = {
103-
action: 'check',
107+
const params: WebguiUnraidCheckExecPayload = {
104108
json: true,
105109
};
106110
// conditionally add altUrl if OS_RELEASES.toString() is not 'https://releases.unraid.net/os'
107111
if (OS_RELEASES.toString() !== 'https://releases.unraid.net/os') {
108112
params.altUrl = OS_RELEASES.toString();
109113
}
110114
const response = await request
111-
.url('/plugins/dynamix.plugin.manager/include/UnraidCheck.php') // @todo replace with /scripts/unraidcheck
115+
.url('/plugins/dynamix.plugin.manager/include/UnraidCheckExec.php')
112116
.query(params)
113117
.get()
114118
.json((json) => {

0 commit comments

Comments
 (0)