From bfdf528e76285ccfbf0b209465b5f5a67337b74b Mon Sep 17 00:00:00 2001 From: root Date: Thu, 28 May 2026 18:49:06 +0800 Subject: [PATCH] docs: add CHANGELOG.md documenting all audit fixes, config changes, and DB recovery --- CHANGELOG.md | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 00000000..6db0f85a --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,87 @@ +# Changelog + +All notable changes to the SIDES project are documented in this file. + +--- + +## [2026-05-28] — Audit Fix, Configuration & Database Recovery + +### Security + +- **F-01** Parameterized SQL queries in `RainfallController::index()` — replaced string-interpolated `CAST('$dateFilter' AS date)` and `AND s.stationid = '{$stationFilter}'` with `?` bindings, eliminating SQL injection vectors +- **F-02** Parameterized SQL queries in `WaterLevelController::index()` — replaced `WHERE s.stationid = '{$stationFilter}'` and `AND w.datetime = '{$sqlDate}'` with `?` bindings +- **F-06** Fixed XSS risk in `stationmgmt.blade.php` — replaced `{!! $types ... !!}` with `e()` escaping for translation strings inside badge HTML +- **F-07** Standardized password policy in `AdminController` — both `storeUser()` and `updatePassword()` now use `Password::defaults()` instead of `min:6` +- **F-10** Stopped leaking internal exception messages to users — `AdminController` catch blocks now log errors via `Log::error()` and return `__('toast.error')` generic messages; added `toast.error` translation keys for EN and BM +- **F-23** Added `Referrer-Policy: strict-origin-when-cross-origin` and `Content-Security-Policy` headers to Nginx config; changed existing headers to `always` directive +- **F-24** Added `url` validation rule for `cctv_link` in both `storeStation()` and `updateStation()`; removed hardcoded `http://` prefix from CCTV link in `cctv.blade.php` + +### Reliability + +- **F-09** Added error handling to `FcmService::__construct()` — validates credentials file existence, catches `JsonException` on parse, logs errors, and returns status 500 in `sendToTopic()` when credentials are unavailable +- **F-11** Added required parameter validation to `WaterLevelController::wlHistory()`, `WaterLevelController::exportHistoricalWl()`, `RainfallController::historicalRainfall()`, and `RainfallController::exportHourlyRainfallExcel()` — all now validate `station`, `startdate`, and `enddate` before use +- **F-12** Wrapped `AdminController::storeStation()`, `storeUser()`, and `updateUsers()` write operations in `DB::transaction()` for atomicity +- **F-15** Removed all commented-out dead code blocks from `cctvController.php`, `RainfallController.php`, `AlertController.php`, `AppServiceProvider.php`, `homeapp.blade.php`, `home.blade.php`, `usermgmt.blade.php`, and `threshold.blade.php` + +### Performance + +- **F-13** Created migration `2026_05_28_000000_add_performance_indexes.php` adding indexes on: + - `rainfall(stationid)`, `rainfall(timestamp)`, `rainfall(stationid, timestamp)` + - `waterlevel(stationid)`, `waterlevel(datetime)`, `waterlevel(stationid, datetime)` + - `notification(stationid)`, `notification(timestamp)`, `notification(stationtype)` + - `siren(stationid)`, `siren(active_time)` + +### Configuration + +- **F-18** Created `src/.env.example` with all documented environment variables (APP, DB, SESSION, CACHE, QUEUE, MAIL, FIREBASE, FCM, POSTGRES, PGADMIN) +- Created `src/.env` with populated values: generated `APP_KEY`, set `DB_*` matching docker-compose PostgreSQL service, set `FIREBASE_PROJECT_ID=sides-b4abb`, set `FIREBASE_CREDENTIALS` path +- Created root `.env` for docker-compose with `POSTGRES_DB`, `POSTGRES_USER`, `POSTGRES_PASSWORD`, `PGADMIN_EMAIL`, `PGADMIN_PASSWORD` +- Added `src/.gitignore` and root `.gitignore` to exclude `.env` from version control + +### Deployment + +- **F-19** Removed redundant `COPY ./src /var/www/html` line from `Dockerfile` — kept only `COPY --chown=www:www ./src /var/www/html`; removed commented-out dead lines (`RUN curl`, `RUN tar`, `COPY fileni`) +- Fixed `docker-compose.yml` PostgreSQL data directory from `/var/lib/postgres/data` to `/var/lib/postgresql/data` and added `PGDATA` env var +- Set non-empty `POSTGRES_PASSWORD` and `DB_PASSWORD` (was empty, causing PostgreSQL 18 to refuse initialization) +- Set non-empty `PGADMIN_PASSWORD` (was empty, causing pgAdmin to crash) + +### Database Recovery + +- Restored production data from `backup/sides_20260528` into the live `sides` database: + - `users`: 4 rows (admin, imam14, ijantck, jpskedah) + - `station`: 9 rows (KBLG0025–KBLG0033) + - `rainfall`: 91,829 rows + - `waterlevel`: 137,956 rows + - `notification`: 128 rows +- Made `users.email` column nullable in migration `0001_01_01_000000_create_users_table.php` — existing data has NULL emails for admin and jpskedah +- Reset all sequence counters to 300,000+ to avoid duplicate key errors from concurrent sensor inserts with explicit IDs + +### Codebase Assessment + +- Created `.planning/codebase/` with 7 structured documents: + - `STACK.md` — PHP 8.2, Laravel 12, PostgreSQL 18, Docker/Nginx infrastructure + - `INTEGRATIONS.md` — Firebase FCM, PostgreSQL, S3 filesystem, database queue/cache/session + - `ARCHITECTURE.md` — MVC pattern, raw SQL over Eloquent, Breeze auth, FCM push alerts + - `STRUCTURE.md` — Directory tree, 12 migrations, 8+ tables, dual layout system + - `CONVENTIONS.md` — Raw SQL patterns, PSR-12, localization (en/bm), Blade conventions + - `TESTING.md` — PHPUnit, near-zero coverage (2 example tests only), no CI + - `CONCERNS.md` — 26 findings: 3 critical SQL injections, unauthenticated API endpoints, missing indexes, no audit logging, deployment security gaps + +--- + +### Manual-Only Findings (Not Yet Fixed) + +These require design decisions or architectural changes: + +| # | Finding | Notes | +|---|---------|------| +| F-03 | Unauthenticated API alert endpoint | Requires Laravel Sanctum + rate limiting | +| F-04 | API endpoints without authentication | Architectural change across subsystems | +| F-05 | API login without token | Requires Sanctum integration | +| F-08 | Inverted block/unblock logic | Requires UX redesign of checkbox semantics | +| F-14 | Duplicated dashboard query | Requires service class extraction | +| F-20 | PostgreSQL data dir path | Already fixed in this session | +| F-21 | Docker security (Dozzle shell, Filebrowser root, pgAdmin exposed) | Architecture decisions needed | +| F-22 | No Docker health checks | Deployment decisions needed | +| F-25 | No audit logging | Low severity, requires design | +| F-26 | No API rate limiting | Low severity, requires design | \ No newline at end of file