76 lines
3.9 KiB
Markdown
76 lines
3.9 KiB
Markdown
# Zmiana: Fix przekierowania w summaryView
|
|
|
|
## Plik
|
|
`autoload/front/Controllers/ShopBasketController.php`
|
|
|
|
## Problem
|
|
Po złożeniu pierwszego zamówienia, próba złożenia drugiego zamówienia powodowała przekierowanie na stronę poprzedniego zamówienia (`/zamowienie/{hash}`) zamiast na stronę podsumowania koszyka (`/koszyk-podsumowanie`).
|
|
|
|
## Przyczyna
|
|
W metodzie `summaryView()` był guard sprawdzający sesyjny klucz `order-submit-last-order-id`. Jeśli istniał (a istniał po każdym złożonym zamówieniu), metoda od razu redirectowała na stronę starego zamówienia — nigdy nie dochodziło do `createOrderSubmitToken()`, które czyści ten klucz.
|
|
|
|
## Co usunięto
|
|
Usunięto blok (dawne linie 279-290):
|
|
```php
|
|
$existingOrderId = isset( $_SESSION[ self::ORDER_SUBMIT_LAST_ORDER_ID_SESSION_KEY ] )
|
|
? (int)$_SESSION[ self::ORDER_SUBMIT_LAST_ORDER_ID_SESSION_KEY ]
|
|
: 0;
|
|
if ( $existingOrderId > 0 )
|
|
{
|
|
$existingOrderHash = $this->orderRepository->findHashById( $existingOrderId );
|
|
if ( $existingOrderHash )
|
|
{
|
|
header( 'Location: /zamowienie/' . $existingOrderHash );
|
|
exit;
|
|
}
|
|
}
|
|
```
|
|
|
|
## Zabezpieczenie double-submit
|
|
Ochrona przed podwójnym wysłaniem formularza pozostaje nienaruszona w metodzie `basketSave()` — tam ten sam mechanizm działa poprawnie.
|
|
|
|
---
|
|
|
|
# Zmiana 2: Logowanie błędów w basketSave + naprawa tokena zamówienia
|
|
|
|
## Plik
|
|
`autoload/front/Controllers/ShopBasketController.php`
|
|
|
|
## Problem
|
|
Klientka nie mogła złożyć zamówienia — komunikat "Podczas składania zamówienia wystąpił błąd". Brak logowania uniemożliwiał diagnozę. Dodatkowo token zamówienia był jednorazowy i nadpisywany przy każdym wejściu na podsumowanie — otwarcie drugiej karty, użycie "wstecz" w przeglądarce lub odświeżenie strony unieważniało token i blokowało złożenie zamówienia.
|
|
|
|
## Dodane logowanie do `logs/logs-order-{data}.log`
|
|
Dodana prywatna metoda `logOrder()` zapisująca do pliku `logs/logs-order-YYYY-MM-DD.log` (schemat jak `logs-db-*`).
|
|
|
|
Logowanie w 4 miejscach w `basketSave()`:
|
|
|
|
1. **Double-submit (pusty koszyk + istnieje stare zamówienie)** — log: `Double-submit detected, redirecting to existing order id=...`
|
|
2. **Token nieprawidłowy** — log: `Token validation failed. formToken=...`
|
|
3. **createFromBasket rzucił wyjątek** — log: `createFromBasket exception: ...`
|
|
4. **createFromBasket zwróciło falsy order_id** — log: `createFromBasket returned falsy order_id. client_id=... email=...`
|
|
|
|
## Naprawa tokena — z jednorazowego na czasowy (TTL 30 min)
|
|
|
|
### Stare zachowanie
|
|
- `createOrderSubmitToken()` generował nowy token przy KAŻDYM wejściu na podsumowanie
|
|
- Każde otwarcie nowej karty/odświeżenie nadpisywało token w sesji
|
|
- Formularz w starej karcie miał stary token → walidacja failowała
|
|
- Przy nieudanej walidacji tokena redirect na `/koszyk` (użytkownik tracił cały kontekst)
|
|
|
|
### Nowe zachowanie
|
|
- Dodana stała `ORDER_SUBMIT_TOKEN_TTL = 1800` (30 minut)
|
|
- Token przechowywany jako `['token' => '...', 'created_at' => time()]`
|
|
- `createOrderSubmitToken()`: jeśli istnieje ważny token (< 30 min), zwraca ten sam zamiast generować nowy
|
|
- `isValidOrderSubmitToken()`: sprawdza czy token nie wygasł + backward compatibility ze starymi stringowymi tokenami
|
|
- `consumeOrderSubmitToken()`: bez zmian — po złożeniu zamówienia token jest usuwany
|
|
- Przy nieudanej walidacji tokena redirect na `/koszyk-podsumowanie` (nowy token się generuje, użytkownik może od razu ponowić)
|
|
- Dodany osobny guard na double-submit: pusty koszyk + istniejące zamówienie w sesji → redirect na stronę zamówienia
|
|
|
|
### Efekt
|
|
- Wiele kart z podsumowaniem → ten sam token → wszystkie działają
|
|
- Przycisk "wstecz" → token nadal ważny
|
|
- Odświeżenie strony → token nadal ważny
|
|
- Po 30 minutach token wygasa → redirect na podsumowanie, nowy token, ponów
|
|
- Po złożeniu zamówienia token jest konsumowany + koszyk czyszczony → double-submit chroniony
|
|
- Błąd tokena nie wyrzuca na /koszyk tylko na /koszyk-podsumowanie
|