Dieser Artikel ist Teil der Friends4-Enzyklopädie und wird nach Wiki-Prinzipien gepflegt, geprüft und versioniert.
Friends4 – Projekt-Audit (2026-07-10)
Vollständige technische Prüfung des Repositories dome9201/friends4 auf Branch claude/friends4analysisrefactorsjybav. Vorgehen: statische Analyse (ESLint mit SecurityPlugin, TypeScriptTypecheck), Ausführung der kompletten Testsuite, npm audit, SecretScan, AltlastenSuche und gezielte SicherheitsReviews von Session, CSRF, Admin und SQLSchichten. Projektübersicht Technologien Backend: Node.js (ES Modules), Express 4, Socket.IO 4 (mit RedisAdapter für MultiInstanz), expresssession mit MySQLSessionSto
Friends4 – Projekt-Audit (2026-07-10)
Vollständige technische Prüfung des Repositories `dome9201/friends4` auf Branch
`claude/friends4-analysis-refactor-sjybav`. Vorgehen: statische Analyse
(ESLint mit Security-Plugin, TypeScript-Typecheck), Ausführung der kompletten
Testsuite, `npm audit`, Secret-Scan, Altlasten-Suche und gezielte
Sicherheits-Reviews von Session-, CSRF-, Admin- und SQL-Schichten.
---
Projektübersicht
Technologien
- **Backend:** Node.js (ES Modules), Express 4, Socket.IO 4 (mit Redis-Adapter
für Multi-Instanz), express-session mit MySQL-Session-Store, MySQL (mysql2),
Redis, Nodemailer, Multer (Uploads), AWS S3 SDK, PayPal Server SDK.
- **Frontend:** Serverseitig gerenderte EJS-Views (`views/`), gebündelte Assets
via esbuild (`scripts/build-assets.mjs` → `public/dist/`), Leaflet
(lokal gevendort in `leaflet-2.0.0-alpha.1/`, serviert als `/vendor/leaflet`).
- **Mobile:** `friends4-android-app/` (Android), `friends4-ios-app/` (iOS);
Download-APK wird über `public/app-debug.apk` ausgeliefert.
- **Sonstiges:** `jarvis/` (AI-Agent inkl. Alexa-Skill), `house/`
(3D-Assets), Emergency-3D-Spiel unter `public/games/emergency3d/`.
- **Betrieb:** PM2 (`npm run pm2:start`, Prozessname `friends4`),
Deploy-/Nginx-/RTMP-Skripte unter `deploy/` und `scripts/`.
Einstiegspunkte und Hauptprozesse
- `src/start.js` → `src/server.js` (Haupt-App: Express + Socket.IO).
- Bootstrap-Schicht: `src/bootstrap/` (App-Factory, Session, Security-Header,
Socket-Setup, Lifecycle).
- Migrationen: `config/migrate.js` + `migrations/` (84 Dateien, durch
`scripts/ci/migration-guard.mjs` abgesichert).
Wichtige Ordner
| Ordner | Inhalt |
|---|---|
| `src/routes`, `src/controllers`, `src/services`, `src/models` | Saubere Schichtung Route → Controller → Service → Model |
| `src/middleware` | Auth, Admin-Guards, CSRF/Security, Rate-Limit, Bot-Schutz |
| `src/sockets` | Echtzeit (Worldchat, Nachrichten, Calls) |
| `views/` | EJS-Frontend inkl. GameWorld/VideoWorld |
| `public/` | Statische Assets, `dist/`-Bundles, Emergency-3D-Spiel |
| `tests/` | 291 Unit-/Regressionstests (node:test) + Contract-Tests |
Die Struktur ist insgesamt sinnvoll, konsistent und wartbar; Controller-,
Service- und Model-Schicht sind klar getrennt, Sicherheitslogik ist
zentralisiert (`src/middleware/`).
---
Behobene Fehler
1. Emergency3D: Werkfeuerwehr-Zone vom Wachen-Block entkoppelt (Priorität: hoch)
- **Betroffene Datei:** `public/games/emergency3d/js/access-control.js`
- **Fehlerbeschreibung:** Beim Umbau des Industriegebiets (Commit-Historie:
`CHEMICAL_WORKS` wurde von bx 6–8 auf bx 7–10 verschoben,
`DISTRICTS.WORKS_FIRE_STATION` von Block (8,2) auf (9,2) verlegt) blieb die
Zone `halter-werkfeuerwehr` hart auf Block (8,2) kodiert. Die
Werkfeuerwehr-Wache lag dadurch **außerhalb aller Werkszonen**
(`isInsideWorks()` lieferte `false` für den Wachen-Standort).
- **Auswirkung:** `routeThroughFactoryGate()` behandelte Werkfeuerwehr-Ausfahrten
als normale Fahrten (Start und Ziel "beide außerhalb") — die gesamte
Pforten-Logik (Haupt-/Lkw-Pforte, Ausweichpforte, Blockade-Meldung) wurde für
die WF-Wache übersprungen. 5 Regressionstests in
`tests/emergencyFactoryNavigation.test.js` schlugen fehl (Tests 9, 11, 12,
15, 16).
- **Korrektur:** Das Zonen-Polygon der Werkfeuerwehrwache wird jetzt aus
`DISTRICTS.WORKS_FIRE_STATION` abgeleitet statt aus festen Koordinaten. Bei
künftigen Kartenumbauten bleiben Spawn-Position und Zone automatisch synchron.
- **Verifikation:** `tests/emergencyFactoryNavigation.test.js` 26/26 grün,
komplette Suite 291/291 grün.
Weitere Prüfungen ohne Befund: Syntax-Check (284 Dateien), ESLint (0 Errors,
400 Warnings — ausschließlich heuristische `security/detect-object-injection`-
Hinweise, überwiegend in Tests, kein realer Injection-Pfad), TypeScript-
Typecheck fehlerfrei.
---
Sicherheitsprobleme
Es wurde bereits ein umfangreiches Sicherheits-Fundament vorgefunden (siehe
auch vorhandenes `SECURITY_AUDIT_2026-07.md`). Ergebnis dieser Prüfung:
| Schwere | Befund | Status |
|---|---|---|
| kritisch | keine gefunden | — |
| hoch | keine gefunden | — |
| mittel | `SESSION_SECRET`-Fallback: fehlt die Variable, wird ein lokales Secret in `.session-secret` erzeugt (mit deutlicher Warnung im Log). Für Multi-Instanz-Betrieb muss die Variable gesetzt sein. | offen (bewusstes Design, Warnung vorhanden) |
| niedrig | ESLint-Security-Warnings (`detect-object-injection`, `non-literal-fs-filename`) — heuristisch, geprüfte Stellen nutzen interne Konstanten bzw. Testfixtures. | offen, unkritisch |
Positiv verifiziert:
- **Sessions:** `__Host-`-Cookie-Präfix in Produktion, `httpOnly`,
`sameSite=lax`, `secure`, rolling expiry, `unset: 'destroy'`.
- **CSRF:** eigene Token-Middleware (`src/middleware/security.js`) mit
Token-Rotation, Alters-Limit (2 h) und Pattern-Validierung.
- **Admin:** alle nativen Admin-APIs hinter `requireAdmin` /
`requireNativeAdminAccess`; Rollenprüfung zentral in
`src/middleware/authMiddleware.js`.
- **SQL:** durchgängig parametrisierte Queries; die einzigen dynamischen
`ALTER TABLE`-Statements (`src/models/reportModel.js`) verwenden
ausschließlich interne Konstanten, keine Nutzereingaben.
- **Prozess-Aufrufe:** `spawn`/`execFile` mit Argument-Arrays (kein Shell-
String-Zusammensetzen) in E-Mail-, HLS- und RTMP-Services.
- **Secrets:** kein Klartext-Secret im Repository; `.env`-Dateien nicht
eingecheckt, `.env.example` enthält nur Platzhalter.
- **Abhängigkeiten:** `npm audit` (inkl. Produktion): **0 Vulnerabilities**;
Overrides für bekannte transitive Probleme (qs, path-to-regexp,
socket.io-parser, minimatch) bereits gepflegt.
---
Unnötige Dateien
| Datei | Status | Nachweis | Begründung |
|---|---|---|---|
| `/app-debug.apk` (Repo-Wurzel, 7,2 MB) | **archiviert** → `archive/review-before-delete/` | Volltextsuche: einziger Code-Verweis (`src/server.js:1102`) zeigt auf `public/app-debug.apk`; MD5 der Wurzel-Datei weicht von der ausgelieferten APK ab | Alter Debug-Build, wird nicht serviert; Details in `archive/review-before-delete/README.md` |
| `public/app-debug.apk` | behalten | von `src/server.js` als App-Download serviert | produktiv |
| Root-SQL-Dateien (`friends4.sql`, `A.Sql`, `G.sql`, `2506.spl`, `2706.sql`, `qr.sql`, `games.sql`, `Jarvis.sql`, `jarvis.sql`) | behalten | Kopfkommentare weisen sie als dokumentierte manuelle Hotfix-/Neuaufbau-Skripte aus („Apply manually only if migrations are not available…") | bewusste Betriebs-Dokumentation; Empfehlung: mittelfristig in `docs/sql/` bündeln |
| `leaflet-2.0.0-alpha.1/` | behalten | `src/server.js:1052` serviert `dist/` als `/vendor/leaflet`; Fallback-Hinweis in `views/GameWorld/partials/game-shell.ejs` | aktiv genutzt (lokales Vendoring) |
| `tests/emergency/` (194 MB DDS-/Textur-Quellmaterial) | behalten, **Prüf-Kandidat** | keine Code-Referenz mehr (nur Kommentare); ein Test erzwingt sogar, dass Prefabs NICHT auf `tests/emergency` verweisen | Quellmaterial der EM5-Texturen. Löschen verkleinert das Arbeitsverzeichnis, aber nicht die Git-Historie; Entscheidung (inkl. evtl. History-Rewrite) sollte der Maintainer treffen |
| `public/dist/` ältere Hash-Versionen (z. B. mehrere `admin.*.css/js`) | behalten | `asset-manifest.json` referenziert aktuelle Hashes; alte Hashes können von gecachten Seiten noch angefragt werden | risikoarm erst nach Cache-Ablauf aufräumen |
| Leere Chunk-Dateien `public/dist/chunks/chunk.QFTOWZEP.js`, `chunk.ZQEDDR42.js` | behalten | werden von mehreren Bundles per `import` referenziert | leere Side-Effect-Chunks von esbuild, korrekt |
| `.old`/`.bak`/`.tmp`/`~`-Dateien | keine vorhanden | `find`-Suche über das gesamte Repo | — |
| Leere Dateien/Ordner | keine problematischen | nur die o. g. esbuild-Chunks und `public/streams/` (Laufzeit-Zielordner für HLS) | — |
---
Abhängigkeiten
- **Entfernt:** keine. Alle deklarierten Pakete werden verwendet
(stichprobenartig über Imports verifiziert); nichts Ungenutztes gefunden.
- **Aktualisiert:** keine (bewusst). `npm audit` meldet 0 Vulnerabilities,
es gibt also keinen sicherheitsgetriebenen Update-Zwang.
- **Bewusst nicht aktualisiert (Major-Versionen mit Breaking Changes):**
Express 4→5, Helmet 6→8, EJS 3→6, bcryptjs 2→3, Redis 5→6,
ESLint 9→10, TypeScript 5→7. Ein Major-Upgrade sollte jeweils einzeln mit
Regressionstests erfolgen.
- **Bekannte Risiken:** keine offenen CVEs; transitive Risiken sind über die
`overrides` in `package.json` bereits fixiert.
---
Datenbankänderungen
Keine erforderlich. Es wurden keine neuen Migrationen angelegt, keine
bestehenden verändert (Migrations-Guard: 82 Migrationen geprüft, erfolgreich).
Produktive Daten wurden nicht berührt.
---
Testergebnisse
| Prüfung | Ergebnis |
|---|---|
| Syntax-Check (`scripts/check-syntax.sh`, 284 Dateien) | ✅ erfolgreich |
| ESLint (`npm run lint`) | ✅ 0 Errors (400 heuristische Warnings) |
| TypeScript (`npm run typecheck`) | ✅ erfolgreich |
| Unit-/Regressionstests (`npm run ci:unit`) | ✅ **291/291** (vorher 286/291 — 5 Fehlschläge durch den behobenen Zonen-Bug) |
| Contract-Tests (`npm run ci:contract`) | ✅ 2/2 |
| Migrations-Guard (`npm run ci:migration-check`) | ✅ 82 Migrationen |
| `npm audit` (inkl. `--omit=dev`) | ✅ 0 Vulnerabilities |
| Anwendungsstart mit echter DB / manuelle E2E-Flows (Login, Uploads, Sockets) | ⚠️ nicht ausführbar — in dieser Umgebung existiert keine MySQL/Redis-Instanz; die App fällt korrekt auf lokale Fallbacks zurück und loggt verständliche Hinweise |
---
Noch offene Punkte
- **Manuell prüfen:** `tests/emergency/` (194 MB Texturen-Quellmaterial) —
Entscheidung über Löschung/Auslagerung (ggf. Git-LFS oder separates
Asset-Repo) beim Maintainer.
- **Archiv-Review:** `archive/review-before-delete/app-debug.apk` nach
Gegenprüfung endgültig löschen.
- **Technische Schuld:** Root-SQL-Hotfix-Dateien nach `docs/sql/` bündeln;
ältere gehashte `public/dist/`-Artefakte nach Cache-Ablauf aufräumen.
- **Betrieb:** `SESSION_SECRET` in allen Produktionsumgebungen explizit setzen
(Multi-Instanz-Konsistenz).
- **Ohne automatisierte Tests:** echte E2E-Flows (Login/Registrierung mit
Live-DB, Datei-Uploads, Socket-Reconnects, PayPal, Push) — Unit-Abdeckung
ist gut, ein Staging-Smoke-Test bleibt empfohlen.
- **Repo `dome9201/community-android-app`:** ist leer (keine Commits) —
dort war nichts zu prüfen oder zu ändern.
Hinweise
Nutze diesen Artikel als Orientierung. Bei Regeln gilt die aktuell freigegebene Version und bei Unsicherheit die Moderation.
Warnungen
Melde veraltete, missverständliche oder sicherheitsrelevante Informationen direkt über das Formular.
Diskussion
Die Diskussionsseite ist für konkrete Verbesserungsvorschläge gedacht: fehlende Abschnitte, unklare Formulierungen, Quellenhinweise oder Korrekturen. Sie ist keine Chatfunktion.
Bilder und Downloads
Optionale Medien, Grafiken oder Downloads können über strukturierte Daten und zukünftige Dateifreigaben ergänzt werden.