diff --git a/.gitignore b/.gitignore index 00329bc..de36060 100755 --- a/.gitignore +++ b/.gitignore @@ -16,6 +16,7 @@ caches/last_settings_migrate_run /storage/caches/*.json /storage/caches/*.txt /storage/caches/*.log +/storage/caches/*.mfa /storage/caches/*/ /storage/logs/*.log /storage/frontend/node_modules diff --git a/app/LEGAL_STUFF.md b/app/LEGAL_STUFF.md new file mode 100644 index 0000000..928dd9b --- /dev/null +++ b/app/LEGAL_STUFF.md @@ -0,0 +1,74 @@ + +# MythicalSystems End User License Agreement (EULA) + +This End User License Agreement ("EULA") constitutes a binding legal agreement between you ("the User") and MythicalSystems Ltd. or its applicable local affiliates (collectively referred to as "MythicalSystems"). + +By accessing or using any MythicalSystems services, software, or content ("Services"), you acknowledge that you have read, understood, and agree to be bound by the terms and conditions of this EULA and the MythicalSystems Services Agreement. Please read these terms carefully. + +## 1. Scope of Agreement + +This EULA, together with the MythicalSystems Services Agreement, governs your use of all MythicalSystems websites, software, products, and services, including any updates, patches, or modifications that may be provided in the future. By accepting these terms, you also agree to abide by any supplemental policies, including but not limited to our community standards and Software Usage Guidelines, which may be updated from time to time. + +## 2. Ownership and Intellectual Property + +While MythicalSystems values your creative contributions, we retain exclusive ownership of all proprietary software, code, content, and intellectual property developed by us. You are granted a non-exclusive, non-transferable, and revocable license to use our Services in accordance with this EULA. + +Your original works, including plugins, themes, and modifications, remain your property, provided they do not incorporate a substantial portion of MythicalSystems' code or intellectual property. MythicalSystems does not claim ownership of your original creations, but we reserve the right to determine whether content contains infringing elements. + +### 2.1 Restrictions on Distribution + +You are expressly prohibited from distributing, sublicensing, or commercially exploiting any MythicalSystems software, content, or services without prior written consent from MythicalSystems. This includes but is not limited to sharing, copying, or reselling our products, software, and any related modifications or derivatives. + +## 3. Account Usage and Terms + +A MythicalSystems account is required to access certain features, purchase services, or interact with MythicalSystems platforms. You are responsible for maintaining the security and confidentiality of your account credentials. If you acquire any MythicalSystems product via a third-party platform (e.g., Spigot or BuiltByBit), the respective terms of that platform will also apply in conjunction with this EULA. + +MythicalSystems reserves the right to suspend or terminate accounts that are in breach of this EULA or related agreements. + +## 4. Permitted Modifications (Plugins and Themes) + +We encourage the development of plugins, themes, and other creative contributions, subject to the following conditions: + +- **Plugins and Themes must not contain significant portions of MythicalSystems' proprietary code.** +- **Originality:** Any plugin or theme created by you must be your own original work. +- **Commercial Restrictions:** You are not permitted to sell plugins or themes for excessive or inflated prices. Nulled or unauthorized versions of plugins and themes are strictly forbidden. +- **Compatibility:** MythicalSystems assumes no responsibility for ensuring that your plugins or themes will be compatible with future updates or modifications to our Services. + +We reserve the right to review, approve, or revoke permissions for plugins and themes at any time. + +## 5. Content Ownership + +Your content remains your own, including any text, images, or code that you develop independently. However, MythicalSystems retains ownership of any substantial derivative works or content that incorporates or mimics our proprietary software, designs, or materials. + +For example: + +- If your plugin consists of less than 100 lines of code based on MythicalSystems' core code, we maintain ownership of that derivative work. +- If you create a standalone plugin with significant new functionality (e.g., Discord integration) containing over 400 lines of code, you retain ownership of that original creation. + +## 6. Community Standards and Online Safety + +MythicalSystems is committed to fostering a safe, respectful, and inclusive community. As a user of our Services, you agree to uphold these values and avoid engaging in any activities that promote hate speech, harassment, violence, or illegal conduct. Fraudulent behavior, such as using deceit or misrepresentation for personal gain, is strictly prohibited. + +Interactions with others through our Services, third-party platforms, or community forums are at your own risk. We advise caution when sharing personal information or communicating with others, as MythicalSystems cannot guarantee the authenticity or integrity of third-party participants. + +We reserve the right to suspend or permanently ban any user who violates these standards or any other terms of this EULA. + +## 7. Legal Compliance and Amendments + +This EULA and any supplemental policies may be updated or amended by MythicalSystems at any time, without prior notice. It is your responsibility to review these terms periodically to ensure compliance. Continued use of MythicalSystems' Services after changes to the EULA signifies your acceptance of the revised terms. + +## 8. Limitation of Liability + +To the fullest extent permitted by law, MythicalSystems shall not be held liable for any indirect, incidental, or consequential damages resulting from the use or inability to use our Services, including but not limited to lost profits, data loss, or compatibility issues arising from third-party plugins or updates. + +## 9. Termination + +Failure to comply with this EULA may result in immediate termination of your license and access to MythicalSystems' Services. MythicalSystems reserves the right to terminate or suspend access to any account, service, or content without notice if the User violates any provision of this EULA. + +## 10. Governing Law + +This EULA shall be governed by and construed in accordance with the laws of the jurisdiction in which MythicalSystems Ltd. is established, without regard to conflicts of law principles. Any disputes arising from this EULA shall be resolved in the courts of that jurisdiction. + +## 11. Contact Information + +For any questions regarding this EULA or MythicalSystems' Services, please contact us at `abuse@mythicalsystems.xyz`. \ No newline at end of file diff --git a/app/Plugins/PluginCompilerHelper.php b/app/Plugins/PluginCompilerHelper.php index 72199f9..32c45d4 100755 --- a/app/Plugins/PluginCompilerHelper.php +++ b/app/Plugins/PluginCompilerHelper.php @@ -585,39 +585,19 @@ public static function removeGhostPermissions(): void } } } - - /** - * @deprecated Do not use this method. It is not implemented yet. - */ - public static function installJavaPlugin(): void - { - } - /** - * @deprecated Do not use this method. It is not implemented yet. + * Get the buttons for a plugin. + * + * @param mixed $plugin_name The name of the plugin + * + * @return array The buttons */ - public static function installPythonPlugin(): void - { - } - - /** - * @deprecated Do not use this method. It is not implemented yet. - */ - public static function installRubyPlugin(): void - { - } - - /** - * @deprecated Do not use this method. It is not implemented yet. - */ - public static function installNodePlugin(): void - { - } - - /** - * @deprecated Do not use this method. It is not implemented yet. - */ - public static function installGoPlugin(): void - { + public static function getButtons($plugin_name) : array { + $plugin_info = self::readPluginFile($plugin_name); + $buttons = []; + if (isset($plugin_info['buttons'])) { + $buttons = $plugin_info['buttons']; + } + return $buttons; } } diff --git a/app/Web/Routes/admin/addons.php b/app/Web/Routes/admin/addons.php index 3b1d18f..27acff5 100755 --- a/app/Web/Routes/admin/addons.php +++ b/app/Web/Routes/admin/addons.php @@ -16,10 +16,63 @@ use MythicalSystemsFramework\Web\Template\Engine; use MythicalSystemsFramework\User\UserDataHandler; use MythicalSystemsFramework\CloudFlare\CloudFlare; +use MythicalSystemsFramework\Kernel\Debugger; use MythicalSystemsFramework\User\Activity\UserActivity; +use MythicalSystemsFramework\Plugins\Database as PluginDB; global $router; +$router->add('/admin/plugins/(.*)/delete', function (string $id): void { + global $router, $event, $renderer; + if (isset($_COOKIE['token']) === false) { + exit(header('location: /auth/login')); + } + + $user = new UserHelper($_COOKIE['token'], $renderer); + UserDataHandler::requireAuthorization($renderer, $_COOKIE['token']); + $uuid = UserDataHandler::getSpecificUserData($_COOKIE['token'], 'uuid', false); + + if ( + !UserDataHandler::hasPermission($_COOKIE['token'], 'mythicalframework.admin.plugins.delete') + ) { + exit(header('location: /errors/403')); + } + + if (MythicalSystemsFramework\Plugins\Database::doesPluginExistID($id) == false) { + exit(header('location: /admin/plugins?s=not_found')); + } + $plugin_name = MythicalSystemsFramework\Plugins\Database::getPluginNameById($id); + UserActivity::addActivity($uuid, 'Disabled the plugin: (' . $plugin_name . ')', CloudFlare::getRealUserIP(), 'plugin:disabled'); + MythicalSystemsFramework\Plugins\PluginsManager::disablePlugin($plugin_name); + + function deleteDirectory($dir) { + if (!file_exists($dir)) { + return true; + } + + if (!is_dir($dir)) { + return unlink($dir); + } + + foreach (scandir($dir) as $item) { + if ($item == '.' || $item == '..') { + continue; + } + + if (!deleteDirectory($dir . DIRECTORY_SEPARATOR . $item)) { + return false; + } + } + + return rmdir($dir); + } + + $pluginDir = __DIR__ . '/../../../../storage/addons/' . $plugin_name; + deleteDirectory($pluginDir); + + exit(header('location: /admin/plugins?s=ok')); +}); + $router->add('/admin/plugins/upload', function (): void { global $router, $event, $renderer; $template = 'admin/plugins/upload.twig'; @@ -38,6 +91,7 @@ $renderer->addGlobal('page_name', 'Upload Plugin'); Engine::registerAlerts($renderer, $template); + Debugger::ShowAllErrors(); if ($_SERVER['REQUEST_METHOD'] === 'POST') { if (isset($_FILES['pluginFile']) && $_FILES['pluginFile']['error'] === UPLOAD_ERR_OK) { @@ -45,28 +99,50 @@ $fileName = $_FILES['pluginFile']['name']; $fileSize = $_FILES['pluginFile']['size']; $fileType = $_FILES['pluginFile']['type']; + if (file_exists($fileTmpPath) === false) { + exit(header('location: /admin/plugins?e=error')); + } + $fileNameCmps = explode(".", $fileName); + if (count($fileNameCmps) === 0) { + exit(header('location: /admin/plugins?e=error')); + } + if (PluginDB::doesInfoExist("name",$fileNameCmps[0])) { + exit(header('location: /admin/plugins?e=plugin_already_exists')); + } + $fileExtension = strtolower(end($fileNameCmps)); if ($fileExtension === 'mfa') { - // Process the file upload (e.g., move to the desired directory) - $uploadFileDir = '/path/to/upload/directory/'; + $uploadFileDir = __DIR__.'/../../../../storage/addons/'; $dest_path = $uploadFileDir . $fileName; - + $dest_path = $uploadFileDir . basename($fileName); if (move_uploaded_file($fileTmpPath, $dest_path)) { + $newFileName = pathinfo($fileName, PATHINFO_FILENAME) . '.zip'; + rename($dest_path, $uploadFileDir . $newFileName); + $newFileName = $uploadFileDir . $newFileName; + $zip = new ZipArchive; + $zip->open($newFileName); + $zip->extractTo($dest_path); + $zip->close(); + unlink($newFileName); + $newFolderName = pathinfo($fileName, PATHINFO_FILENAME); + rename($dest_path, $uploadFileDir . $newFolderName); exit(header('location: /admin/plugins?s=ok')); } else { - exit(header('location: /admin/plugins?s=error')); + exit(header('location: /admin/plugins?e=error')); } + } else { - $renderer->addGlobal('error', 'Invalid file type. Only .mfa files are allowed.'); + exit(header('location: /admin/plugins?e=error')); } } else { - $renderer->addGlobal('error', 'There was an error with the file upload.'); + exit(header('location: /admin/plugins?e=error')); } + } else { + exit(header('location: /admin/plugins')); } - exit($renderer->render($template)); }); $router->add('/admin/plugins', function (): void { @@ -92,6 +168,14 @@ $plugins = MythicalSystemsFramework\Plugins\Database::getAllPlugins(); $renderer->addGlobal('plugins', $plugins); $renderer->addGlobal('page_name', 'Plugins'); + $renderer->addFunction(new Twig\TwigFunction('getButtons', function ($id) { + $plugin_name = MythicalSystemsFramework\Plugins\Database::getPluginNameById($id); + if ($plugin_name == null) { + return null; + } + return MythicalSystemsFramework\Plugins\PluginsManager::getButtons($plugin_name); + })); + Engine::registerAlerts($renderer, $template); exit($renderer->render($template)); }); diff --git a/app/Web/Routes/admin/legal.php b/app/Web/Routes/admin/legal.php new file mode 100644 index 0000000..9ea3d35 --- /dev/null +++ b/app/Web/Routes/admin/legal.php @@ -0,0 +1,40 @@ + - All rights reserved + * (c) NaysKutzu - All rights reserved + * (c) Cassian Gherman - All rights reserved + * + * You should have received a copy of the MIT License + * along with this program. If not, see . + */ + +use MythicalSystemsFramework\Kernel\Logger; +use MythicalSystemsFramework\User\UserHelper; +use MythicalSystemsFramework\Web\Template\Engine; +use MythicalSystemsFramework\User\UserDataHandler; + +global $router; + +$router->add('/admin/legal', function (): void { + global $router, $event, $renderer; + $template = 'admin/legal.twig'; + if (isset($_COOKIE['token']) === false) { + exit(header('location: /auth/login')); + } + + $user = new UserHelper($_COOKIE['token'], $renderer); + UserDataHandler::requireAuthorization($renderer, $_COOKIE['token']); + + $renderer->addGlobal('page_name', 'Legal'); + + Engine::registerAlerts($renderer, $template); + $content = file_get_contents(__DIR__.'/../../../LEGAL_STUFF.md'); + + $renderer->addGlobal('content', $content); + + + exit($renderer->render($template)); +}); diff --git a/app/Web/Template/Engine.php b/app/Web/Template/Engine.php index 9044d0c..e4b80a3 100755 --- a/app/Web/Template/Engine.php +++ b/app/Web/Template/Engine.php @@ -268,6 +268,10 @@ public static function registerAlerts(Environment $renderer, string $template_na $error_title = self::getError('NoPermission.Title'); $error_message = self::getError('NoPermission.Message'); break; + case 'plugin_already_exists': + $error_title = self::getError('PluginAlreadyExists.Title'); + $error_message = self::getError('PluginAlreadyExists.Message'); + break; default: $error_title = self::getError('UnknownError.Title'); $error_message = self::getError('UnknownError.Message'); diff --git a/storage/lang/en_US.yml b/storage/lang/en_US.yml index 4189890..c717193 100755 --- a/storage/lang/en_US.yml +++ b/storage/lang/en_US.yml @@ -616,3 +616,6 @@ Alerts: UnknownError: Title: "Unknown Error" Message: "An unknown error occurred. Please try again." + PluginAlreadyExists: + Title: "Plugin Already exists" + Message: "The plugin already exists. Please try again." \ No newline at end of file diff --git a/storage/themes/v2/admin/lang/editor.twig b/storage/themes/v2/admin/lang/editor.twig index 3c4438f..fd2abbf 100755 --- a/storage/themes/v2/admin/lang/editor.twig +++ b/storage/themes/v2/admin/lang/editor.twig @@ -26,6 +26,7 @@ + + + +{% endblock %} diff --git a/storage/themes/v2/admin/plugins/list.twig b/storage/themes/v2/admin/plugins/list.twig index 3d296fe..a85587e 100755 --- a/storage/themes/v2/admin/plugins/list.twig +++ b/storage/themes/v2/admin/plugins/list.twig @@ -66,6 +66,9 @@ {% if plugin.enabled == "true" %} + {% for button in getButtons(plugin.id) %} + + {% endfor %} {% else %} diff --git a/storage/themes/v2/components/sidebar.twig b/storage/themes/v2/components/sidebar.twig index 874fd26..33d9b50 100755 --- a/storage/themes/v2/components/sidebar.twig +++ b/storage/themes/v2/components/sidebar.twig @@ -37,6 +37,12 @@ + {% if hasPermission("mythicalframework.admin.ticket.view") or hasPermission("mythicalframework.admin.ticket.create") or hasPermission("mythicalframework.admin.ticket.reply") or hasPermission("mythicalframework.admin.ticket.delete") %}