From acec47062fd2a9377dc9ddb400d62dee4680875a Mon Sep 17 00:00:00 2001 From: Petr Hejna Date: Sun, 10 May 2020 00:43:39 +0200 Subject: [PATCH] Reason for payment is now list of fake reasons instead of random string ID to obfuscate fact its from the Bisq --- .../bisq/common/util/ReasonsForPayment.java | 30 +++++++++++++++++++ .../common/util/ReasonsForPaymentTests.java | 17 +++++++++++ core/src/main/java/bisq/core/offer/Offer.java | 5 ++++ core/src/main/java/bisq/core/trade/Trade.java | 5 ++++ .../resources/i18n/displayStrings.properties | 7 +++-- .../pendingtrades/PendingTradesDataModel.java | 4 +-- .../steps/buyer/BuyerStep2View.java | 2 +- .../steps/seller/SellerStep3View.java | 14 ++++----- 8 files changed, 71 insertions(+), 13 deletions(-) create mode 100644 common/src/main/java/bisq/common/util/ReasonsForPayment.java create mode 100644 common/src/test/java/bisq/common/util/ReasonsForPaymentTests.java diff --git a/common/src/main/java/bisq/common/util/ReasonsForPayment.java b/common/src/main/java/bisq/common/util/ReasonsForPayment.java new file mode 100644 index 00000000000..5c84611d040 --- /dev/null +++ b/common/src/main/java/bisq/common/util/ReasonsForPayment.java @@ -0,0 +1,30 @@ +package bisq.common.util; + +public class ReasonsForPayment { + + private static final String[] REASONS = { + "Miss you", + "Groceries", + "Virtual coffee date!!!", + "To help w/ your bills this month", + "Thanks for everything you do", + "Rent's due, dude", + "Takeout > Going out", + "Thank you, friend", + "Pizza for din. And bfast too.", + "You got this", + "Dinner", + "Treat yo self", + "Grab a snack on me!" + }; + + public static String getReason(String id) { + int hash = 7; + for (char c : id.toCharArray()) { + hash = hash * 31 + Character.getNumericValue(c); + } + + return REASONS[hash % REASONS.length]; + } + +} diff --git a/common/src/test/java/bisq/common/util/ReasonsForPaymentTests.java b/common/src/test/java/bisq/common/util/ReasonsForPaymentTests.java new file mode 100644 index 00000000000..d6e2eadda24 --- /dev/null +++ b/common/src/test/java/bisq/common/util/ReasonsForPaymentTests.java @@ -0,0 +1,17 @@ +package bisq.common.util; + +import org.junit.Test; + + + +import junit.framework.TestCase; + +public class ReasonsForPaymentTests extends TestCase { + @Test + public void testWhenStringIdIsProvidedReasonIsReturned() { + assertEquals("Thank you, friend", ReasonsForPayment.getReason("")); + + assertEquals("Grab a snack on me!", ReasonsForPayment.getReason("G")); + assertEquals("Miss you", ReasonsForPayment.getReason("H")); + } +} diff --git a/core/src/main/java/bisq/core/offer/Offer.java b/core/src/main/java/bisq/core/offer/Offer.java index d52bd9471e7..012949ed079 100644 --- a/core/src/main/java/bisq/core/offer/Offer.java +++ b/core/src/main/java/bisq/core/offer/Offer.java @@ -38,6 +38,7 @@ import bisq.common.proto.persistable.PersistablePayload; import bisq.common.util.JsonExclude; import bisq.common.util.MathUtils; +import bisq.common.util.ReasonsForPayment; import bisq.common.util.Utilities; import org.bitcoinj.core.Coin; @@ -321,6 +322,10 @@ public String getShortId() { return Utilities.getShortId(offerPayload.getId()); } + public String getReasonForPayment() { + return ReasonsForPayment.getReason(getShortId()); + } + @Nullable public Volume getVolume() { return getVolumeByAmount(getAmount()); diff --git a/core/src/main/java/bisq/core/trade/Trade.java b/core/src/main/java/bisq/core/trade/Trade.java index 6071e59d504..922e7df4fea 100644 --- a/core/src/main/java/bisq/core/trade/Trade.java +++ b/core/src/main/java/bisq/core/trade/Trade.java @@ -53,6 +53,7 @@ import bisq.common.proto.ProtoUtil; import bisq.common.storage.Storage; import bisq.common.taskrunner.Model; +import bisq.common.util.ReasonsForPayment; import bisq.common.util.Utilities; import com.google.protobuf.ByteString; @@ -1028,6 +1029,10 @@ public String getShortId() { return offer.getShortId(); } + public String getReasonForPayment() { + return ReasonsForPayment.getReason(getShortId()); + } + public Price getTradePrice() { return Price.valueOf(offer.getCurrencyCode(), tradePrice); } diff --git a/core/src/main/resources/i18n/displayStrings.properties b/core/src/main/resources/i18n/displayStrings.properties index 2e8e17cb622..ef0d76d0379 100644 --- a/core/src/main/resources/i18n/displayStrings.properties +++ b/core/src/main/resources/i18n/displayStrings.properties @@ -114,6 +114,7 @@ shared.depositTransactionId=Deposit transaction ID shared.TheBTCBuyer=The BTC buyer shared.You=You shared.reasonForPayment=Reason for payment +shared.reasonForPayment.tooltip=Reason for payment is selected from the list of random reasons\nto make it harder for the bank to identify it as Bisq transaction. shared.sendingConfirmation=Sending confirmation... shared.sendingConfirmationAgain=Please send confirmation again shared.exportCSV=Export to csv @@ -688,11 +689,11 @@ portfolio.pending.step3_seller.altcoin={0}Please check {1} if the transaction to has already sufficient blockchain confirmations.\nThe payment amount has to be {3}\n\n\ You can copy & paste your {4} address from the main screen after closing that popup. portfolio.pending.step3_seller.postal={0}Please check if you have received {1} with \"US Postal Money Order\" from the BTC buyer.\n\n\ -The trade ID (\"reason for payment\" text) of the transaction is: \"{2}\" +Reason for payment text of the transaction is: \"{2}\" # suppress inspection "TrailingSpacesInProperty" portfolio.pending.step3_seller.bank=Your trading partner has confirmed that they have initiated the {0} payment.\n\n\ Please go to your online banking web page and check if you have received {1} from the BTC buyer.\n\n\ -The trade ID (\"reason for payment\" text) of the transaction is: \"{2}\"\n\n +Reason for payment text of the transaction is: \"{2}\"\n\n portfolio.pending.step3_seller.cash=Because the payment is done via Cash Deposit the BTC buyer has to write \"NO REFUND\" on the paper receipt, tear it in 2 parts and send you a photo by email.\n\n\ To avoid chargeback risk, only confirm if you received the email and if you are sure the paper receipt is valid.\n\ If you are not sure, {0} @@ -729,7 +730,7 @@ portfolio.pending.step3_seller.openForDispute=You have not confirmed the receipt # suppress inspection "TrailingSpacesInProperty" portfolio.pending.step3_seller.onPaymentReceived.part1=Have you received the {0} payment from your trading partner?\n\n # suppress inspection "TrailingSpacesInProperty" -portfolio.pending.step3_seller.onPaymentReceived.fiat=The trade ID (\"reason for payment\" text) of the transaction is: \"{0}\"\n\n +portfolio.pending.step3_seller.onPaymentReceived.fiat=Reason for payment text of the transaction is: \"{0}\"\n\n # suppress inspection "TrailingSpacesInProperty" portfolio.pending.step3_seller.onPaymentReceived.name=Please also verify that the name of the sender specified on the trade contract matches the name that appears on your bank statement:\nSender''s name, per trade contract: {0}\n\nIf the names are not exactly the same, don''t confirm payment receipt. Instead, open a dispute by pressing \"alt + o\" or \"option + o\".\n\n portfolio.pending.step3_seller.onPaymentReceived.note=Please note, that as soon you have confirmed the receipt, the locked trade amount will be released to the BTC buyer and the security deposit will be refunded.\n\n diff --git a/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/PendingTradesDataModel.java b/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/PendingTradesDataModel.java index 9f5276f9b97..5026702dc1e 100644 --- a/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/PendingTradesDataModel.java +++ b/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/PendingTradesDataModel.java @@ -408,8 +408,8 @@ public PaymentAccountPayload getBuyersPaymentAccountPayload() { return null; } - public String getReference() { - return getOffer() != null ? getOffer().getShortId() : ""; + public String getReasonForPayment() { + return getOffer() != null ? getOffer().getReasonForPayment() : ""; } /////////////////////////////////////////////////////////////////////////////////////////// diff --git a/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/steps/buyer/BuyerStep2View.java b/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/steps/buyer/BuyerStep2View.java index 80826ccbde4..95bd21af3ce 100644 --- a/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/steps/buyer/BuyerStep2View.java +++ b/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/steps/buyer/BuyerStep2View.java @@ -231,7 +231,7 @@ protected void addContent() { if (!(paymentAccountPayload instanceof AssetsAccountPayload) && !(paymentAccountPayload instanceof F2FAccountPayload)) addTopLabelTextFieldWithCopyIcon(gridPane, gridRow, 1, - Res.get("shared.reasonForPayment"), model.dataModel.getReference(), + Res.get("shared.reasonForPayment"), model.dataModel.getReasonForPayment(), Layout.COMPACT_FIRST_ROW_AND_GROUP_DISTANCE); switch (paymentMethodId) { diff --git a/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/steps/seller/SellerStep3View.java b/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/steps/seller/SellerStep3View.java index 07ab8774ed4..1b29686528e 100644 --- a/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/steps/seller/SellerStep3View.java +++ b/desktop/src/main/java/bisq/desktop/main/portfolio/pendingtrades/steps/seller/SellerStep3View.java @@ -200,9 +200,10 @@ protected void addContent() { } if (!isBlockChain && !trade.getOffer().getPaymentMethod().equals(PaymentMethod.F2F)) { - addTopLabelTextFieldWithCopyIcon( + TextFieldWithCopyIcon reasonForPaymentTextField = addTopLabelTextFieldWithCopyIcon( gridPane, gridRow, 1, Res.get("shared.reasonForPayment"), - model.dataModel.getReference(), Layout.COMPACT_FIRST_ROW_AND_GROUP_DISTANCE); + model.dataModel.getReasonForPayment(), Layout.COMPACT_FIRST_ROW_AND_GROUP_DISTANCE).second; + reasonForPaymentTextField.setTooltip(new Tooltip(Res.get("shared.reasonForPayment.tooltip"))); GridPane.setRowSpan(titledGroupBg, 4); } @@ -285,7 +286,7 @@ private void onPaymentReceived() { if (!(paymentAccountPayload instanceof WesternUnionAccountPayload) && !(paymentAccountPayload instanceof HalCashAccountPayload) && !(paymentAccountPayload instanceof F2FAccountPayload)) { - message += Res.get("portfolio.pending.step3_seller.onPaymentReceived.fiat", trade.getShortId()); + message += Res.get("portfolio.pending.step3_seller.onPaymentReceived.fiat", trade.getReasonForPayment()); } Optional optionalHolderName = getOptionalHolderName(); @@ -318,7 +319,6 @@ private void showPopup() { String tradeVolumeWithCode = DisplayUtils.formatVolumeWithCode(trade.getTradeVolume()); String currencyName = CurrencyUtil.getNameByCode(trade.getOffer().getCurrencyCode()); String part1 = Res.get("portfolio.pending.step3_seller.part", currencyName); - String id = trade.getShortId(); if (paymentAccountPayload instanceof AssetsAccountPayload) { String address = ((AssetsAccountPayload) paymentAccountPayload).getAddress(); String explorerOrWalletString = trade.getOffer().getCurrencyCode().equals("XMR") ? @@ -327,11 +327,11 @@ private void showPopup() { message = Res.get("portfolio.pending.step3_seller.altcoin", part1, explorerOrWalletString, address, tradeVolumeWithCode, currencyName); } else { if (paymentAccountPayload instanceof USPostalMoneyOrderAccountPayload) { - message = Res.get("portfolio.pending.step3_seller.postal", part1, tradeVolumeWithCode, id); + message = Res.get("portfolio.pending.step3_seller.postal", part1, tradeVolumeWithCode, trade.getReasonForPayment()); } else if (!(paymentAccountPayload instanceof WesternUnionAccountPayload) && !(paymentAccountPayload instanceof HalCashAccountPayload) && !(paymentAccountPayload instanceof F2FAccountPayload)) { - message = Res.get("portfolio.pending.step3_seller.bank", currencyName, tradeVolumeWithCode, id); + message = Res.get("portfolio.pending.step3_seller.bank", currencyName, tradeVolumeWithCode, trade.getReasonForPayment()); } String part = Res.get("portfolio.pending.step3_seller.openDispute"); @@ -357,7 +357,7 @@ else if (paymentAccountPayload instanceof F2FAccountPayload) } if (!DevEnv.isDevMode() && DontShowAgainLookup.showAgain(key)) { DontShowAgainLookup.dontShowAgain(key, true); - new Popup().headLine(Res.get("popup.attention.forTradeWithId", id)) + new Popup().headLine(Res.get("popup.attention.forTradeWithId", trade.getShortId())) .attention(message) .show(); }