|
Some checks failed
Veza CI / Backend (Go) (push) Failing after 0s
Veza CI / Frontend (Web) (push) Failing after 0s
Veza CI / Rust (Stream Server) (push) Failing after 0s
Security Scan / Secret Scanning (gitleaks) (push) Failing after 0s
Veza CI / Notify on failure (push) Failing after 0s
Closes a bypass surfaced by the 2026-04 audit probe (axis-1 Q2): any authenticated user could POST /api/v1/subscriptions/subscribe on a paid plan and receive 201 active without the payment provider ever being invoked. The resulting row satisfied `checkEligibility()` in the distribution service via `can_sell_on_marketplace=true` on the Creator plan — effectively free access to /api/v1/distribution/submit, which dispatches to external partners. Fix is centralised in `GetUserSubscription` so there is no code path that can grant subscription-gated access without routing through the payment check. Effective-payment = free plan OR unexpired trial OR invoice with non-empty hyperswitch_payment_id. Migration 980 sweeps pre-existing fantôme rows into `expired`, preserving the tuple in a dated audit table for support outreach. Subscribe and subscribeToFreePlan treat the new ErrSubscriptionNoPayment as equivalent to ErrNoActiveSubscription so re-subscription works cleanly post-cleanup. GET /me/subscription surfaces needs_payment=true with a support-contact message rather than a misleading "you're on free" or an opaque 500. TODO(v1.0.7-item-G) annotation marks where the `if s.paymentProvider != nil` short-circuit needs to become a mandatory pending_payment state. Probe script `scripts/probes/subscription-unpaid-activation.sh` kept as a versioned regression test — dry-run by default, --destructive logs in and attempts the exploit against a live backend with automatic cleanup. 8-case unit test matrix covers the full hasEffectivePayment predicate. Smoke validated end-to-end against local v1.0.6.2: POST /subscribe returns 201 (by design — item G closes the creation path), but GET /me/subscription returns subscription=null + needs_payment=true, distribution eligibility returns false. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|---|---|---|
| .. | ||
| archive | ||
| probes | ||
| align-8px-grid.py | ||
| audit_backend_endpoints.py | ||
| auto_migrate_tailwind_colors.py | ||
| auto_migrate_tailwind_colors_batch.py | ||
| deploy-blue-green.sh | ||
| deploy-staging.sh | ||
| diagnose-register.sh | ||
| generate-bug-report.sh | ||
| generate-jwt-keys.sh | ||
| generate-ssl-cert.sh | ||
| generate_full_schema.sh | ||
| generate_tailwind_list.py | ||
| mark_consolidated.sql | ||
| README_TAILWIND_MIGRATION.md | ||
| replace-decorative-cyan.py | ||
| rotate_logs.sh | ||
| run-all-mvp-tests.sh | ||
| run-e2e-local.sh | ||
| setup-mvp-test-env.sh | ||
| setup_logs.sh | ||
| smoke_test.go | ||
| squash_migrations.sh | ||
| staging-stability-check.sh | ||
| start-backend.sh | ||
| start_boot.sh | ||
| start_minimal.sh | ||
| stop_minimal.sh | ||
| sync-cursor.py | ||
| test-endpoint-formats.sh | ||
| test-mvp-api.sh | ||
| validate-env.sh | ||
| validate-full.sh | ||
| validate-light.sh | ||
| verify-rust-build.sh | ||
| verify_minimal_journey.sh | ||
| view_logs.sh | ||