April 2026 waren Wirtschaft Feedback
This commit is contained in:
parent
02f2a4c23e
commit
9ce711d6b2
167 changed files with 25278 additions and 8518 deletions
253
dev/docs/project-audit.md
Normal file
253
dev/docs/project-audit.md
Normal file
|
|
@ -0,0 +1,253 @@
|
|||
# Projekt-Audit: Kritische Stellen & Verbesserungsvorschlaege
|
||||
|
||||
Erstellt: 2026-03-12
|
||||
|
||||
> Hinweis: Einige Stellen (auskommentierter Code, Debug-Statements) sind bewusst so,
|
||||
> da der Code an vielen Stellen noch in Entwicklung ist. Diese Datei dokumentiert
|
||||
> trotzdem alle Fundstellen, damit sie spaeter gezielt aufgeraeumt werden koennen.
|
||||
|
||||
---
|
||||
|
||||
## 1. Sicherheit
|
||||
|
||||
### 1.1 APP_KEY als Passwort (KRITISCH) — BEHOBEN 2026-03-12
|
||||
|
||||
**Problem:** Der Laravel APP_KEY wurde als Default-Passwort fuer neue User gesetzt und mit
|
||||
loose comparison (`==`) statt `Hash::check()` verglichen.
|
||||
|
||||
**Fix:**
|
||||
- `app/Repositories/UserRepository.php` — `Hash::make(config('app.key'))` statt `env('APP_KEY')`
|
||||
- `app/User.php isPasswort()` — `Hash::check(config('app.key'), $this->password)` statt `==`
|
||||
- `app/Repositories/CustomerRepository.php:22` — war bereits auskommentiert, kein Handlungsbedarf
|
||||
|
||||
> ACHTUNG: Bestehende User mit dem alten Klartext-APP_KEY als Passwort muessen
|
||||
> einmalig migriert werden (z.B. per Artisan-Command), da `Hash::check()` gegen
|
||||
> den alten Klartext-Wert nicht mehr matcht. Alternativ: Beim naechsten Login
|
||||
> pruefen und automatisch re-hashen.
|
||||
|
||||
---
|
||||
|
||||
### 1.2 Unauthentifizierter Cron-Endpoint
|
||||
|
||||
**Problem:** `/cron/jobs/action/{action}/{key}` in `routes/web.php` ist ein GET-Endpoint
|
||||
ohne Auth-Middleware. Cron-Jobs koennen von aussen getriggert werden, wenn die URL bekannt ist.
|
||||
|
||||
**Vorschlag:**
|
||||
- Signed-URL Middleware (`signed`) oder ein geheimer Token-Vergleich in Middleware
|
||||
- Alternativ: Cron-Jobs ausschliesslich ueber `php artisan schedule:run` ausfuehren
|
||||
und den HTTP-Endpoint entfernen
|
||||
|
||||
---
|
||||
|
||||
### 1.3 env() ausserhalb von Config-Dateien — TEILWEISE BEHOBEN 2026-03-12
|
||||
|
||||
**Problem:** `env()` funktioniert nicht wenn `config:cache` aktiv ist.
|
||||
|
||||
**Fix (im Rahmen von 1.1):**
|
||||
- `app/User.php` und `app/Repositories/UserRepository.php` — `env('APP_KEY')` durch
|
||||
`config('app.key')` ersetzt.
|
||||
- `app/Repositories/CustomerRepository.php:22` — war bereits auskommentiert.
|
||||
|
||||
**Pruefen:** Ob weitere `env()` Aufrufe ausserhalb von `config/` existieren.
|
||||
|
||||
---
|
||||
|
||||
### 1.4 Datei-Upload: Client-Extension vertraut
|
||||
|
||||
**Problem:** `getClientOriginalExtension()` nutzt die vom Browser gelieferte Dateiendung.
|
||||
Ein manipulierter Upload koennte eine unerwartete Extension erhalten.
|
||||
|
||||
**Dateien:**
|
||||
- `app/Repositories/FileRepository.php:56`
|
||||
- `app/Repositories/ImportRepository.php` (gleicher Ansatz)
|
||||
|
||||
**Vorschlag:** `$file->extension()` verwenden (leitet Extension aus MIME-Type ab)
|
||||
oder zusaetzlich gegen eine Whitelist validieren.
|
||||
|
||||
---
|
||||
|
||||
### 1.5 PayPal-Fehler an User exponiert
|
||||
|
||||
**Problem:** `abort(403, 'PayPal Type: '.$order['type'])` gibt interne PayPal-Fehlertypen
|
||||
direkt an den User weiter.
|
||||
|
||||
**Datei:** `app/Http/Controllers/Pay/PayPalController.php:65`
|
||||
|
||||
**Vorschlag:** Fehler intern loggen, dem User eine generische Fehlermeldung zeigen.
|
||||
|
||||
---
|
||||
|
||||
## 2. Routing-Probleme
|
||||
|
||||
### 2.1 Doppelte Route-Namen — BEHOBEN 2026-03-12
|
||||
|
||||
**Fix in `routes/web.php`:**
|
||||
|
||||
| Alt (doppelt) | Neu (eindeutig) | Route |
|
||||
|---------------------|------------------------------|------------------------------------------|
|
||||
| `home` (GET `/`) | `landing` | Oeffentliche Startseite |
|
||||
| `home` (GET `/home`)| `home` (unveraendert) | Auth-geschuetztes Dashboard |
|
||||
| `user_sales` (Z.204)| `user_sales_orders` | User-Bestellungen (orders-Methode) |
|
||||
| `user_sales_detail` (Z.205)| `user_sales_order_detail` | User-Bestellungsdetail (orderDetail) |
|
||||
| `user_sales` (Z.248)| `user_sales` (unveraendert) | Shop-Verkaeufe (index-Methode) |
|
||||
| `user_sales_detail` (Z.249)| `user_sales_detail` (unveraendert) | Shop-Verkaufsdetail (detail) |
|
||||
|
||||
Die umbenannten Routen (`user_sales_orders`, `user_sales_order_detail`) wurden in keinen
|
||||
Views/Controllern referenziert, daher waren keine weiteren Anpassungen noetig.
|
||||
|
||||
---
|
||||
|
||||
### 2.2 GET-Routen fuer Loeschaktionen
|
||||
|
||||
**Problem:** Loeschaktionen wie `admin_product_delete`, `admin_product_image_delete`,
|
||||
`admin_lead_delete_file` sind als GET definiert. GET-Requests sollten keine Daten aendern
|
||||
(Browser-Prefetch, Crawler, CSRF-Risiko).
|
||||
|
||||
**Vorschlag:** Auf DELETE-Method umstellen mit `@method('DELETE')` in Blade-Forms.
|
||||
|
||||
---
|
||||
|
||||
### 2.3 GET-Route mutiert Daten
|
||||
|
||||
**Problem:** `SalesController::detail()` setzt `shipped = 1` bei einem GET-Request.
|
||||
|
||||
**Datei:** `app/Http/Controllers/SalesController.php` (detail-Methode)
|
||||
|
||||
**Vorschlag:** Versand-Status per separatem POST/PATCH-Endpoint setzen.
|
||||
|
||||
---
|
||||
|
||||
## 3. Bugs / Korrektheitsprobleme
|
||||
|
||||
### 3.1 Stornierungs-Mail sendet Rechnungs-Mail
|
||||
|
||||
**Problem:** `createCancellation()` ruft `Invoice::sendInvoiceMail()` auf statt eine
|
||||
dedizierte Stornierungs-Mail. Kunden erhalten bei Stornierung die Rechnungs-Mail.
|
||||
|
||||
**Datei:** `app/Repositories/InvoiceRepository.php:279`
|
||||
|
||||
**Vorschlag:** Eigene `sendCancellationMail()` Methode erstellen und hier aufrufen.
|
||||
|
||||
---
|
||||
|
||||
### 3.2 Schedule: payments:reminders ohne Frequenz
|
||||
|
||||
**Problem:** Der Command `payments:reminders` hat keine Schedule-Frequenz (`->daily()` etc.)
|
||||
konfiguriert. Ohne Frequenz laeuft er ggf. jede Minute.
|
||||
|
||||
**Datei:** `app/Console/Kernel.php:37-43`
|
||||
|
||||
**Vorschlag:** Gewuenschte Frequenz setzen, z.B. `->dailyAt('08:00')`.
|
||||
|
||||
---
|
||||
|
||||
### 3.3 helpers.php: Doppelte Funktion
|
||||
|
||||
**Problem:** `make_old_url()` ist zweimal definiert (Zeile 3-9 und 11-16).
|
||||
Die zweite Definition wird durch `function_exists`-Guard ignoriert.
|
||||
|
||||
**Datei:** `app/helpers.php`
|
||||
|
||||
**Vorschlag:** Doppelte Definition entfernen.
|
||||
|
||||
---
|
||||
|
||||
## 4. Performance
|
||||
|
||||
### 4.1 N+1 Query-Probleme
|
||||
|
||||
Mehrere Controller laden Beziehungen in Schleifen ohne Eager Loading:
|
||||
|
||||
| Datei | Stelle | Problem |
|
||||
|-------|--------|---------|
|
||||
| `app/Http/Controllers/SalesController.php` | datatable() | `$order->member->getFullName()` pro DataTable-Zeile |
|
||||
| `app/Repositories/InvoiceRepository.php` | prepairForDelivery() | `Attribute::find()` in dreifach verschachtelter Schleife |
|
||||
| `app/Http/Controllers/SyS/AdminToolsController.php` | _dbOrderPaymentFor() | `ShoppingUser::all()` dann `->shopping_order` pro Eintrag |
|
||||
| `app/Http/Controllers/User/PaymentController.php` | index() | `user_margins`/`user_credits` in DataTable-Callback |
|
||||
|
||||
**Vorschlag:** `with()` / `load()` fuer Eager Loading nutzen. Bei DataTables die
|
||||
Relationships im Query vorladen.
|
||||
|
||||
---
|
||||
|
||||
### 4.2 AdminToolsController: Ganze Tabellen laden
|
||||
|
||||
**Problem:** `ShoppingUser::all()` laedt die komplette Tabelle ohne Pagination.
|
||||
|
||||
**Datei:** `app/Http/Controllers/SyS/AdminToolsController.php:97`
|
||||
|
||||
**Vorschlag:** Chunking (`chunk()`) oder Query mit Filtern nutzen.
|
||||
|
||||
---
|
||||
|
||||
## 5. Code-Qualitaet (bei Gelegenheit)
|
||||
|
||||
### 5.1 Keine FormRequest-Klassen
|
||||
|
||||
Das Projekt hat keinen einzigen FormRequest. Alle 25+ Controller nutzen inline
|
||||
`Validator::make()`. Bei neuen Features sollten FormRequests genutzt werden.
|
||||
Bestehende nach und nach migrieren.
|
||||
|
||||
### 5.2 Fehlende Return-Type-Deklarationen
|
||||
|
||||
Projekt-weit fehlen Return-Types auf Methoden (Controller, Models, Services, Repositories).
|
||||
Bei jeder Aenderung an einer Datei sollten Return-Types ergaenzt werden.
|
||||
|
||||
### 5.3 Model-Relationships ohne Return-Type-Hints
|
||||
|
||||
Alle Relationship-Methoden in `app/User.php` und `app/Models/*.php` haben keine
|
||||
Return-Type-Hints (`BelongsTo`, `HasMany`, etc.).
|
||||
|
||||
### 5.4 `$dates` deprecated (10+ Models)
|
||||
|
||||
`protected $dates = ['deleted_at']` ist seit Laravel 10 deprecated.
|
||||
Sollte durch `casts()` Methode ersetzt werden:
|
||||
|
||||
```php
|
||||
protected function casts(): array
|
||||
{
|
||||
return ['deleted_at' => 'datetime'];
|
||||
}
|
||||
```
|
||||
|
||||
Betroffene Models: `ShoppingOrder`, `UserAccount`, `ShoppingOrderItem`, `UserShop`,
|
||||
`PromotionUser`, `Product`, `ShoppingUser`, `ShoppingOrderMargin`, `PromotionAdmin`,
|
||||
`UserMessage`.
|
||||
|
||||
### 5.5 PayPal: Fehlendes Error-Handling
|
||||
|
||||
`PayPalController::paymentSuccess()` und `payment()` haben kein try/catch.
|
||||
Netzwerkfehler oder unerwartete PayPal-Antworten fuehren zu unbehandelten 500-Fehlern.
|
||||
|
||||
**Datei:** `app/Http/Controllers/Pay/PayPalController.php`
|
||||
|
||||
### 5.6 Invoice Service: Nur statische Methoden
|
||||
|
||||
`app/Services/Invoice.php` ist komplett statisch — nicht testbar und nicht per
|
||||
Dependency Injection nutzbar. Bei Ueberarbeitung auf Instanz-Methoden umstellen.
|
||||
|
||||
### 5.7 Typo: prepairForDelivery
|
||||
|
||||
`app/Repositories/InvoiceRepository.php:156` — Methode heisst `prepairForDelivery`
|
||||
statt `prepareForDelivery`.
|
||||
|
||||
---
|
||||
|
||||
## Zusammenfassung nach Prioritaet
|
||||
|
||||
| Prio | # | Thema | Aufwand |
|
||||
|------|---|-------|---------|
|
||||
| ~~KRITISCH~~ | ~~1.1~~ | ~~APP_KEY als Passwort~~ | ~~BEHOBEN~~ |
|
||||
| KRITISCH | 1.2 | Cron-Endpoint ohne Auth | Klein |
|
||||
| ~~HOCH~~ | ~~1.3~~ | ~~env() ausserhalb Config~~ | ~~BEHOBEN~~ |
|
||||
| ~~HOCH~~ | ~~2.1~~ | ~~Doppelte Route-Namen~~ | ~~BEHOBEN~~ |
|
||||
| HOCH | 3.1 | Falsche Mail bei Stornierung | Klein |
|
||||
| HOCH | 3.2 | Schedule ohne Frequenz | Klein |
|
||||
| MITTEL | 1.4 | File-Upload Extension | Klein |
|
||||
| MITTEL | 1.5 | PayPal-Fehler exponiert | Klein |
|
||||
| MITTEL | 2.2 | GET fuer Loeschaktionen | Mittel |
|
||||
| MITTEL | 2.3 | GET mutiert Daten | Klein |
|
||||
| MITTEL | 3.3 | Doppelte Funktion helpers.php | Klein |
|
||||
| MITTEL | 4.1 | N+1 Queries | Mittel |
|
||||
| MITTEL | 4.2 | Ganze Tabellen laden | Klein |
|
||||
| NIEDRIG | 5.1-5.7 | Code-Qualitaet | Fortlaufend |
|
||||
Loading…
Add table
Add a link
Reference in a new issue