Fix Horizon URL validation bypass, tier price formatting, preview race condition, and drawer focus trap - #1037
Merged
temma02 merged 4 commits intoJul 28, 2026
Conversation
…ation Compares URL hostnames instead of raw strings so trailing slashes, path segments, scheme, or case differences no longer bypass the mainnet/testnet horizon URL mismatch check. Closes StellerCraft#1003 Co-authored-by: Fidelis <fidelisobed79@gmail.com>
Adds a shared formatTierPrice helper built on Intl.NumberFormat and replaces the ad-hoc `cents / 100` string interpolation across SubscriptionComparison, UpgradeFlow, UpgradePrompt, and the billing settings page so fractional-dollar prices always render two decimal places and large prices get thousands separators. Closes StellerCraft#1002 Co-authored-by: Fidelis <fidelisobed79@gmail.com>
Adds an AbortController-based staleness check in usePreviewService and a request-sequence guard in PreviewWorkspace's handleRefresh/effect so an earlier, slower refreshPreview call can no longer clobber state set by a more recent viewport/customization change, mirroring the pattern in useTemplates.ts. Closes StellerCraft#1000 Co-authored-by: Fidelis <fidelisobed79@gmail.com>
Moves focus into the drawer's close button when it opens, traps Tab/Shift+Tab cycling within the drawer's focusable elements while open, and restores focus to the triggering element on close. Adds role="dialog" and aria-modal so assistive tech announces it as a modal surface. Closes StellerCraft#1001 Co-authored-by: Fidelis <fidelisobed79@gmail.com>
|
@Fidelis900 Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits. You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Four independent bug fixes bundled into one PR per request:
Repair Horizon URL Network-Mismatch Validation Bypass in Stellar Config Schema #1003 —
stellarConfigSchema.superRefineinvalidate-stellar.tscomparedhorizonUrlagainst the testnet/mainnet Horizon constants with strict string equality, so a trailing slash, different scheme, or casing silently bypassed the mainnet/testnet mismatch check. Replaced the raw===comparisons with agetHorizonHost()helper that parses the URL and compares the lowercasedhostname, so trailing slashes, path segments, and scheme/case differences can no longer evade the check. Error messages and thehorizonUrlfield path are unchanged.Harden Currency Formatting in Subscription Tier Price Displays #1002 —
SubscriptionComparison.tsxandUpgradeFlow.tsx(plusUpgradePrompt.tsxand the billing settings page) derived tier price strings viacents / 100interpolation with no decimal normalization, so a non-round-dollar price (e.g. 1950 cents) would render as$19.5instead of$19.50, and large prices had no thousands separator. Added a centralizedformatTierPrice(cents)helper inpricing.tsbuilt onIntl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }), and updated all four consumers to use it instead of ad-hoc math.Eliminate Out-of-Order Preview Race Condition in Viewport Refresh Pipeline #1000 —
PreviewWorkspace.tsx's refresh effect had no request-identity tracking, so rapidly switching viewports (or editing customization) could let an earlier, slowerrefreshPreviewcall resolve after a newer one and clobber the current preview state with stale data. Added anAbortController-based staleness guard inusePreviewService.ts(aborts the previous in-flight call when a new one starts, and throws anAbortErrorif a call turns out to be superseded) plus a request-sequence guard inPreviewWorkspace.tsx'shandleRefresh/effect, mirroring the existing pattern inuseTemplates.ts.Engineer Accessible Focus Trap for Mobile Navigation Drawer #1001 —
MobileDrawer.tsxnever moved focus into the drawer on open, never trappedTab/Shift+Tabwithin it, and never restored focus to the triggering element on close, and it lackedrole="dialog"/aria-modal. Added focus-in-on-open (to the close button), aTab/Shift+Tabfocus trap cycling within the drawer's focusable elements, focus restoration to the previously-focused trigger element on close, androle="dialog"+aria-modal={open}on the drawer element.Changes
apps/frontend/src/lib/customization/validate-stellar.tsapps/frontend/src/lib/stripe/pricing.tsapps/frontend/src/components/app/SubscriptionComparison.tsxapps/frontend/src/components/app/UpgradeFlow.tsxapps/frontend/src/components/app/UpgradePrompt.tsxapps/frontend/src/app/app/settings/billing/page.tsxapps/frontend/src/hooks/usePreviewService.tsapps/frontend/src/components/app/preview/PreviewWorkspace.tsxapps/frontend/src/components/app/MobileDrawer.tsxCloses #1003
Closes #1002
Closes #1000
Closes #1001
Test plan
pnpm test --filter=frontend -- validate-stellarpnpm test --filter=frontend -- pricingpnpm test --filter=frontend -- SubscriptionComparisonpnpm test --filter=frontend -- PreviewWorkspacepnpm test --filter=frontend -- usePreviewServicepnpm test --filter=frontend -- MobileDrawerpnpm lintpnpm typecheckNo automated tests were added in this PR per explicit request from the author; the checklist above reflects the tickets' original test requirements and is left for reviewer follow-up.