Constrain payment method and invoice recipient - #859
Merged
Conversation
Two remaining server-side controls for arrival billing integrity. Rules now restrict paymentMethod.method to the known set (card, checkout, cash, card_external, twint_external, invoice) instead of any non-empty string. On the trusted arrival write path, authorize the declared invoice recipient: a recipient is only kept when the arrival author's authenticated email is listed on it in settings/invoiceRecipients; otherwise it is cleared. The recipient list is an array the rules cannot search, so this is enforced server-side, gated by the same landing-fee-strategy switch as the fee recompute.
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.
What
Closes the two remaining server-side controls of the client-controlled-billing
finding (the fee/tax half is already server-owned):
Payment method enum. RTDB rules restricted
paymentMethod.methodfrom"any non-empty string ≤ 50 chars" to the known set —
card,checkout,cash,card_external,twint_external,invoice(the canonicalPAYMENT_METHODS). Safe global tightening: the client only ever writes these.Invoice-recipient authorization. A direct database writer could set
invoiceRecipientNameto any value and bill another organization. On thetrusted arrival write path, a declared invoice recipient is now kept only
when the arrival author's authenticated email is listed on that recipient in
settings/invoiceRecipients; otherwise it is cleared (and logged). Thismirrors what
fetchUserInvoiceRecipientsalready enforces for the UI.Why the recipient check is server-side
settings/invoiceRecipientsis an array of{ name, emails }. RTDB rulescannot iterate an array to find a matching name and check its
emails, so theauthorization can't be expressed in rules. It runs on the same trusted write
path as the fee recompute, gated by the same
/settings/landingFeesStrategyswitch, and only acts on
method === 'invoice'records with an unauthorizedrecipient (never touches legitimate invoices).
Tests
functions/fees/computeArrivalFees.spec.js— clears an unauthorized recipient,keeps an authorized one, clears when the author has no authenticated email,
ignores non-invoice methods, no-ops when no recipient is set, and handles the
recipient list stored as an index-keyed object; plus an integration case
through the recompute trigger. Rules generation verified (method enum present,
no stray tokens). Full functions suite green (443).
Generated by Claude Code