feat(#175): validate fiat code before submitting an order - #304
Conversation
create_order took the selected fiat code straight into the outgoing request with no submit-time check. The currency picker constrains the happy path, but a stale or tampered saved default could still send an unsupported code that only came back as a daemon CantDo. This adds a local preflight so the request is rejected on-device with a clear, actionable message instead. - orders.rs: create_order now validates the fiat code before publishing, reusing settings::validate_fiat_code (made pub(crate)). This replaces the previous empty-only check and covers empty and malformed codes alike, failing with the stable InvalidFiatCode marker so every caller inherits the check (per grunch's note, same pattern as BondRequired). - settings.rs: validate_fiat_code is pub(crate); added validate_fiat_code_marker_cases covering valid codes plus empty/short/long/ lowercase/mixed/symbol/non-ASCII, all rejected with the InvalidFiatCode marker. - daemon_errors.dart: map InvalidFiatCode to a localized message via the existing localizedDaemonError helper. - l10n: add invalidFiatCode in all five locales. Scope: format-level (ISO 4217 shape) validation, which catches the stale/ tampered cases the issue describes. Membership validation against the bundled fiat list would require porting that list into Rust — raised as a question on the PR. Closes MostroP2P#175.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (8)
Included review availability: Your plan includes up to 1 review per rolling hour; 0 remain after this review. WalkthroughThe order API now validates trimmed fiat codes before publication. The validator is reused across the crate and has expanded unit coverage. Invalid-code errors now map to dedicated English, German, Spanish, French, and Italian messages. ChangesFiat code validation
Estimated code review effort: 2 (Simple) | ~10 minutes Merge Risk: 🟡 Moderate · up to This PR adds submit-time fiat-format validation and a localized rejection path for malformed saved or tampered currency codes. The change is localized, but merge readiness remains moderate until the required binding, Flutter test, and localization regeneration checks are completed. Suggested reviewers: Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
@coderabbitai full review |
✅ Action performedFull review finished. |
Problem
create_ordertook the selected fiat code straight into the outgoing request with no submit-time validation. The currency picker constrains the happy path, but if the saved default fiat code becomes stale or is tampered with, the request could still go out with an unsupported code and come back as a daemon-sideCantDoinstead of being rejected locally.Fix
A local preflight in
create_order, reusingsettings::validate_fiat_code(madepub(crate)):orders.rscreate_ordervalidates the fiat code before publishing. This replaces the previous empty-only check and covers empty and malformed codes alike, failing with the stableInvalidFiatCodemarker so every caller inherits the check (per @grunch's note, same pattern asBondRequired).settings.rsvalidate_fiat_codeis nowpub(crate); addedvalidate_fiat_code_marker_casescovering valid codes plus empty / short / long / lowercase / mixed / symbol / non-ASCII, all rejected with the marker.daemon_errors.dartmapsInvalidFiatCodeto a localized message through the existinglocalizedDaemonErrorhelper.invalidFiatCodein all five locales.Testing
cargo test(256 pass) +cargo clippyclean;flutter analyzeclean. Verified on device (Nokia C31): a normal order with a valid currency still creates successfully. The bad-code path is a defense-in-depth guard against a tampered/stale saved default it can't be reached through the picker in normal use, so it's covered by the Rust test rather than a device repro.Scope question for @grunch
This validates the fiat code's format (ISO 4217 shape), which catches the stale/tampered cases the issue describes and emits the
InvalidFiatCodemarker as you suggested. Full membership validation (rejecting valid-format-but-unsupported codes like"XYZ") would mean porting the bundled fiat list into Rust, creating a second source of truth to keep in sync with the Dart asset. Happy to add that here or as a follow-up which would you prefer?Closes #175.
Summary by CodeRabbit
Bug Fixes
Localization