# Known Issues & Patches Upstream Atheos is an actively-moving project with **no releases**, and its plugin market ships plugins that are **ports from Codiad** (Atheos's predecessor). Two of those plugins use APIs that Atheos has since removed or changed. This file records what we hit, what we changed, and why the fix is done the way it is. Pinned Atheos commit: `f90cd1806dbe0e25673a77e27390e8b1a240c3f6` (build 611). --- ## 1. ๐Ÿ”ด Plugin market: the **Terminal** plugin does not work as shipped **Symptom:** installed the Terminal plugin from the market; it failed / did not function. **Root cause โ€” a removed API.** `plugins/Terminal/terminal.php` calls `Common::execute(...)`, which **no longer exists** in Atheos (it was renamed): ``` plugin calls : Common::execute(...) -> MISSING available : Common::raw_execute(...) -> returns ["code" => int, "output" => array] Common::safe_execute(...) ``` The plugin's header says it is a port of `Fluidbyte/Codiad-Terminal`, so it targets the old API. Its return-shape assumption is also stale (the old `execute()` returned `text`; `raw_execute()` returns `output` as an array). **Fix applied** (`patches/Terminal-terminal.php.patched`): ```diff - $output = Common::execute("pwd"); + $output = Common::raw_execute("pwd"); - $_SESSION["activeDir"] = array([$_SESSION["project"]] => $output["text"]); + $_SESSION["activeDir"] = array([$_SESSION["project"]] => implode("\n", (array)$output["output"])); - $output = Common::execute($cmd); - return $output["text"]; + $output = Common::raw_execute($cmd); + return implode("\n", (array)$output["output"]); ``` **Verified** against the real method (`php83 -l` clean; both call patterns exercised): | Call | Result | |---|---| | `raw_execute("pwd")` | `code=0`, `output=["/root",""]` | | `raw_execute("echo ...")` | `code=0`, returns the text | | after `chdir` to the repo | returns `/var/www/atheos/workspace/blog` โ€” so the terminal opens in the blog | **Re-apply after an Atheos update** โ€” `scripts/update-atheos.sh` replaces the application files, so this patch is lost on update. Re-apply it, or drop the plugin. ### Two further defects in the same plugin (NOT fixed โ€” upstream, and mostly harmless) 1. **`terminal.php:95`** โ€” `$blocked = explode(",", BLOCKED === true);` passes a **boolean** to `explode()`. This evaluates to `explode(",", false)`, so the intended block-list (`define("BLOCKED","ssh,telnet")`) **never actually blocks anything**. The plugin's own guard is dead code. Cosmetic in effect (the command would just fail on its own), but worth knowing rather than trusting. 2. **`terminal.php:124`** โ€” `if (strtolower($command === "exit"))` passes a boolean to `strtolower()`. Should be `strtolower($command) === "exit"`. Result: typing `exit` does not clear `term_auth`; the session stays authenticated until the browser session ends. Left as-is: they are upstream bugs, and fixing them changes the plugin's behaviour beyond the minimum needed to make it run. Recorded here so nobody "fixes" them by accident or trusts the block-list. ### โš ๏ธ Security note This plugin gives a **browser terminal that executes shell commands as the php-fpm user** (`atheos`) โ€” and its own password gate is a **hardcoded, in-app constant**: ```php define("PASSWORD", "terminal"); // terminal.php:24 โ€” you type this once per session ``` It is not a stored credential, but it is not a secret either: anyone who reaches the Login page can look up the source and unlock it. **This is the strongest argument yet for keeping the container LAN-only.** It also means plugin installation should be treated as a **privilege decision**, not a convenience one โ€” see `docs/security-notes.md` ยง2 (S-7 covers disabling `exec`/`proc_open`, which would neutralise macros *and* this plugin). --- ## 2. ๐ŸŸ  The Macro dialog crashed when folder-scoped macros existed **Symptom:** the Settings โ†’ Macro dialog returned HTTP 500. **Root cause โ€” invalid data by Atheos's own design.** `components/macro/dialog.php:35` does: ```php implode(", ", $macro["fTypes"]) // requires an ARRAY ``` but `components/macro/class.macro.php` `save()` writes the **string** `"N/A"` for folder macros: ```php "fTypes" => $type === "file" ? explode(",", $fTypes) : "N/A", ``` So **any folder-type macro** makes that dialog fatal: ``` PHP Fatal error: Uncaught TypeError: implode(): Argument #2 ($array) must be of type ?array, string given in /var/www/atheos/components/macro/dialog.php:35 ``` **Fix applied โ€” correct the DATA, not Atheos's code.** The stored `fTypes` for folder macros is now `[]` (an empty array) instead of `"N/A"`: ```sh sed -i 's/"fTypes": "N\/A"/"fTypes": []/g' /var/www/atheos/data/macros.db.php ``` Verified: `implode()` now succeeds for all 8 macros. **Why data rather than code:** patching `dialog.php` would be overwritten by `update-atheos.sh` (and by any Atheos update), whereas valid data keeps working. The trade-off is that the UI's own "save" path could re-introduce `"N/A"` if a macro is edited in the UI โ€” see the follow-up below. **Follow-up (not done):** the real upstream fix is `$type === "file" ? explode(",", $fTypes) : []` in `class.macro.php::save()`. Applying it would stop the UI re-introducing the bad value, at the cost of a patch that must be re-applied after updates. Worth doing if the dialog starts 500-ing again after editing a macro in the UI. --- ## 3. Checking for plugin problems in future The plugin's JS is bundled into `public/plugins.min.js` (built by `classes/sourcemanager.php`), and its rightbar button is rendered by `components/sidebars/sb-right.php` from `plugin.json`. Both were verified working: ``` plugins.min.js contains 'plugins/Terminal/init.js' -> YES (bundle is fine) rightbar HTML -> Terminal ``` So when a plugin misbehaves, check in this order: ```sh # 1. did it install? tail /var/www/atheos/data/log/market.log.php # 2. is its JS in the served bundle? grep -c "plugins//init.js" /var/www/atheos/public/plugins.min.js # 3. is it a stale-API port? (Codiad-era plugins are the risk) grep -rhoE 'Common::[a-zA-Z_]+' /var/www/atheos/plugins// | sort -u # then check each exists: grep -rn "function " /var/www/atheos/common.php /var/www/atheos/traits/ # 4. is there a PHP fatal? grep -E 'PHP Fatal' /var/log/nginx/atheos.error.log | tail ``` **Rule of thumb:** if a plugin was ported from Codiad, assume its `Common::` calls are stale and verify them before trusting it.