fix(security): RQ-3893 remove the AppSumo redemption flow - #116
fix(security): RQ-3893 remove the AppSumo redemption flow#116rohitneharabrowserstack wants to merge 1 commit into
Conversation
AppSumo is being retired, so the escalation path this ticket describes is removed rather than guarded. The redemption screen was the only client-side reader and writer of the `appSumoCodes` collection — it validated a typed code with `getDoc` and marked it `redeemed` in a batch write — which is the sole reason the Firestore rules had to grant every authenticated user read+update on that collection. Removed, all of it reachable only from the redemption screen: - components/landing/Appsumo/ (the modal and its workspace dropdown) - the /appsumo route and PATHS.APPSUMO - the entry in onboarding's EXCLUDED_PATHS - the "Signup to redeem your AppSumo code" variant of the signup header, plus the now-orphaned PATHS / useLocation imports it was the last consumer of - trackAppsumoCodeRedeemed and its APPSUMO_CODE_REDEEMED event name Deliberately kept: everything that serves customers who already hold the deal. An AppSumo plan is a persisted value on the team document (`plan: 'basic_appsumo_v0'`), not something derived from `appsumo.codes` at read time, so entitlement display and gating — PremiumPlanBadge, PricingUtils' "AppSumo" label, UserPlanDetails, ActiveLicenseInfo, PlanType.APPSUMO — are untouched. Removing those would revoke live lifetime plans, which is a separate decision with a migration attached. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Production bundle verified — nothing else breaksBuilt the full production bundle on this branch and inspected the output, which is the check Redemption code is gone from the shipped bundle
Entitlement code is still shipped, as intended
( Also verified
Note for anyone reproducing thisThe app build needs a three-level chain that no single command wires up: Not covered hereThis was verified by build and static analysis, not by a running app: both PR-preview workflows are disabled ( |
Client half of removing AppSumo redemption for RQ-3893. Backend: requestly/requestly-cloud#882.
Supersedes #115. AppSumo is being retired, so rather than routing the redemption screen through new server-side callables, the screen is deleted. That closes the finding outright and removes the cross-repo deploy ordering #115 needed.
Why this file was the security problem
The redemption screen was the only client reader and writer of the
appSumoCodesFirestore collection:Those two calls are the sole reason the rules had to grant every authenticated user
read, updateon the collection — which let any account enumerate licence codes and clearredeemedon a paying customer's. With the screen gone, requestly-cloud#882 can delete the rule outright.Removed
Everything below was reachable only from the redemption screen:
components/landing/Appsumo/— the modal and its workspace dropdown (4 files)/appsumoroute inmiscRoutes.tsxandPATHS.APPSUMOEXCLUDED_PATHSPATHS/useLocationimports the header was the last consumer oftrackAppsumoCodeRedeemedand itsAPPSUMO_CODE_REDEEMEDevent nameDeliberately kept — existing customers are unaffected
An AppSumo plan is a persisted value on the team document (
plan: 'basic_appsumo_v0'), not something derived fromappsumo.codesat read time. So everything that recognises and displays the deal stays:PremiumPlanBadge(suppresses the upgrade nudge for AppSumo teams)PricingUtils'"AppSumo"labelUserPlanDetails,ActiveLicenseInfo/SubscriptionInfo(the "N codes redeemed" display)PlanType.APPSUMO, and the workspace/user types carrying the fieldDeleting those would revoke live lifetime plans. That is a separate product decision with a migration attached, and this PR does not make it.
Verification
tsc --noEmitover the wholeapp/project, branch vsmaster:masterThe single reduction is the deleted
AppSumoWorkspaceDropdown.tsxdiagnostic. Normalising line numbers (this PR shifts lines in files it edits), the set difference of new errors is empty.eslint --ext .js,.jsxon every.jsfile this PR touches: clean — which is why the orphanedPATHS/useLocationimports were removed rather than left behind.No residual references remain:
PATHS.APPSUMO,APPSUMO_CODE_REDEEMED,trackAppsumoCodeRedeemed,appSumoCodesandlanding/Appsumoall return zero matches underapp/src.