diff --git a/emhttp/plugins/dynamix.plugin.manager/Downgrade.page b/emhttp/plugins/dynamix.plugin.manager/Downgrade.page
deleted file mode 100644
index 037740ac6..000000000
--- a/emhttp/plugins/dynamix.plugin.manager/Downgrade.page
+++ /dev/null
@@ -1,154 +0,0 @@
-Menu="About:20"
-Title="Downgrade OS"
-Icon="icon-update"
-Tag="upload"
----
-check();
-
-require_once "$docroot/plugins/dynamix.my.servers/include/reboot-details.php";
-$rebootDetails = new RebootDetails();
-$rebootDetails->setPrevious();
-
-$serverNameEscaped = htmlspecialchars(str_replace(' ', '_', strtolower($var['NAME'])));
-?>
-
-
-
-
-
-
diff --git a/emhttp/plugins/dynamix.plugin.manager/Update.page b/emhttp/plugins/dynamix.plugin.manager/Update.page
deleted file mode 100644
index c3a5e52e6..000000000
--- a/emhttp/plugins/dynamix.plugin.manager/Update.page
+++ /dev/null
@@ -1,54 +0,0 @@
-Menu="About:10"
-Title="Update OS"
-Icon="icon-update"
-Tag="upload"
----
-check();
-
-require_once "$docroot/plugins/dynamix.my.servers/include/reboot-details.php";
-$rebootDetails = new RebootDetails();
-?>
-
-
-
-
-
diff --git a/emhttp/plugins/dynamix.plugin.manager/include/UnraidCheck.php b/emhttp/plugins/dynamix.plugin.manager/include/UnraidCheck.php
deleted file mode 100644
index a474ea9ba..000000000
--- a/emhttp/plugins/dynamix.plugin.manager/include/UnraidCheck.php
+++ /dev/null
@@ -1,271 +0,0 @@
-checkForUpdate();
- *
- * 2. Unraid webgui web components can GET this file with action params to get updates, ignore updates, etc.
- * - EX: Unraid webgui web components can check for updates via a GET request and receive a response with the json file directly
- * - this is useful for the UPC to check for updates and display a model based on the value
- * - `/plugins/dynamix.plugin.manager/scripts/unraidcheck.php?json=true`
- * - note the json=true query param to receive a json response
- *
- * @param action {'check'|'removeAllIgnored'|'removeIgnoredVersion'|'ignoreVersion'} - the action to perform
- * @param version {string} - the version to ignore or remove
- * @param json {string} - if set to true, will return the json response from the external request
- * @param altUrl {URL} - if set, will use this url instead of the default
- */
-$docroot ??= ($_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp');
-require_once "$docroot/webGui/include/Wrappers.php";
-require_once "$docroot/plugins/dynamix.plugin.manager/include/PluginHelpers.php";
-
-class UnraidOsCheck
-{
- private const BASE_RELEASES_URL = 'https://releases.unraid.net/os';
- private const JSON_FILE_IGNORED = '/tmp/unraidcheck/ignored.json';
- private const JSON_FILE_IGNORED_KEY = 'updateOsIgnoredReleases';
- private const JSON_FILE_RESULT = '/tmp/unraidcheck/result.json';
- private const PLG_PATH = '/usr/local/emhttp/plugins/unRAIDServer/unRAIDServer.plg';
-
- public function __construct()
- {
- $isGetRequest = !empty($_SERVER) && isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] === 'GET';
- $getHasAction = $_GET !== null && !empty($_GET) && isset($_GET['action']);
-
- if ($isGetRequest && $getHasAction) {
- $this->handleGetRequestWithActions();
- }
- }
-
- private function handleGetRequestWithActions()
- {
- switch ($_GET['action']) {
- case 'check':
- $this->checkForUpdate();
- break;
-
- case 'removeAllIgnored':
- $this->removeAllIgnored();
- break;
-
- case 'removeIgnoredVersion':
- if (isset($_GET['version'])) {
- $this->removeIgnoredVersion($_GET['version']);
- }
- break;
-
- case 'ignoreVersion':
- if (isset($_GET['version'])) {
- $this->ignoreVersion($_GET['version']);
- }
- break;
-
- default:
- $this->respondWithError(400, "Unhandled action");
- break;
- }
- }
-
- public function getUnraidOSCheckResult()
- {
- if (file_exists(self::JSON_FILE_RESULT)) {
- return $this->readJsonFile(self::JSON_FILE_RESULT);
- }
- }
-
- public function getIgnoredReleases()
- {
- if (!file_exists(self::JSON_FILE_IGNORED)) {
- return [];
- }
-
- $ignoredData = $this->readJsonFile(self::JSON_FILE_IGNORED);
-
- if (is_array($ignoredData) && array_key_exists(self::JSON_FILE_IGNORED_KEY, $ignoredData)) {
- return $ignoredData[self::JSON_FILE_IGNORED_KEY];
- }
-
- return [];
- }
-
- /** @todo clean up this method to be more extensible */
- public function checkForUpdate()
- {
- // Multi-language support
- if (!function_exists('_')) {
- function _($text) {return $text;}
- }
-
- // this command will set the $notify array
- extract(parse_plugin_cfg('dynamix', true));
-
- $var = (array)@parse_ini_file('/var/local/emhttp/var.ini');
-
- $params = [];
- $params['branch'] = plugin('category', self::PLG_PATH, 'stable');
- // Get current version from patches.json if it exists, otherwise fall back to plugin version or var.ini
- $patcherVersion = null;
- if (file_exists('/tmp/Patcher/patches.json')) {
- $patcherData = @json_decode(file_get_contents('/tmp/Patcher/patches.json'), true);
- $unraidVersionInfo = parse_ini_file('/etc/unraid-version');
- if ($patcherData['unraidVersion'] === $unraidVersionInfo['version']) {
- $patcherVersion = $patcherData['combinedVersion'] ?? null;
- }
- }
-
- $params['current_version'] = $patcherVersion ?: plugin('version', self::PLG_PATH) ?: _var($var, 'version');
- if (_var($var,'regExp')) $params['update_exp'] = date('Y-m-d', _var($var,'regExp')*1);
- $defaultUrl = self::BASE_RELEASES_URL;
- // pass a param of altUrl to use the provided url instead of the default
- $parsedAltUrl = (array_key_exists('altUrl',$_GET) && $_GET['altUrl']) ? $_GET['altUrl'] : null;
- // if $parsedAltUrl pass to params
- if ($parsedAltUrl) $params['altUrl'] = $parsedAltUrl;
-
- $urlbase = $parsedAltUrl ?? $defaultUrl;
- $url = $urlbase.'?'.http_build_query($params);
- $curlinfo = [];
- $response = http_get_contents($url,[],$curlinfo);
- if (array_key_exists('error', $curlinfo)) {
- $response = json_encode(array('error' => $curlinfo['error']), JSON_PRETTY_PRINT);
- }
- $responseMutated = json_decode($response, true);
- if (!$responseMutated) {
- $response = json_encode(array('error' => 'Invalid response from '.$urlbase), JSON_PRETTY_PRINT);
- $responseMutated = json_decode($response, true);
- }
-
- // add params that were used for debugging
- $responseMutated['params'] = $params;
-
- // store locally for UPC to access
- $this->writeJsonFile(self::JSON_FILE_RESULT, $responseMutated);
-
- // if we have a query param of json=true then just output the json
- if (array_key_exists('json',$_GET) && $_GET['json']) {
- header('Content-Type: application/json');
- echo $response;
- exit(0);
- }
-
- // send notification if a newer version is available and not ignored
- $isNewerVersion = array_key_exists('isNewer',$responseMutated) ? $responseMutated['isNewer'] : false;
- $isReleaseIgnored = array_key_exists('version',$responseMutated) ? in_array($responseMutated['version'], $this->getIgnoredReleases()) : false;
-
- if ($responseMutated && $isNewerVersion && !$isReleaseIgnored) {
- $output = _var($notify,'plugin');
- $server = strtoupper(_var($var,'NAME','server'));
- $newver = (array_key_exists('version',$responseMutated) && $responseMutated['version']) ? $responseMutated['version'] : 'unknown';
- $script = '/usr/local/emhttp/webGui/scripts/notify';
- $event = "System - Unraid [$newver]";
- $subject = "Notice [$server] - Version update $newver";
- $description = "A new version of Unraid is available";
- exec("$script -e ".escapeshellarg($event)." -s ".escapeshellarg($subject)." -d ".escapeshellarg($description)." -i ".escapeshellarg("normal $output")." -l '/Tools/Update' -x");
- }
-
- exit(0);
- }
-
- private function removeAllIgnored()
- {
- if (file_exists(self::JSON_FILE_IGNORED)) {
- $this->deleteJsonFile(self::JSON_FILE_IGNORED);
- $this->respondWithSuccess([]);
- }
- // fail silently if file doesn't exist
- }
-
- private function removeIgnoredVersion($removeVersion)
- {
- if ($this->isValidSemVerFormat($removeVersion)) {
- if (file_exists(self::JSON_FILE_IGNORED)) {
- $existingData = $this->readJsonFile(self::JSON_FILE_IGNORED);
-
- if (isset($existingData[self::JSON_FILE_IGNORED_KEY])) {
- $existingData[self::JSON_FILE_IGNORED_KEY] = array_diff($existingData[self::JSON_FILE_IGNORED_KEY], [$removeVersion]);
- $this->writeJsonFile(self::JSON_FILE_IGNORED, $existingData);
- $this->respondWithSuccess($existingData);
- } else {
- $this->respondWithError(400, "No versions to remove in the JSON file");
- }
- } else {
- $this->respondWithError(400, "No JSON file found");
- }
- } else {
- $this->respondWithError(400, "Invalid removeVersion format");
- }
- }
-
- private function ignoreVersion($version)
- {
- if ($this->isValidSemVerFormat($version)) {
- $newData = [$this::JSON_FILE_IGNORED_KEY => [$version]];
- $existingData = file_exists(self::JSON_FILE_IGNORED) ? $this->readJsonFile(self::JSON_FILE_IGNORED) : [];
-
- if (isset($existingData[self::JSON_FILE_IGNORED_KEY])) {
- $existingData[self::JSON_FILE_IGNORED_KEY][] = $version;
- } else {
- $existingData[self::JSON_FILE_IGNORED_KEY] = [$version];
- }
-
- $this->writeJsonFile(self::JSON_FILE_IGNORED, $existingData);
- $this->respondWithSuccess($existingData);
- } else {
- $this->respondWithError(400, "Invalid version format");
- }
- }
-
- private function isValidSemVerFormat($version)
- {
- return preg_match('/^\d+\.\d+(\.\d+)?(-.+)?$/', $version);
- }
-
- private function readJsonFile($file)
- {
- return @json_decode(@file_get_contents($file), true) ?? [];
- }
-
- private function writeJsonFile($file, $data)
- {
- if (!is_dir(dirname($file))) { // prevents errors when directory doesn't exist
- mkdir(dirname($file));
- }
- file_put_contents($file, json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES));
- }
-
- private function deleteJsonFile($file)
- {
- unlink($file);
- }
-
- private function respondWithError($statusCode, $message)
- {
- http_response_code($statusCode);
- echo $message;
- }
-
- private function respondWithSuccess($data)
- {
- http_response_code(200);
- header('Content-Type: application/json');
- echo json_encode($data, JSON_PRETTY_PRINT);
- }
-}
-
-// Instantiate and handle the request for GET requests with actions – vars are duplicated here for multi-use of this file
-$isGetRequest = !empty($_SERVER) && isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] === 'GET';
-$getHasAction = $_GET !== null && !empty($_GET) && isset($_GET['action']);
-if ($isGetRequest && $getHasAction) {
- new UnraidOsCheck();
-}
diff --git a/emhttp/plugins/dynamix.plugin.manager/include/UnraidCheckExec.php b/emhttp/plugins/dynamix.plugin.manager/include/UnraidCheckExec.php
deleted file mode 100644
index 7b2881cd2..000000000
--- a/emhttp/plugins/dynamix.plugin.manager/include/UnraidCheckExec.php
+++ /dev/null
@@ -1,68 +0,0 @@
- '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/emhttp/plugins/dynamix.plugin.manager/include/UnraidUpdateCancel.php b/emhttp/plugins/dynamix.plugin.manager/include/UnraidUpdateCancel.php
deleted file mode 100644
index 6180dd041..000000000
--- a/emhttp/plugins/dynamix.plugin.manager/include/UnraidUpdateCancel.php
+++ /dev/null
@@ -1,60 +0,0 @@
-PLG_FILENAME = "unRAIDServer.plg";
- $this->PLG_BOOT = "/boot/config/plugins/{$this->PLG_FILENAME}";
- $this->PLG_VAR = "/var/log/plugins/{$this->PLG_FILENAME}";
- $this->USR_LOCAL_PLUGIN_UNRAID_PATH = "/usr/local/emhttp/plugins/unRAIDServer";
-
- // Handle the cancellation
- $revertResult = $this->revertFiles();
- // Return JSON response for front-end client
- $statusCode = $revertResult['success'] ? 200 : 500;
- http_response_code($statusCode);
- header('Content-Type: application/json');
- echo json_encode($revertResult);
- }
-
- public function revertFiles() {
- try {
- $command = '/sbin/mount | grep -q "/boot/previous/bz"';
- exec($command, $output, $returnCode);
-
- if ($returnCode !== 0) {
- return ['success' => true]; // Nothing to revert
- }
-
- // Clear the results of previous unraidcheck run
- @unlink("/tmp/unraidcheck/result.json");
-
- // Revert changes made by unRAIDServer.plg
- shell_exec("mv -f /boot/previous/* /boot");
- unlink($this->PLG_BOOT);
- unlink($this->PLG_VAR);
- symlink("{$this->USR_LOCAL_PLUGIN_UNRAID_PATH}/{$this->PLG_FILENAME}", $this->PLG_VAR);
-
- // Restore README.md by echoing the content into the file
- $readmeFile = "{$this->USR_LOCAL_PLUGIN_UNRAID_PATH}/README.md";
- $readmeContent = "**Unraid OS**\n\n";
- $readmeContent .= "Unraid OS by [Lime Technology, Inc.](https://lime-technology.com).\n";
- file_put_contents($readmeFile, $readmeContent);
-
- return ['success' => true]; // Upgrade handled successfully
- } catch (\Throwable $th) {
- return [
- 'success' => false,
- 'message' => $th->getMessage(),
- ];
- }
- }
-}
-
-// Self instantiate the class and handle the cancellation
-new UnraidUpdateCancel();
diff --git a/emhttp/plugins/dynamix.plugin.manager/scripts/unraidcheck b/emhttp/plugins/dynamix.plugin.manager/scripts/unraidcheck
deleted file mode 100755
index 81cb3ea58..000000000
--- a/emhttp/plugins/dynamix.plugin.manager/scripts/unraidcheck
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/usr/bin/php -q
-
-
-$docroot ??= ($_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp');
-
-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/emhttp/plugins/dynamix/include/ReplaceKey.php b/emhttp/plugins/dynamix/include/ReplaceKey.php
deleted file mode 100644
index d180d92f2..000000000
--- a/emhttp/plugins/dynamix/include/ReplaceKey.php
+++ /dev/null
@@ -1,237 +0,0 @@
-docroot = $GLOBALS['docroot'] ?? $_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp';
-
- $this->var = (array)@parse_ini_file('/var/local/emhttp/var.ini');
- $this->guid = @$this->var['regGUID'] ?? null;
-
- $keyfileBase64 = empty($this->var['regFILE']) ? null : @file_get_contents($this->var['regFILE']);
- if ($keyfileBase64 !== false) {
- $keyfileBase64 = @base64_encode($keyfileBase64);
- $this->keyfile = str_replace(['+', '/', '='], ['-', '_', ''], trim($keyfileBase64));
- }
-
- $this->regExp = @$this->var['regExp'] ?? null;
- }
-
- private function request($url, $method, $payload = null, $headers = null)
- {
- $ch = curl_init($url);
-
- // Set the request method
- curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
- // store the response in a variable instead of printing it
- curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
-
- // Set the payload if present
- if ($payload !== null) {
- curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
- }
-
- if ($headers !== null) {
- // Set the headers
- curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
- }
-
- // Set additional options as needed
-
- // Execute the request
- $response = curl_exec($ch);
-
- // Check for errors
- if (curl_errno($ch)) {
- $error = [
- 'heading' => 'CurlError',
- 'message' => curl_error($ch),
- 'level' => 'error',
- 'ref' => 'curlError',
- 'type' => 'request',
- ];
- // @todo store error
- }
-
- // Close the cURL session
- curl_close($ch);
-
- return $response;
- }
-
- private function validateGuid()
- {
- $headers = [
- 'Content-Type: application/x-www-form-urlencoded',
- ];
-
- $params = [
- 'guid' => $this->guid,
- 'keyfile' => $this->keyfile,
- ];
-
- /**
- * returns {JSON}
- * hasNewerKeyfile : boolean;
- * purchaseable: true;
- * registered: false;
- * replaceable: false;
- * upgradeable: false;
- * upgradeAllowed: string[];
- * updatesRenewable: false;
- */
- $response = $this->request(
- self::KEY_SERVER_URL . '/validate/guid',
- 'POST',
- http_build_query($params),
- $headers,
- );
-
- // Handle the response as needed (parsing JSON, etc.)
- $decodedResponse = json_decode($response, true);
-
- if (!empty($decodedResponse)) {
- return $decodedResponse;
- }
-
- // @todo save error response somewhere
- return [];
- }
-
- private function getLatestKey()
- {
- $headers = [
- 'Content-Type: application/x-www-form-urlencoded',
- ];
-
- $params = [
- 'keyfile' => $this->keyfile,
- ];
-
- /**
- * returns {JSON}
- * license: string;
- */
- $response = $this->request(
- self::KEY_SERVER_URL . '/key/latest',
- 'POST',
- http_build_query($params),
- $headers,
- );
-
- // Handle the response as needed (parsing JSON, etc.)
- $decodedResponse = json_decode($response, true);
-
- if (!empty($decodedResponse) && !empty($decodedResponse['license'])) {
- return $decodedResponse['license'];
- }
- return null;
- }
-
- private function installNewKey($key)
- {
- require_once "$this->docroot/webGui/include/InstallKey.php";
-
- $KeyInstaller = new KeyInstaller();
- $installResponse = $KeyInstaller->installKey($key);
-
- $installSuccess = false;
-
- if (!empty($installResponse)) {
- $decodedResponse = json_decode($installResponse, true);
- if (isset($decodedResponse['error'])) {
- $this->writeJsonFile(
- '/tmp/ReplaceKey/error.json',
- [
- 'error' => $decodedResponse['error'],
- 'ts' => time(),
- ]
- );
- $installSuccess = false;
- } else {
- $installSuccess = true;
- }
- }
-
- $keyType = basename($key, '.key');
- $output = isset($GLOBALS['notify']) ? _var($GLOBALS['notify'],'plugin') : '';
- $script = '/usr/local/emhttp/webGui/scripts/notify';
-
- if ($installSuccess) {
- $event = "Installed New $keyType License";
- $subject = "Your new $keyType license key has been automatically installed";
- $description = "";
- $importance = "normal $output";
- } else {
- $event = "Failed to Install New $keyType License";
- $subject = "Failed to automatically install your new $keyType license key";
- $description = isset($decodedResponse['error']) ? $decodedResponse['error'] : "Unknown error occurred";
- $importance = "alert $output";
- }
-
- exec("$script -e ".escapeshellarg($event)." -s ".escapeshellarg($subject)." -d ".escapeshellarg($description)." -i ".escapeshellarg($importance)." -l '/Tools/Registration' -x");
-
- return $installSuccess;
- }
-
- private function writeJsonFile($file, $data)
- {
- if (!is_dir(dirname($file))) {
- mkdir(dirname($file));
- }
-
- file_put_contents($file, json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES));
- }
-
- public function check(bool $forceCheck = false)
- {
- // we don't need to check
- if (empty($this->guid) || empty($this->keyfile) || empty($this->regExp)) {
- return;
- }
-
- // Check if we're within the 7-day window before and after regExp
- $now = time();
- $sevenDaysBefore = strtotime('-7 days', $this->regExp);
- $sevenDaysAfter = strtotime('+7 days', $this->regExp);
-
- $isWithinWindow = ($now >= $sevenDaysBefore && $now <= $sevenDaysAfter);
-
- if (!$forceCheck && !$isWithinWindow) {
- return;
- }
-
- // see if we have a new key
- $validateGuidResponse = $this->validateGuid();
-
- $hasNewerKeyfile = @$validateGuidResponse['hasNewerKeyfile'] ?? false;
- if (!$hasNewerKeyfile) {
- return; // if there is no newer keyfile, we don't need to do anything
- }
-
- $latestKey = $this->getLatestKey();
- if (!$latestKey) {
- // we supposedly have a new key, but didn't get it back…
- $this->writeJsonFile(
- '/tmp/ReplaceKey/error.json',
- [
- 'error' => 'Failed to retrieve latest key after getting a `hasNewerKeyfile` in the validation response.',
- 'ts' => time(),
- ]
- );
- return;
- }
-
- $this->installNewKey($latestKey);
- }
-}
diff --git a/emhttp/plugins/dynamix/include/UpdateDNS.php b/emhttp/plugins/dynamix/include/UpdateDNS.php
deleted file mode 100644
index c33893561..000000000
--- a/emhttp/plugins/dynamix/include/UpdateDNS.php
+++ /dev/null
@@ -1,22 +0,0 @@
-
-
-// This is a stub, does nothing but return success
-$cli = php_sapi_name()=='cli';
-if ($cli) {
- exit("success".PHP_EOL);
-}
-header('Content-Type: application/json');
-http_response_code(204);
-exit(0);
-?>