mirror of
https://github.com/bisq-network/bisq.git
synced 2024-11-19 09:52:23 +01:00
Clear account payload info & chats from closed trades & disputes.
This commit is contained in:
parent
44b02b3cbb
commit
57821b7474
@ -100,7 +100,7 @@ public final class Dispute implements NetworkPayload, PersistablePayload {
|
|||||||
private final PubKeyRing traderPubKeyRing;
|
private final PubKeyRing traderPubKeyRing;
|
||||||
private final long tradeDate;
|
private final long tradeDate;
|
||||||
private final long tradePeriodEnd;
|
private final long tradePeriodEnd;
|
||||||
private final Contract contract;
|
private Contract contract;
|
||||||
@Nullable
|
@Nullable
|
||||||
private final byte[] contractHash;
|
private final byte[] contractHash;
|
||||||
@Nullable
|
@Nullable
|
||||||
@ -111,7 +111,7 @@ public final class Dispute implements NetworkPayload, PersistablePayload {
|
|||||||
private final String depositTxId;
|
private final String depositTxId;
|
||||||
@Nullable
|
@Nullable
|
||||||
private final String payoutTxId;
|
private final String payoutTxId;
|
||||||
private final String contractAsJson;
|
private String contractAsJson;
|
||||||
@Nullable
|
@Nullable
|
||||||
private final String makerContractSignature;
|
private final String makerContractSignature;
|
||||||
@Nullable
|
@Nullable
|
||||||
@ -351,6 +351,31 @@ public final class Dispute implements NetworkPayload, PersistablePayload {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean removeAllChatMessages() {
|
||||||
|
if (chatMessages.size() > 0) {
|
||||||
|
chatMessages.clear();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void maybeClearSensitiveData() {
|
||||||
|
String change = "";
|
||||||
|
if (contract.maybeClearSensitiveData()) {
|
||||||
|
change += "contract;";
|
||||||
|
}
|
||||||
|
String edited = contract.sanitizeContractAsJson(contractAsJson);
|
||||||
|
if (!edited.equals(contractAsJson)) {
|
||||||
|
contractAsJson = edited;
|
||||||
|
change += "contractAsJson;";
|
||||||
|
}
|
||||||
|
if (removeAllChatMessages()) {
|
||||||
|
change += "chat messages;";
|
||||||
|
}
|
||||||
|
if (change.length() > 0) {
|
||||||
|
log.info("cleared sensitive data from {} of dispute for trade {}", change, Utilities.getShortId(getTradeId()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Setters
|
// Setters
|
||||||
|
@ -66,6 +66,8 @@ import javafx.collections.ObservableList;
|
|||||||
|
|
||||||
import java.security.KeyPair;
|
import java.security.KeyPair;
|
||||||
|
|
||||||
|
import java.time.Instant;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
@ -282,6 +284,8 @@ public abstract class DisputeManager<T extends DisputeList<Dispute>> extends Sup
|
|||||||
log.error(disputeReplayException.toString());
|
log.error(disputeReplayException.toString());
|
||||||
validationExceptions.add(disputeReplayException);
|
validationExceptions.add(disputeReplayException);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
maybeClearSensitiveData();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isTrader(Dispute dispute) {
|
public boolean isTrader(Dispute dispute) {
|
||||||
@ -298,6 +302,15 @@ public abstract class DisputeManager<T extends DisputeList<Dispute>> extends Sup
|
|||||||
return disputeList.stream().filter(e -> e.getTradeId().equals(tradeId)).findAny();
|
return disputeList.stream().filter(e -> e.getTradeId().equals(tradeId)).findAny();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void maybeClearSensitiveData() {
|
||||||
|
log.info("{} checking closed disputes eligibility for having sensitive data cleared", super.getClass().getSimpleName());
|
||||||
|
Instant safeDate = closedTradableManager.getSafeDateForSensitiveDataClearing();
|
||||||
|
getDisputeList().getList().stream()
|
||||||
|
.filter(e -> e.isClosed())
|
||||||
|
.filter(e -> e.getTradeDate().toInstant().isBefore(safeDate))
|
||||||
|
.forEach(Dispute::maybeClearSensitiveData);
|
||||||
|
requestPersistence();
|
||||||
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Message handler
|
// Message handler
|
||||||
|
@ -338,6 +338,7 @@ public final class ArbitrationManager extends DisputeManager<ArbitrationDisputeL
|
|||||||
sendAckMessage(chatMessage, dispute.getAgentPubKeyRing(), success, errorMessage);
|
sendAckMessage(chatMessage, dispute.getAgentPubKeyRing(), success, errorMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
maybeClearSensitiveData();
|
||||||
requestPersistence();
|
requestPersistence();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -223,6 +223,7 @@ public final class MediationManager extends DisputeManager<MediationDisputeList>
|
|||||||
}
|
}
|
||||||
sendAckMessage(chatMessage, dispute.getAgentPubKeyRing(), true, null);
|
sendAckMessage(chatMessage, dispute.getAgentPubKeyRing(), true, null);
|
||||||
|
|
||||||
|
maybeClearSensitiveData();
|
||||||
requestPersistence();
|
requestPersistence();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -224,6 +224,7 @@ public final class RefundManager extends DisputeManager<RefundDisputeList> {
|
|||||||
openOfferOptional.ifPresent(openOffer -> openOfferManager.closeOpenOffer(openOffer.getOffer()));
|
openOfferOptional.ifPresent(openOffer -> openOfferManager.closeOpenOffer(openOffer.getOffer()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
maybeClearSensitiveData();
|
||||||
requestPersistence();
|
requestPersistence();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,9 +49,12 @@ import com.google.common.collect.ImmutableList;
|
|||||||
|
|
||||||
import javafx.collections.ObservableList;
|
import javafx.collections.ObservableList;
|
||||||
|
|
||||||
|
import java.time.Instant;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
@ -120,10 +123,12 @@ public class ClosedTradableManager implements PersistedDataHost {
|
|||||||
|
|
||||||
public void onAllServicesInitialized() {
|
public void onAllServicesInitialized() {
|
||||||
cleanupMailboxMessagesService.handleTrades(getClosedTrades());
|
cleanupMailboxMessagesService.handleTrades(getClosedTrades());
|
||||||
|
maybeClearSensitiveData();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void add(Tradable tradable) {
|
public void add(Tradable tradable) {
|
||||||
if (closedTradables.add(tradable)) {
|
if (closedTradables.add(tradable)) {
|
||||||
|
maybeClearSensitiveData();
|
||||||
requestPersistence();
|
requestPersistence();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -153,6 +158,29 @@ public class ClosedTradableManager implements PersistedDataHost {
|
|||||||
return closedTradables.stream().filter(e -> e.getId().equals(id)).findFirst();
|
return closedTradables.stream().filter(e -> e.getId().equals(id)).findFirst();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void maybeClearSensitiveData() {
|
||||||
|
log.info("checking closed trades eligibility for having sensitive data cleared");
|
||||||
|
closedTradables.stream()
|
||||||
|
.filter(e -> e instanceof Trade)
|
||||||
|
.map(e -> (Trade) e)
|
||||||
|
.filter(e -> canTradeHaveSensitiveDataCleared(e.getId()))
|
||||||
|
.forEach(Trade::maybeClearSensitiveData);
|
||||||
|
requestPersistence();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean canTradeHaveSensitiveDataCleared(String tradeId) {
|
||||||
|
Instant safeDate = getSafeDateForSensitiveDataClearing();
|
||||||
|
return closedTradables.stream()
|
||||||
|
.filter(e -> e.getId().equals(tradeId))
|
||||||
|
.filter(e -> e.getDate().toInstant().isBefore(safeDate))
|
||||||
|
.count() > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Instant getSafeDateForSensitiveDataClearing() {
|
||||||
|
return Instant.ofEpochSecond(Instant.now().getEpochSecond()
|
||||||
|
- TimeUnit.DAYS.toSeconds(preferences.getClearDataAfterDays()));
|
||||||
|
}
|
||||||
|
|
||||||
public Stream<Trade> getTradesStreamWithFundsLockedIn() {
|
public Stream<Trade> getTradesStreamWithFundsLockedIn() {
|
||||||
return getClosedTrades().stream()
|
return getClosedTrades().stream()
|
||||||
.filter(Trade::isFundsLockedIn);
|
.filter(Trade::isFundsLockedIn);
|
||||||
|
@ -350,6 +350,30 @@ public final class Contract implements NetworkPayload {
|
|||||||
return isBuyerMakerAndSellerTaker() == isMyRoleBuyer(myPubKeyRing);
|
return isBuyerMakerAndSellerTaker() == isMyRoleBuyer(myPubKeyRing);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean maybeClearSensitiveData() {
|
||||||
|
boolean changed = false;
|
||||||
|
if (makerPaymentAccountPayload != null) {
|
||||||
|
makerPaymentAccountPayload = null;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
if (takerPaymentAccountPayload != null) {
|
||||||
|
takerPaymentAccountPayload = null;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
// edits a contract json string, removing the payment account payloads
|
||||||
|
public static String sanitizeContractAsJson(String contractAsJson) {
|
||||||
|
return contractAsJson
|
||||||
|
.replaceAll(
|
||||||
|
"\"takerPaymentAccountPayload\": \\{[^}]*}",
|
||||||
|
"\"takerPaymentAccountPayload\": null")
|
||||||
|
.replaceAll(
|
||||||
|
"\"makerPaymentAccountPayload\": \\{[^}]*}",
|
||||||
|
"\"makerPaymentAccountPayload\": null");
|
||||||
|
}
|
||||||
|
|
||||||
public void printDiff(@Nullable String peersContractAsJson) {
|
public void printDiff(@Nullable String peersContractAsJson) {
|
||||||
String json = JsonUtil.objectToJson(this);
|
String json = JsonUtil.objectToJson(this);
|
||||||
String diff = StringUtils.difference(json, peersContractAsJson);
|
String diff = StringUtils.difference(json, peersContractAsJson);
|
||||||
|
@ -689,6 +689,14 @@ public abstract class Trade extends TradeModel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean removeAllChatMessages() {
|
||||||
|
if (chatMessages.size() > 0) {
|
||||||
|
chatMessages.clear();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean mediationResultAppliedPenaltyToSeller() {
|
public boolean mediationResultAppliedPenaltyToSeller() {
|
||||||
// If mediated payout is same or more then normal payout we enable otherwise a penalty was applied
|
// If mediated payout is same or more then normal payout we enable otherwise a penalty was applied
|
||||||
// by mediators and we keep the confirm disabled to avoid that the seller can complete the trade
|
// by mediators and we keep the confirm disabled to avoid that the seller can complete the trade
|
||||||
@ -698,6 +706,26 @@ public abstract class Trade extends TradeModel {
|
|||||||
return payoutAmountFromMediation < normalPayoutAmount;
|
return payoutAmountFromMediation < normalPayoutAmount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void maybeClearSensitiveData() {
|
||||||
|
String change = "";
|
||||||
|
if (contract != null && contract.maybeClearSensitiveData()) {
|
||||||
|
change += "contract;";
|
||||||
|
}
|
||||||
|
if (contractAsJson != null) {
|
||||||
|
String edited = contract.sanitizeContractAsJson(contractAsJson);
|
||||||
|
if (!edited.equals(contractAsJson)) {
|
||||||
|
contractAsJson = edited;
|
||||||
|
change += "contractAsJson;";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (removeAllChatMessages()) {
|
||||||
|
change += "chat messages;";
|
||||||
|
}
|
||||||
|
if (change.length() > 0) {
|
||||||
|
log.info("cleared sensitive data from {} of trade {}", change, getShortId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// TradeModel implementation
|
// TradeModel implementation
|
||||||
|
@ -145,7 +145,8 @@ public final class Preferences implements PersistedDataHost, BridgeAddressProvid
|
|||||||
));
|
));
|
||||||
|
|
||||||
public static final boolean USE_SYMMETRIC_SECURITY_DEPOSIT = true;
|
public static final boolean USE_SYMMETRIC_SECURITY_DEPOSIT = true;
|
||||||
|
public static final int CLEAR_DATA_AFTER_DAYS_INITIAL = 99999; // feature effectively disabled until user agrees to settings notification
|
||||||
|
public static final int CLEAR_DATA_AFTER_DAYS_DEFAULT = 20; // used when user has agreed to settings notification
|
||||||
|
|
||||||
// payload is initialized so the default values are available for Property initialization.
|
// payload is initialized so the default values are available for Property initialization.
|
||||||
@Setter
|
@Setter
|
||||||
@ -355,6 +356,10 @@ public final class Preferences implements PersistedDataHost, BridgeAddressProvid
|
|||||||
setIgnoreDustThreshold(600);
|
setIgnoreDustThreshold(600);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (prefPayload.getClearDataAfterDays() < 1) {
|
||||||
|
setClearDataAfterDays(Preferences.CLEAR_DATA_AFTER_DAYS_INITIAL);
|
||||||
|
}
|
||||||
|
|
||||||
// For users from old versions the 4 flags a false but we want to have it true by default
|
// For users from old versions the 4 flags a false but we want to have it true by default
|
||||||
// PhoneKeyAndToken is also null so we can use that to enable the flags
|
// PhoneKeyAndToken is also null so we can use that to enable the flags
|
||||||
if (prefPayload.getPhoneKeyAndToken() == null) {
|
if (prefPayload.getPhoneKeyAndToken() == null) {
|
||||||
@ -785,6 +790,11 @@ public final class Preferences implements PersistedDataHost, BridgeAddressProvid
|
|||||||
requestPersistence();
|
requestPersistence();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setClearDataAfterDays(int value) {
|
||||||
|
prefPayload.setClearDataAfterDays(value);
|
||||||
|
requestPersistence();
|
||||||
|
}
|
||||||
|
|
||||||
public void setShowOffersMatchingMyAccounts(boolean value) {
|
public void setShowOffersMatchingMyAccounts(boolean value) {
|
||||||
prefPayload.setShowOffersMatchingMyAccounts(value);
|
prefPayload.setShowOffersMatchingMyAccounts(value);
|
||||||
requestPersistence();
|
requestPersistence();
|
||||||
|
@ -121,6 +121,7 @@ public final class PreferencesPayload implements PersistableEnvelope {
|
|||||||
private String takeOfferSelectedPaymentAccountId;
|
private String takeOfferSelectedPaymentAccountId;
|
||||||
private double buyerSecurityDepositAsPercent = getDefaultBuyerSecurityDepositAsPercent();
|
private double buyerSecurityDepositAsPercent = getDefaultBuyerSecurityDepositAsPercent();
|
||||||
private int ignoreDustThreshold = 600;
|
private int ignoreDustThreshold = 600;
|
||||||
|
private int clearDataAfterDays = Preferences.CLEAR_DATA_AFTER_DAYS_INITIAL;
|
||||||
private double buyerSecurityDepositAsPercentForCrypto = getDefaultBuyerSecurityDepositAsPercent();
|
private double buyerSecurityDepositAsPercentForCrypto = getDefaultBuyerSecurityDepositAsPercent();
|
||||||
private int blockNotifyPort;
|
private int blockNotifyPort;
|
||||||
private boolean tacAcceptedV120;
|
private boolean tacAcceptedV120;
|
||||||
@ -192,6 +193,7 @@ public final class PreferencesPayload implements PersistableEnvelope {
|
|||||||
.setIsDaoFullNode(isDaoFullNode)
|
.setIsDaoFullNode(isDaoFullNode)
|
||||||
.setBuyerSecurityDepositAsPercent(buyerSecurityDepositAsPercent)
|
.setBuyerSecurityDepositAsPercent(buyerSecurityDepositAsPercent)
|
||||||
.setIgnoreDustThreshold(ignoreDustThreshold)
|
.setIgnoreDustThreshold(ignoreDustThreshold)
|
||||||
|
.setClearDataAfterDays(clearDataAfterDays)
|
||||||
.setBuyerSecurityDepositAsPercentForCrypto(buyerSecurityDepositAsPercentForCrypto)
|
.setBuyerSecurityDepositAsPercentForCrypto(buyerSecurityDepositAsPercentForCrypto)
|
||||||
.setBlockNotifyPort(blockNotifyPort)
|
.setBlockNotifyPort(blockNotifyPort)
|
||||||
.setTacAcceptedV120(tacAcceptedV120)
|
.setTacAcceptedV120(tacAcceptedV120)
|
||||||
@ -290,6 +292,7 @@ public final class PreferencesPayload implements PersistableEnvelope {
|
|||||||
proto.getTakeOfferSelectedPaymentAccountId().isEmpty() ? null : proto.getTakeOfferSelectedPaymentAccountId(),
|
proto.getTakeOfferSelectedPaymentAccountId().isEmpty() ? null : proto.getTakeOfferSelectedPaymentAccountId(),
|
||||||
proto.getBuyerSecurityDepositAsPercent(),
|
proto.getBuyerSecurityDepositAsPercent(),
|
||||||
proto.getIgnoreDustThreshold(),
|
proto.getIgnoreDustThreshold(),
|
||||||
|
proto.getClearDataAfterDays(),
|
||||||
proto.getBuyerSecurityDepositAsPercentForCrypto(),
|
proto.getBuyerSecurityDepositAsPercentForCrypto(),
|
||||||
proto.getBlockNotifyPort(),
|
proto.getBlockNotifyPort(),
|
||||||
proto.getTacAcceptedV120(),
|
proto.getTacAcceptedV120(),
|
||||||
|
@ -1324,6 +1324,7 @@ setting.preferences.txFeeMin=Transaction fee must be at least {0} satoshis/vbyte
|
|||||||
setting.preferences.txFeeTooLarge=Your input is above any reasonable value (>5000 satoshis/vbyte). Transaction fee is usually in the range of 50-400 satoshis/vbyte.
|
setting.preferences.txFeeTooLarge=Your input is above any reasonable value (>5000 satoshis/vbyte). Transaction fee is usually in the range of 50-400 satoshis/vbyte.
|
||||||
setting.preferences.ignorePeers=Ignored peers [onion address:port]
|
setting.preferences.ignorePeers=Ignored peers [onion address:port]
|
||||||
setting.preferences.ignoreDustThreshold=Min. non-dust output value
|
setting.preferences.ignoreDustThreshold=Min. non-dust output value
|
||||||
|
setting.preferences.clearDataAfterDays=Clear sensitive data after (days)
|
||||||
setting.preferences.currenciesInList=Currencies in market price feed list
|
setting.preferences.currenciesInList=Currencies in market price feed list
|
||||||
setting.preferences.prefCurrency=Preferred currency
|
setting.preferences.prefCurrency=Preferred currency
|
||||||
setting.preferences.displayFiat=Display national currencies
|
setting.preferences.displayFiat=Display national currencies
|
||||||
@ -1386,6 +1387,15 @@ settings.preferences.editCustomExplorer.name=Name
|
|||||||
settings.preferences.editCustomExplorer.txUrl=Transaction URL
|
settings.preferences.editCustomExplorer.txUrl=Transaction URL
|
||||||
settings.preferences.editCustomExplorer.addressUrl=Address URL
|
settings.preferences.editCustomExplorer.addressUrl=Address URL
|
||||||
|
|
||||||
|
setting.info.headline=New data-privacy feature
|
||||||
|
settings.preferences.sensitiveDataRemoval.msg=To protect the privacy of yourself and other traders, Bisq intends to \
|
||||||
|
remove payment account details from old trades. This is particularly important for fiat trades which may include bank \
|
||||||
|
account details. Read more about this at [HYPERLINK:https://bisq.wiki/Data_Privacy].\n\n\
|
||||||
|
The threshold for data removal can be configured on this screen via the field "Clear sensitive data after (days)". \
|
||||||
|
It is recommended to set it as low as possible, for example 20 days. That means trades from more than 20 \
|
||||||
|
days ago will have payment account details cleared, as long as they are finished. Finished trades are ones which \
|
||||||
|
are found in the Portfolio / History tab.
|
||||||
|
|
||||||
settings.net.btcHeader=Bitcoin network
|
settings.net.btcHeader=Bitcoin network
|
||||||
settings.net.p2pHeader=Bisq network
|
settings.net.p2pHeader=Bisq network
|
||||||
settings.net.onionAddressLabel=My onion address
|
settings.net.onionAddressLabel=My onion address
|
||||||
|
@ -58,5 +58,6 @@ public class SettingsPresentation {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setup() {
|
public void setup() {
|
||||||
|
showNotification.set(preferences.showAgain(SETTINGS_NEWS));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,11 +24,14 @@ import bisq.desktop.common.view.FxmlView;
|
|||||||
import bisq.desktop.common.view.View;
|
import bisq.desktop.common.view.View;
|
||||||
import bisq.desktop.common.view.ViewLoader;
|
import bisq.desktop.common.view.ViewLoader;
|
||||||
import bisq.desktop.main.MainView;
|
import bisq.desktop.main.MainView;
|
||||||
|
import bisq.desktop.main.overlays.popups.Popup;
|
||||||
|
import bisq.desktop.main.presentation.SettingsPresentation;
|
||||||
import bisq.desktop.main.settings.about.AboutView;
|
import bisq.desktop.main.settings.about.AboutView;
|
||||||
import bisq.desktop.main.settings.network.NetworkSettingsView;
|
import bisq.desktop.main.settings.network.NetworkSettingsView;
|
||||||
import bisq.desktop.main.settings.preferences.PreferencesView;
|
import bisq.desktop.main.settings.preferences.PreferencesView;
|
||||||
|
|
||||||
import bisq.core.locale.Res;
|
import bisq.core.locale.Res;
|
||||||
|
import bisq.core.user.DontShowAgainLookup;
|
||||||
import bisq.core.user.Preferences;
|
import bisq.core.user.Preferences;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
@ -85,6 +88,9 @@ public class SettingsView extends ActivatableView<TabPane, Void> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void activate() {
|
protected void activate() {
|
||||||
|
// Hide new badge if user saw this section
|
||||||
|
preferences.dontShowAgain(SettingsPresentation.SETTINGS_NEWS, true);
|
||||||
|
|
||||||
root.getSelectionModel().selectedItemProperty().addListener(tabChangeListener);
|
root.getSelectionModel().selectedItemProperty().addListener(tabChangeListener);
|
||||||
navigation.addListener(navigationListener);
|
navigation.addListener(navigationListener);
|
||||||
|
|
||||||
|
@ -127,7 +127,7 @@ public class PreferencesView extends ActivatableViewAndModel<GridPane, Preferenc
|
|||||||
private int gridRow = 0;
|
private int gridRow = 0;
|
||||||
private int displayCurrenciesGridRowIndex = 0;
|
private int displayCurrenciesGridRowIndex = 0;
|
||||||
private InputTextField transactionFeeInputTextField, ignoreTradersListInputTextField, ignoreDustThresholdInputTextField,
|
private InputTextField transactionFeeInputTextField, ignoreTradersListInputTextField, ignoreDustThresholdInputTextField,
|
||||||
autoConfRequiredConfirmationsTf, autoConfServiceAddressTf, autoConfTradeLimitTf,
|
autoConfRequiredConfirmationsTf, autoConfServiceAddressTf, autoConfTradeLimitTf, clearDataAfterDaysInputTextField,
|
||||||
rpcUserTextField, blockNotifyPortTextField;
|
rpcUserTextField, blockNotifyPortTextField;
|
||||||
private PasswordTextField rpcPwTextField;
|
private PasswordTextField rpcPwTextField;
|
||||||
private TitledGroupBg daoOptionsTitledGroupBg;
|
private TitledGroupBg daoOptionsTitledGroupBg;
|
||||||
@ -156,7 +156,7 @@ public class PreferencesView extends ActivatableViewAndModel<GridPane, Preferenc
|
|||||||
private ObservableList<TradeCurrency> tradeCurrencies;
|
private ObservableList<TradeCurrency> tradeCurrencies;
|
||||||
private InputTextField deviationInputTextField, bsqAverageTrimThresholdTextField;
|
private InputTextField deviationInputTextField, bsqAverageTrimThresholdTextField;
|
||||||
private ChangeListener<String> deviationListener, bsqAverageTrimThresholdListener, ignoreTradersListListener, ignoreDustThresholdListener,
|
private ChangeListener<String> deviationListener, bsqAverageTrimThresholdListener, ignoreTradersListListener, ignoreDustThresholdListener,
|
||||||
rpcUserListener, rpcPwListener, blockNotifyPortListener,
|
rpcUserListener, rpcPwListener, blockNotifyPortListener, clearDataAfterDaysListener,
|
||||||
autoConfTradeLimitListener, autoConfServiceAddressListener;
|
autoConfTradeLimitListener, autoConfServiceAddressListener;
|
||||||
private ChangeListener<Boolean> deviationFocusedListener, bsqAverageTrimThresholdFocusedListener;
|
private ChangeListener<Boolean> deviationFocusedListener, bsqAverageTrimThresholdFocusedListener;
|
||||||
private ChangeListener<Boolean> useCustomFeeCheckboxListener;
|
private ChangeListener<Boolean> useCustomFeeCheckboxListener;
|
||||||
@ -225,6 +225,22 @@ public class PreferencesView extends ActivatableViewAndModel<GridPane, Preferenc
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void activate() {
|
protected void activate() {
|
||||||
|
String key = "sensitiveDataRemovalInfo";
|
||||||
|
if (DontShowAgainLookup.showAgain(key)) {
|
||||||
|
new Popup()
|
||||||
|
.headLine(Res.get("setting.info.headline"))
|
||||||
|
.backgroundInfo(Res.get("settings.preferences.sensitiveDataRemoval.msg"))
|
||||||
|
.actionButtonText(Res.get("shared.iUnderstand"))
|
||||||
|
.onAction(() -> {
|
||||||
|
DontShowAgainLookup.dontShowAgain(key, true);
|
||||||
|
// user has acknowledged, enable the feature with a reasonable default value
|
||||||
|
preferences.setClearDataAfterDays(preferences.CLEAR_DATA_AFTER_DAYS_DEFAULT);
|
||||||
|
clearDataAfterDaysInputTextField.setText(String.valueOf(preferences.getClearDataAfterDays()));
|
||||||
|
})
|
||||||
|
.closeButtonText(Res.get("shared.cancel"))
|
||||||
|
.show();
|
||||||
|
}
|
||||||
|
|
||||||
// We want to have it updated in case an asset got removed
|
// We want to have it updated in case an asset got removed
|
||||||
allCryptoCurrencies = FXCollections.observableArrayList(CurrencyUtil.getActiveSortedCryptoCurrencies(assetService, filterManager));
|
allCryptoCurrencies = FXCollections.observableArrayList(CurrencyUtil.getActiveSortedCryptoCurrencies(assetService, filterManager));
|
||||||
allCryptoCurrencies.removeAll(cryptoCurrencies);
|
allCryptoCurrencies.removeAll(cryptoCurrencies);
|
||||||
@ -250,7 +266,7 @@ public class PreferencesView extends ActivatableViewAndModel<GridPane, Preferenc
|
|||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
private void initializeGeneralOptions() {
|
private void initializeGeneralOptions() {
|
||||||
int titledGroupBgRowSpan = displayStandbyModeFeature ? 9 : 8;
|
int titledGroupBgRowSpan = displayStandbyModeFeature ? 10 : 9;
|
||||||
TitledGroupBg titledGroupBg = addTitledGroupBg(root, gridRow, titledGroupBgRowSpan, Res.get("setting.preferences.general"));
|
TitledGroupBg titledGroupBg = addTitledGroupBg(root, gridRow, titledGroupBgRowSpan, Res.get("setting.preferences.general"));
|
||||||
GridPane.setColumnSpan(titledGroupBg, 1);
|
GridPane.setColumnSpan(titledGroupBg, 1);
|
||||||
|
|
||||||
@ -382,6 +398,22 @@ public class PreferencesView extends ActivatableViewAndModel<GridPane, Preferenc
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// clearDataAfterDays
|
||||||
|
clearDataAfterDaysInputTextField = addInputTextField(root, ++gridRow, Res.get("setting.preferences.clearDataAfterDays"));
|
||||||
|
IntegerValidator clearDataAfterDaysValidator = new IntegerValidator();
|
||||||
|
clearDataAfterDaysValidator.setMinValue(1);
|
||||||
|
clearDataAfterDaysValidator.setMaxValue(Preferences.CLEAR_DATA_AFTER_DAYS_INITIAL);
|
||||||
|
clearDataAfterDaysInputTextField.setValidator(clearDataAfterDaysValidator);
|
||||||
|
clearDataAfterDaysListener = (observable, oldValue, newValue) -> {
|
||||||
|
try {
|
||||||
|
int value = Integer.parseInt(newValue);
|
||||||
|
if (!newValue.equals(oldValue)) {
|
||||||
|
preferences.setClearDataAfterDays(value);
|
||||||
|
}
|
||||||
|
} catch (Throwable ignore) {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
if (displayStandbyModeFeature) {
|
if (displayStandbyModeFeature) {
|
||||||
// AvoidStandbyModeService feature works only on OSX & Windows
|
// AvoidStandbyModeService feature works only on OSX & Windows
|
||||||
avoidStandbyMode = addSlideToggleButton(root, ++gridRow,
|
avoidStandbyMode = addSlideToggleButton(root, ++gridRow,
|
||||||
@ -825,6 +857,7 @@ public class PreferencesView extends ActivatableViewAndModel<GridPane, Preferenc
|
|||||||
/* referralIdService.getOptionalReferralId().ifPresent(referralId -> referralIdInputTextField.setText(referralId));
|
/* referralIdService.getOptionalReferralId().ifPresent(referralId -> referralIdInputTextField.setText(referralId));
|
||||||
referralIdInputTextField.setPromptText(Res.get("setting.preferences.refererId.prompt"));*/
|
referralIdInputTextField.setPromptText(Res.get("setting.preferences.refererId.prompt"));*/
|
||||||
ignoreDustThresholdInputTextField.setText(String.valueOf(preferences.getIgnoreDustThreshold()));
|
ignoreDustThresholdInputTextField.setText(String.valueOf(preferences.getIgnoreDustThreshold()));
|
||||||
|
clearDataAfterDaysInputTextField.setText(String.valueOf(preferences.getClearDataAfterDays()));
|
||||||
userLanguageComboBox.setItems(languageCodes);
|
userLanguageComboBox.setItems(languageCodes);
|
||||||
userLanguageComboBox.getSelectionModel().select(preferences.getUserLanguage());
|
userLanguageComboBox.getSelectionModel().select(preferences.getUserLanguage());
|
||||||
userLanguageComboBox.setConverter(new StringConverter<>() {
|
userLanguageComboBox.setConverter(new StringConverter<>() {
|
||||||
@ -889,6 +922,7 @@ public class PreferencesView extends ActivatableViewAndModel<GridPane, Preferenc
|
|||||||
useCustomFee.selectedProperty().addListener(useCustomFeeCheckboxListener);
|
useCustomFee.selectedProperty().addListener(useCustomFeeCheckboxListener);
|
||||||
//referralIdInputTextField.textProperty().addListener(referralIdListener);
|
//referralIdInputTextField.textProperty().addListener(referralIdListener);
|
||||||
ignoreDustThresholdInputTextField.textProperty().addListener(ignoreDustThresholdListener);
|
ignoreDustThresholdInputTextField.textProperty().addListener(ignoreDustThresholdListener);
|
||||||
|
clearDataAfterDaysInputTextField.textProperty().addListener(clearDataAfterDaysListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Coin getTxFeeForWithdrawalPerVbyte() {
|
private Coin getTxFeeForWithdrawalPerVbyte() {
|
||||||
@ -1165,6 +1199,7 @@ public class PreferencesView extends ActivatableViewAndModel<GridPane, Preferenc
|
|||||||
useCustomFee.selectedProperty().removeListener(useCustomFeeCheckboxListener);
|
useCustomFee.selectedProperty().removeListener(useCustomFeeCheckboxListener);
|
||||||
//referralIdInputTextField.textProperty().removeListener(referralIdListener);
|
//referralIdInputTextField.textProperty().removeListener(referralIdListener);
|
||||||
ignoreDustThresholdInputTextField.textProperty().removeListener(ignoreDustThresholdListener);
|
ignoreDustThresholdInputTextField.textProperty().removeListener(ignoreDustThresholdListener);
|
||||||
|
clearDataAfterDaysInputTextField.textProperty().removeListener(clearDataAfterDaysListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void deactivateDisplayCurrencies() {
|
private void deactivateDisplayCurrencies() {
|
||||||
|
@ -1999,6 +1999,7 @@ message PreferencesPayload {
|
|||||||
bool deny_api_taker = 60;
|
bool deny_api_taker = 60;
|
||||||
bool notify_on_pre_release = 61;
|
bool notify_on_pre_release = 61;
|
||||||
bool use_full_mode_dao_monitor = 62;
|
bool use_full_mode_dao_monitor = 62;
|
||||||
|
int32 clear_data_after_days = 63;
|
||||||
}
|
}
|
||||||
|
|
||||||
message AutoConfirmSettings {
|
message AutoConfirmSettings {
|
||||||
|
Loading…
Reference in New Issue
Block a user