4862526fa1
Lets a page under App/pages/ be previewed by an admin before the public can see it: list its route in draft_routes (App/config.php), checked in bootstrap.php alongside the existing /admin/* gate. Not authenticated -> same plain 404 an unmatched route gets, not a login prompt, so a draft's existence isn't revealed. Authenticated -> renders normally. No separate login flow needed - Basic Auth credentials are scoped to the whole origin/realm, so authenticating once at /admin covers draft URLs too. AdminAuth::isAuthenticated() is extracted out of requireLogin() so the draft gate can reuse the same credential check with a different failure response (404 vs. a 401 challenge). Renderer::render() gains an $excludeFromCache param so a draft without its own sidecar can't get written to the static HTML cache - .htaccess serves a cached file before PHP, and therefore any auth check, ever runs again, so an uncached exception is required, not just the auth gate. While testing this, found the same bug already existed for /admin itself: novaconium/pages/admin/index.twig has no sidecar, so it was already being cached - meaning any admin visiting /admin once caused the panel to be served to everyone, unauthenticated, straight from public/cache/admin/. Fixed in this change by excluding every /admin/* route from the cache the same way, and documented as a standing rule in AGENTS.md: any future mechanism that conditionally hides page content from the public has to make the same check, not just gate the initial request. Closes the "Draft pages (admin-only preview)" backlog item in novaconium/ISSUES.md.
46 lines
1.8 KiB
PHP
46 lines
1.8 KiB
PHP
<?php
|
|
|
|
// Override any subset of novaconium/config.php's defaults here — only list
|
|
// the keys you want to change. novaconium/bootstrap.php (and
|
|
// novaconium/bin/clear-cache.php) shallow-merge this over the framework
|
|
// defaults; see /admin/docs/config. Uncomment and adjust any of the
|
|
// examples below, or leave this file returning an empty array to keep
|
|
// every framework default as-is.
|
|
return [
|
|
// 'debug' => false,
|
|
|
|
// 'site_name' => 'My Site',
|
|
|
|
// Docs: /admin/docs/matomo
|
|
// 'matomo_url' => 'https://matomo.example.com/',
|
|
// 'matomo_site_id' => '1',
|
|
|
|
// Docs: /admin/docs/admin-auth — generate a hash with:
|
|
// php -r "echo password_hash('yourpassword', PASSWORD_DEFAULT), PHP_EOL;"
|
|
// or use the built-in /admin/password-hash form.
|
|
// 'admin_username' => 'admin',
|
|
// 'admin_password_hash' => '$2y$10$...',
|
|
|
|
// Docs: /admin/docs/database — adds (or overrides) named Lib\Db
|
|
// connections. This merges into db_connections by name rather than
|
|
// replacing the whole map, so adding 'legacy' here doesn't require
|
|
// repeating 'default' — see Lib\Db::config().
|
|
// 'db_connections' => [
|
|
// 'legacy' => [
|
|
// 'driver' => 'mysql',
|
|
// 'host' => 'localhost',
|
|
// 'port' => 3306,
|
|
// 'database' => 'legacy_app',
|
|
// 'username' => 'root',
|
|
// 'password' => '...',
|
|
// 'charset' => 'utf8mb4', // optional, defaults to utf8mb4
|
|
// 'migrations_dir' => __DIR__ . '/migrations/legacy', // optional
|
|
// ],
|
|
// ],
|
|
|
|
// Docs: /admin/docs/drafts — requires admin_password_hash above to be
|
|
// set to actually gate anything; open access otherwise, same as the
|
|
// rest of /admin/*.
|
|
// 'draft_routes' => ['blog/upcoming-post'],
|
|
];
|