Sequential IDs in /planner/export/<id> and /leads/<id>/unlock leaked business volume (e.g. export_id=47 reveals ~47 PDFs sold). Replace with 22-char URL-safe tokens that carry no countable information. - Migration 0017: adds `token TEXT` to business_plan_exports and lead_requests, backfills existing rows with secrets.token_urlsafe(16), creates unique indexes for fast lookups - billing/routes.py: INSERT into business_plan_exports includes token - leads/routes.py: INSERT into lead_requests includes token; enqueue payload includes lead_token; verify_quote() looks up by token - planner/routes.py: /export/<token> route (was /export/<int:export_id>) - suppliers/routes.py: /leads/<token>/unlock (was /leads/<int:lead_id>) - worker.py: email links use token for both export and verify URLs - Templates: url_for() calls use token= param - test_phase0.py: _submit_guest_quote() returns (lead_id, auth_token, lead_token); verify URL tests use opaque lead token Integer PKs unchanged; admin routes unchanged. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
29 KiB
29 KiB