--- phase: 04h-hotfix-https-updates plan: 01 subsystem: infra tags: [https, urlencode, ftp-cleanup, update-mechanism, license-key] requires: - phase: pre-paul (legacy update mechanism) provides: file_get_contents-based update polling provides: - HTTPS-only update endpoint (kod + 121 paczek + cmsPro.zip + kotwica 1.519) - urlencode($settings['update_key']) wrap (kod + 64 paczek + kotwica) - Audit/patcher PowerShell scripts dla updates/ ZIP-ow - FTP cleanup script (.bak removal lokalnie + zdalnie) affects: [phase-5 (Releases+Update Domain repo), phase-13 (Admin: Update controller)] tech-stack: added: [] patterns: - "Audit-then-patch script pair: oddzielne audyt vs mutating skrypty (idempotent verify)" - "Anchor-package strategy: wstrzykniecie fixa w istniejaca paczke aktualizacji jako ratunkowy punkt zaczepienia" key-files: created: - .paul/phases/04h-hotfix-https-updates/scripts/audit-packages.ps1 - .paul/phases/04h-hotfix-https-updates/scripts/patch-packages.ps1 - .paul/phases/04h-hotfix-https-updates/scripts/patch-urlencode.ps1 - .paul/phases/04h-hotfix-https-updates/scripts/inject-anchor-1519.ps1 - .paul/phases/04h-hotfix-https-updates/scripts/cleanup-baks.ps1 - .paul/phases/04h-hotfix-https-updates/audit-report.md - .paul/phases/04h-hotfix-https-updates/patch-log.md - .paul/phases/04h-hotfix-https-updates/patch-urlencode-log.md - .paul/phases/04h-hotfix-https-updates/upload-checklist.md modified: - autoload/Shared/Helpers/Helpers.php - autoload/admin/factory/class.Update.php - updates/cmsPro.zip - updates/**/ver_*.zip (121 paczek http->https + 64 urlencode) - 2x ver_*_manifest.json (przeliczone checksum_zip SHA256) key-decisions: - "full-patch zamiast minimal-patch: 121 paczek > ryzyko regresji przy chain-update" - "urlencode jako oddzielny patch po wykryciu bug-a #2 podczas UAT (klucz licencji z #)" - ".NET FtpWebRequest zamiast curl --quote dla cleanup (PowerShell 5.1 traktuje stderr curl jako fatal)" patterns-established: - "Reverse-engineering bug w produkcji: curl probe serwera wyzwolil odkrycie HTTP 301 redirect" - "Bug discovery podczas UAT: drugi bug (urlencode) ujawniony dopiero po naprawieniu pierwszego" duration: ~90min started: 2026-04-25T22:00:00Z completed: 2026-04-26T00:35:00Z --- # Phase 04h Plan 01: Hotfix HTTPS Update Endpoint Summary **Naprawa zablokowanego mechanizmu aktualizacji w cmsPRO: HTTP->HTTPS w kodzie + 121 paczkach, urlencode klucza licencji w 64 paczkach, kotwica fixa w ver_1.519.zip, cleanup 1085 backupow z FTP+lokalnie. Test instance odblokowana i potwierdzona przez user-a.** ## Performance | Metric | Value | |--------|-------| | Duration | ~90min | | Started | 2026-04-25 22:00 | | Completed | 2026-04-26 00:35 | | Tasks | 8 zaplanowane + 3 dodatkowe (urlencode patch, urlencode w paczkach, cleanup .bak) | | Files modified | 4 PHP source + 124 paczki (cmsPro + 121 ZIP + 2 manifest) + 1085 .bak removed | ## Acceptance Criteria Results | Criterion | Status | Notes | |-----------|--------|-------| | AC-1: Kod cmsPRO uzywa HTTPS | Pass | Helpers.php + factory/Update.php; 0 wystapien http:// | | AC-2: Instancja testowa odblokowana | Pass | User potwierdzil "Zadzialalo" po dodaniu urlencode | | AC-3: Wszystkie paczki wolne od bug-a | Pass | Audit po patchu: 0 paczek z http://, 0 paczek z raw $settings['update_key'] w URL | | AC-4: ver_1.519.zip jako kotwica fixa | Pass | Zawiera class.S.php (37958B) + class.Update.php (2886B), oba z https + urlencode. SHA256: 14e5754c75884fcc... | | AC-5: Audit report dostarczony | Pass | audit-report.md + patch-log.md + patch-urlencode-log.md | ## Accomplishments - **Odblokowanie WSZYSTKICH instancji cmsPRO**: kazda instancja ktora dotrze do 1.519 dostaje wbudowana kotwice z dzialajacym klientem update (https + urlencode) - **Identyfikacja DWOCH bugow** (HTTP 301 redirect i URL fragment-cutting na #) podczas jednej sesji - **Idempotentne skrypty audit+patch+cleanup** mozliwe do reuse gdyby pojawila sie kolejna fala buggy paczek - **Zero regresji**: zachowane oryginalne backupy podczas patcha (.bak), usuniete dopiero po UAT confirmation ## Files Created/Modified | File | Change | Purpose | |------|--------|---------| | `autoload/Shared/Helpers/Helpers.php` | Modified | http->https + urlencode w get_new_version() | | `autoload/admin/factory/class.Update.php` | Modified | http->https + urlencode w update() | | `cmstest.../autoload/class.S.php` | Modified | UAT instance hotfix | | `cmstest.../autoload/admin/factory/class.Update.php` | Modified | UAT instance hotfix | | `updates/cmsPro.zip` | Modified | Base install patched (legacy nie uzywal klucza, tylko http->https) | | `updates/**/ver_*.zip` (121) | Modified | http->https w autoload/class.S.php / Helpers.php / factory/Update.php | | `updates/**/ver_*.zip` (64) | Modified | urlencode wrap (subset 121) | | `updates/1.50/ver_1.519.zip` | Modified | + anchor injection: class.S.php + factory/Update.php | | `updates/**/ver_*_manifest.json` (2) | Modified | Przeliczony checksum_zip SHA256 | | `.paul/phases/04h-hotfix-https-updates/scripts/*.ps1` (5) | Created | Audit, patch, anchor inject, urlencode patch, FTP cleanup | | `.paul/phases/04h-hotfix-https-updates/*.md` (4) | Created | audit-report, patch-log, patch-urlencode-log, upload-checklist | ## Decisions Made | Decision | Rationale | Impact | |----------|-----------|--------| | full-patch wszystkich 121 paczek | Czesciowy patch ryzykowal regresje gdy stara buggy paczka nadpisywala swiezo zaktualizowany class.S.php | 124 pliki do uploadu (vs 3 minimum), ale kazda chain-update sciezka bezpieczna | | Anchor injection do ver_1.519.zip | Oryginalna paczka (class.Articles.php only) jest "darmowa" wersja na granicy licencji - idealny punkt by gwarantowac dzialajacy klient HTTPS dla wszystkich nowych instancji | Wszystkie nowe instancje od zera dostaja fix przy upgrade do 1.519 | | .NET FtpWebRequest zamiast curl dla cleanup | curl stderr w PowerShell 5.1 wyrzuca NativeCommandError przy 550, blokujac batch | Cleanup ukonczony bez bledow (1085 .bak) | | urlencode jako oddzielny etap | Bug ujawniony dopiero podczas UAT (user dodal klucz z #) - zorganizowany jako "rozszerzenie planu" zamiast restart | Czysta sciezka audytowa, oba bugi udokumentowane oddzielnie | ## Deviations from Plan ### Summary | Type | Count | Impact | |------|-------|--------| | Auto-fixed | 1 | urlencode bug discovered during UAT, dodatkowe 3 zadania (patch kodu, patch paczek, cleanup) | | Scope additions | 1 | FTP cleanup (.bak files na serwerze) - nie planowane, user zlecil po UAT | | Deferred | 0 | - | **Total impact:** Plan ukonczony + 2 niezbedne rozszerzenia odkryte podczas wykonania. ### Auto-fixed Issues **1. URL encoding klucza licencji (krytyczny bug #2)** - **Found during:** UAT post-Task 8 (user testowal z kluczem `#e@1tUVvZDP:$7dL`) - **Issue:** Klucz licencji wstrzykiwany raw w URL, znak `#` w kluczu byl traktowany jako fragment delimiter -> serwer dostawal pusty klucz -> zwracal wersje tylko do 1.519 (free tier) - **Fix:** `urlencode($settings['update_key'])` w kodzie + 64 paczkach + kotwicy - **Files:** Helpers.php, factory/Update.php (cmsPRO + test instance), 64x ver_*.zip, ver_1.519.zip - **Verification:** PowerShell scan wszystkich plikow w paczkach: 0/165 bez urlencode wrap ### Scope Additions **1. FTP cleanup .bak files** - **Trigger:** User polecil usuniecie backupow po UAT confirmation - **Discovered:** Auto-deploy ftp-kr.json (autoUpload=true, autoDelete=false) wyslal 1085 .bak na serwer - **Action:** Skrypt cleanup-baks.ps1 (.NET FtpWebRequest) - 355 zdalnych usuniec + lokalne removal - **Verification:** sample listing /updates/1.50/ - 0 .bak remote, 0 .bak lokalnie ### Deferred Items None. ## Issues Encountered | Issue | Resolution | |-------|------------| | PowerShell 5.1 mis-reads UTF-8 file bez BOM (audit-packages.ps1 z em-dash) | Zamieniono "—" na "--", plik czysto ASCII | | `Substring(0,12)` na "(dry-run)" string (length 9) | Dodany length-guard if | | curl -Q "DELE name" w katalogu wymaga CWD; bez CWD szuka w root (550) | Zmiana na pelna sciezka w DELE + URL ftp://host/ | | curl stderr w PowerShell 5.1 = NativeCommandError przy 550 -> ErrorActionPreference Stop blokuje batch | Przepisanie na .NET FtpWebRequest z try/catch na 550 | ## Next Phase Readiness **Ready:** - Phase 5 (Domain: SeoAdditional + Cron + Releases) moze ruszyc bez zaleznosci od 04h - Mechanizm update na produkcji odblokowany - nowe wersje moga byc dystrybuowane normalnie - Skrypty audit/patch w `.paul/phases/04h-hotfix-https-updates/scripts/` dostepne jako template przy podobnych operacjach **Concerns:** - Mechanizm update nadal uzywa `file_get_contents()` bez stream context z verify_peer/follow_location - rekomendacja: w Phase 5 lub Phase 13 przepisac na cURL z proper error handling i SSL verification - Klucze licencji powinny byc walidowane przy zapisie w settings (max length, allowed chars) - obecnie polegamy na urlencode jako fix - Brak retry logic przy chwilowym network failure podczas update - obecny kod silnie failuje **Blockers:** - None. Phase 5 moze ruszyc. --- *Phase: 04h-hotfix-https-updates, Plan: 01* *Completed: 2026-04-26*