thats-me/dev/AUDIT-2026-09-17.md
Kevin Adametz 10251e4f41 Doku und Werkzeuge: Tickets, Audit, Logos, Playwright-MCP
- dev/: Ticketliste, Audit und Vorschläge vom 17.09., Logo-SVGs,
  Lifeline-Bildwerkzeuge.
- AGENTS.md auf den aktuellen Stand (syncQueue statt syncService, kein
  legacy-Ordner mehr).
- .codex/ und __pycache__/ ignoriert; Playwright-MCP in .mcp.json.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-25 07:00:35 +00:00

48 KiB
Raw Blame History

Projektaudit: Quasar-Frontend und Laravel-Backend

Datum: 17.09.2026
Geprüfter Commit: f79dcb992839cba04e824b3d9e23231efa7b6bdc vom 07.07.2026
Umfang: Entwicklungsstand, aktive Anwendung, API, Persistenz, Authentifizierung, Medien, Abhängigkeiten und Qualitätssicherung.
Ergebnis dieser Arbeit: Audit und Maßnahmenvorschläge; keine Änderungen an Anwendungscode, Datenmodell oder Abhängigkeiten.

Kontextnachtrag vom 17.09.2026: Projektziel und Maßnahmenreihenfolge nach Rückmeldung des Projektverantwortlichen angepasst. Die technischen Befunde und bisherigen Prüfergebnisse bleiben bestehen; ihre Dringlichkeit wird nach Entwicklungsphase eingeordnet. Für diesen Nachtrag wurden Auth-Store und Seeder erneut gelesen, keine Builds, Tests oder Registry-Prüfungen wiederholt.

1. Einschätzung

Das Projekt befindet sich nach Auskunft des Projektverantwortlichen in Entwicklung und wird aktuell getestet. Das nächste Ziel ist eine kleine Demo, die das Produkt vorstellt und Interesse weckt. Social Media soll dabei helfen, Interessenten und spätere Kunden zu erreichen. Bei ausreichendem Interesse kommt eine Crowdfunding-Kampagne infrage; sie ist noch keine beschlossene Projektphase.

Aktuell gibt es keine regulären Kundenkonten im vorgesehenen Testbetrieb. Die sechs auswählbaren API-Konten dienen bewusst dazu, serverseitiges Speichern und Benutzerwechsel zu testen. Hinzu kommt ein lokaler Demo-Zugang ohne API-Anmeldung. Dieses Testmodell passt zum Entwicklungsziel; sechs feste Testkonten und vereinfachte Zugangsdaten sind für sich genommen kein Entwicklungsfehler.

Das Projekt hat eine brauchbare Grundlage für diese Demo. Die Quasar-Oberfläche, lokale Demo-Daten, API-Anmeldung, Event-CRUD, Benutzereinstellungen und geschützte Bildauslieferung sind implementiert. Die serverseitige Einschränkung der meisten Datenzugriffe auf den angemeldeten Benutzer ist sauber erkennbar und durch API-Tests teilweise abgesichert.

Für den nächsten Entwicklungsschritt stehen zuverlässige Demo-Abläufe im Vordergrund: Speichern und Wiederladen, vollständige Event-Felder, korrektes Umschalten zwischen Testkonten und eine verständliche Fehleranzeige. Die nachgewiesenen Speicher- und Benutzerwechselprobleme beeinträchtigen bereits die Testbarkeit und eine Präsentation mit Beispieldaten. Anforderungen an einen späteren Betrieb mit echten privaten Konten werden gesondert vorgemerkt.

Prioritäten:

  • P1 – hoch: im jeweils genannten Nutzungsszenario vorrangig bearbeiten; aktuell vor allem wesentliche Demo- und Speicherfehler, bei öffentlichem Betrieb zusätzlich erreichbare Sicherheitsrisiken.
  • P2 – mittel: im nächsten Stabilisierungsschritt beheben; teilweise abhängig von Fehlersituationen, Datenmenge oder Nutzung.
  • P3 – niedrig / Optimierung: Wartbarkeit, Performance und Entwicklungsabläufe verbessern.

1.1 Bewertung nach Entwicklungsphase

Phase Schwerpunkt Konsequenz für diesen Audit
Aktueller Teststand mit sechs API-Testkonten und lokalem Demo-Zugang Persistenz, Darstellung und Benutzerwechsel überprüfen Testkonten beibehalten; A04–A08 als Funktionsfehler priorisieren. Vollständige Kundenregistrierung oder ein ausgebautes Kontensystem sind dafür nicht erforderlich.
Geplante Werbedemo Produkt verständlich und zuverlässig präsentieren Bei einer betreuten Präsentation stehen die gezeigten Abläufe im Vordergrund. Falls Besucher selbst API-Konten und Uploads nutzen dürfen, zusätzlich Missbrauch und Veränderung gemeinsamer Beispieldaten berücksichtigen. Das spätere Zugangsmodell ist noch offen.
Öffentliche Erreichbarkeit von API oder Entwicklungsdiensten Verfügbarkeit und Schutz der Infrastruktur Sicherheitsupdates für erreichbare Schwachstellen, Zugriffsschutz sowie angemessene Request-/Upload-Limits werden auch ohne echte Kundenkonten relevant. Ob die derzeitige Testinstallation öffentlich erreichbar ist, wurde nicht geprüft.
Möglicher späterer Betrieb mit echten Konten und privaten Inhalten Verbindliche Benutzertrennung, Zugriffsschutz und Datenlebenszyklus Demo-Seeding von echten Konten trennen und die vorgemerkten Sicherheits-/Betriebsanforderungen vor dieser Nutzung abarbeiten.

Die Nutzerangaben beschreiben den vorgesehenen Testbetrieb; Datenbankinhalte und Live-Erreichbarkeit wurden nicht kontrolliert. Es wurde kein Angriff auf einen Live-Server ausgeführt. Ein verwundbarer Paketstand oder ein Seeder ohne Umgebungsschutz ist kein Beweis dafür, dass eine Installation bereits kompromittiert ist.

2. Entwicklung und tatsächlicher Stand

2.1 Verlauf

Stand Entwicklung Einordnung
20.02.2026, 98084de LifeWave-Oberfläche, Timeline, Shader, Event-Panel und mobile Vorarbeiten Schwerpunkt auf Darstellung und Interaktion
25.02.2026, 70a7776 Passport, Event-API, Migrationen, API-Tests, IndexedDB und Synchronisationsservice Beginn der Backend-/Offline-Anbindung
April 2026 Weitere UI-/Medienarbeit und zusätzliche Prototypquellen Mehrere Entwicklungsstände liegen nebeneinander
05.06.2026, c151499 Hybrid-Anmeldung, Remote-Events, Settings und geschützte Medien Aktueller wesentlicher Integrationsstand
07.07.2026, f79dcb9 Performance- und Sync-Anpassungen überwiegend unter frontend/_src Änderungen dort gehören nicht automatisch zur aktiven App

Maßgeblich sind Router und Quasar-Konfiguration: Die aktive Oberfläche verwendet src/pages/LifeWavePage.vue und src/layouts/LifeWaveLayout.vue. frontend/_src, frontend/src/legacy, dot-line-system und die HTML-Experimente unter test sind keine gleichwertigen Teile dieses produktiven Ausführungspfads.

2.2 Architektur

Bereich Tatsächliches Verhalten
Frontend Quasar 2 / Vue 3, Pinia, Vue Router mit Hash-Routing, Vite, Dexie, Three.js
Lokaler Demo-Benutzer Events und Medien in IndexedDB, Settings in localStorage; neue Demo-Mutationen werden nicht in die API-SyncQueue geschrieben
Sechs Remote-Testbenutzer Bewusst persistierende API-Konten für Events, Settings und Uploads; IndexedDB/localStorage dienen zusätzlich als Cache
Authentifizierung Passport-Bearer-Token in IndexedDB; Benutzerprofil zusätzlich in localStorage
Backend Laravel 12 mit Passport; daneben Website und Livewire-/Volt-Einstellungen
Medien Private Dateien, benutzergebundene Auslieferung; Thumbnail, Preview und verkleinertes Original
Synchronisation Separater älterer Service existiert; kein durchgehend funktionierender Offline-Schreibpfad für die aktive Remote-App
Infrastruktur Compose mit PHP 8.4 und Node 20; externe Dienste und externes proxy-Netz werden vorausgesetzt

Aus den Lockfiles: Quasar 2.18.6, Vue 3.5.29, Pinia 3.0.4, Dexie 4.3.0, Three.js 0.183.1, Frontend-Vite 7.3.1; Laravel 12.52.0, Passport 13.5.0, Livewire 4.1.4, Volt 1.10.2, Pest 3.8.5, Backend-Vite 6.4.0.

Der erneute Codeabgleich bestätigt die sechs auswählbaren Remote-Testkonten und local-demo im Auth-Store. Der Backend-Seeder legt daneben einen zusätzlichen allgemeinen Test User an, der nicht zur sechs Einträge umfassenden Frontend-Auswahl gehört. Der lokale Demo-Zugang wird im Frontend definiert und ist kein siebtes API-Konto. Damit sind lokale Demo-Speicherung und serverseitige Persistenztests bewusst getrennte Abläufe.

2.3 Dokumentation weicht vom Code ab

Der Implementierungsplan bezeichnet wesentliche Phasen als abgeschlossen und fordert die Speicherung von location und key_image_title. Diese Felder fehlen weiterhin im Backend. Außerdem verweist der Sync-Nachtrag vom Juli ausdrücklich auf _src; die aktive Implementierung unter src enthält diese Änderungen nicht.

frontend/package.json, appVersion.js und das Root-README nennen 0.0.1; der Implementierungsplan nennt 0.5.0, das Migrationsprotokoll weitere Zwischenversionen. Historische Versionsangaben sind sinnvoll, müssen aber klar vom aktuellen Release-Stand unterschieden werden. Ein konsistenter Implementierungsstatus und ein verbindlicher API-Vertrag fehlen.

3. Ausgeführte Prüfungen

Prüfung Ergebnis
Frontend: npm run lint Erfolgreich
Frontend: npm run build Erfolgreich; Warnung wegen eines großen JavaScript-Chunks
Backend: npm run build Erfolgreich; leerer app-JS-Chunk gemeldet
Backend: php artisan test --compact 62 bestanden, 1 fehlgeschlagen, 210 Assertions; Fehler bei der Profilseite, siehe A17; beim zweiten Lauf bestätigt
Backend: php artisan route:list --path=api -v 18 API-Routen; kein Login-/API-Throttle in der registrierten Middleware sichtbar
Frontend: npm audit --json 21 betroffene Pakete: 13 high, 5 moderate, 3 low
Backend-Assets: npm audit --json 11 betroffene Pakete: 1 critical, 9 high, 1 moderate
Backend-PHP: composer audit --locked --format=json 45 Advisory-Einträge zu 14 Paketen; siehe A01
Event-Store: Wechsel vor Ablauf des Debounce Änderungsverlust isoliert reproduziert, siehe A06
Event-Store: Antworten in umgekehrter Reihenfolge beim Benutzerwechsel Falscher Benutzerkontext isoliert reproduziert, siehe A04
Datum in America/Los_Angeles 2026-01-01 wird mit aktueller Konvertierung als 31.12.2025 dargestellt, siehe A18

Die Checks liefen mit lokal vorhandenem Node 24.14.1 und PHP 8.4.19. Es wurden keine Paketupdates installiert. PHPUnit erzwingt SQLite :memory:; diese Ergebnisse ersetzen keinen MySQL-Integrationstest. Die API-Tests innerhalb der Suite meldeten keinen Fehler.

Für die beiden Store-Reproduktionen wurde der tatsächliche events.js-Funktionscode mit Vue-Reaktivität ausgeführt; API, Datenbankzugriffe und Store-Registrierung wurden kontrolliert ersetzt. Das prüft die Ablaufprobleme, ersetzt jedoch keinen Browser-/IndexedDB-End-to-End-Test. Es entstanden keine zusätzlichen Testdateien im Repository.

Nicht durchgeführt: vollständige Browser-/Mobilgeräte-QA, Lasttest, Live-Penetrationstest, Prüfung produktiver Konfiguration, Backups oder realer Nutzerdaten. Die Paketmeldungen stammen aus den am Auditdatum abgefragten Registern; ihre Zahl kann sich ändern. npm test im Frontend wurde nicht als Testnachweis verwendet, da das Skript lediglich erfolgreich beendet.

4. Kernbefunde und phasenabhängige Prioritäten

A01 – Bekannte Sicherheitslücken in Abhängigkeiten

Priorität: P2 im abgeschirmten Entwicklungsbetrieb; P1 für erreichbare relevante Schwachstellen vor öffentlicher Nutzung. Nachweis: Registry-Prüfungen des ursprünglichen Audits; konkrete Ausnutzbarkeit je Advisory gesondert bewerten.

Einordnung für die Demo: Paketmeldungen bedeuten nicht, dass zuerst ein vollständiges Produktionssystem aufgebaut werden muss. Erreichbarkeit und betroffener Ausführungspfad bestimmen die Dringlichkeit. Öffentlich erreichbare Entwicklungsdienste können auch bei ausschließlichen Testkonten ein Risiko für die Infrastruktur sein.

Die drei Paketprüfungen melden bekannte Schwachstellen. Besonders relevant:

Paket / Bereich Befund und Bedeutung
Passport 13.5.0 Liegt im betroffenen Bereich einer TokenGuard-Lücke für client_credentials-Tokens; Fix für dieses Advisory ab 13.7.1. Die dokumentierte Benutzerverwechslung hängt unter anderem von Client-/Benutzer-IDs und verwendeten Grants ab. Im Projekt werden Personal-Access-Tokens erzeugt; eine konkrete Ausnutzung wurde nicht nachgewiesen. Hersteller-Advisory
Vite 7.3.1 / 6.4.0 Bekannter Dateizugriff über den WebSocket eines erreichbaren Dev-Servers. Compose veröffentlicht Entwicklungsports und routet Entwicklungsdienste über Traefik. Eine tatsächliche externe Erreichbarkeit wurde nicht geprüft. Das Advisory betrifft den Dev-Server, nicht automatisch die ausgelieferte statische SPA. Hersteller-Advisory
Quasar 2.18.6 Prototype Pollution in extend(); Fix für dieses Advisory ab 2.22.0. Voraussetzung ist ein geeigneter Deep-Merge mit kontrollierbaren Eingaben; kein entsprechender Exploitpfad in dieser App bestätigt. Hersteller-Advisory
Weitere Pakete Unter anderem Laravel, Guzzle, CommonMark, Livewire, Symfony-Komponenten sowie Build-Werkzeuge. Der kritische npm-Befund im Backend betrifft shell-quote und ist kein Nachweis einer kritischen Lücke in einer Laravel-API-Route.

Die Composer-Ausgabe enthält 45 Meldungseinträge: 15 high, 24 medium, 5 low und einen ohne Schweregrad. Einträge können denselben Sachverhalt aus unterschiedlichen Quellen betreffen; die Zahl bezeichnet keine 45 bestätigten unabhängigen Angriffe auf die Anwendung.

Maßnahme: Sicherheitsupdates in einem separaten, überprüfbaren Änderungsschritt einspielen, Lockfiles aktualisieren und danach Builds, API-Tests und Browser-Abläufe prüfen. Laufzeitpakete und nur beim Entwickeln verwendete Werkzeuge getrennt priorisieren. Dev-Server nur für den vorgesehenen Entwicklungskreis erreichbar machen. Die genannten Fixversionen schließen jeweils das zitierte Advisory, nicht zwangsläufig alle inzwischen gemeldeten Lücken.

A02 – Bewusste Testzugänge und spätere Trennung vom Echtbetrieb

Priorität: P3 als Vorbereitung im aktuellen Teststand; P1 vor einer Nutzung derselben Umgebung mit echten privaten Konten/Inhalten. Nachweis: Code, bestehender Seeder-Test und Klarstellung des Projektverantwortlichen.

Fundstellen: DatabaseSeeder.php, Z. 16–34; LoginPage.vue, Z. 62–76; Deployment-Protokoll, Abschnitt 05.06.2026.

Die sechs festen API-Zugänge sind ausdrücklich zum Testen gewollt. Sie ermöglichen wiederholbare Persistenz- und Benutzerwechseltests und können für den aktuellen Zweck bestehen bleiben. Ein öffentliches Demokonto mit bewusst gemeinsamen Beispieldaten benötigt ebenfalls kein Versprechen individueller Vertraulichkeit.

Der technische Übergangspunkt bleibt relevant: updateOrCreate setzt beim erneuten Seeden auch Passwörter bestehender Konten zurück. Eine Beschränkung auf lokale oder ausdrücklich freigegebene Demo-Umgebungen fehlt. Das Protokoll dokumentiert den Seeder-Aufruf auch beim damaligen Live-Deployment; daraus folgt nicht, dass dort echte Kundenkonten existieren.

Auswirkung im Testbetrieb: Veränderungen gemeinsam verwendeter Testdaten und Passwort-Resets können Tests oder Vorführungen beeinflussen. Der ursprüngliche Hinweis auf den Zugriff auf private Kundeninhalte beschreibt ein späteres Nutzungsszenario, keinen festgestellten aktuellen Datenbestand.

Maßnahme: Die sechs Testkonten für die Persistenztests beibehalten; Seed-/Reset-Verhalten dokumentieren. Für eine öffentlich interaktive Demo entscheiden, ob Besucher gemeinsame Beispieldaten bearbeiten oder nur den lokalen Demo-Modus nutzen. Vor Einführung echter Konten Demo-Seeding ausdrücklich von deren Einrichtung und Daten trennen; bestehende individuelle Passwörter dann nicht durch einen allgemeinen Seeder überschreiben.

A03 – API-Login ohne Rate-Limit

Priorität: P2 im begrenzten Testbetrieb; P1 vor öffentlichem API-Zugriff. Nachweis: Quellcode und registrierte Routen.

Fundstellen: api.php, Z. 11; AuthController.php, Z. 16–30; bootstrap/app.php, Middleware-Konfiguration.

POST /api/login prüft Zugangsdaten und erzeugt Tokens, ohne Fehlversuche zu begrenzen. Ein möglicher Schutz der separaten Web-Anmeldung greift für diesen eigenen API-Controller nicht. Auch für Uploads und Sync ist kein anwendungseigenes Throttling sichtbar. Ein vorgelagerter Infrastruktur-Schutz ist unbekannt.

Auswirkung: Wiederholte Passwortversuche sowie Last durch Passwort-Hash-Prüfungen und Token-Erzeugung. Bei bewusst bekannten Demo-Zugängen steht zunächst die Verfügbarkeit der öffentlich erreichbaren Demo im Vordergrund; für individuelle Konten kommt der Schutz vor Passwortversuchen hinzu.

Maßnahme: Login-Limiter pro normalisierter Identität und IP, ergänzend passende Limits für API und Uploads. Mit Tests für HTTP 429 und die Rücksetzung nach erfolgreichen/zeitlich abgelaufenen Versuchen absichern.

A04 – Verspätete Antworten überschreiten den Benutzerkontext

Priorität: P1. Nachweis: Event-Store isoliert reproduziert; verwandtes Muster in Settings und Uploads durch Codeprüfung.

Fundstellen: events.js, Z. 170–233, 308–325, 607–658 und 712–720; settings.js, Z. 225–252.

loadRemoteEvents() bindet die Anfrage nicht dauerhaft an den Benutzer, für den sie gestartet wurde. normalizeRemoteEvent() liest nach dem Warten die dann aktuelle currentUserId. Antworten schreiben ohne Prüfung einer Sitzungs-/Anfragegeneration in den gemeinsamen Store und Cache.

Reproduktion: Anfrage von A offen lassen, auf B wechseln, zuerst Bs Antwort und danach As Antwort auflösen. Ergebnis: aktiver Benutzer B, angezeigter Event private A, lokal mit userId: B versehen. Das ist ein Fehler im Frontend; die API musste dafür keinen fremden Zugriff erlauben.

private A war lediglich der künstliche Titel im isolierten Reproduktionstest, kein ausgelesener privater Kundeninhalt. Im aktuellen Testmodell verfälscht der Fehler die Zuordnung zwischen den sechs Testkonten und damit die Persistenztests; diese Bedeutung bleibt auch ohne echte Kundenkonten hoch.

Bei Settings kann die verspätete Antwort ebenfalls den aktuellen Zustand überschreiben. Bei Medien wird editingEventId nach asynchronen Schritten erneut gelesen; ein Panelwechsel während eines Uploads kann die Antwort dem falschen Event zuordnen.

Maßnahme: Benutzer-ID, Sitzungsgeneration und Event-ID beim Start festhalten; nach jedem relevanten await prüfen; alte Requests abbrechen oder deren Ergebnisse verwerfen. Dasselbe Prinzip für Cache-Schreibvorgänge und Settings anwenden. Regressionsfälle mit verzögerten Antworten aufnehmen.

A05 – Ort und Bildtitel werden für Remote-Events nicht gespeichert

Priorität: P1. Nachweis: durchgängiger Abgleich von UI, Payload, Request, Model, Migration und Resource.

Fundstellen: events.js, Z. 179–188, 197–207 und 527–537; StoreEventRequest.php; Event.php; EventResource.php; Event-Migration.

Das Panel bearbeitet location und keyImageTitle. eventPayload() überträgt beide nicht; im Backend fehlen Validierung, Spalten, Mapping und Antwortfelder. Beim Zusammenführen der Serverantwort setzt die Normalisierung sie wieder auf leere Werte. Das betrifft somit bereits bestätigte Speicherantworten, nicht erst einen späteren Gerätewechsel.

Maßnahme: Beide Felder über die gesamte Datenkette ergänzen und mit einem Create-/Update-/Reload-Roundtrip testen. Migration und API-Vertrag dokumentieren. Globale Farbverläufe liegen dagegen bereits in Settings; gleichnamige Event-Altlasten nicht ungeprüft zu neuen Pflichtfeldern machen.

A06 – Automatisches Speichern verliert Änderungen beim Eventwechsel

Priorität: P1. Nachweis: isoliert mit dem tatsächlichen Store-Code reproduziert.

Fundstellen: events.js, Z. 500–519 und 551–564; zusätzlich Z. 266–285 für überlappende PUT-Anfragen.

Die Formularwerte werden mit 300 ms Verzögerung gespeichert. openPanel() ersetzt die ausgewählte Event-ID und Formularwerte, ohne zuvor den ausstehenden Speicherauftrag des bisherigen Events abzuschließen. Der Timer arbeitet anschließend mit den neuen Werten.

Reproduktion: Event A öffnen, Titel ändern und innerhalb der Verzögerung Event B öffnen. Im kontrollierten Lauf wurde nur /events/e2 mit Bs unverändertem Titel gespeichert; As Titel blieb original A.

Zusätzlich sind mehrere PUT-Anfragen desselben Events nicht serialisiert oder versioniert. Eine ältere Antwort kann den lokalen Zustand zurücksetzen; eine ältere, später verarbeitete Anfrage kann auch neuere Serverwerte überschreiben. Settings verwenden ebenfalls unkoordinierte vollständige PUT-Snapshots.

Maßnahme: Vor dem Eventwechsel den alten Entwurf mit seiner festen ID sichern. Pro Event eine geordnete Schreibfolge oder Revisionen verwenden und veraltete Antworten ignorieren. Für konkurrierende Geräte ein Konfliktverfahren vorsehen. Debounce allein garantiert keine Schreibreihenfolge.

A07 – Speicherfehler bleiben unsichtbar und können Daten verlieren lassen

Priorität: P1. Nachweis: Codeprüfung der Fehler- und Wiederladepfade.

Fundstellen: events.js, Z. 225–232, 252–257, 286–305, 338–369 und 594–604; settings.js, Z. 194–210; EventPanel.vue, Z. 454–458 und 484–488; quasar.config.js, framework.plugins.

Remote-Änderungen werden zunächst lokal dargestellt. Fehler beim Erstellen/Ändern setzen teilweise nur syncStatus: 'error'; beim Löschen wird der Eintrag vor der Serverbestätigung entfernt und ein Fehler lediglich geloggt. Es gibt keine aktive Retry-Queue für diese Schreibvorgänge. Beim nächsten erfolgreichen Laden ersetzt der Serverstand den Cache: nie gespeicherte Änderungen verschwinden, fehlgeschlagene Löschungen tauchen wieder auf.

Ein fehlgeschlagenes initiales Remote-Laden ergibt eine leere Eventliste, obwohl ein Cache vorhanden sein kann. Die Oberfläche unterscheidet diesen Fehler nicht zuverlässig von einem leeren Konto. Upload-Fehlermeldungen verwenden $q.notify?.(...), aber Quasar registriert nur Dark; die optionale Verkettung verschluckt das fehlende Notify-Plugin.

Maßnahme: Sichtbare Zustände für Laden, Speichern, gespeichert und fehlgeschlagen; Entwürfe und fehlgeschlagene Mutationen erhalten; Löschfehler zurückrollen oder als ausstehend anzeigen. Entweder einen vollständigen Offline-/Retry-Vertrag implementieren oder Offline-Schreiben ausdrücklich begrenzen. Notify korrekt registrieren und Validierungsfehler am betroffenen Feld anzeigen.

A08 – Cursor-Paginierung kann Events mit gleichem Datum überspringen

Priorität: P1. Nachweis: Controller und Pagination-Implementierung geprüft; kein eigener Datenbank-Reproduktionstest hinzugefügt.

Fundstelle: EventController.php, Z. 19–33.

Die Abfrage sortiert ausschließlich nach date. Dieses Feld ist nicht eindeutig. Liegt eine Seitengrenze innerhalb mehrerer Events desselben Tages, springt der nächste Cursor zu einem späteren Datum; noch nicht gelieferte Events dieses Tages werden übersprungen. Bereits limit=1 und zwei Events am selben Tag reichen als Regressionsszenario. Der aktive Client lädt zwar Folgeseiten, kann übersprungene Datensätze aber nicht wiederherstellen.

Laravel verlangt hierfür eine eindeutige Sortierspalte oder eindeutige Spaltenkombination. Laravel-Dokumentation

Maßnahme: Stabil nach Datum und eindeutiger ID sortieren; über mehrere Seiten mit gleichen Datumswerten testen. limit, since und Cursor-Eingaben validieren; Filter beim Erzeugen der Folgelinks erhalten. Aktuell begrenzt min(..., 200) nur die Obergrenze und ersetzt keine Eingabevalidierung.

A09 – Sync-Endpunkt umgeht die normalen Event-Validierungen

Priorität: P1. Nachweis: Codeprüfung; Endpunkt ist für angemeldete Benutzer erreichbar.

Fundstelle: EventController.php, Z. 127–193.

Validiert werden Action, UUID und der äußere Payload-Typ. Werte wie Titel, Datum, Emotion, URL und Notiz werden aus dem Payload direkt übernommen. Die Regeln von StoreEventRequest und UpdateEventRequest greifen hier nicht. Beispielsweise passiert emotion: 2 die Sync-Validierung, obwohl normales CRUD nur den Bereich −1 bis 1 erlaubt. Fehler werden mit dem unveränderten Exception-Text an den Client zurückgegeben; darunter können SQL- und Schema-Details sein. Ein Update eines nicht existierenden Events wird außerdem als ok quittiert.

Maßnahme: Gemeinsame Feldregeln für CRUD und Sync, aktionsabhängige Payload-Validierung und klar definierte Ergebnisse für fehlende Events. Technische Exception-Details serverseitig protokollieren, nach außen stabile Fehlercodes liefern. Eigentümerfilter beibehalten: Eine direkte Änderung fremder Events wurde in diesem Controller nicht festgestellt.

5. Weitere Fehler und Stabilitätsrisiken

A10 – Bildcache ist nicht nach Benutzer getrennt

Priorität: P2; relevant auf gemeinsam verwendeten Browserprofilen. Nachweis: Codeprüfung.

Fundstellen: useImageCache.js, Z. 9, 86–95 und 166–177; db/index.js, imageCache; auth.js, Z. 144–153.

Memory- und IndexedDB-Cache verwenden die Bild-URL als Schlüssel. Cachetreffer benötigen weder aktuellen Token noch passenden Benutzer. Beim Abmelden werden die Bildcaches nicht geleert. Settings-Hintergrund-URLs enthalten keine Benutzer-ID, sondern nur einen optionalen Zeitparameter. Event-Medien haben unterschiedliche IDs, bleiben aber unter ihrer alten URL lokal abrufbar. Das ist eine lokale Datenschutzlücke, kein nachgewiesener fehlender Ownership-Check des Servers.

Maßnahme: API-Origin, Benutzer-ID, Medien-ID/URL und Bildvariante in Cache-Schlüssel aufnehmen; Caches beim Benutzerwechsel kontrolliert verwerfen. Blob-URLs freigeben und ein Größenlimit vorsehen. clearEventImages() existiert, wird vom aktiven Anwendungscode aber nicht aufgerufen; vollständig geladene Bilder sind zudem nicht durchgängig im IndexedDB-Index für diese Bereinigung enthalten.

A11 – Abgelaufener Token und Frontend-Anmeldestatus laufen auseinander

Priorität: P2. Nachweis: Codeprüfung.

Fundstellen: apiClient.js, Z. 105–107; auth.js, Z. 67–90 und 144–153; router/index.js, Router-Guard.

Bei HTTP 401 wird der Token entfernt, das Benutzerprofil in localStorage und der Auth-Store bleiben jedoch angemeldet. Der Router leitet einen Besuch von /login dann erneut zur App um. Die API ist weiterhin geschützt, aber die UI kann in einem nicht mehr speicherfähigen Zustand hängen bleiben.

Logout wartet außerdem nicht auf die Token-Widerruf-Anfrage und ignoriert Fehler. Die bestehende Logout-Prüfung mit Passport::actingAs bestätigt HTTP 204, nicht den vollständigen Lebenszyklus eines zuvor real ausgestellten Tokens.

Maßnahme: Zentrale sitzungsgebundene 401-Behandlung für Token, Profil, Requests und Navigation; keine neue Sitzung wegen einer verspäteten 401-Antwort der alten Sitzung löschen. Widerruf mit festgehaltenem Token ausführen und Token-Laufzeiten festlegen. Test: Login → echter Tokenzugriff → Logout → derselbe Token wird abgewiesen.

A12 – Älterer Synchronisationsservice ist unvollständig und nicht benutzergebunden

Priorität: P2; vor einer Aktivierung als Offline-Lösung zwingend bearbeiten. Nachweis: Codeprüfung einschließlich tatsächlicher Aufrufer.

Fundstellen: syncService.js, Z. 10–12, 31–42, 77–79 und 99–161; events.js, Z. 349–369.

Konkrete Probleme:

  • Die gesamte Queue wird ohne userId-Filter mit dem aktuell gespeicherten Token gesendet. Bei vorhandenen Altaufträgen können so Daten im falschen Konto angelegt werden.
  • lastSyncCursor ist global; neue eingehende Events werden ohne userId gespeichert.
  • Es wird nur eine Seite abgeholt, anschließend aber bereits die lokale aktuelle Uhrzeit als Sync-Marke gespeichert. Weitere Seiten und Änderungen während des Abrufs können verloren gehen.
  • Löschungen besitzen keine Tombstones und werden deshalb beim Delta-Abruf nicht übertragen.
  • Die Rekursion für den nächsten 100er-Batch endet sofort am noch gesetzten isSyncing-Flag.
  • Erfolgreiches Remote-Laden kehrt in init() vor startAutoSync() zurück. Unabhängig davon startet der beim Import registrierte online-Listener die Queue-Verarbeitung bei einem Reconnect.

Neue Demo-Daten erzeugen aktuell keine Queue-Einträge. Deshalb wäre die Aussage „alle Demo-Daten werden hochgeladen“ falsch. Das Risiko betrifft insbesondere Altbestände und eine spätere Nutzung dieses Services.

Maßnahme: Einen verbindlichen Persistenzweg festlegen. Bis zur Fertigstellung alte Queue-Verarbeitung kontrolliert deaktivieren oder strikt pro Benutzer betreiben. Danach vollständige Pagination, serverseitige Sync-Marken, Löschmarker, Retry und Konfliktbehandlung ergänzen.

A13 – Event-Löschung hinterlässt Bilddateien

Priorität: P2. Nachweis: Löschpfade, Modelle und Fremdschlüssel geprüft.

Fundstellen: EventController.php, Z. 113–121 und 188–190; Event-Medien-Migration; Event.php.

Das Löschen eines Events entfernt über cascadeOnDelete dessen Medien-Datensätze, aber keine Dateien. Die Datei-Löschlogik liegt ausschließlich im Mediencontroller und wird beim Löschen des gesamten Events nicht aufgerufen. Die Models enthalten keinen entsprechenden Cleanup. Dasselbe Grundproblem besteht beim kaskadierenden Löschen eines Benutzers; Settings-Hintergründe benötigen ebenfalls einen eigenen Löschpfad.

Auswirkung: Private Dateien verbleiben ohne Datensatz auf dem Datenträger, der Speicherverbrauch wächst. Daraus folgt keine automatische öffentliche Abrufbarkeit, aber die erwartete Datenlöschung ist unvollständig.

Maßnahme: Gemeinsamen Löschservice bzw. zuverlässigen Cleanup-Job für alle Löschwege entwickeln. Dateipfade vor der Datenbanklöschung erfassen; ein reiner Model-Observer reicht für Query-Builder-Massenlöschungen und Datenbank-Kaskaden nicht. Löschung aller drei Varianten testen.

A14 – Medienersatz kann bei Teilfehlern alte und neue Bilder verlieren

Priorität: P2. Nachweis: Codeprüfung; Speicherfehler wurden nicht künstlich ausgelöst.

Fundstellen: EventMediaController.php, Z. 39–75; SettingsMediaController.php, store(); filesystems.php, lokaler Datenträger.

Datei-Schreibergebnisse werden nicht geprüft, während der Datenträger throw: false verwendet. Beim Key-Image-Ersatz werden bisherige Bilder gelöscht, bevor der neue Datensatz vollständig gespeichert ist. Ein voller Datenträger oder ein Datenbankfehler kann dadurch zu einer positiven Antwort mit fehlenden Dateien, verlorenen bisherigen Bildern oder verwaisten neuen Dateien führen. Parallele Key-Image-Uploads sind ebenfalls nicht als eine Operation geschützt.

Maßnahme: Schreibfehler explizit behandeln, neue Dateien zunächst vollständig bereitstellen, Metadaten konsistent umschalten und alte Dateien erst danach entfernen. Fehler mit kompensierender Bereinigung behandeln. Eine Datenbanktransaktion allein macht Dateisystemoperationen nicht atomar.

A15 – Bildgröße wird erst nach vollständigem Dekodieren reduziert

Priorität: P2. Nachweis: Request-Regeln und GD-Verarbeitung geprüft.

Fundstellen: StoreEventMediaRequest.php; StoreSettingsMediaRequest.php; EventMediaImageProcessor.php, process(); SettingsMediaController.php, processBackground().

Das Limit von 10 MB begrenzt die komprimierte Datei, nicht ihre Pixelzahl. imagecreatefromstring() dekodiert das Bild vollständig, bevor es verkleinert wird. Große stark komprimierte Bilder können deshalb viel Speicher und CPU verbrauchen. Pro Benutzer/Event existieren außerdem keine erkennbaren Medienquoten.

Maßnahme: Maximale Dimensionen und Pixelzahl vor dem teuren Verarbeitungsschritt prüfen, Upload-Rate und Speichermengen begrenzen. Bei wachsendem Volumen Bildverarbeitung in begrenzte Worker auslagern. Fehler kontrolliert zurückmelden; die vorhandene Prüfung von Dateitypen beibehalten.

A16 – Settings werden strukturell zu wenig validiert

Priorität: P2. Nachweis: Request und unmittelbare Verbraucher geprüft.

Fundstellen: UpdateSettingsRequest.php, Z. 24–39; settings.js, Z. 127 und 245–249.

floatingLines und presets werden nur als Arrays validiert. Für Elemente, Schlüssel, Anzahlen, Farben und Zahlenbereiche fehlen überwiegend Regeln. Beispielsweise kann presets: [null] die äußere Array-Regel erfüllen, während das Frontend anschließend preset.id liest. Unbekannte Schlüssel im Gesamt-Settings-Array können ebenfalls in die gespeicherten Daten gelangen. Das eröffnet in erster Linie Fehlzustände des eigenen Kontos und Ressourcenverbrauch, keine bestätigte Fremddatenänderung.

Maßnahme: Versioniertes Settings-Schema mit erlaubten Schlüsseln, Elementvalidierung, Grenzwerten und Größenlimit einführen. Geladene Cache- und API-Daten zusätzlich defensiv normalisieren. Laravel-Hinweis zu Array-Validierung

A17 – Laravel-Profilseite liefert HTTP 500

Priorität: P2. Nachweis: vorhandener Feature-Test zweimal fehlgeschlagen.

Fundstellen: ProfileUpdateTest.php, Z. 6–10; web.php, Z. 17; Profil-Komponente; vorhandenes Layout.

profile page is displayed erwartet HTTP 200 und erhält HTTP 500. Die konkrete Exception lautet No hint path defined for [layouts]. Der installierte Livewire-Stand erwartet standardmäßig layouts::app; das vorhandene App-Layout liegt unter components/layouts/app.blade.php, eine passende Anwendungskonfiguration ist nicht vorhanden.

Maßnahme: Layout-Zuordnung für den verwendeten Livewire-/Volt-Stand explizit und konsistent konfigurieren. Die Profilseite und die benachbarten Settings-Seiten als vollständige HTTP-Seiten prüfen. Erfolgreiche komponenteninterne Methoden-Tests beweisen nicht, dass die Seite gerendert werden kann.

A18 – Kalenderdaten werden in westlichen Zeitzonen verschoben

Priorität: P2. Nachweis: Datumsausdruck unter America/Los_Angeles ausgeführt.

Fundstellen: TimelineView.vue, Z. 129–155; EventPanel.vue, Z. 336–339.

new Date('YYYY-MM-DD') wird anschließend mit lokalen Monats-/Jahres-/Datumsfunktionen dargestellt. Dadurch wird 2026-01-01 in der überprüften Zeitzone zu 31.12.2025. Neben dem Eventdatum können somit auch Monats- und Jahreszuordnungen der Timeline falsch sein.

Maßnahme: Reine Kalenderdaten als solche behandeln: Datumsteile ohne UTC-Zeitpunkt parsen oder UTC-Auswertung und Darstellung konsequent vereinheitlichen. Mindestens UTC, Europa/Berlin und Amerika/Los_Angeles testen.

A19 – Zulässige URL-Länge passt nicht zur MySQL-Spalte

Priorität: P2. Nachweis: Schema-/Request-Abgleich; nicht gegen MySQL ausgeführt.

Fundstellen: StoreEventRequest.php und UpdateEventRequest.php, Regel image; Event-Migration, Spalte image.

Die API erlaubt 500 Zeichen, die Migration erzeugt eine normale String-Spalte mit standardmäßig 255 Zeichen. Unter MySQL kann eine formal gültige Anfrage mit längerer URL deshalb beim Speichern scheitern. SQLite-Tests decken diese Längenbeschränkung nicht gleichwertig ab. Die eigenen kurzen Medienpfade erreichen das Limit normalerweise nicht, externe URLs können es erreichen.

Maßnahme: Vertrag und Spaltenlänge angleichen oder externe Bild-URLs bewusst einschränken; Grenzwertprüfung zusätzlich unter MySQL ausführen.

6. Optimierungen und Wartbarkeit

O01 – Datenladen und Bildspeicher begrenzen

Der aktive Event-Store lädt sämtliche Seiten einschließlich Medienmetadaten, bevor der endgültige Zustand gesetzt wird. Die DOM-Virtualisierung reduziert den Renderaufwand, aber weder Gesamttransfer noch Cache-Schreibmenge. Für große Timelines bieten sich seitenweises Anzeigen und bei Bedarf geladene Galerie-Metadaten an. Vorher A08 beheben, damit Datensätze nicht bereits an Seitengrenzen fehlen.

Medien werden serverseitig über Storage::get() vollständig in den PHP-Speicher geladen. Bei höherem Volumen Streaming bzw. autorisierte Webserver-Auslieferung und kontrolliertes HTTP-Caching prüfen. Der clientseitige Bildcache braucht ein Budget und eine Eviction-Strategie; gleiche parallele Bildanfragen lassen sich außerdem zusammenfassen.

O02 – Bundle und öffentliche Assets verkleinern

Der gemessene LifeWaveLayout-Chunk hat 714,12 kB minifiziert / 195,67 kB gzip. frontend/public/images belegt rund 59 MiB, das erzeugte SPA-Verzeichnis rund 106 MiB. Die Verzeichnisgröße bedeutet nicht, dass beim Start alles übertragen wird; Quasar kopiert aber auch ungenutzte öffentliche Assets in das Build-Ergebnis.

Große Beispielbilder verkleinern, ungenutzte Assets aus dem Produktionspfad entfernen und selten geöffnete Panels bei Bedarf laden. Three.js-/Shader-Anteil gezielt mit einem Bundle-Report prüfen. Die existierende Timeline-Virtualisierung, Begrenzung auf 16 Shaderpunkte, adaptive Pixelauflösung und Freigabe der WebGL-Ressourcen sind positive Ansätze und sollten erhalten bleiben.

O03 – Settings-Schreiblast reduzieren

Änderungen von Scrollposition oder Darstellung lösen nach kurzer Verzögerung PUTs des gesamten Settings-Dokuments einschließlich Presets aus. Bei vielen Presets entsteht unnötiger Transfer und konkurrierende Snapshots erhöhen das Überschreibungsrisiko.

Persistente Benutzerpräferenzen von flüchtigem Viewport-Zustand trennen, nur geänderte Bereiche übertragen oder die Schreibfrequenz begrenzen. Beim lokalen Demo-Modus kann ein großes Base64-Hintergrundbild zusätzlich die localStorage-Quota erreichen; localStorage.setItem() in persist() behandelt diesen Fehler nicht. Größere Bilder gehören in den Blob-Speicher.

O04 – Reproduzierbare Entwicklung und automatische Prüfgates

frontend/package.json führt vor jedem Dev-Start npm install aus; Compose startet ebenfalls npm install vor npm run dev. Damit wird beim Containerstart zweimal installiert. Installation und Start trennen, für kontrollierte Builds den vorhandenen Lockfile mit npm ci verwenden.

Im Repository wurde keine GitHub-Actions-Prüfpipeline unter .github/workflows gefunden. Lint, beide Builds, Backend-Tests und Paketprüfungen sollten nachvollziehbare CI-Gates erhalten. Frontend-Tests für Auth-/Store-Abläufe fehlen besonders; npm test ist nur ein Platzhalter. MySQL-Prüfungen ergänzen die vorhandenen schnellen SQLite-Tests.

Die generierten Buildwarnungen zu veralteten Browserslist-Daten und npm-Konfigurationsschlüsseln sind Wartungsthemen. Sie verursachten in dieser Prüfung keinen Buildabbruch.

O05 – Prototypen und Statusdokumentation eindeutig zuordnen

src, _src, legacy und die Visualisierungsexperimente sollten klar als aktiv, archiviert oder experimentell markiert sein. Änderungen am falschen Baum bleiben sonst wirkungslos. Das Root-README enthält weiterhin Platzhalter; Setup, externe Infrastruktur, Demo-/Remote-Verhalten und Versionsstand sollten aus dem aktuellen Code beschrieben werden.

Größere Stores und das Event-Panel bündeln UI, Entwurf, API und Cache. Nach Absicherung der kritischen Abläufe lohnt sich eine Aufteilung in klar abgegrenzte Verantwortlichkeiten. Ein großer Umbau vor Regressionstests würde die bereits vorhandenen Ablaufprobleme schwerer überprüfbar machen.

7. Was bereits gut gelöst ist

  • Geschützte API-Routen verwenden auth:api; Event-Abfragen werden über die Benutzerrelation eingeschränkt.
  • Direkte Medienauslieferung prüft den Besitzer; Settings-Hintergrundpfade werden aus dem authentifizierten Benutzer abgeleitet.
  • Fremdzugriffe auf Events, Settings und Medien sind teilweise ausdrücklich durch Feature-Tests abgedeckt.
  • Normales Event-CRUD verwendet Form Requests und explizites Feldmapping; dort wird kein beliebiges Request-Objekt massenhaft übernommen.
  • Private Medien liegen auf dem privaten Datenträger; Dateipfade werden serverseitig erzeugt, Bildtypen eingeschränkt und Bilder neu kodiert.
  • Medien werden beim Event-Laden eager geladen; die offensichtliche N+1-Abfrage pro Event wird damit vermieden.
  • Stabile Client-UUIDs, Indizes für Benutzer/Datum und Benutzer/Änderungszeit sind eine passende Grundlage für weitere Synchronisationsarbeit.
  • CORS enthält konkrete erlaubte Origins. Fehlendes Login-Throttling wird dadurch allerdings nicht ersetzt.
  • Im aktiven Frontend wurde bei der gezielten Suche keine Verwendung von v-html, innerHTML oder eval() gefunden. Das ist keine vollständige XSS-Freigabe, aber ein positiver Ausgangspunkt.

8. Empfohlene Reihenfolge

8.1 Jetzt: bestehende Testversion zu einer verlässlichen Demo entwickeln

  1. Demo-Kernabläufe reparieren: A04–A08. Kontenwechsel, vollständige Feldspeicherung, zuverlässiges Autosave, sichtbare Fehler und vollständiges Wiederladen haben Vorrang.
  2. Vorführung mit reproduzierbaren Daten vorbereiten: Die sechs API-Konten für Persistenztests und ausgewählte Beispielgeschichten verwenden. Den lokalen Demo-Modus separat testen. Festlegen, wie ein definierter Präsentationsstand wiederhergestellt wird, ohne laufende Tests unbeabsichtigt zurückzusetzen.
  3. Betroffene Nebenabläufe stabilisieren: A09–A19 nach tatsächlicher Demo-Nutzung abarbeiten. Besonders relevant sind Anmeldung nach Tokenablauf, Uploads, Medienersatz und Löschung. A17 blockiert eine Vorführung der Laravel-Profilseite; wenn nur die Quasar-Oberfläche gezeigt wird, ist dieser Fehler kein unmittelbarer Hindernisgrund für genau diese Präsentation.
  4. Gezielt absichern: Tests für die nachgewiesenen Store-Fehler ergänzen und die gezeigten Abläufe auf den vorgesehenen Browsern/Mobilgeräten durchspielen. Eine vollständige Offline-Synchronisation ist für eine bewusst online genutzte Werbedemo nicht erforderlich; Fehler und Offline-Grenzen müssen trotzdem verständlich bleiben.

8.2 Vor öffentlicher, interaktiver Nutzung

Zugangsmodell festlegen: betreute Präsentation, lokal ausprobierbare Demo oder gemeinsame serverseitige Testkonten. Werden API-Schreibzugriffe oder Uploads öffentlich angeboten, A01/A03 sowie die Validierungs- und Ressourcenbegrenzungen aus A09/A15/A16 vor dieser Freigabe bearbeiten. Für gemeinsame Konten sind Veränderungen durch andere Besucher erwartbares Verhalten; eine Kennzeichnung als gemeinsame Beispieldaten und ein kontrollierter Reset helfen der Vorführbarkeit.

Falls API oder Entwicklungsdienste bereits öffentlich erreichbar sind, ist dieser Teil entsprechend vorgezogen. Der Status der Erreichbarkeit ist im Audit offen.

8.3 Vor echten individuellen Konten

Demo-Seeding gemäß A02 trennen, Benutzer-/Cache-/Token-Isolation vollständig absichern und zuverlässige Speicherung sowie Medienlöschung verbindlich machen. Weitergehende Kontenverwaltung und Betriebsanforderungen an dieser Phase ausrichten. Die mögliche spätere Crowdfunding-Kampagne ändert an der technischen Reihenfolge für die aktuelle Demo zunächst nichts.

Abnahmekriterien für die Demo-Stabilisierung

  • Testkonto A laden, währenddessen zu B wechseln: keine Daten, Bilder oder Settings von A im Kontext B; auch bei verspäteter 401-Antwort bleibt B korrekt angemeldet.
  • Event A ändern und unmittelbar B öffnen: As Änderung bleibt nach Reload erhalten.
  • Zwei Schreibanfragen absichtlich verzögern/umordnen: der jüngere Stand gewinnt kontrolliert.
  • Ort und Bildtitel nach Create, Update, Reload und erneutem Login unverändert vorhanden.
  • Mehrere Events mit identischem Datum über mehrere Cursorseiten vollständig und ohne Dubletten geladen.
  • Netzwerk-/422-/500-Fehler beim Schreiben sichtbar; keine still verworfenen Entwürfe oder bestätigten Löschungen ohne Servererfolg.
  • Lokalen Demo-Modus separat prüfen: Anlegen und Reload funktionieren browserlokal; neue Demo-Mutationen gehen nicht an die API.
  • Definierte Beispieldaten lassen sich für die Vorführung nachvollziehbar herstellen; persistierte Testdaten bleiben zwischen normalen Sitzungen erhalten.
  • Frontend-Build/Lint und die Tests der kritischen Abläufe erfolgreich; betroffene Vorführpfade im Browser geprüft.

Ergänzende Kriterien für öffentliche API-Nutzung und späteren Echtbetrieb

  • Ungültige Sync-Payloads werden abgewiesen; technische Exception-Texte erscheinen nicht in API-Antworten.
  • Event-/Benutzerlöschung beseitigt zugehörige Dateien; fehlgeschlagener Bildersatz erhält das bisherige Bild.
  • API-Login wird bei wiederholten Fehlversuchen begrenzt; reales Token ist nach erfolgreichem Logout unbrauchbar.
  • Öffentlich nutzbare Uploads haben angemessene Mengen-/Größenlimits; relevante Sicherheitsupdates sind geprüft.
  • Vor echten Konten: kein allgemeiner Seeder setzt deren individuelle Passwörter zurück oder vermischt ihre Daten mit Präsentationsdaten.
  • Gesamte Backend-Suite grün; MySQL-Integration und automatische Prüfungen ergänzen die Demo-Tests.

9. Paketprüfung: kompakte Bestandsaufnahme

Die folgenden Zahlen dokumentieren den Registry-Stand vom 17.09.2026 und dienen der Nachverfolgung. npm zählt betroffene Pakete einschließlich transitiv betroffener Pakete; Composer zählt hier Advisory-Einträge. Die Zahlen dürfen daher nicht direkt addiert oder als Anzahl ausnutzbarer Anwendungslücken interpretiert werden.

Composer-Paket Meldungseinträge
guzzlehttp/guzzle 9
guzzlehttp/psr7 4
laravel/framework 3
laravel/passport 1
league/commonmark 12
livewire/livewire 1
phpseclib/phpseclib 4
symfony/http-foundation 1
symfony/http-kernel 1
symfony/mailer 1
symfony/mime 2
symfony/polyfill-intl-idn 1
symfony/routing 2
symfony/yaml 3

Frontend-npm meldet: @humanfs/node, @quasar/app-vite, baseline-browser-mapping, body-parser, brace-expansion, browserslist, esbuild, flatted, immutable, js-yaml, lodash, nanoid, node-forge, path-to-regexp, picomatch, postcss, postcss-selector-parser, qs, quasar, serialize-javascript, vite.

Backend-npm meldet: axios, browserslist, follow-redirects, form-data, lodash, nanoid, picomatch, postcss, rollup, shell-quote, vite.

Reproduzierbare Basisbefehle: npm audit --json jeweils in frontend/ und backend/, sowie composer audit --locked --format=json in backend/. Nach Updates die dann aktuellen Einzelmeldungen und ihre tatsächlichen Ausführungspfade erneut bewerten.