Commit Graph

18 Commits

Author SHA1 Message Date
derekc acfa21ec38 Update README to reflect current state
Add rate limits, pagination, Ntfy events, ALLOWED_ORIGINS, security
section, notify.py in project structure, corrected admin seed behaviour,
and updated stack versions.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-25 01:23:47 -07:00
derekc 84b07e33e7 Pin image digests and disable TRACE method in nginx
- nginx and mysql images pinned to SHA256 digests
- nginx: return 405 on TRACE requests

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-25 01:20:18 -07:00
derekc e08e031ad0 Add HSTS, gzip, Ntfy notifications, and paginate entries endpoint
- nginx: add HSTS (max-age=31536000) and gzip for text/css/js/json
- entries: add limit/offset query params (default 200, max 1000)
- Ntfy: wire NTFY_URL/NTFY_TOKEN through env; notify on startup, new
  registration, admin login, user disable, and user delete
- httpx==0.28.1 added for async Ntfy HTTP calls

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-25 01:12:59 -07:00
derekc 2c45e599c0 Run backend as non-root user, add resource limits to all containers
- Dockerfile: create and switch to unprivileged appuser (HIGH fix)
- docker-compose: mem_limit + cpus on nginx (128m/0.25), backend (512m/0.5), db (512m/0.5)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-25 01:06:40 -07:00
derekc 95d648210c Patch CRITICAL/HIGH CVEs: python-jose 3.5.0, python-multipart 0.0.29
- python-jose 3.3.0 → 3.5.0 (CVE-2024-33663: CRITICAL, algorithm confusion)
- python-multipart 0.0.20 → 0.0.29 (CVE-2026-24486, CVE-2026-42561: HIGH)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-25 01:03:57 -07:00
derekc 50ee1f9fed Fix auth bypasses, race condition, stale connections, and unbounded query
- Block disabled accounts at login and unimpersonate (C4, C2)
- Catch IntegrityError on register commit to return 409 instead of 500 (C5)
- Stop _seed_admin from overwriting existing admin password on restart (C8)
- Cap public/stats query at 500 users to bound memory usage (C3)
- Rate-limit PUT /me/password at 5/minute (C6)
- Bump SQLAlchemy to 2.0.50 and aiomysql to 0.3.2; re-enable pool_pre_ping (C7)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-25 00:55:12 -07:00
derekc ef8b44934c Fix aiomysql pool_pre_ping crash, add rate limiting and security hardening
Remove pool_pre_ping=True to fix startup crash caused by aiomysql 0.2.0
async adapter requiring a reconnect argument SQLAlchemy does not pass.
Add slowapi rate limiting, structured logging, CORS config, backend
health check, and nginx security headers.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-25 00:44:23 -07:00
derekc 866c2e0bed Fix stale DB connections, add Why Bourbonacci section, harden auth
- Add pool_pre_ping and pool_recycle to prevent lost connection errors on idle pool
- Add Why Bourbonacci card to about page
- Redirect to login on 401 in API layer
- Check JWT expiry in isLoggedIn instead of just token presence

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-09 21:37:04 -07:00
derekc a9de081a8a Update README: name origin, about page, login redirect, new page
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 22:22:50 -07:00
derekc 46499f4cb9 Add about page, update login redirect, and hero button tweaks
- Add about.html explaining infinity bottles, why to track, how to start
- Hero shows "What is it?" + "Track Your Bottle" when logged out; hides about button when logged in
- Redirect after login goes to index (community page) instead of dashboard
- redirectIfLoggedIn also sends to index

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 22:14:24 -07:00
derekc 1ac5a191be Update README with current features, API, and data model
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 21:55:32 -07:00
derekc ca83351e9d Add bottle size, bourbon list modal, and stat improvements
- Add bottle_size field to User model and UserResponse/UserUpdate schemas
- Settings modal includes bottle size input (shots capacity)
- Community bottles and My Bottle page show fill bar based on bottle size
- Community bottle cards are clickable — opens searchable bourbon list modal
- Add total_shots_added stat to replace duplicate net volume on dashboard
- Reorder dashboard stats: Bourbons Added, Total Poured In, Shots Remaining, Est. Proof
- Theme-matched custom scrollbar (amber on dark)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 21:53:50 -07:00
derekc f1b82baebd Overhaul nav, fix DB transaction bugs, add admin UI
- Replace nav user area with display name (non-clickable), gear settings
  modal, admin button (admins only), and logout button
- Settings modal handles display name, timezone, and password change
- Add admin.html + admin.js: user table with reset PW, disable/enable,
  login-as (impersonation), and delete; return-to-admin flow in nav
- Add is_admin to UserResponse so frontend can gate the Admin button
- Fix all db.begin() bugs in admin.py and users.py (transaction already
  active from get_current_user query; use commit() directly instead)
- Add email-validator and pin bcrypt==4.0.1 for passlib compatibility
- Add escHtml() to api.js and admin API namespace
- Group nav brand + links in nav-left for left-aligned layout

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 21:09:38 -07:00
derekc 48a15c54f6 Add admin account with user management endpoints
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 20:45:19 -07:00
derekc 7994cc5ff2 Add emoji favicon and README title icon
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 19:38:04 -07:00
derekc 916d638e84 Update README with full project documentation
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 19:12:51 -07:00
derekc 72b23c18aa Add initial project files
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 19:11:00 -07:00
derekc bfab8f71fb Initial commit 2026-03-24 19:08:32 -07:00