# CodePress CMS v2.6.5 — Release Notes **Release datum:** 2026-08-27 **Codename:** Lyra **Status:** stable --- ## Samenvatting Deze release richt zich op **dynamische pad-resolutie**, **volledige code-documentatie** en een **belangrijke security-fix** rond het standaard admin-wachtwoord. Daarnaast is de git-geschiedenis schoongemaakt van kraakbare wachtwoord-hashes die per ongeluk gecommit waren. --- ## Nieuwe features & wijzigingen ### 1. Dynamische pad-resolutie via de Plugin-API Eerder gaf `AdminPluginAPI::getContentDir()` een relatief pad ("content") terug zonder dat te normaliseren tegen de project-root. Omdat Apache `admin.php` uit de `public/` map draait, resolvedde dat relatieve pad naar `public/content` (niet-bestaand) → het dashboard toonde 0 pagina's, 0 mappen en 0 B aan content. Nu: - `PluginAPIInterface` definieert universele pad-methodes (`getProjectRoot()`, `getContentDir()`, `getPluginsDir()`, `getVersionInfo()`) die door zowel `CMSAPI` (frontend) als `AdminPluginAPI` (admin) worden geïmplementeerd. - `AdminPluginAPI::getContentDir()` normaliseert relatieve paden tegen de project-root (met Windows-drive-letter detectie), conform `cms/core/config.php`. - `CMSAPI` heeft deze methodes erbij gekregen (deze ontbraken op de frontend-API). - `public/index.php` media-/assets-serving gebruikt `$config['content_dir']` i.p.v. een hardcoded `/content` pad, zodat een aangepaste `content_dir` in `config.json` wordt gevolgd. - De `Navigation` plugin haalt de content-root via `$this->api->getContentDir()` i.p.v. hardcoded `dirname(__DIR__, 2)`; de guide-root via `getProjectRoot()`. - De `Logs` plugin haalt de log-dir via `$this->api->getProjectRoot()` i.p.v. hardcoded `dirname(__DIR__, 2)`. ### 2. WordPress-stijl code-documentatie Alle classes, methods, properties en functies in de codebase zijn voorzien van volledige docblocks in WordPress-stijl (~450 docblocks): ``` /** * Summary. * * Description. * * @since 2.6.5 * * @param type $var Description. * @param array $args { * Optional. An array of arguments. * * @type type $key Description. Default 'value'. Accepts 'value', 'value'. * @type type $key Description. * } * @param type $var Description. * @return type Description. */ ``` Behandelde bestanden: `AdminAuth`, `Cache`, `RateLimiter`, `RequestLogger`, `Analytics`, `BotGuard`, `ContentBackup`, `GeoIP`, `Logger`, `LogManager`, `ThemeManager`, `CodePressCMS`, `PluginAPIInterface`, `CMSAPI`, `AdminPluginAPI`, `PluginManager`, alle 6 plugins, `public/admin.php` (82 functies), en de entrypoints/CLI-bestanden. --- ## Security fixes ### 3. Hardcoded plaintext-wachtwoord verwijderd In `admin/src/AdminAuth.php` stond het standaard-wachtwoord letterlijk in de broncode: ```php 'password_hash' => password_hash('admin', PASSWORD_BCRYPT), ``` Deze fallback draaide bij een nieuwe installatie wanneer zowel `admin.json` als `admin.json.example` ontbraken. Het wachtwoord `'admin'` was hierdoor in de gecommitte broncode zichtbaar. Nu: - Bij eerste installatie wordt een **cryptografisch veilig willekeurig wachtwoord** gegenereerd (`random_bytes`, 16 alfanumerieke tekens). - De bcrypt-hash wordt weggeschreven naar `admin/config/admin.json`. - Het plaintext wachtwoord wordt **eenmalig** op het inlogscherm getoond via een waarschuwing, zodat de beheerder het kan noteren. - Na de eerste succesvolle login is het wachtwoord nergens meer in plaintext opgeslagen. Nieuwe methodes in `AdminAuth`: - `generateRandomPassword(int $length = 16): string` — CSPRNG-gebaseerd. - `getGeneratedPassword(): string` — geeft het gegenereerde wachtwoord terug voor weergave op de login-pagina. ### 4. Git-geschiedenis schoongemaakt Bij eerdere commits (`d97c67c`, `b8d4a4e`, `5884877`) was `admin/config/admin.json` per ongeluk gecommit voordat het bestand gitignored werd. Dit bestand bevatte een bcrypt-hash die kraakt naar het wachtwoord `'admin'`. Ook `admin/config/admin.json.example` (gecommit) en het oude `admin-console/config/admin.json` pad bevatten dergelijke hashes. Uitgevoerd: - `git filter-branch` om `admin/config/admin.json`, `admin/config/admin.json.example` en `admin-console/config/admin.json` te verwijderen uit **alle commits** op alle branches en tags. - `reflog expire --expire=now --all` + `gc --prune=now --aggressive` om oude objecten te verwijderen. - Verificatie: beide bekende hashes (`nUpoaCNZZ...`, `CV2uORTI...`) en `password_hash('admin'` komen 0× voor in de hele object-database. ### 5. admin.json.example verwijderd Het gecommitte `admin/config/admin.json.example` bevatte een geldige bcrypt-hash (kraakt naar `'admin'`). Omdat de `AdminAuth`-fallback nu zelf een veilig wachtwoord genereert, is het example-bestand overbodig geworden en verwijderd uit de repo. --- ## Bijgewerkte documentatie - `README.md` en `README.en.md`: installatie-stappen herschreven (geen `admin.json.example` kopie-stap meer; verwijzing naar `admin`/`admin` inlog verwijderd; uitleg over automatisch gegenereerd wachtwoord bij eerste installatie). - `AGENTS.md`: admin-inlog beschrijving bijgewerkt. - `TODO.md`: v2.6.5 entry toegevoegd. --- ## Onder de motorkap | Bestand | Wijziging | |---|---| | `cms/core/plugin/PluginAPIInterface.php` | Universele pad-methodes toegevoegd | | `cms/core/plugin/CMSAPI.php` | `getProjectRoot`/`getContentDir`/`getPluginsDir`/`getVersionInfo` toegevoegd | | `cms/core/plugin/AdminPluginAPI.php` | `getContentDir` normaliseert relatieve paden | | `public/index.php` | Media-serving via `$config['content_dir']` | | `plugins/Navigation/Navigation.php` | Content/guide-root via de API | | `plugins/Logs/Logs.php` | Log-dir via de API | | `admin/src/AdminAuth.php` | Random-wachtwoord-generator + `getGeneratedPassword` | | `admin/theme/default/views/login.twig` | Waarschuwing bij eerste installatie | | `version.php` | 2.6.4 → 2.6.5 | | `README.md`, `README.en.md`, `AGENTS.md`, `TODO.md` | Docs bijgewerkt | | ~20 PHP-bestanden | WordPress-stijl docblocks toegevoegd | --- ## Tests uitgevoerd - `php -l` over alle 67 PHP-bestanden (zonder vendor): 0 syntax-errors. - Apache smoke-test: login (nieuw wachtwoord), dashboard (4 pagina's / 2 mappen / 282 KB), content, users, plugins, logs, guide, homepage, pagina en media-serving allen HTTP 200. - Inloggen met oud wachtwoord `admin` werkt niet meer. - Eerste-installatie flow getest: bij afwezigheid van `admin.json` wordt een nieuw wachtwoord gegenereerd en op het inlogscherm getoond. - Git-historie: beide oude hashes en `password_hash('admin'` 0× aanwezig in `git log --all -p`. --- ## Upgrade-instructies 1. Pull de nieuwe versie. 2. Als je nog met het standaard-wachtwoord `admin` inlogt: wijzig het direct na upgrade via de admin-interface of `php cli/reset-admin-password.php admin `. 3. optioneel: verwijder `admin/config/admin.json.example` uit je working tree (is niet meer nodig).