13 Commits

Author SHA1 Message Date
myron 72ba4743f9 simplify: cache dirname(__DIR__), use str_starts_with, drop finfo object for mime_content_type() 2026-06-23 16:35:17 +00:00
myron bb21fca399 Security: block direct upload access, fix view-doc path traversal guard
- uploads/.htaccess: deny all direct web access to uploaded customer docs
- admin/view-doc.php: add realpath() path-traversal check (mirrors view-doc.php)
- admin/view-doc.php: remove dead double-query (result was always overwritten)
- .gitignore: uploads/* wildcard so .htaccess can be tracked
2026-06-13 14:20:41 +00:00
myron 072272104e Migrate to parkerslingshotrentals.com domain
- db.php: SITE_URL -> https://www.parkerslingshotrentals.com
- db.php: add ADMIN_PHONE (817) 266-2022
- index.html, contact.php, admin/index.php: fix placeholder phone 555-0199 -> 266-2022
- admin/view-doc.php: new secure doc viewer (URL-token auth, bookings table)
- upload-docs.php, view-doc.php: added from subdomain (already used db.php/bookings)
2026-06-08 17:23:40 +00:00
myron 41773a6905 Customer detail: expandable rows with full booking flow + payment controls 2026-05-22 22:06:49 +00:00
myron 3b0daa72e4 Add customers CRUD section to admin panel 2026-05-22 21:52:56 +00:00
myron 654aecc2dd Replace cookie auth with URL token auth in admin portal
Cookies failed consistently in real browsers despite working in curl.
Replaced with DB-stored token passed as ?_t=TOKEN in URL:
- Login generates 64-char hex token, stores in admin_tokens table
- Redirect to /admin/?_t=TOKEN after successful login
- Every request validated via DB lookup (no cookies needed)
- All 7 AJAX calls include &_t=TOKEN in POST body
- Logout deletes token from DB
- Requires admin_tokens table (created in DB)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 18:59:50 +00:00
myron 0b36064cc6 Fix admin navigation — eliminate page reloads and browser cache
- Add PHP no-cache headers (Cache-Control: no-store) at top of file so OLS
  cannot cache the login page and serve it to authenticated users — this was
  the root cause (OLS ignores .htaccess Header directives)
- Replace status filter anchor links (/admin/?status=X) with client-side JS
  filterBookings() — no page navigation means no cookie re-verification on
  each filter click, eliminating the persistent login redirect
- Add data-status attribute to booking rows for JS filtering
- Load all bookings at once; filter is instant and stays on same page

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 18:51:00 +00:00
myron 10e1ffa27b Change deposit to $45, add balance-due-at-pickup calculations
- DEPOSIT_AMOUNT changed from $100 to $45
- Balance (package price minus $45) shown dynamically in booking form when package selected
- Customer confirmation email shows breakdown: deposit hold + balance at pickup
- Admin email table includes deposit hold and balance columns
- Admin booking flow step 5 shows deposit held + balance at pickup
- Reminder email deposit detail updated to reflect held deposit and balance
- Live status field shows $45 during card authorization flow

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 18:38:04 +00:00
myron cca3129f6e Add Square deposit payment integration
- Square Web Payments SDK card element in booking form
- Delayed-capture hold ($100) on booking submit — not charged until confirmed
- Live payment status field: Verifying card → Authorizing → Confirmed w/ hold ID
- Admin: Capture / Void / Refund actions for each booking
- square_payment_id returned in API response for frontend confirmation display

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 18:33:16 +00:00
myron 8f5362aa95 Fix admin login: replace PHP sessions with HMAC cookie auth
PHP sessions were unreliable on this host — the web process could write
session files but LiteSpeed served cached login-page responses on the
redirect, bypassing PHP entirely.

Replace sessions with a self-contained signed cookie:
- On login: generate random 32-byte token + expiry, sign with HMAC-SHA256
- On each request: verify signature and expiry — no filesystem reads needed
- Cookie: Secure, HttpOnly, SameSite=Lax, path=/admin/, 24h expiry
- admin/.htaccess: CacheEnable off + no-store headers to prevent LiteSpeed
  from caching admin responses

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 14:15:33 +00:00
myron b3b831e4a0 Add per-customer booking flow checklist + fix admin login
Admin portal overhaul:
- Fix require_once path (was admin/db.php, should be ../db.php) — this was
  the root cause of the login always redirecting back to the login page
- Fix session save path to /home/parkerslingshotrentals.com/sessions so the
  web user (parke1909) can actually read sessions back (the system default
  /var/lib/php/sessions was write-only for non-root)
- Fix AJAX unauthenticated response: return 401 JSON instead of login HTML
- Fresh bcrypt hash for admin password (Parker2026!)
- Add 3 new DB columns: insurance_verified, deposit_received, license_verified
- Replace flat bookings table with expandable per-customer flow panel:
  click any row to open a 3-column detail drawer showing:
  (1) full contact info + admin notes
  (2) 6-step booking flow checklist with inline toggle buttons for steps
      that admin marks (insurance, deposit, license)
  (3) send-reminder email builder — pick which pending items to include,
      send customer a personalized nudge with waiver link + instructions
- Progress dots in table row update live when admin toggles a step
- Stats row now includes waiver, insurance, deposit counts

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 14:01:42 +00:00
myron 85448d18c5 Add digital e-signature waiver + update How It Works to 5 steps
- waiver.php: full rental agreement with canvas e-signature pad, 6 required
  checkboxes, typed name field; stores sig image + IP + timestamp in DB;
  emails signed confirmation to customer and admin
- bookings table: add waiver_signed, waiver_signed_at, waiver_ip, waiver_name,
  waiver_sig columns
- contact.php: confirmation email now includes Sign Rental Agreement button/link
- admin/index.php: Waiver column shows Signed (date) or Pending + Send Link
- index.html: How It Works expanded to 5 steps (added Get Approved + Sign Waiver
  before Hit the Road); insurance updated to Proof of insurance required; FAQ
  and JSON-LD updated to match

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 13:49:31 +00:00
myron 2ecf8f04c4 Add availability calendar, admin portal, and booking backend
- db.php: shared config, PDO, SendGrid, package definitions
- availability.php: GET endpoint returning booked/blocked dates by month
- contact.php: booking handler with DB record, availability check, SendGrid emails
- admin/index.php: full admin portal (login, bookings table, status/notes AJAX, block dates)
- index.html: interactive availability calendar with click-to-select, wires to /contact.php
- .htaccess: block direct access to db.php

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 13:39:20 +00:00