380 lines
17 KiB
Markdown
380 lines
17 KiB
Markdown
---
|
|
phase: 04h-hotfix-https-updates
|
|
plan: 01
|
|
type: execute
|
|
wave: 1
|
|
depends_on: []
|
|
files_modified:
|
|
- autoload/Shared/Helpers/Helpers.php
|
|
- autoload/admin/factory/class.Update.php
|
|
- C:/visual studio code/projekty/cmstest.pagedev.pl/autoload/class.S.php
|
|
- C:/visual studio code/projekty/cmstest.pagedev.pl/autoload/admin/factory/class.Update.php
|
|
- updates/cmsPro.zip
|
|
- updates/1.50/ver_1.519.zip
|
|
- updates/**/ver_*.zip (audit + warunkowy patch)
|
|
- updates/**/ver_*_manifest.json (regeneracja checksum_zip jeśli paczka patchowana)
|
|
autonomous: false
|
|
delegation: off
|
|
---
|
|
|
|
<objective>
|
|
## Goal
|
|
Naprawić mechanizm wykrywania nowych wersji aktualizacji (HTTP 301 → HTTPS bug) w trzech warstwach:
|
|
1. Bieżący kod cmsPRO (źródło)
|
|
2. Instancja testowa cmstest.pagedev.pl (działający bug)
|
|
3. Wszystkie dystrybuowane paczki (cmsPro.zip baseline + ver_*.zip), aby nowe instalacje cmsPRO nigdy nie utknęły z tym samym problemem
|
|
|
|
## Purpose
|
|
Serwer cmspro.project-dc.pl został przeniesiony z HTTP na HTTPS i odpowiada `301 Moved Permanently`.
|
|
PHP-owy `file_get_contents()` bez kontekstu nie podąża za redirectem, więc zwraca HTML 301 zamiast listy wersji.
|
|
Skutkiem `(float)max($html_lines)` daje 0 i `S::get_new_version()` nigdy nie pokazuje nowszej wersji niż zainstalowana.
|
|
Aktualnie WSZYSTKIE instancje cmsPRO zainstalowane przed migracją serwera są zablokowane.
|
|
|
|
## Output
|
|
- Patch HTTP→HTTPS w kodzie źródłowym i w instancji testowej
|
|
- Audit-report listujący każdą paczkę aktualizacji zawierającą `http://www.cmspro.project-dc.pl`
|
|
- Patchowane paczki ZIP + zaktualizowane manifesty (SHA256)
|
|
- ver_1.519.zip rozszerzony o poprawione class.S.php i class.Update.php — "kotwica fixa" dla instancji przechodzących przez tę wersję
|
|
- Lista plików do uploadu na cmspro.project-dc.pl (dla użytkownika)
|
|
</objective>
|
|
|
|
<context>
|
|
## Project Context
|
|
@.paul/PROJECT.md
|
|
@.paul/STATE.md
|
|
@.paul/ROADMAP.md
|
|
|
|
## Source Files
|
|
@autoload/Shared/Helpers/Helpers.php
|
|
@autoload/admin/factory/class.Update.php
|
|
@build-update.ps1
|
|
</context>
|
|
|
|
<acceptance_criteria>
|
|
|
|
## AC-1: Kod źródłowy cmsPRO używa HTTPS
|
|
```gherkin
|
|
Given pliki autoload/Shared/Helpers/Helpers.php oraz autoload/admin/factory/class.Update.php
|
|
When zostają zaktualizowane
|
|
Then nie zawierają już ciągu "http://www.cmspro.project-dc.pl"
|
|
And zawierają "https://www.cmspro.project-dc.pl"
|
|
```
|
|
|
|
## AC-2: Instancja testowa jest odblokowana
|
|
```gherkin
|
|
Given instancja w C:\visual studio code\projekty\cmstest.pagedev.pl\ na wersji 1.519
|
|
When pliki autoload/class.S.php i autoload/admin/factory/class.Update.php zostają poprawione (http→https)
|
|
And sesja "new-version" zostaje wyczyszczona (przez wylogowanie/restart sesji)
|
|
Then panel admina pokazuje nową wersję > 1.519
|
|
And klik "Aktualizuj" pobiera kolejną paczkę bez błędu
|
|
```
|
|
|
|
## AC-3: Wszystkie paczki dystrybucyjne wolne od bug-a
|
|
```gherkin
|
|
Given katalog updates/ z plikami cmsPro.zip oraz updates/**/ver_*.zip
|
|
When skrypt audit przeskanuje każdą paczkę
|
|
Then żadna paczka nie zawiera pliku z ciągiem "http://www.cmspro.project-dc.pl"
|
|
And paczki które zawierały bug zostały sparowane z patched-wersjami
|
|
And manifesty (jeśli istnieją) mają zaktualizowane checksum_zip (SHA256) zgodne z nowym ZIP
|
|
```
|
|
|
|
## AC-4: ver_1.519.zip jest "kotwicą fixa"
|
|
```gherkin
|
|
Given oryginalny ver_1.519.zip zawiera tylko class.Articles.php
|
|
When zostaje rozszerzony o poprawione autoload/class.S.php i autoload/admin/factory/class.Update.php
|
|
Then każda nowa instancja cmsPRO przechodząca update do 1.519 dostaje plik z https://
|
|
And tym samym może wykryć i pobrać kolejne aktualizacje
|
|
```
|
|
|
|
## AC-5: Audit report dostarczony
|
|
```gherkin
|
|
Given wykonany skrypt audit
|
|
When skanowanie się kończy
|
|
Then powstaje plik .paul/phases/04h-hotfix-https-updates/audit-report.md
|
|
Z listą: każda paczka, jakie zawiera podejrzane pliki, czy zawiera http://, akcja podjęta (patched|skipped|N/A)
|
|
```
|
|
|
|
</acceptance_criteria>
|
|
|
|
<tasks>
|
|
|
|
<task type="auto">
|
|
<name>Task 1: Patch kodu źródłowego cmsPRO (HTTP → HTTPS)</name>
|
|
<files>
|
|
autoload/Shared/Helpers/Helpers.php,
|
|
autoload/admin/factory/class.Update.php
|
|
</files>
|
|
<action>
|
|
Zamień wszystkie wystąpienia `http://www.cmspro.project-dc.pl` → `https://www.cmspro.project-dc.pl`
|
|
w obu plikach (Edit replace_all).
|
|
|
|
Plików łącznie ~6 wystąpień:
|
|
- Helpers.php:456 (versions.php)
|
|
- factory/class.Update.php: versions.php, .zip, _manifest.json, _sql.txt, _files.txt
|
|
|
|
NIE dodawaj kontekstu stream (follow_location=1) — wystarczy zmiana protokołu, bo
|
|
serwer obsługuje HTTPS bezpośrednio i bez redirectu.
|
|
NIE zmieniaj logiki parsowania, kontroli wersji, manifestów — tylko URL.
|
|
NIE ruszaj index.php:92 (`\S::get( 'hash' ) == $settings['update_key']`) — to inna sprawa.
|
|
</action>
|
|
<verify>
|
|
grep -c "http://www.cmspro.project-dc.pl" autoload/Shared/Helpers/Helpers.php autoload/admin/factory/class.Update.php
|
|
→ wynik 0:0 (zero wystąpień)
|
|
grep -c "https://www.cmspro.project-dc.pl" → wynik >=1:>=4
|
|
</verify>
|
|
<done>AC-1 satisfied</done>
|
|
</task>
|
|
|
|
<task type="auto">
|
|
<name>Task 2: Hotfix instancji testowej cmstest.pagedev.pl</name>
|
|
<files>
|
|
C:/visual studio code/projekty/cmstest.pagedev.pl/autoload/class.S.php,
|
|
C:/visual studio code/projekty/cmstest.pagedev.pl/autoload/admin/factory/class.Update.php
|
|
</files>
|
|
<action>
|
|
W instancji testowej zamień `http://www.cmspro.project-dc.pl` → `https://www.cmspro.project-dc.pl`
|
|
w obu plikach (Edit replace_all).
|
|
|
|
Pliki w instancji testowej mają STARSZĄ strukturę (przed refaktoringiem) — class.S.php
|
|
zawiera get_new_version(), class.Update.php (factory) zawiera 4 wystąpienia URL
|
|
(versions.php, .zip, _sql.txt, _files.txt — bez manifest, bez SHA256).
|
|
|
|
Po patchu trzeba poinstruować użytkownika, żeby:
|
|
- wylogował się z panelu (wyczyści sesję `new-version`),
|
|
- lub w przeglądarce otworzył dowolny link admina po wylogowaniu i ponownym zalogowaniu.
|
|
|
|
NIE modyfikuj innych plików w instancji testowej — to środowisko UAT, ma odzwierciedlać
|
|
stan produkcyjny.
|
|
</action>
|
|
<verify>
|
|
grep -c "http://www.cmspro.project-dc.pl" w obu plikach → 0:0
|
|
</verify>
|
|
<done>AC-2 satisfied (część kodowa, weryfikacja UAT w Task 8)</done>
|
|
</task>
|
|
|
|
<task type="auto">
|
|
<name>Task 3: Skrypt audit paczek aktualizacji</name>
|
|
<files>
|
|
.paul/phases/04h-hotfix-https-updates/scripts/audit-packages.ps1,
|
|
.paul/phases/04h-hotfix-https-updates/audit-report.md
|
|
</files>
|
|
<action>
|
|
Napisz PowerShell-owy skrypt audytujący wszystkie ZIP-y w `updates/` (rekurencyjnie),
|
|
który dla każdego ZIP:
|
|
1. Wymienia pliki kandydujące: `autoload/class.S.php`, `autoload/Shared/Helpers/Helpers.php`,
|
|
`autoload/admin/factory/class.Update.php` (i ich starsze warianty jak `class.Update.php`).
|
|
2. Jeśli któryś istnieje — rozpakowuje go do tempu, sprawdza zawartość `Select-String -Pattern 'http://www\.cmspro\.project-dc\.pl'`.
|
|
3. Wynik dla każdej paczki: { package, files_present, has_buggy_url, action }.
|
|
|
|
Skrypt MUSI obsłużyć też `updates/cmsPro.zip` (base install).
|
|
Skrypt NIE patchuje paczek — tylko raportuje. Patch w Task 4.
|
|
|
|
Output do `audit-report.md` jako tabela markdown sortowana wersjami.
|
|
Skrypt nie wymaga uprawnień do zapisu w paczkach.
|
|
</action>
|
|
<verify>
|
|
pwsh -File .paul/phases/04h-hotfix-https-updates/scripts/audit-packages.ps1
|
|
→ audit-report.md powstaje i zawiera wpis dla cmsPro.zip + co najmniej ver_1.518, ver_1.620
|
|
</verify>
|
|
<done>AC-5 satisfied: pełna lista dotkniętych paczek</done>
|
|
</task>
|
|
|
|
<task type="checkpoint:decision" gate="blocking">
|
|
<decision>
|
|
Czy patchować WSZYSTKIE paczki z bugiem, czy tylko baseline cmsPro.zip + ver_1.519 jako kotwica?
|
|
</decision>
|
|
<context>
|
|
Po audycie znamy listę dotkniętych paczek. Możliwe strategie:
|
|
- Patch wszystkich (pełna sanityzacja, ale każda zmieniona paczka wymaga regeneracji manifestu+checksum
|
|
i upload na serwer).
|
|
- Patch minimum (cmsPro.zip + ver_1.519 jako kotwica) — nowe instalacje od zera są OK,
|
|
a każdy upgrade dochodząc do 1.519 dostaje fix.
|
|
|
|
Decyzja zależy od liczby dotkniętych paczek z audit-report.md.
|
|
</context>
|
|
<options>
|
|
<option id="full-patch">
|
|
<name>Patch wszystkich dotkniętych paczek</name>
|
|
<pros>Spójność, brak buggy artefaktów na serwerze, każda ścieżka aktualizacji bezpieczna</pros>
|
|
<cons>Więcej pracy + uploadu, ryzyko zepsucia checksum jeśli manifesty istnieją</cons>
|
|
</option>
|
|
<option id="minimal-patch">
|
|
<name>Patch tylko cmsPro.zip + ver_1.519 (kotwica)</name>
|
|
<pros>Najmniejsza ingerencja, jasny "punkt zaczepienia"</pros>
|
|
<cons>Stare paczki nadal zawierają zepsuty kod — ryzyko regresji jeśli ktoś użyje pojedynczej paczki ręcznie</cons>
|
|
</option>
|
|
</options>
|
|
<resume-signal>Select: full-patch lub minimal-patch</resume-signal>
|
|
</task>
|
|
|
|
<task type="auto">
|
|
<name>Task 4: Patch dotkniętych paczek (zgodnie z decyzją z Task 3.5)</name>
|
|
<files>
|
|
updates/cmsPro.zip,
|
|
updates/1.50/ver_1.518.zip (jeśli buggy),
|
|
updates/1.60/ver_1.620.zip (jeśli buggy),
|
|
updates/**/ver_*.zip (każda inna z audit-report.md jeśli wybrano full-patch),
|
|
updates/**/ver_*_manifest.json (regeneracja checksum_zip dla patched paczek z manifestem)
|
|
</files>
|
|
<action>
|
|
Dla każdej paczki do patcha:
|
|
1. Skopiuj ZIP do tempu (backup)
|
|
2. Wyciągnij plik(i) zawierające http://www.cmspro.project-dc.pl
|
|
3. Zamień http:// → https:// (zachowaj BOM, encoding UTF-8 bez BOM zgodnie z konwencją projektu)
|
|
4. Wsadź spowrotem do ZIP-a (Compress-Archive -Update lub System.IO.Compression.ZipArchive)
|
|
5. Jeśli istnieje `ver_X.YYY_manifest.json` w tym samym katalogu — przelicz SHA256 całego ZIP
|
|
i zaktualizuj `checksum_zip` w manifeście (format: `sha256:HEX`)
|
|
6. Zachowaj oryginał jako `.bak` w tym samym katalogu
|
|
|
|
Dla cmsPro.zip nie ma manifestu (to base install) — sam ZIP wystarczy.
|
|
|
|
NIE ruszaj paczek, które audit zaznaczył jako N/A (brak buggy plików).
|
|
NIE zmieniaj struktury katalogów wewnątrz ZIP-ów.
|
|
</action>
|
|
<verify>
|
|
Powtórz audit z Task 3 — każda zmieniona paczka pokazuje `has_buggy_url: false`.
|
|
Dla każdej paczki z manifestem: `(Get-FileHash -Algorithm SHA256 paczka.zip).Hash.ToLower()`
|
|
równe wartości checksum_zip w manifeście.
|
|
</verify>
|
|
<done>AC-3 satisfied</done>
|
|
</task>
|
|
|
|
<task type="auto">
|
|
<name>Task 5: Wstrzyknięcie kotwicy fixa do ver_1.519.zip</name>
|
|
<files>
|
|
updates/1.50/ver_1.519.zip
|
|
</files>
|
|
<action>
|
|
ver_1.519.zip oryginalnie zawiera tylko `autoload/admin/controls/class.Articles.php`.
|
|
Dodać do niego (Compress-Archive -Update lub równoważne):
|
|
- `autoload/class.S.php` — wersja z https:// (taka sama jaka ląduje w cmsPro.zip post-patch)
|
|
- `autoload/admin/factory/class.Update.php` — wersja z https://
|
|
- `autoload/admin/controls/class.Update.php` — bez zmian (kontrola, nie ma URL)
|
|
- `autoload/admin/view/class.Update.php` — bez zmian
|
|
|
|
Pliki muszą mieć strukturę pasującą do legacy układu (PRZED refaktoringiem do Shared\Helpers),
|
|
czyli class.S.php zawiera get_new_version() inline. Skopiuj odpowiednie wersje z post-patched
|
|
`cmsPro.zip` lub z wcześniejszej paczki (np. patched ver_1.518.zip jeśli była buggy).
|
|
|
|
Cel: każda instancja cmsPRO doczołgająca się do 1.519 dostaje WORKING klient HTTPS,
|
|
nawet jeśli wcześniejsze paczki były buggy.
|
|
|
|
Jeśli istnieje ver_1.519_manifest.json — dodaj wpisy `files.added` z nowo wstrzykniętymi
|
|
plikami i przelicz checksum_zip.
|
|
Jeśli nie istnieje — opcjonalnie wygeneruj go (zgodnie ze schematem z build-update.ps1).
|
|
</action>
|
|
<verify>
|
|
unzip -l updates/1.50/ver_1.519.zip → zawiera autoload/class.S.php oraz autoload/admin/factory/class.Update.php
|
|
unzip -p updates/1.50/ver_1.519.zip autoload/class.S.php | grep -c "https://" → >=1
|
|
unzip -p updates/1.50/ver_1.519.zip autoload/class.S.php | grep -c "http://www.cmspro" → 0
|
|
</verify>
|
|
<done>AC-4 satisfied</done>
|
|
</task>
|
|
|
|
<task type="auto">
|
|
<name>Task 6: Generacja listy plików do uploadu na serwer</name>
|
|
<files>
|
|
.paul/phases/04h-hotfix-https-updates/upload-checklist.md
|
|
</files>
|
|
<action>
|
|
Wygeneruj plik z listą paczek wymagających uploadu na cmspro.project-dc.pl/updates/:
|
|
- cmsPro.zip (jeśli zmieniony)
|
|
- każda zmieniona ver_*.zip wraz ze swoim manifestem (jeśli istnieje)
|
|
- ver_1.519.zip + ewentualny nowy ver_1.519_manifest.json
|
|
|
|
Format: tabela markdown { plik, ścieżka źródłowa, ścieżka docelowa na serwerze, SHA256 }.
|
|
Dodaj sekcję "Po uploadzie" z krokami: smoke-test (curl https://.../updates/versions.php?key=KLUCZ),
|
|
weryfikacja że versions.php nadal zwraca poprawną listę.
|
|
</action>
|
|
<verify>
|
|
Plik istnieje i zawiera co najmniej cmsPro.zip + ver_1.519.zip + smoke-test command
|
|
</verify>
|
|
<done>Dostarczona instrukcja uploadu dla użytkownika</done>
|
|
</task>
|
|
|
|
<task type="checkpoint:human-action" gate="blocking">
|
|
<what-built>
|
|
Zestaw spatchowanych paczek + cmsPro.zip + ver_1.519.zip kotwica fixa, gotowe do uploadu.
|
|
</what-built>
|
|
<how-to-verify>
|
|
1. Otwórz `.paul/phases/04h-hotfix-https-updates/upload-checklist.md`
|
|
2. Wgraj wskazane pliki na serwer cmspro.project-dc.pl do katalogu updates/
|
|
(FTP/SSH/panel hostingu — wedle Twojej procedury)
|
|
3. Uruchom smoke-test:
|
|
curl -sS "https://www.cmspro.project-dc.pl/updates/versions.php?key=DOWOLNY_VALID_KEY"
|
|
→ powinno zwrócić listę wersji bez 301
|
|
4. Pobierz testowo jedną z paczek:
|
|
curl -sS -o /tmp/test.zip "https://www.cmspro.project-dc.pl/updates/1.50/ver_1.519.zip"
|
|
file /tmp/test.zip → powinno być "Zip archive"
|
|
</how-to-verify>
|
|
<resume-signal>Wpisz "uploaded" gdy paczki są na serwerze, lub opisz problem</resume-signal>
|
|
</task>
|
|
|
|
<task type="checkpoint:human-verify" gate="blocking">
|
|
<what-built>
|
|
Hotfix instancji testowej: pliki zaktualizowane lokalnie + paczki na serwerze.
|
|
</what-built>
|
|
<how-to-verify>
|
|
1. W instancji testowej (cmstest.pagedev.pl) wyloguj się i zaloguj ponownie do panelu
|
|
(czyści sesję `new-version`).
|
|
2. Wejdź w sekcję aktualizacji (admin → Aktualizacja).
|
|
3. Sprawdź:
|
|
- Pokazuje wersję 1.519 jako bieżącą
|
|
- Pokazuje "Dostępna nowa wersja: X.YYY" gdzie X.YYY > 1.519
|
|
- Klik "Aktualizuj" przebiega bez błędu i zwiększa wersję
|
|
4. Powtórz update kilka razy aż dojdziesz do najnowszej dostępnej wersji.
|
|
5. Sprawdź `libraries/version.ini` w instancji — odzwierciedla najnowszą wersję.
|
|
</how-to-verify>
|
|
<resume-signal>Wpisz "approved" gdy aktualizacje działają, lub opisz problem</resume-signal>
|
|
</task>
|
|
|
|
</tasks>
|
|
|
|
<boundaries>
|
|
|
|
## DO NOT CHANGE
|
|
- index.php:92 (`\S::get('hash') == $settings['update_key']`) — to oddzielna funkcja (front-devel mode), nie URL
|
|
- Logika parsowania wersji, manifestów, SQL — tylko URL ma się zmienić
|
|
- Struktura katalogowa updates/ na serwerze — tylko zawartość plików
|
|
- Inne pliki w instancji testowej cmstest.pagedev.pl — to UAT, ma odzwierciedlać prod
|
|
- Roadmap Phase 5+ — to hotfix poza roadmapą, nie blokuje Phase 5
|
|
|
|
## SCOPE LIMITS
|
|
- Plan NIE refaktoryzuje update systemu do nowej architektury (to robota dla Phase 5/13)
|
|
- Plan NIE wprowadza retry/cURL/stream-context — wystarczy zmiana protokołu, serwer wspiera HTTPS bezpośrednio
|
|
- Plan NIE patchuje pojedynczych instancji produkcyjnych poza testową — użytkownicy końcowi dostaną fix przez kotwicę 1.519 lub baseline cmsPro.zip
|
|
- Plan NIE rozwiązuje problemu "stare instancje na <1.519 zablokowane przed migracją serwera" — wymagałyby manualnego patcha (out of scope)
|
|
|
|
</boundaries>
|
|
|
|
<verification>
|
|
Przed zamknięciem planu:
|
|
- [ ] Task 1 verify (grep w kodzie cmsPRO)
|
|
- [ ] Task 2 verify (grep w instancji testowej)
|
|
- [ ] Task 3: audit-report.md istnieje i jest kompletny
|
|
- [ ] Task 4: powtórzony audit pokazuje 0 buggy paczek (dla full-patch) lub tylko nie-patched paczki świadomie pominięte
|
|
- [ ] Task 5: ver_1.519.zip zawiera fix files
|
|
- [ ] Task 6: upload-checklist.md istnieje
|
|
- [ ] Checkpoint upload: użytkownik potwierdził upload + smoke-test OK
|
|
- [ ] Checkpoint UAT: instancja testowa aktualizuje się do najnowszej wersji bez błędu
|
|
- [ ] Wszystkie AC spełnione
|
|
</verification>
|
|
|
|
<success_criteria>
|
|
- Bieżąca instancja testowa odblokowana — widzi i instaluje aktualizacje > 1.519
|
|
- Bazowy install (cmsPro.zip) na serwerze nie zawiera buggy http://
|
|
- ver_1.519.zip jest "kotwicą fixa" dla każdej nowej instalacji
|
|
- Audit report dokumentuje stan wszystkich paczek
|
|
- Brak regresji w innych modułach (URL change to jedyna ingerencja)
|
|
</success_criteria>
|
|
|
|
<output>
|
|
Po zamknięciu utwórz `.paul/phases/04h-hotfix-https-updates/04h-01-SUMMARY.md`
|
|
zawierający:
|
|
- Co zmieniono (kod + paczki)
|
|
- Listę paczek patched z SHA256 przed/po
|
|
- Decyzję checkpoint (full-patch vs minimal-patch) i uzasadnienie
|
|
- Lessons learned (np. "zawsze używać HTTPS w endpointach update", "rozważyć stream context z follow_location jako defense-in-depth")
|
|
- Sugestię dla Phase 5/13 Releases+Update: rozważyć cURL z verify SSL i obsługą redirectów jako trwałe rozwiązanie
|
|
</output>
|