Redirect the other www spelling to SITE_ORIGIN, hold roles to the role help and fix the audit findings
SITE_ORIGIN alone decides whether the site is www or not: CanonicalHostSubscriber sends the other spelling there with 301, cms:site:origin writes the setting, the system screen shows it. The roles now match the role help (editor: drafts, publisher: live content, admin: design, settings, users, system). The installer no longer reopens on an unreachable database, the session cookie follows ADMIN_PATH, percent-encoded credentials no longer break the container, consent only accepts same-site decisions, JSON-LD is HTML-safe, own CSS stays in its block, plus the editor, updater, download and public-output findings from the full review (ADR 099, ADR 100). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
1 parent
45040b2ca6
commit
7eb462ac7b
53 files changed
+1023
-122
No files matched your search
@@ -200,6 +200,39 @@ final class InstallationTest extends TestCase
|
||||
self::assertFalse($this->installation->verify('website', $issued, 'falsch'));
|
||||
}
|
||||
|
||||
public function testAnUnreachableDatabaseDoesNotReopenTheInstaller(): void
|
||||
{
|
||||
// Ein gedrehtes Passwort oder eine Wartung beim Hoster: die Datenbank antwortet nicht.
|
||||
// Frueher hiess das "nicht installiert" - und der Installer nahm von jedem Besucher eine
|
||||
// neue Datenbank samt Administratorkonto an.
|
||||
$unreachable = ConnectionFactory::create('mysql://niemand:nichts@127.0.0.1:1/weg');
|
||||
$settings = new SiteSettings($unreachable, new MediaLibrary($unreachable, $this->root.'/var/media'));
|
||||
$broken = new Installation(
|
||||
$unreachable,
|
||||
new PageRepository($unreachable, new DocumentValidator(), $settings),
|
||||
new PartialRepository($unreachable, new DocumentValidator()),
|
||||
new MenuRepository($unreachable, $settings),
|
||||
$settings,
|
||||
new UserPasswordHasher(new PasswordHasherFactory([CmsUser::class => ['algorithm' => 'auto']])),
|
||||
$this->root,
|
||||
$this->root.'/var/media',
|
||||
'test-secret',
|
||||
);
|
||||
// Vor dem Datenbankschritt gibt es noch nichts zu schuetzen.
|
||||
self::assertFalse($broken->isInstalled());
|
||||
// Sobald eine Datenbank eingetragen ist, ist eine tote Verbindung eine Stoerung.
|
||||
$broken->writeEnvironment(['DATABASE_URL' => 'mysql://niemand:nichts@127.0.0.1:1/weg']);
|
||||
self::assertTrue($broken->isInstalled());
|
||||
// Die Marke der Website zaehlt auch ohne jede Verbindung - selbst ohne .env.
|
||||
unlink($this->root.'/.env');
|
||||
self::assertFalse($broken->isInstalled());
|
||||
file_put_contents($this->root.'/var/installed', gmdate('c')."\n");
|
||||
self::assertTrue($broken->isInstalled());
|
||||
// Eine leere SQLite-Datenbank ohne Marke bleibt dagegen der Installer-Fall.
|
||||
unlink($this->root.'/var/installed');
|
||||
self::assertFalse($this->installation->isInstalled());
|
||||
}
|
||||
|
||||
private function make(): Installation
|
||||
{
|
||||
$settings = new SiteSettings($this->db, new MediaLibrary($this->db, $this->root.'/var/media'));
|
||||
|
||||
Reference in new issue
Block a user