This repo now contains the live Cloudflare Worker for Garden Dashboard. The app behavior is built and deployed; the current task is security hardening for public beta on garden.paropter.com.
As of April 8, 2026:
Verified successfully:
- local Python Worker spike proved the product logic and D1 schema
- signed auth cookie issuance and protected route access
- CSRF protection on login, logout, and plant POST routes
- plant create/edit/delete flows
- watering status calculation, urgency sorting, and summary counters
- dashboard status filters with filter-preserving add/edit/delete/water flows
- TypeScript/Hono fallback Worker now ports the same route surface and D1-backed behavior
npm run checkpasses for the fallback Workernpm run test:workerpasses for the active TypeScript Worker- auth cookies now invalidate when
APP_PASSWORDchanges AUTH_VERSIONcan invalidate all sessions without changing the password/debug/d1is disabled by default and only available whenENABLE_DEBUG_ROUTES=true- HTML responses now send strict CSP and baseline browser hardening headers
wrangler deploy --dry-runandwrangler deploy --dry-run --env previewboth bundle successfully
Active workstream:
- Cloudflare-side beta hardening and final production verification
- put Cloudflare Access in front of
garden.paropter.com - add a WAF/rate-limit rule for
POST /login - review managed WAF/Bot settings and decide on HSTS for the zone
- deploy this security slice and verify production headers, session invalidation, and debug-route shutdown
- decide whether production should start with starter plants or remain empty
- add any remaining presentation polish that still matters for handoff
worker/index.ts: active Cloudflare Worker entrypoint and route registrationworker/auth.ts: signed auth cookie, session-scope invalidation, and CSRF helpersworker/plants.ts: D1 access, form validation, plant models, and dashboard status logicworker/render.ts: HTML page rendering helpers for login, dashboard, forms, and errorstests/worker_security.test.ts: direct Node-run Worker security testssrc/assets/: static assets served by Workersmigrations/0001_initial_schema.sql: initial D1 schemasrc/*.pyandsrc/routes/*.py: previous Python Worker implementation retained as reference while the TypeScript Worker becomes the deployable pathtests/test_auth_helpers.py: stdlib-only smoke tests for auth and CSRF helperstests/test_plant_form.py: plant form parsing and validation teststests/test_models.py: model normalization and display helper teststests/test_plant_status.py: watering status and dashboard sorting tests
Code-side hardening in this repo now assumes these runtime vars exist:
APP_PASSWORDSESSION_SECRETAPP_TIMEZONEAUTH_VERSIONENABLE_DEBUG_ROUTES
Current intended values:
- production:
AUTH_VERSION=1ENABLE_DEBUG_ROUTES=false
- preview/local:
AUTH_VERSION=1ENABLE_DEBUG_ROUTES=true
Operational notes:
- changing
APP_PASSWORDnow invalidates existing sessions after the new Worker version deploys - bump
AUTH_VERSIONwhen you want to force-log-out every user without changing the password - keep
ENABLE_DEBUG_ROUTES=falsein production
These are still manual:
- Create a Cloudflare Access self-hosted application for
garden.paropter.com. - Add allow rules for the specific beta-user email addresses.
- Add a WAF rate-limit rule for
POST /login. - Review Managed WAF rules, Bot Fight Mode, and HSTS for
paropter.com. - After deploying this commit, verify the production headers and confirm
/debug/d1is gone on the public domain.
The active runtime now uses a standard TypeScript Worker with Hono.
- Install dependencies:
npm install- Copy the local secrets template:
cp .dev.vars.example .dev.vars- Create your D1 databases and replace the IDs in
wrangler.jsonc.
Suggested names:
garden-dashboard-productiongarden-dashboard-preview
- Apply the schema locally:
npm run d1:migrate:local- Start the local dev server:
npm run devType-check the fallback Worker:
npm run checkRun the direct Worker security tests:
npm run test:workerCreate a preview D1 database:
npx wrangler d1 create garden-dashboard-previewCreate a production D1 database:
npx wrangler d1 create garden-dashboard-productionApply preview migrations:
npm run d1:migrate:previewApply production migrations:
npm run d1:migrate:prodDeploy the preview environment:
npm run deploy:previewDeploy production:
npm run deployPython spike regression tests:
python3 -m unittest tests/test_auth_helpers.py tests/test_models.py tests/test_plant_form.py tests/test_plant_status.pyGET /healthz: simple JSON health checkGET /login: shared-password login pagePOST /login: checks shared password and sets signed cookiePOST /logout: clears auth cookieGET /: protected watering dashboard with sorted plant statuses and status filters Query params:status=all|overdue|due-soon|good|no-schedule, optionalnotice=<flash-key>GET /plants/new: add plant formPOST /plants/new: create plantGET /plants/{id}/edit: edit plant formPOST /plants/{id}/edit: update plantPOST /plants/{id}/water: mark a plant as watered todayPOST /plants/{id}/delete: delete plantGET /debug/d1: preview/local-only D1 probe endpoint whenENABLE_DEBUG_ROUTES=true