Sanitize email user attribute before sending to checkout API#462
Merged
yusuftor merged 4 commits intosuperwall:developfrom Apr 28, 2026
Merged
Conversation
The checkout API rejects `context.identity.email` unless it is a valid email address or null. Apps that set a placeholder like `"none"` when the user has no email silently break the Stripe checkout flow because the server returns a validation error and no checkout session is created. Introduce an `Email` domain primitive with a failable initializer that validates against the same regex the API enforces. When merging user attributes, the SDK now parses the `email` value through `Email` and drops it (sends null) when invalid, with a warning log. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
ICU treats $ as matching before a final \n, so user@example.com\n was slipping through. Switch to \z and add a regression case. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Collaborator
|
Thanks for submitting! |
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
Emailtype with a failable initializer that validates against the regex enforced by the checkout API (^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$)emailuser attribute inmergeAttributes— invalid values are replaced withnilso the server receivesnullinstead of a malformed stringContext
When an app sets the
emailuser attribute to a placeholder like"none"(e.g. when the user hasn't provided an email yet), the checkout API rejects the request with anHttpApiDecodeErrorbecause"none"is neither a valid email nornull. This silently breaks the Stripe checkout — the payment sheet never opens and the user sees no feedback.The fix parses the email value at the SDK boundary so the server always receives either a valid email or
null, regardless of what the app sends.Test plan
Emailtype (valid addresses, parameterized invalid inputs including"none","","null","N/A")sanitizeAttribute(valid passthrough, invalid → nil, non-email keys untouched, non-string values untouched)emailattribute to"none"→ verify Stripe checkout opens (previously broken)emailattribute to a real email → verify it's forwarded correctly🤖 Generated with Claude Code
Greptile Summary
This PR introduces an
Emailvalue type that validates against the checkout API's regex, and applies it inmergeAttributesso that invalid email strings (e.g."none") are silently dropped instead of forwarded to the server. The change is focused and well-tested with a parameterized test suite covering both the type and the sanitizer.Confidence Score: 5/5
Safe to merge — change is well-scoped, correctly integrated, and fully covered by unit tests.
No P0 or P1 issues found. The Email type is correctly anchored with
\z, the sanitizer integrates cleanly with existing nil-drop semantics inmergeAttributes, and the test suite covers the key invalid placeholders and edge cases.No files require special attention.
Important Files Changed
\zanchor and force-try with lint suppression comment.sanitizeAttributestatic helper that validates email values; integrates cleanly into existingmergeAttributesflow with correct nil-drop semantics.Flowchart
%%{init: {'theme': 'neutral'}}%% flowchart TD A["setUserAttributes(['email': value])"] --> B[mergeAttributes] B --> C{value is nil?} C -- yes --> D[skip key] C -- no --> E{isValidJSONObject?} E -- no --> D E -- yes --> F["sanitizeAttribute(key:value:)"] F --> G{key == 'email'?} G -- no --> H[return value unchanged] G -- yes --> I{value is String?} I -- no --> H I -- yes --> J{Email init succeeds?} J -- yes --> K[return email.rawValue] J -- no --> L[log warning\nreturn nil] L --> M[key removed from customAttributes] K --> N[customAttributes updated] H --> N N --> O[identityManager.mergeUserAttributes] M --> O O --> P[IdentityLogic.mergeAttributes\nmerges with stored attrs] P --> Q[Server receives valid email or null]Reviews (3): Last reviewed commit: "Add CHANGELOG entry for email user attri..." | Re-trigger Greptile