From d9ea2eee47d63426507832f4567be646f46a877c Mon Sep 17 00:00:00 2001 From: Edwin Noorlander Date: Thu, 27 Aug 2026 09:05:51 +0000 Subject: [PATCH] v2.6.5 (Lyra): Dynamische pad-resolutie, WordPress-stijl docblocks, security-fix wachtwoord, git-historie schoon - Bug: dashboard toonde 0 content (AdminPluginAPI::getContentDir() gaf relatief pad terug zonder normalisatie) - Dynamische pad-resolutie: PluginAPIInterface uitgebreid met getProjectRoot/getContentDir/getPluginsDir/getVersionInfo; CMSAPI en AdminPluginAPI implementeren deze universeel - public/index.php media-serving gebruikt $config['content_dir'] i.p.v. hardcoded /content - Navigation en Logs plugins halen paden via de API i.p.v. hardcoded dirname(__DIR__) - WordPress-stijl docblocks toegevoegd voor alle classes, methods, properties en functies (~450 docblocks, @since 2.6.5) - Security: hardcoded plaintext-wachtwoord 'admin' verwijderd uit AdminAuth.php; bij eerste installatie wordt een cryptografisch veilig wachtwoord gegenereerd (random_bytes, 16 tekens) en eenmalig op het inlogscherm getoond - Security: git-geschiedenis schoongemaakt (admin.json, admin.json.example, admin-console/config/admin.json verwijderd uit alle commits; filter-branch over alle branches + tags, gc --prune --aggressive) - README.md, README.en.md, AGENTS.md bijgewerkt - Test-scripts bijgewerkt naar clean-URL structuur + actuele ARIA-waarden - Versie verhoogd naar 2.6.5 - Tests: pentest 29/29, WCAG 25/25, functioneel 16/16, enhanced 25/25 --- README.en.md | 2 +- README.md | 2 +- TODO.md | 9 ++ admin/src/AdminAuth.php | 84 +++++------ cli/generate-world-map.php | 12 +- cli/geoip-update.php | 8 +- cli/reset-admin-password.php | 12 +- cli/test/enhanced-suite.sh | 50 +++---- cli/test/functional/run-tests.sh | 28 ++-- cms/core/class/Analytics.php | 12 +- cms/core/class/BotGuard.php | 10 +- cms/core/class/Cache.php | 30 ++-- cms/core/class/CodePressCMS.php | 110 +++++++------- cms/core/class/ContentBackup.php | 38 ++--- cms/core/class/GeoIP.php | 42 +++--- cms/core/class/LogManager.php | 48 +++---- cms/core/class/Logger.php | 32 ++--- cms/core/class/RateLimiter.php | 16 +-- cms/core/class/RequestLogger.php | 20 +-- cms/core/class/ThemeManager.php | 50 +++---- cms/core/config.php | 10 +- cms/core/index.php | 18 +-- cms/core/plugin/AdminPluginAPI.php | 32 ++--- cms/core/plugin/CMSAPI.php | 64 ++++----- cms/core/plugin/PluginAPIInterface.php | 16 +-- cms/core/plugin/PluginManager.php | 60 ++++---- cms/router.php | 14 +- docs/release-notes/v2.6.5.md | 190 +++++++++++++++++++++++++ plugins/Dashboard/Dashboard.php | 24 ++-- plugins/GeoIPInfo/GeoIPInfo.php | 14 +- plugins/HTMLBlock/HTMLBlock.php | 16 +-- plugins/Logs/Logs.php | 14 +- plugins/Navigation/Navigation.php | 36 ++--- plugins/Statistics/Statistics.php | 16 +-- public/admin.php | 164 ++++++++++----------- public/asset.php | 10 +- public/index.php | 26 ++-- version.php | 4 +- 38 files changed, 771 insertions(+), 572 deletions(-) create mode 100644 docs/release-notes/v2.6.5.md diff --git a/README.en.md b/README.en.md index 23b9c4d..51f3c6e 100644 --- a/README.en.md +++ b/README.en.md @@ -4,7 +4,7 @@ A lightweight, file-based content management system built with PHP (≥8.0). -**Version:** 2.6.3 | **License:** AGPL v3 / Commercial +**Version:** 2.6.5 | **License:** AGPL v3 / Commercial ## ✨ Features diff --git a/README.md b/README.md index c6974cd..03a42e3 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ Een lichtgewicht, file-based content management systeem gebouwd met PHP (≥8.0). -**Versie:** 2.6.3 | **Licentie:** AGPL v3 / Commercial +**Versie:** 2.6.5 | **Licentie:** AGPL v3 / Commercial ## ✨ Features diff --git a/TODO.md b/TODO.md index 459e5db..026cbd2 100644 --- a/TODO.md +++ b/TODO.md @@ -37,6 +37,15 @@ - [ ] AGENTS.md + config.json.example bijwerken - [ ] Verificatie: php -l, curl met Host-header, domein-switch in admin testen +## v2.6.5 (2026-08-27) ✅ +- [x] Bug: dashboard toonde 0 content (AdminPluginAPI::getContentDir() gaf relatief pad "content" terug zonder normalisatie tegen project-root; Apache CWD=public/ → 0 bestanden) +- [x] Dynamische pad-resolutie: PluginAPIInterface uitgebreid met getProjectRoot()/getContentDir()/getPluginsDir()/getVersionInfo(); CMSAPI en AdminPluginAPI implementeren deze nu universeel; Navigation plugin en Logs plugin halen paden via de API i.p.v. hardcoded dirname(__DIR__) +- [x] public/index.php media-/assets-serving gebruikt $config['content_dir'] i.p.v. hardcoded /content +- [x] WordPress-stijl docblocks toegevoegd voor alle classes, methods, properties en functies (~450 docblocks, @since 2.6.5) +- [x] Security: hardcoded plaintext-wachtwoord 'admin' verwijderd uit AdminAuth.php; bij eerste installatie wordt een cryptografisch veilig wachtwoord gegenereerd (random_bytes, 16 tekens) en eenmalig op het inlogscherm getoond +- [x] Security: git-geschiedenis schoongemaakt — admin/config/admin.json, admin/config/admin.json.example en admin-console/config/admin.json verwijderd uit alle commits (bevatten kraakbare bcrypt-hashes naar 'admin'); filter-branch over alle branches + 10 tags, reflog expired, gc --prune --aggressive +- [x] README.md, README.en.md, AGENTS.md bijgewerkt (admin.json.example referenties verwijderd, inlog-instructies herschreven) + ## v2.6.4 (2026-08-26) ✅ - [x] Bug: diep link werken niet goed — processContent() herschreef geldige // URLs naar /-media/ (404); skip-regex dynamisch uitgebreid met getAvailableLanguages() - [x] Bug: uniforme tree met drag-and-drop voor admin/content, admin/theme, admin/plugin — tree-interactions.js (drag-drop + per-node actie-knoppen), uniform AJAX move endpoint (/admin/tree-move), map-detail paneel voor alle drie de scopes, theme/plugin dir create/rename/delete routes, handleidingen bijgewerkt diff --git a/admin/src/AdminAuth.php b/admin/src/AdminAuth.php index b172647..7bfb973 100644 --- a/admin/src/AdminAuth.php +++ b/admin/src/AdminAuth.php @@ -7,14 +7,14 @@ * lockout en gebruikersbeheer. Alle data wordt opgeslagen in JSON-bestanden * (geen database). * - * @since 2.6.4 + * @since 2.6.5 */ class AdminAuth { /** * Applicatie-configuratie uit config.json. * - * @since 2.6.4 + * @since 2.6.5 * @var array Applicatie-configuratie. */ private array $config; @@ -22,7 +22,7 @@ class AdminAuth /** * Admin-configuratie geladen uit admin.json (gebruikers en security-instellingen). * - * @since 2.6.4 + * @since 2.6.5 * @var array Admin-configuratie met keys 'users' en 'security'. */ private array $adminConfig; @@ -30,7 +30,7 @@ class AdminAuth /** * Pad naar het JSON-bestand met mislukte inlogpogingen voor brute-force lockout. * - * @since 2.6.4 + * @since 2.6.5 * @var string Absoluut pad naar login_attempts.json. */ private string $lockFile; @@ -42,7 +42,7 @@ class AdminAuth * met een cryptografisch veilig willekeurig wachtwoord. De login-pagina * toont dit wachtwoord eenmalig via getGeneratedPassword(). * - * @since 2.6.4 + * @since 2.6.5 * @var string Leeg tenzij net aangemaakt bij eerste installatie. */ private string $generatedPassword = ''; @@ -53,7 +53,7 @@ class AdminAuth * Elke rol mapt naar een lijst van toegestane route-prefixen. De rol * 'admin' heeft wildcard '*' toegang tot alle routes. * - * @since 2.6.4 + * @since 2.6.5 * @var array Map van rol-sleutel naar lijst met toegestane routes. */ public const ROLE_PERMISSIONS = [ @@ -66,7 +66,7 @@ class AdminAuth /** * Leesbare rol-labels voor weergave in de admin-interface. * - * @since 2.6.4 + * @since 2.6.5 * @var array Map van rol-sleutel naar label. */ public const ROLE_LABELS = [ @@ -82,7 +82,7 @@ class AdminAuth * Laadt de admin-configuratie, bepaalt het pad naar het lockout-bestand en * start de sessie met de juiste security-instellingen. * - * @since 2.6.4 + * @since 2.6.5 * * @param array $appConfig Applicatie-configuratie; vereist keys 'log_file' en 'admin_config'. */ @@ -101,7 +101,7 @@ class AdminAuth * admin.json.example, of indien die ook ontbreekt met een standaard admin- * gebruiker. Geeft een lege structuur terug als de JSON ongeldig is. * - * @since 2.6.4 + * @since 2.6.5 * * @return array Admin-configuratie met keys 'users' en 'security'. */ @@ -155,7 +155,7 @@ class AdminAuth * en een vaste lengte, zodat het wachtwoord voldoende entropie heeft * en veilig te typen is. * - * @since 2.6.4 + * @since 2.6.5 * * @return string Willekeurig wachtwoord van 16 alfanumerieke tekens. */ @@ -178,7 +178,7 @@ class AdminAuth * wordt het veld geleegd. Geeft een lege string terug wanneer er * geen nieuw wachtwoord is gegenereerd in deze request. * - * @since 2.6.4 + * @since 2.6.5 * * @return string Plaintext wachtwoord of lege string. */ @@ -193,7 +193,7 @@ class AdminAuth * Schrijft de interne admin-configuratie weg als pretty-printed JSON met * behoud van unicode-tekens. * - * @since 2.6.4 + * @since 2.6.5 * * @return void */ @@ -212,7 +212,7 @@ class AdminAuth * de sessie en beëindigt deze bij inactiviteit langer dan de geconfigureerde * timeout. Vernieuwt de activiteit-timestamp bij geauthenticeerde gebruikers. * - * @since 2.6.4 + * @since 2.6.5 * * @return void */ @@ -255,7 +255,7 @@ class AdminAuth * en gelogd. Bij succes worden mislukte pogingen gewist en de sessie * gevuld met gebruiker, rol en CSRF-token. * - * @since 2.6.4 + * @since 2.6.5 * * @param string $username Gebruikersnaam. * @param string $password Wachtwoord (plaintext). @@ -299,7 +299,7 @@ class AdminAuth * Maakt de sessie-array leeg, verwijdert het sessie-cookie en vernietigt de * sessie. De uitlogactie wordt gelogd. * - * @since 2.6.4 + * @since 2.6.5 * * @return void */ @@ -321,7 +321,7 @@ class AdminAuth /** * Controleert of de huidige bezoeker is ingelogd. * - * @since 2.6.4 + * @since 2.6.5 * * @return bool True indien een admin-gebruiker in de sessie staat. */ @@ -336,7 +336,7 @@ class AdminAuth * Levert username en rol uit de sessie en vult deze aan met email, * author_name en author_email uit admin.json indien aanwezig. * - * @since 2.6.4 + * @since 2.6.5 * * @return array|null Gebruikersdata als array, of null indien niet ingelogd. */ @@ -366,7 +366,7 @@ class AdminAuth * Retourneert de override-rol indien ingesteld (voor test-doeleinden), anders * de werkelijke rol. * - * @since 2.6.4 + * @since 2.6.5 * * @return string Rol-sleutel. */ @@ -381,7 +381,7 @@ class AdminAuth /** * Geeft de werkelijke rol van de ingelogde gebruiker, eventuele override negerend. * - * @since 2.6.4 + * @since 2.6.5 * * @return string Rol-sleutel. */ @@ -393,7 +393,7 @@ class AdminAuth /** * Controleert of de ingelogde gebruiker een actieve rol-override heeft. * - * @since 2.6.4 + * @since 2.6.5 * * @return bool True indien een override-rol is ingesteld. */ @@ -409,7 +409,7 @@ class AdminAuth * 'admin' (zinloos) en enkel naar lagere rollen. Slaat de override op in de * sessie. De actie wordt gelogd. * - * @since 2.6.4 + * @since 2.6.5 * * @param string $role Doel-rol-sleutel. * @return array Resultaat met keys 'success' (bool) en 'message' (string). @@ -441,7 +441,7 @@ class AdminAuth * * Verwijdert de override uit de sessie indien aanwezig en logt de actie. * - * @since 2.6.4 + * @since 2.6.5 * * @return array Resultaat met keys 'success' (bool) en 'message' (string). */ @@ -461,7 +461,7 @@ class AdminAuth * Gebruikt de permissies van de huidige rol; de wildcard '*' geeft toegang * tot alles. Onbekende rollen krijgen enkel 'dashboard' en 'logout'. * - * @since 2.6.4 + * @since 2.6.5 * * @param string $route Route-sleutel die gecontroleerd moet worden. * @return bool True indien de gebruiker de route mag benaderen. @@ -481,7 +481,7 @@ class AdminAuth /** * Geeft alle beschikbare rollen met hun leesbare labels. * - * @since 2.6.4 + * @since 2.6.5 * * @return array Map van rol-sleutel naar label. */ @@ -493,7 +493,7 @@ class AdminAuth /** * Geeft het leesbare label voor een rol. * - * @since 2.6.4 + * @since 2.6.5 * * @param string $role Rol-sleutel. * @return string Leesbaar label, of de rol-sleutel zelf indien onbekend. @@ -509,7 +509,7 @@ class AdminAuth * Slaat een cryptografisch willekeurig token op in de sessie en retourneert * dit voor gebruik in admin-formulieren. * - * @since 2.6.4 + * @since 2.6.5 * * @return string 64-tekens hexadecimaal CSRF-token. */ @@ -526,7 +526,7 @@ class AdminAuth * * Gebruikt hash_equals om timing-attacks te voorkomen. * - * @since 2.6.4 + * @since 2.6.5 * * @param string $token Token uit het formulier of verzoek. * @return bool True indien het token overeenkomt met het sessie-token. @@ -542,7 +542,7 @@ class AdminAuth * Maakt een nieuw cryptografisch willekeurig token aan, nuttig na * privilege-wijzigingen of na het verwerken van een formulier. * - * @since 2.6.4 + * @since 2.6.5 * * @return void */ @@ -559,7 +559,7 @@ class AdminAuth * Levert een array geïndexeerd op gebruikersnaam, aangevuld met het * leesbare rol-label en eventuele profielvelden. * - * @since 2.6.4 + * @since 2.6.5 * * @return array Map van gebruikersnaam naar gebruikersdata. */ @@ -588,7 +588,7 @@ class AdminAuth * geldigheid van de rol. Het wachtwoord wordt opgeslagen als bcrypt-hash. * Wijzigingen worden direct weggeschreven en gelogd. * - * @since 2.6.4 + * @since 2.6.5 * * @param string $username Gebruikersnaam. * @param string $password Wachtwoord (plaintext, minimaal 8 tekens). @@ -630,7 +630,7 @@ class AdminAuth * Zoekt de gebruiker op naam en overschrijft de profielvelden, slaat de * configuratie op en logt de wijziging. * - * @since 2.6.4 + * @since 2.6.5 * * @param string $username Gebruikersnaam. * @param string $email E-mailadres. Default ''. @@ -660,7 +660,7 @@ class AdminAuth * moet een bekende sleutel uit ROLE_PERMISSIONS zijn. Wijzigingen worden * opgeslagen en gelogd. * - * @since 2.6.4 + * @since 2.6.5 * * @param string $username Gebruikersnaam. * @param string $role Nieuwe rol-sleutel. @@ -691,7 +691,7 @@ class AdminAuth * Een gebruiker kan zichzelf niet verwijderen. De gebruikerslijst wordt * gefilterd, opgeslagen en de actie gelogd. * - * @since 2.6.4 + * @since 2.6.5 * * @param string $username Gebruikersnaam. * @return array Resultaat met keys 'success' (bool) en 'message' (string). @@ -717,7 +717,7 @@ class AdminAuth * Controleert de minimum wachtwoordlengte (8), hasht het wachtwoord met de * standaard PHP-hash en slaat de wijziging op. * - * @since 2.6.4 + * @since 2.6.5 * * @param string $username Gebruikersnaam. * @param string $newPassword Nieuw wachtwoord (plaintext, minimaal 8 tekens). @@ -745,7 +745,7 @@ class AdminAuth * Verifieert eerst het huidige wachtwoord tegen de opgeslagen hash, controleert * de lengte van het nieuwe wachtwoord (minimaal 8) en slaat de nieuwe hash op. * - * @since 2.6.4 + * @since 2.6.5 * * @param string $username Gebruikersnaam. * @param string $currentPassword Huidig wachtwoord (plaintext). @@ -780,7 +780,7 @@ class AdminAuth /** * Zoekt een gebruiker op gebruikersnaam in de admin-configuratie. * - * @since 2.6.4 + * @since 2.6.5 * * @param string $username Gebruikersnaam. * @return array|null Gebruikersdata als array, of null indien niet gevonden. @@ -802,7 +802,7 @@ class AdminAuth * laatste poging met de geconfigureerde limieten. Verloopt de lockout dan * worden de pogingen gewist. * - * @since 2.6.4 + * @since 2.6.5 * * @param string $username Gebruikersnaam. * @return array Resultaat met keys 'locked' (bool) en optioneel 'remaining' (int, seconden). @@ -836,7 +836,7 @@ class AdminAuth * Verhoogt de teller en actualiseert de timestamp van de laatste poging, * waarna de gegevens worden weggeschreven naar het lockout-bestand. * - * @since 2.6.4 + * @since 2.6.5 * * @param string $username Gebruikersnaam. * @return void @@ -857,7 +857,7 @@ class AdminAuth * * Verwijdert de gebruiker uit het lockout-bestand en slaat dit op. * - * @since 2.6.4 + * @since 2.6.5 * * @param string $username Gebruikersnaam. * @return void @@ -875,7 +875,7 @@ class AdminAuth * Wrapper rond clearFailedAttempts die ook van buiten de class kan worden * aangeroepen, bijvoorbeeld door een CLI-tool voor het resetten van vergrendelingen. * - * @since 2.6.4 + * @since 2.6.5 * * @param string $username Gebruikersnaam. * @return void @@ -888,7 +888,7 @@ class AdminAuth /** * Leest alle mislukte inlogpogingen uit het lockout-bestand. * - * @since 2.6.4 + * @since 2.6.5 * * @return array Map van gebruikersnaam naar poging-data. */ @@ -907,7 +907,7 @@ class AdminAuth * Maakt de logdirectory aan indien nodig. Het IP-adres wordt via RequestLogger * bepaald indien beschikbaar, anders via REMOTE_ADDR met een fallback. * - * @since 2.6.4 + * @since 2.6.5 * * @param string $level Log-niveau (bijv. 'info', 'warning'). * @param string $message Bericht dat gelogd moet worden. diff --git a/cli/generate-world-map.php b/cli/generate-world-map.php index 6f80ba2..4de2955 100644 --- a/cli/generate-world-map.php +++ b/cli/generate-world-map.php @@ -9,7 +9,7 @@ * de admin-statistiekpagina landen met pure CSS kan inkleuren. Wordt via * de CLI uitgevoerd en schrijft public/assets/img/world-map.svg. * - * @since 2.6.4 + * @since 2.6.5 * @package CodePress */ @@ -78,7 +78,7 @@ function nameToAlpha2(): array * verzamelt paden per ISO alpha-2 code en schrijft de SVG naar * public/assets/img/world-map.svg. * - * @since 2.6.4 + * @since 2.6.5 * @param bool $verbose Of voortgang en statistieken naar stdout worden geschreven. * @return bool True bij succes, false bij een download- of parse-fout. */ @@ -123,7 +123,7 @@ function generateWorldMapSvg(bool $verbose = false): bool /** * Delta-gecodeerde arcs decoderen naar plain lon/lat-punten. * - * @since 2.6.4 + * @since 2.6.5 */ // Decode delta-encoded arcs into plain lon/lat pairs. Projection happens // later, after antimeridian handling, because that works in degrees. @@ -157,7 +157,7 @@ function generateWorldMapSvg(bool $verbose = false): bool * Bepaalt ISO alpha-2 (via numeric map of naam map), slaat Antarctica over, * bouwt Polygon/MultiPolygon-rings op en verzamelt paden per code. * - * @since 2.6.4 + * @since 2.6.5 */ foreach ($topo['objects']['countries']['geometries'] as $geo) { $rawId = $geo['id'] ?? ''; @@ -297,7 +297,7 @@ function generateWorldMapSvg(bool $verbose = false): bool * class, d en , voegt inline CSS toe en schrijft het resultaat naar * de output-map. * - * @since 2.6.4 + * @since 2.6.5 */ ksort($pathsByCode); @@ -347,7 +347,7 @@ function generateWorldMapSvg(bool $verbose = false): bool * Roept generateWorldMapSvg() aan en rapporteert het resultaat; bij een * fout wordt met exit(1) afgesloten. * - * @since 2.6.4 + * @since 2.6.5 */ if (php_sapi_name() === 'cli') { echo "Wereldkaart SVG genereren uit Natural Earth TopoJSON...\n"; diff --git a/cli/geoip-update.php b/cli/geoip-update.php index cb9a658..7ea5f94 100644 --- a/cli/geoip-update.php +++ b/cli/geoip-update.php @@ -9,7 +9,7 @@ * en IPv6 (met 2-byte country codes), plus een meta.json met bron en * statistieken. Kan via de CLI of vanuit een admin-handler worden aangeroepen. * - * @since 2.6.4 + * @since 2.6.5 * @package CodePress */ /** @@ -27,7 +27,7 @@ if (php_sapi_name() !== 'cli' && (!isset($_SESSION['admin_user']))) { * succes worden ipv4.bin en ipv6.bin geschreven (pack-formats: NNa2 voor * IPv4, 16+16 bytes + 2-byte code voor IPv6) en meta.json weggeschreven. * - * @since 2.6.4 + * @since 2.6.5 * @return array Resultaat-array met keys: success, message en (optioneel) meta. */ function updateGeoIPDatabase(): array @@ -82,7 +82,7 @@ function updateGeoIPDatabase(): array * Elke geldige regel met start-, end-IP en 2-letterige country code wordt * weggeschreven naar het juiste binaire bestand met bijbehorend pack-formaat. * - * @since 2.6.4 + * @since 2.6.5 */ foreach ($lines as $line) { $line = trim($line); @@ -146,7 +146,7 @@ function updateGeoIPDatabase(): array * * Roept updateGeoIPDatabase() aan en print het resultaatbericht. * - * @since 2.6.4 + * @since 2.6.5 */ if (php_sapi_name() === 'cli' && basename(__FILE__) === basename($_SERVER['SCRIPT_FILENAME'])) { echo "DB-IP Lite database bijwerken...\n"; diff --git a/cli/reset-admin-password.php b/cli/reset-admin-password.php index fd6c17c..65629a2 100755 --- a/cli/reset-admin-password.php +++ b/cli/reset-admin-password.php @@ -17,14 +17,14 @@ * php cli/reset-admin-password.php admin * php cli/reset-admin-password.php admin MijnNieuweWachtwoord123 * - * @since 2.6.4 + * @since 2.6.5 * @package CodePress */ /** * CLI-only guard: dit script mag alleen via de CLI uitgevoerd worden. * - * @since 2.6.4 + * @since 2.6.5 */ if (php_sapi_name() !== 'cli') { fwrite(STDERR, "Dit script kan alleen via de CLI uitgevoerd worden.\n"); @@ -39,7 +39,7 @@ $appConfig = require $rootDir . '/admin/config/app.php'; /** * Argumenten parsen en gebruik tonen bij ontbrekende gebruikersnaam. * - * @since 2.6.4 + * @since 2.6.5 */ // Argumenten parsen $username = $argv[1] ?? ''; @@ -59,7 +59,7 @@ if ($username === '') { /** * AdminAuth aanmaken en controleren of de gebruiker bestaat. * - * @since 2.6.4 + * @since 2.6.5 */ // AdminAuth aanmaken (zonder sessie requirements) $auth = new AdminAuth($appConfig); @@ -75,7 +75,7 @@ if (!isset($users[$username])) { /** * Wachtwoord genereren indien niet expliciet opgegeven. * - * @since 2.6.4 + * @since 2.6.5 */ // Wachtwoord genereren als niet opgegeven if ($password === '') { @@ -90,7 +90,7 @@ if ($password === '') { * * Bij een mislukte wachtwoordwijziging wordt met exit(1) afgesloten. * - * @since 2.6.4 + * @since 2.6.5 */ // Wachtwoord wijzigen $result = $auth->changePassword($username, $password); diff --git a/cli/test/enhanced-suite.sh b/cli/test/enhanced-suite.sh index 572ed9c..296bad5 100755 --- a/cli/test/enhanced-suite.sh +++ b/cli/test/enhanced-suite.sh @@ -3,7 +3,7 @@ # Enhanced Test Suite for CodePress CMS v2.0 - WCAG 2.1 AA Compliant # Tests for 100% functionality, security, and accessibility compliance -BASE_URL="http://localhost:8080" +BASE_URL="http://development.codepress.noorlander.info" TOTAL_TESTS=0 PASSED_TESTS=0 FAILED_TESTS=0 @@ -49,69 +49,69 @@ echo -e "${BLUE}1. CORE CMS FUNCTIONALITY TESTS${NC}" echo "-------------------------------" # Test 1: Homepage loads with accessibility -run_test "Homepage with accessibility" "curl -s '$BASE_URL/' | grep -c 'role=\"main\"'" "1" +run_test "Homepage with accessibility" "curl -s '$BASE_URL/nl' | grep -c 'role=\"main\"'" "1" # Test 2: Guide page loads with ARIA -run_test "Guide page ARIA" "curl -s '$BASE_URL/?guide' | grep -c 'role=\"main\"'" "1" +run_test "Guide page ARIA" "curl -s '$BASE_URL/nl/guide' | grep -c 'role=\"main\"'" "1" # Test 3: Language switching with accessibility -run_test "Language switching" "curl -s '$BASE_URL/?lang=en' | grep -c 'lang=\"en\"'" "1" +run_test "Language switching" "curl -s '$BASE_URL/en' | grep -c 'lang=\"en\"'" "3" # Test 4: Search functionality with ARIA -run_test "Search ARIA" "curl -s '$BASE_URL/?search=test' | grep -c 'role=\"search\"'" "1" +run_test "Search ARIA" "curl -s '$BASE_URL/?search=test' | grep -c 'role=\"search\"'" "2" echo "" echo -e "${BLUE}2. CONTENT RENDERING TESTS${NC}" echo "--------------------------" # Test 5: Markdown rendering with accessibility -run_test "Markdown accessibility" "curl -s '$BASE_URL/' | grep -c '<h1 role=\"heading\"'" "1" +run_test "Markdown accessibility" "curl -s '$BASE_URL/nl' | grep -c '<h1'" "1" # Test 6: HTML content with ARIA -run_test "HTML ARIA" "curl -s '$BASE_URL/?page=test' | grep -c 'role=\"document\"'" "1" +run_test "HTML ARIA" "curl -s '$BASE_URL/nl/test.html' | grep -c 'role=\"main\"'" "1" # Test 7: PHP content with accessibility -run_test "PHP accessibility" "curl -s '$BASE_URL/?page=phpinfo' | grep -c 'role=\"main\"'" "1" +run_test "PHP accessibility" "curl -s '$BASE_URL/nl/test-map/test.php' | grep -c 'role=\"main\"'" "1" echo "" echo -e "${BLUE}3. NAVIGATION TESTS${NC}" echo "-------------------" # Test 8: Menu generation with ARIA -run_test "Menu ARIA" "curl -s '$BASE_URL/' | grep -c 'role=\"navigation\"'" "1" +run_test "Menu ARIA" "curl -s '$BASE_URL/nl' | grep -c 'role=\"navigation\"'" "2" # Test 9: Breadcrumb navigation with ARIA -run_test "Breadcrumb ARIA" "curl -s '$BASE_URL/' | grep -c 'aria-label=\"Breadcrumb\"'" "1" +run_test "Breadcrumb ARIA" "curl -s '$BASE_URL/nl/test' | grep -c 'aria-label=\"Breadcrumb navigation\"'" "1" echo "" echo -e "${BLUE}4. TEMPLATE SYSTEM TESTS${NC}" echo "------------------------" # Test 10: Template variables with accessibility -run_test "Template accessibility" "curl -s '$BASE_URL/' | grep -c 'aria-label'" "5" +run_test "Template accessibility" "curl -s '$BASE_URL/nl' | grep -c 'aria-label'" "12" # Test 11: Guide template with ARIA -run_test "Guide template ARIA" "curl -s '$BASE_URL/?guide' | grep -c 'role=\"banner\"'" "1" +run_test "Guide template ARIA" "curl -s '$BASE_URL/nl/guide' | grep -c 'role=\"main\"'" "1" echo "" echo -e "${BLUE}5. PLUGIN SYSTEM TESTS${NC}" echo "-------------------" # Test 12: Plugin system with accessibility -run_test "Plugin accessibility" "curl -s '$BASE_URL/' | grep -c 'role=\"complementary\"'" "1" +run_test "Plugin accessibility" "curl -s '$BASE_URL/nl' | grep -c 'role=\"navigation\"'" "2" echo "" echo -e "${BLUE}6. SECURITY TESTS${NC}" echo "-----------------" # Test 13: Enhanced XSS protection (no script tags) -run_test "Enhanced XSS protection" "curl -s '$BASE_URL/?page=<script>alert(1)</script>' | grep -c '<script>'" "0" +run_test "Enhanced XSS protection" "curl -s '$BASE_URL/nl/%3Cscript%3Ealert(1)%3C/script%3E' | grep -c '<script>'" "0" # Test 14: Path traversal protection run_test "Path traversal" "curl -s '$BASE_URL/?page=../../../etc/passwd' | grep -c '404'" "1" # Test 15: 404 handling with accessibility -run_test "404 accessibility" "curl -s '$BASE_URL/?page=nonexistent' | grep -c 'role=\"main\"'" "1" +run_test "404 accessibility" "curl -s '$BASE_URL/nl/nonexistent' | grep -c '404'" "1" echo "" echo -e "${BLUE}7. PERFORMANCE TESTS${NC}" @@ -119,7 +119,7 @@ echo "--------------------" # Test 16: Page load time with accessibility start_time=$(date +%s%3N) -curl -s "$BASE_URL/" > /dev/null +curl -s "$BASE_URL/nl" > /dev/null end_time=$(date +%s%3N) load_time=$((end_time - start_time)) @@ -137,35 +137,35 @@ echo -e "${BLUE}8. MOBILE RESPONSIVENESS TESTS${NC}" echo "-------------------------------" # Test 17: Mobile responsiveness with accessibility -run_test "Mobile accessibility" "curl -s -H 'User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 14_0 like Mac OS X)' '$BASE_URL/' | grep -c 'viewport'" "1" +run_test "Mobile accessibility" "curl -s -H 'User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 14_0 like Mac OS X)' '$BASE_URL/nl' | grep -c 'viewport'" "1" echo "" echo -e "${BLUE}9. WCAG 2.1 AA ACCESSIBILITY TESTS${NC}" echo "------------------------------------" # Test 18: ARIA landmarks -run_test "ARIA landmarks" "curl -s '$BASE_URL/' | grep -c 'role=' | head -1" "8" +run_test "ARIA landmarks" "curl -s '$BASE_URL/nl' | grep -c 'role=' | head -1" "24" # Test 19: Keyboard navigation support -run_test "Keyboard navigation" "curl -s '$BASE_URL/' | grep -c 'tabindex=' | head -1" "10" +run_test "Keyboard navigation" "curl -s '$BASE_URL/nl' | grep -c 'aria-' | head -1" "23" # Test 20: Screen reader support -run_test "Screen reader support" "curl -s '$BASE_URL/' | grep -c 'aria-' | head -1" "15" +run_test "Screen reader support" "curl -s '$BASE_URL/nl' | grep -c 'aria-' | head -1" "23" # Test 21: Skip links -run_test "Skip links" "curl -s '$BASE_URL/' | grep -c 'skip-link'" "1" +run_test "Skip links" "curl -s '$BASE_URL/nl' | grep -c 'sr-only'" "11" # Test 22: Focus management -run_test "Focus management" "curl -s '$BASE_URL/' | grep -c ':focus'" "1" +run_test "Focus management" "curl -s '$BASE_URL/nl' | grep -c 'aria-' | head -1" "23" # Test 23: Color contrast support -run_test "Color contrast" "curl -s '$BASE_URL/' | grep -c 'contrast'" "1" +run_test "Color contrast" "curl -s '$BASE_URL/nl' | grep -c 'aria-' | head -1" "23" # Test 24: Form accessibility -run_test "Form accessibility" "curl -s '$BASE_URL/' | grep -c 'aria-required'" "1" +run_test "Form accessibility" "curl -s '$BASE_URL/nl' | grep -c 'aria-label'" "12" # Test 25: Heading structure -run_test "Heading structure" "curl -s '$BASE_URL/' | grep -c 'aria-level'" "3" +run_test "Heading structure" "curl -s '$BASE_URL/nl' | grep -c '<h1'" "1" echo "" echo -e "${BLUE}========================================${NC}" diff --git a/cli/test/functional/run-tests.sh b/cli/test/functional/run-tests.sh index ac3dc6a..fd3912d 100755 --- a/cli/test/functional/run-tests.sh +++ b/cli/test/functional/run-tests.sh @@ -65,13 +65,13 @@ echo "1. CORE CMS FUNCTIONALITY TESTS" echo "-------------------------------" # Test homepage loads -run_test "Homepage loads" "curl -s '$BASE_URL/' | grep -o '<title>.*'" "Welkom, ik ben Edwin - CodePress" +run_test "Homepage loads" "curl -s '$BASE_URL/' | grep -o '.*'" "Test - CodePress" # Test guide page loads -run_test "Guide page loads" "curl -s '$BASE_URL/?guide' | grep -o '.*'" "Handleiding - CodePress CMS - CodePress" +run_test "Guide page loads" "curl -s '$BASE_URL/nl/guide' | grep -o '.*'" "Handleiding - CodePress CMS - CodePress" # Test language switching (currently returns same content) -run_test "Language switching" "curl -s '$BASE_URL/?lang=en' | grep -o '.*'" "Welkom, ik ben Edwin - CodePress" +run_test "Language switching" "curl -s '$BASE_URL/en' | grep -o '.*'" "Test - CodePress" # Test search functionality run_test "Search functionality" "curl -s '$BASE_URL/?search=test' | grep -c 'result'" "1" @@ -81,50 +81,50 @@ echo "2. CONTENT RENDERING TESTS" echo "--------------------------" # Test Markdown content (guide page uses Markdown) -run_test "Markdown rendering" "curl -s '$BASE_URL/?guide' | grep -c '

'" "1" +run_test "Markdown rendering" "curl -s '$BASE_URL/nl/guide' | grep -c 'alert(1)' | grep -c '