Repository navigation
fix(gift): redeem well-formed gift codes instead of rejecting every o… - #1099
Merged
thlpkee20-wq merged 1 commit intoOct 24, 2026
Merged
Conversation
…ne (Stellabill#1013) RedeemGift validated codes against the 18-character GIFT-XXXXXX-YYYYYY pattern and then rejected anything shorter than 20 characters, so no code the purchase flow hands out could ever be redeemed. It also threw away the resolved payload and re-rendered a duplicated hardcoded gift. Move normalization and lookup into src/utils/giftCode.ts, accept loosely pasted codes (case, spaces, missing dashes or prefix) instead of prefixing them blindly, reuse the same generator in GiftPurchaseModal, and render the details the validation resolves. The ?code= auto-validation now runs once per code so a StrictMode double mount cannot start two validations.
5 tasks
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.
#1013 fix(gift): every well-formed gift code is rejected as "not recognized" because of a length check that can never pass
Close#1013
RedeemGiftvalidated codes against^GIFT-[A-Z0-9]{6}-[A-Z0-9]{6}$(always 18characters) and then rejected anything shorter than 20 characters. Every code that
passed the format check therefore failed the length check, so the redemption flow was
unreachable — including codes handed out by
GiftPurchaseModal. The resolved payload wasalso discarded and replaced with a duplicated hardcoded gift object.
Changes
src/utils/giftCode.ts— owns code normalisation, generation and validation:normalizeGiftCode()uppercases, strips whitespace/separators, and accepts the codewith or without dashes and with or without the
GIFTprefix, sogift-abc123-xyz789,GIFT ABC123 XYZ789andABC123XYZ789all resolve toGIFT-ABC123-XYZ789. Replaces the oldformatCode(), which blindly prependedGIFT-and producedGIFT-GIFTABC123XYZ789for pasted codes.generateGiftCode()— crypto-random, always emits a canonical 12-character body. Theprevious
Math.random().toString(36).substring(2, 8)generator could emit shortsegments and codes that did not match the format.
validateGiftCode()— returns a typed result (ok | invalid | expired | redeemed)with the resolved gift details, instead of rejecting with a thrown object.
RedeemGift.tsx— renders the gift details that validation actually resolved (theduplicated
mockGiftDetailsobject is gone), canonicalises the input on blur, and guardsthe
?code=auto-validation with a ref so a StrictMode double mount starts exactly onevalidation.
GiftPurchaseModal.tsx— uses the sharedgenerateGiftCode(), so a purchased code isguaranteed to be redeemable.
RedeemConfirmModal.tsx— imports the single sharedGiftDetailstype instead of asecond copy.
Testing
New
src/utils/giftCode.test.ts: normalisation variants, malformed input, generated-codeformat/uniqueness, and each
validateGiftCodeoutcome (ok / expired / redeemed /not_found / malformed).
src/pages/RedeemGift.test.tsx: added a regression test that a code produced byGiftPurchaseModalopensRedeemConfirmModal, the/redeem-gift?code=GIFT-ABC123-XYZ789repro, pasted-variant canonicalisation, and a StrictMode single-validation check. The old
formats code input automaticallycase asserted the buggyGIFT-ABC123XYZ789output andnow asserts canonicalisation on blur.
I have not been able to run
vitestlocally (dependency install kept failing on aflaky network), so the new tests are unverified here — please treat the CI run as the
first real signal.
Out of scope
validateGiftCoderemains a placeholder service with thesame latency and fixture codes as before).
GiftRedeemSuccessrendering.