fix(auth): naprawa strony /login (subtitle, inline remember, auto-login z cookie)
- usuniety subtitle "Zaloguj sie, aby przejsc..." z widoku - "Zapamietaj mnie (30 dni)" w jednej linii (selektor .form-field.remember-field) - AuthController::showLogin woluje loginFromRememberToken() -> uzytkownik z waznym cookie remember (30 dni) jest auto-logowany po wygasnieciu sesji PHP zamiast ogladac formularz logowania PLAN: .paul/plans/20260520-1200-fix-login-page-and-remember-me/ Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,10 +1,10 @@
|
|||||||
# STATE — orderPRO
|
# STATE — orderPRO
|
||||||
|
|
||||||
**Tryb:** plan-first
|
**Tryb:** plan-first
|
||||||
**Ostatnia aktualizacja:** 2026-05-19
|
**Ostatnia aktualizacja:** 2026-05-20
|
||||||
|
|
||||||
## Aktywna praca
|
## Aktywna praca
|
||||||
UNIFY zakonczony dla `.paul/plans/20260519-1730-refactor-delivery-status/`. Petla zamknieta, brak aktywnego planu.
|
UNIFY zakonczony dla `.paul/plans/20260520-1200-fix-login-page-and-remember-me/`. Petla zamknieta. Strona `/login`: usuniety subtitle, checkbox "Zapamiętaj mnie (30 dni)" w jednej linii (selektor `.form-field.remember-field`), `AuthController::showLogin` woluje `loginFromRememberToken()` -> uzytkownik z waznym cookie (30 dni) wraca automatycznie na `/settings/users` po wygasnieciu sesji. SUMMARY: `.paul/plans/20260520-1200-fix-login-page-and-remember-me/SUMMARY.md`.
|
||||||
|
|
||||||
```
|
```
|
||||||
PLAN ──▶ APPLY ──▶ UNIFY
|
PLAN ──▶ APPLY ──▶ UNIFY
|
||||||
|
|||||||
@@ -2,6 +2,22 @@
|
|||||||
|
|
||||||
Chronologiczny log zmian technicznych (co i dlaczego). Najnowsze na gorze.
|
Chronologiczny log zmian technicznych (co i dlaczego). Najnowsze na gorze.
|
||||||
|
|
||||||
|
## 2026-05-20 — Strona logowania: usuniecie subtitle, inline "Zapamietaj mnie (30 dni)", auto-login z cookie
|
||||||
|
|
||||||
|
### Co
|
||||||
|
- `resources/views/auth/login.php`: usuniety element `<p class="login-subtitle">`.
|
||||||
|
- `resources/lang/pl.php`: `auth.login.remember_me` -> "Zapamiętaj mnie (30 dni)".
|
||||||
|
- `resources/scss/login.scss`: selektor `.remember-field` -> `.form-field.remember-field` (kompozytowy, specyficznosc 0,2,0 bije `.form-field { display: grid }` zdefiniowane ponizej). Compiled `public/assets/css/login.css` przebudowany przez `sass --style=compressed`.
|
||||||
|
- `src/Modules/Auth/AuthController.php`: `showLogin` woluje `loginFromRememberToken()` przed renderem formularza.
|
||||||
|
|
||||||
|
### Dlaczego
|
||||||
|
- Bug "Zapamietaj mnie nie dziala": `AuthMiddleware` poprawnie konsumowal cookie na route'ach chronionych, ale `/login` go nie wolal -> uzytkownik z waznym cookie po wygasnieciu sesji nadal widzial formularz. Backend (`AuthService::REMEMBER_DAYS=30`, httponly, SameSite=Lax, hash SHA-256 w `users.remember_token`) byl OK.
|
||||||
|
- Bug "label pod checkboxem": rownosc specyficznosci 0,1,0 + pozniejsza regula `.form-field { display: grid }` (linia 128) nadpisywala `.remember-field { display: flex }` (linia 104).
|
||||||
|
|
||||||
|
### Wplyw
|
||||||
|
- Brak zmian schematu DB, brak zmian kontraktow API, brak zmian w innych widokach.
|
||||||
|
- Plan: `.paul/plans/20260520-1200-fix-login-page-and-remember-me/PLAN.md`, SUMMARY: `.paul/plans/20260520-1200-fix-login-page-and-remember-me/SUMMARY.md`.
|
||||||
|
|
||||||
## 2026-05-19 — Dekompozycja DeliveryStatus (fasada + 3 wspolpracownikow)
|
## 2026-05-19 — Dekompozycja DeliveryStatus (fasada + 3 wspolpracownikow)
|
||||||
|
|
||||||
### Co
|
### Co
|
||||||
|
|||||||
7
.paul/governance/governance_2026-05-20.jsonl
Normal file
7
.paul/governance/governance_2026-05-20.jsonl
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
{"ts":"2026-05-20T06:23:51Z","tool":"Bash","cmd":"mkdir -p .paul/plans/20260520-1200-fix-login-page-and-remember-me\",\"description\":\"Create plan directory\"},\"tool_response\":{\"stdout\":\"\",\"stderr\":\"\",\"interrupted\":false,\"isImage\":fals","cwd":"/c/visual-studio-code/projekty/orderPRO"}
|
||||||
|
{"ts":"2026-05-20T06:25:19Z","tool":"Write","file":"C:\\\\visual-studio-code\\\\projekty\\\\orderPRO\\\\.paul\\\\plans\\\\20260520-1200-fix-login-page-and-remember-me\\\\PLAN.md","cwd":"/c/visual-studio-code/projekty/orderPRO"}
|
||||||
|
{"ts":"2026-05-20T06:25:32Z","tool":"Edit","file":"C:\\\\visual-studio-code\\\\projekty\\\\orderPRO\\\\.paul\\\\STATE.md","cwd":"/c/visual-studio-code/projekty/orderPRO"}
|
||||||
|
{"ts":"2026-05-20T06:27:34Z","tool":"Edit","file":"C:\\\\visual-studio-code\\\\projekty\\\\orderPRO\\\\resources\\\\lang\\\\pl.php","cwd":"/c/visual-studio-code/projekty/orderPRO"}
|
||||||
|
{"ts":"2026-05-20T06:27:40Z","tool":"Edit","file":"C:\\\\visual-studio-code\\\\projekty\\\\orderPRO\\\\resources\\\\views\\\\auth\\\\login.php","cwd":"/c/visual-studio-code/projekty/orderPRO"}
|
||||||
|
{"ts":"2026-05-20T06:27:45Z","tool":"Edit","file":"C:\\\\visual-studio-code\\\\projekty\\\\orderPRO\\\\resources\\\\scss\\\\login.scss","cwd":"/c/visual-studio-code/projekty/orderPRO"}
|
||||||
|
{"ts":"2026-05-20T06:27:54Z","tool":"Bash","cmd":"npx --yes sass --style=compressed --no-source-map resources/scss/login.scss public/assets/css/login.css 2>&1 | tail -20\",\"description\":\"Build login CSS\"},\"tool_response\":{\"stdout\":\"\",\"stde","cwd":"/c/visual-studio-code/projekty/orderPRO"}
|
||||||
225
.paul/plans/20260520-1200-fix-login-page-and-remember-me/PLAN.md
Normal file
225
.paul/plans/20260520-1200-fix-login-page-and-remember-me/PLAN.md
Normal file
@@ -0,0 +1,225 @@
|
|||||||
|
---
|
||||||
|
plan_id: 20260520-1200-fix-login-page-and-remember-me
|
||||||
|
title: Strona logowania - usuniecie subtitle, inline checkbox "Zapamietaj mnie" (30 dni) + naprawa auto-logowania
|
||||||
|
storage: plan-first
|
||||||
|
legacy_phase: null
|
||||||
|
created: 2026-05-20T12:00:00+02:00
|
||||||
|
status: planned
|
||||||
|
type: execute
|
||||||
|
autonomous: true
|
||||||
|
delegation: auto
|
||||||
|
files_modified:
|
||||||
|
- resources/views/auth/login.php
|
||||||
|
- resources/lang/pl.php
|
||||||
|
- resources/scss/login.scss
|
||||||
|
- public/assets/css/login.css
|
||||||
|
- src/Modules/Auth/AuthController.php
|
||||||
|
quality_radar: ok
|
||||||
|
---
|
||||||
|
|
||||||
|
<objective>
|
||||||
|
## Goal
|
||||||
|
Poprawic UX i dzialanie strony logowania `/login`: usunac zbedny podtytul, ustawic etykiete checkboxa "Zapamietaj mnie" w jednej linii (z dopiskiem "(30 dni)") oraz upewnic sie, ze opcja zapamietania faktycznie loguje uzytkownika ponownie bez podawania hasla przez 30 dni.
|
||||||
|
|
||||||
|
## Purpose
|
||||||
|
Uzytkownik raportuje:
|
||||||
|
- zbedny tekst "Zaloguj sie, aby przejsc do obslugi zamowien i wysylek.",
|
||||||
|
- etykieta "Zapamietaj mnie" jest pod checkboxem zamiast obok,
|
||||||
|
- opcja "zapamietaj logowanie" nie dziala w praktyce (przy wejsciu na `/login` po wygasnieciu sesji uzytkownik jest proszony o ponowne logowanie, mimo zaznaczenia checkboxa przy poprzednim logowaniu).
|
||||||
|
|
||||||
|
## Output
|
||||||
|
- usuniety podtytul w widoku logowania,
|
||||||
|
- checkbox + label "Zapamietaj mnie (30 dni)" w jednej linii (flex),
|
||||||
|
- `AuthController::showLogin` proboje auto-zalogowac uzytkownika z cookie `remember_token` przed wyrenderowaniem formularza,
|
||||||
|
- nowy klucz tlumaczenia z czasem trwania (centralizacja literalu "30"),
|
||||||
|
- przebudowany `public/assets/css/login.css`.
|
||||||
|
</objective>
|
||||||
|
|
||||||
|
<context>
|
||||||
|
## Project Docs
|
||||||
|
@.paul/PROJECT.md
|
||||||
|
@.paul/STATE.md
|
||||||
|
@.paul/codebase/architecture.md
|
||||||
|
@.paul/codebase/impact_map.md
|
||||||
|
@.paul/codebase/quality_risks.md
|
||||||
|
|
||||||
|
## Source Files
|
||||||
|
@resources/views/auth/login.php
|
||||||
|
@resources/scss/login.scss
|
||||||
|
@resources/lang/pl.php
|
||||||
|
@src/Modules/Auth/AuthController.php
|
||||||
|
@src/Modules/Auth/AuthService.php
|
||||||
|
@src/Modules/Auth/AuthMiddleware.php
|
||||||
|
@src/Modules/Users/UserRepository.php
|
||||||
|
</context>
|
||||||
|
|
||||||
|
<clarifications>
|
||||||
|
- Czas zapamietania potwierdzony przez uzytkownika: **30 dni** (zgodne z `AuthService::REMEMBER_DAYS = 30`).
|
||||||
|
- Etykieta z liczba dni: dopisek "(30 dni)" w nawiasie przy "Zapamietaj mnie".
|
||||||
|
- Po pomyslnym auto-logowaniu z remember tokenem na `/login` przekierowanie zachowuje obecna logike: na `/settings/users` (jak `login()`).
|
||||||
|
</clarifications>
|
||||||
|
|
||||||
|
<impact_scan>
|
||||||
|
## Quality Radar
|
||||||
|
|
||||||
|
**Status:** ok
|
||||||
|
**Tools:** codebase-memory-mcp (architecture.md + impact_map.md przejrzane); jscpd/ast-grep disabled by policy.
|
||||||
|
|
||||||
|
## Affected Areas
|
||||||
|
|
||||||
|
- Auth UI: `resources/views/auth/login.php`, `resources/scss/login.scss`, `public/assets/css/login.css`.
|
||||||
|
- Auth backend: `src/Modules/Auth/AuthController.php` (dodanie auto-loginu w `showLogin`).
|
||||||
|
- I18n: `resources/lang/pl.php` (klucze `auth.login.subtitle` - do usuniecia z widoku, `auth.login.remember_me` - rozszerzenie o czas trwania).
|
||||||
|
|
||||||
|
## Duplicate / Hardcoded Risks
|
||||||
|
|
||||||
|
- Liczba dni "30" wystepuje w `AuthService::REMEMBER_DAYS`. Dopisek w UI to wartosc literal w tlumaczeniu - akceptowalne (UI string), ale wpisujemy ja w `pl.php` raz, nie w widoku. Jezeli kiedys zmieni sie `REMEMBER_DAYS`, trzeba zsynchronizowac napis - odnotowane w `Boundaries`.
|
||||||
|
|
||||||
|
## Explicit Deferrals
|
||||||
|
|
||||||
|
- Rotacja remember tokenu po uzyciu (`loginFromRememberToken`) - dobra praktyka, ale poza zakresem tego planu. Odlozone.
|
||||||
|
- Usuwanie samego klucza `auth.login.subtitle` z `pl.php` - zostawiamy klucz (moze byc uzyty gdzie indziej; obecnie tylko w widoku logowania). Nie usuwamy, tylko przestajemy go renderowac.
|
||||||
|
</impact_scan>
|
||||||
|
|
||||||
|
<skills>
|
||||||
|
SPECIAL-FLOWS.md nie istnieje w projekcie - sekcja pomijana.
|
||||||
|
</skills>
|
||||||
|
|
||||||
|
<acceptance_criteria>
|
||||||
|
|
||||||
|
## AC-1: Usuniecie podtytulu na stronie logowania
|
||||||
|
```gherkin
|
||||||
|
Given uzytkownik otwiera `/login`
|
||||||
|
When strona zostaje wyrenderowana
|
||||||
|
Then nie pojawia sie tekst "Zaloguj sie, aby przejsc do obslugi zamowien i wysylek."
|
||||||
|
And w DOM nie wystepuje element `.login-subtitle` w karcie logowania
|
||||||
|
```
|
||||||
|
|
||||||
|
## AC-2: Checkbox "Zapamietaj mnie" w jednej linii z dopiskiem (30 dni)
|
||||||
|
```gherkin
|
||||||
|
Given uzytkownik widzi formularz logowania
|
||||||
|
When patrzy na pole "Zapamietaj mnie"
|
||||||
|
Then checkbox i etykieta sa w jednej linii (flex, align-items: center)
|
||||||
|
And etykieta brzmi "Zapamietaj mnie (30 dni)"
|
||||||
|
And nie powstaja regresje wizualne w pozostalych polach formularza
|
||||||
|
```
|
||||||
|
|
||||||
|
## AC-3: Auto-logowanie z cookie remember na `/login`
|
||||||
|
```gherkin
|
||||||
|
Given uzytkownik wczesniej zalogowal sie z zaznaczonym "Zapamietaj mnie"
|
||||||
|
And jego sesja PHP wygasla
|
||||||
|
And cookie `remember_token` (30 dni) jest nadal wazne
|
||||||
|
When uzytkownik wchodzi bezposrednio na `/login`
|
||||||
|
Then `AuthController::showLogin` woluje `AuthService::loginFromRememberToken()`
|
||||||
|
And jezeli token jest wazny, uzytkownik zostaje zalogowany i przekierowany na `/settings/users`
|
||||||
|
And nie widzi formularza logowania
|
||||||
|
```
|
||||||
|
|
||||||
|
## AC-4: Persistencja remember tokenu 30 dni
|
||||||
|
```gherkin
|
||||||
|
Given uzytkownik loguje sie z zaznaczonym "Zapamietaj mnie"
|
||||||
|
When `AuthService::createRememberToken` wystawia cookie
|
||||||
|
Then cookie `remember_token` ma `expires = time() + 30*86400` (REMEMBER_DAYS = 30)
|
||||||
|
And cookie ma `httponly=true`, `samesite=Lax`, `secure` zgodnie z HTTPS requestu
|
||||||
|
And hash tokenu zostaje zapisany w `users.remember_token`
|
||||||
|
```
|
||||||
|
|
||||||
|
</acceptance_criteria>
|
||||||
|
|
||||||
|
<tasks>
|
||||||
|
|
||||||
|
<task type="auto">
|
||||||
|
<name>Task 1: Widok logowania - usun subtitle i dodaj dopisek 30 dni</name>
|
||||||
|
<files>resources/views/auth/login.php, resources/lang/pl.php</files>
|
||||||
|
<action>
|
||||||
|
1. W `resources/views/auth/login.php` usun caly element `<p class="login-subtitle">...</p>` (linia 5).
|
||||||
|
2. W `resources/lang/pl.php` (klucz `auth.login.remember_me`) zmien wartosc z `'Zapamietaj mnie'` na `'Zapamietaj mnie (30 dni)'`. Klucza `auth.login.subtitle` nie usuwamy (zachowanie wstecznej kompatybilnosci slownika).
|
||||||
|
3. Sprawdz, ze nie ma innych miejsc renderujacych `auth.login.subtitle` poza `login.php` (rg).
|
||||||
|
</action>
|
||||||
|
<verify>php -l resources/views/auth/login.php; rg "auth\.login\.(subtitle|remember_me)" resources/ -n</verify>
|
||||||
|
<done>AC-1, AC-2 (czesc tekstowa)</done>
|
||||||
|
</task>
|
||||||
|
|
||||||
|
<task type="auto">
|
||||||
|
<name>Task 2: SCSS + rebuild CSS - checkbox w jednej linii</name>
|
||||||
|
<files>resources/scss/login.scss, public/assets/css/login.css</files>
|
||||||
|
<action>
|
||||||
|
1. W `resources/scss/login.scss` dodaj override specyficznosci dla `.remember-field`, aby pokonal regule `.form-field { display: grid }` zdefiniowana ponizej. Najprostsza forma: zmien selektor `.remember-field` na `.form-field.remember-field` (dwie klasy = wyzsza specyficznosc; struktura HTML juz ma obie klasy: `class="form-field form-field--inline remember-field"`).
|
||||||
|
2. Upewnij sie, ze blok zachowuje `display: flex; align-items: center; gap: 8px;` oraz style dla `input[type="checkbox"]` i `.field-label`.
|
||||||
|
3. Przebuduj CSS: `npm run build:css` (lub recznie `sass --style=compressed --no-source-map resources/scss/login.scss public/assets/css/login.css`). Jezeli `npm`/`sass` niedostepne w srodowisku agenta - zrob recznie analogiczna zmiane w `public/assets/css/login.css` (selektor `.form-field.remember-field { display: flex; align-items: center; gap: 8px; }` z zachowaniem reszty).
|
||||||
|
</action>
|
||||||
|
<verify>rg "remember-field" resources/scss/login.scss public/assets/css/login.css -n; otwarcie `/login` w przegladarce i wizualna weryfikacja (smoke).</verify>
|
||||||
|
<done>AC-2</done>
|
||||||
|
</task>
|
||||||
|
|
||||||
|
<task type="auto">
|
||||||
|
<name>Task 3: Auto-logowanie z remember tokenem na `/login`</name>
|
||||||
|
<files>src/Modules/Auth/AuthController.php</files>
|
||||||
|
<action>
|
||||||
|
W `AuthController::showLogin` przed renderem dodaj proba auto-loginu z cookie:
|
||||||
|
|
||||||
|
```php
|
||||||
|
public function showLogin(Request $request): Response
|
||||||
|
{
|
||||||
|
if ($this->auth->check() || $this->auth->loginFromRememberToken()) {
|
||||||
|
return Response::redirect('/settings/users');
|
||||||
|
}
|
||||||
|
// ... existing render
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Nie zmieniaj `login()` ani `logout()`. Pozostaw obecna logike `Flash::get(...)` bez zmian.
|
||||||
|
</action>
|
||||||
|
<verify>php -l src/Modules/Auth/AuthController.php; ewentualny smoke: zaloguj z checkboxem, wyczysc cookie sesyjne (PHPSESSID), wejdz na `/login` -> powinno przekierowac na `/settings/users`.</verify>
|
||||||
|
<done>AC-3</done>
|
||||||
|
</task>
|
||||||
|
|
||||||
|
<task type="auto">
|
||||||
|
<name>Task 4: Weryfikacja parametrow cookie remember (read-only)</name>
|
||||||
|
<files>src/Modules/Auth/AuthService.php</files>
|
||||||
|
<action>
|
||||||
|
Bez modyfikacji kodu: potwierdz, ze `REMEMBER_DAYS = 30` i parametry cookie (`httponly`, `samesite=Lax`, `secure` zalezne od HTTPS) sa zgodne z AC-4. Jezeli `$_SERVER['HTTPS']` nie jest dostepne za reverse proxy - odnotowac jako known issue (nie zmieniamy w tym planie).
|
||||||
|
</action>
|
||||||
|
<verify>rg "REMEMBER_DAYS|REMEMBER_COOKIE|setcookie" src/Modules/Auth/AuthService.php -n</verify>
|
||||||
|
<done>AC-4</done>
|
||||||
|
</task>
|
||||||
|
|
||||||
|
</tasks>
|
||||||
|
|
||||||
|
<boundaries>
|
||||||
|
## Do Not Change
|
||||||
|
- `AuthService::attempt`, `AuthService::createRememberToken`, `AuthService::loginFromRememberToken`, `AuthService::logout` - bez zmian behawioralnych.
|
||||||
|
- `AuthMiddleware` - bez zmian.
|
||||||
|
- `UserRepository::updateRememberToken`, `findByRememberToken` - bez zmian.
|
||||||
|
- Schemat tabeli `users.remember_token` - bez zmian (migracja `000081`).
|
||||||
|
- Inne widoki (`settings/*`) nawet jesli uzywaja `.form-field--inline` - nie ruszamy ich, zmiana SCSS jest dla `.form-field.remember-field` (selektor kompozytowy uzywany tylko na stronie logowania).
|
||||||
|
- Pozostale klucze tlumaczen w `pl.php` poza `auth.login.remember_me`.
|
||||||
|
|
||||||
|
## Scope Limits
|
||||||
|
- Brak rotacji remember tokenu po uzyciu (odlozone).
|
||||||
|
- Brak nowych migracji.
|
||||||
|
- Brak nowych komponentow widokow.
|
||||||
|
- Brak zmian w `routes/web.php`.
|
||||||
|
- Synchronizacja literalu "30" miedzy `REMEMBER_DAYS` a tekstem PL jest manualna - jezeli ktos zmieni `REMEMBER_DAYS`, trzeba odswiezyc tlumaczenie (akceptowalne ryzyko).
|
||||||
|
</boundaries>
|
||||||
|
|
||||||
|
<verification>
|
||||||
|
- [ ] `php -l resources/views/auth/login.php` - OK.
|
||||||
|
- [ ] `php -l src/Modules/Auth/AuthController.php` - OK.
|
||||||
|
- [ ] `rg "login-subtitle" resources/views/auth/login.php` - brak trafien.
|
||||||
|
- [ ] `rg "Zapamietaj mnie \(30 dni\)" resources/lang/pl.php` - 1 trafienie.
|
||||||
|
- [ ] `rg ".form-field.remember-field" resources/scss/login.scss public/assets/css/login.css` - po jednym trafieniu.
|
||||||
|
- [ ] Smoke manualny `/login`: brak subtitle, checkbox + label w jednej linii, dopisek "(30 dni)".
|
||||||
|
- [ ] Smoke manualny: zaloguj z checkboxem -> wyczysc tylko PHPSESSID -> wejdz `/login` -> redirect na `/settings/users`.
|
||||||
|
- [ ] Quality Radar - brak nowych ryzyk; literal "30" odnotowany w Boundaries.
|
||||||
|
</verification>
|
||||||
|
|
||||||
|
<success_criteria>
|
||||||
|
- [ ] AC-1, AC-2, AC-3, AC-4 spelnione.
|
||||||
|
- [ ] Weryfikacja przebiegla bez bledow.
|
||||||
|
- [ ] Zaktualizowany `tech_changelog.md` w fazie UNIFY (nie w APPLY) z notatka o naprawie strony logowania.
|
||||||
|
</success_criteria>
|
||||||
|
|
||||||
|
<output>
|
||||||
|
SUMMARY.md path: `.paul/plans/20260520-1200-fix-login-page-and-remember-me/SUMMARY.md`
|
||||||
|
</output>
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
---
|
||||||
|
plan_id: 20260520-1200-fix-login-page-and-remember-me
|
||||||
|
title: Strona logowania - usuniecie subtitle, inline checkbox "Zapamietaj mnie" (30 dni) + naprawa auto-logowania
|
||||||
|
status: completed
|
||||||
|
completed: 2026-05-20
|
||||||
|
quality_radar: ok
|
||||||
|
---
|
||||||
|
|
||||||
|
## Cel
|
||||||
|
Poprawa UX i dzialania strony `/login`:
|
||||||
|
1. usuniecie zbednego podtytulu,
|
||||||
|
2. ustawienie etykiety checkboxa "Zapamietaj mnie" w jednej linii z dopiskiem "(30 dni)",
|
||||||
|
3. naprawa auto-logowania z cookie `remember_token` przy wejsciu na `/login` po wygasnieciu sesji.
|
||||||
|
|
||||||
|
## Wynik
|
||||||
|
|
||||||
|
| Acceptance Criterion | Status |
|
||||||
|
|---|---|
|
||||||
|
| AC-1 Usuniecie podtytulu | ✅ |
|
||||||
|
| AC-2 Checkbox + label w jednej linii, dopisek "(30 dni)" | ✅ |
|
||||||
|
| AC-3 Auto-login z remember tokenem na `/login` | ✅ |
|
||||||
|
| AC-4 Persistencja cookie 30 dni (`REMEMBER_DAYS=30`, httponly, SameSite=Lax) | ✅ (read-only weryfikacja) |
|
||||||
|
|
||||||
|
## Zmienione pliki
|
||||||
|
|
||||||
|
| Plik | Zmiana |
|
||||||
|
|---|---|
|
||||||
|
| `resources/views/auth/login.php` | usuniety `<p class="login-subtitle">` |
|
||||||
|
| `resources/lang/pl.php` | `auth.login.remember_me` -> "Zapamiętaj mnie (30 dni)" |
|
||||||
|
| `resources/scss/login.scss` | selektor `.remember-field` -> `.form-field.remember-field` (wyzsza specyficznosc bije `.form-field { display: grid }`) |
|
||||||
|
| `public/assets/css/login.css` | rebuild `sass --style=compressed` |
|
||||||
|
| `src/Modules/Auth/AuthController.php` | `showLogin` woluje `loginFromRememberToken()` przed renderem |
|
||||||
|
|
||||||
|
## Diagnoza root cause "Zapamietaj mnie nie dziala"
|
||||||
|
|
||||||
|
Backend byl poprawny:
|
||||||
|
- `AuthService::REMEMBER_DAYS = 30`,
|
||||||
|
- cookie `remember_token`: `httponly=true`, `samesite=Lax`, `secure` zalezne od HTTPS,
|
||||||
|
- hash SHA-256 zapisany w `users.remember_token`,
|
||||||
|
- `AuthMiddleware` poprawnie woluje `loginFromRememberToken()` na route'ach chronionych.
|
||||||
|
|
||||||
|
Bug: **`AuthController::showLogin` nie konsumowal cookie remember**. Gdy uzytkownikowi wygasala sesja PHP (`PHPSESSID`) i wracal bezposrednio na `/login`, formularz byl renderowany pomimo waznego cookie - zaden middleware nie chronil samego `/login`. Fix: dodanie `|| $this->auth->loginFromRememberToken()` w warunku redirectu.
|
||||||
|
|
||||||
|
## Diagnoza root cause "label pod checkboxem"
|
||||||
|
|
||||||
|
W `login.scss` regula `.form-field { display: grid; gap: 7px; }` (linia 128) byla zdefiniowana **po** `.remember-field { display: flex; ... }` (linia 104). Element ma obie klasy (`form-field form-field--inline remember-field`), wiec przy rownej specyficznosci pojedynczej klasy wygrywa pozniejsza regula -> grid -> stack. Fix: zmiana selektora na kompozytowy `.form-field.remember-field` (specyficznosc 0,2,0 vs 0,1,0).
|
||||||
|
|
||||||
|
## Weryfikacja
|
||||||
|
|
||||||
|
- `php -l` na wszystkich modyfikowanych plikach PHP: clean.
|
||||||
|
- Compiled CSS zawiera `.form-field.remember-field{display:flex;align-items:center;gap:8px}`.
|
||||||
|
- Brak trafien na `login-subtitle` w `resources/views/auth/login.php`.
|
||||||
|
- Sass build wykonany przez `npx sass`.
|
||||||
|
|
||||||
|
## Smoke test (do wykonania recznie)
|
||||||
|
|
||||||
|
1. `/login` - brak podtytulu, checkbox + "Zapamiętaj mnie (30 dni)" w jednej linii.
|
||||||
|
2. Login z checkboxem -> wyczysc `PHPSESSID` -> wejdz `/login` -> redirect na `/settings/users`.
|
||||||
|
|
||||||
|
## Deferrals
|
||||||
|
|
||||||
|
- Rotacja remember tokenu po uzyciu (`loginFromRememberToken` nie odswieza tokenu). Odlozone.
|
||||||
|
- Synchronizacja literalu "30" miedzy `AuthService::REMEMBER_DAYS` a stringiem PL pozostaje manualna - akceptowalne ryzyko.
|
||||||
|
|
||||||
|
## Quality Radar - delty
|
||||||
|
|
||||||
|
Brak nowych ryzyk. `auth/login.php` (47 -> 46 lin.), `AuthController.php` (89 -> 89 lin., zmiana semantyczna 1 linii), `login.scss` (selektor kompozytowy). Skala zmian: pojedyncze linie.
|
||||||
File diff suppressed because one or more lines are too long
@@ -99,7 +99,7 @@ return [
|
|||||||
'title' => 'Logowanie',
|
'title' => 'Logowanie',
|
||||||
'heading' => 'Panel zarządzania zamówieniami',
|
'heading' => 'Panel zarządzania zamówieniami',
|
||||||
'subtitle' => 'Zaloguj się, aby przejść do obsługi zamówień i wysyłek.',
|
'subtitle' => 'Zaloguj się, aby przejść do obsługi zamówień i wysyłek.',
|
||||||
'remember_me' => 'Zapamiętaj mnie',
|
'remember_me' => 'Zapamiętaj mnie (30 dni)',
|
||||||
'email_label' => 'Email',
|
'email_label' => 'Email',
|
||||||
'email_placeholder' => 'np. admin@firma.pl',
|
'email_placeholder' => 'np. admin@firma.pl',
|
||||||
'password_label' => 'Hasło',
|
'password_label' => 'Hasło',
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ h1 {
|
|||||||
margin-bottom: 18px;
|
margin-bottom: 18px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.remember-field {
|
.form-field.remember-field {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
<header class="login-header">
|
<header class="login-header">
|
||||||
<p class="login-badge"><?= $e($t('brand.name_full')) ?></p>
|
<p class="login-badge"><?= $e($t('brand.name_full')) ?></p>
|
||||||
<h1 id="login-title"><?= $e($t('auth.login.heading')) ?></h1>
|
<h1 id="login-title"><?= $e($t('auth.login.heading')) ?></h1>
|
||||||
<p class="login-subtitle"><?= $e($t('auth.login.subtitle')) ?></p>
|
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<?php if (!empty($errorMessage)): ?>
|
<?php if (!empty($errorMessage)): ?>
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ final class AuthController
|
|||||||
|
|
||||||
public function showLogin(Request $request): Response
|
public function showLogin(Request $request): Response
|
||||||
{
|
{
|
||||||
if ($this->auth->check()) {
|
if ($this->auth->check() || $this->auth->loginFromRememberToken()) {
|
||||||
return Response::redirect('/settings/users');
|
return Response::redirect('/settings/users');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user