mirror of
https://github.com/sparrowwallet/sparrow.git
synced 2024-11-02 20:36:44 +00:00
add separate button to backup tapsigner without changing pin
This commit is contained in:
parent
bcbb531414
commit
f8fa7f4cf2
3 changed files with 66 additions and 28 deletions
|
@ -22,20 +22,25 @@ public class CardPinDialog extends Dialog<CardPinDialog.CardPinChange> {
|
|||
private final CheckBox backupFirst;
|
||||
private final ButtonType okButtonType;
|
||||
|
||||
public CardPinDialog() {
|
||||
public CardPinDialog(boolean backupOnly) {
|
||||
this.existingPin = new ViewPasswordField();
|
||||
this.newPin = new ViewPasswordField();
|
||||
this.newPinConfirm = new ViewPasswordField();
|
||||
this.backupFirst = new CheckBox();
|
||||
|
||||
if(backupOnly) {
|
||||
newPin.textProperty().bind(existingPin.textProperty());
|
||||
newPinConfirm.textProperty().bind(existingPin.textProperty());
|
||||
}
|
||||
|
||||
final DialogPane dialogPane = getDialogPane();
|
||||
setTitle("Change Card PIN");
|
||||
dialogPane.setHeaderText("Enter the current PIN, and then the new PIN twice. PIN must be between 6 and 32 digits.");
|
||||
setTitle(backupOnly ? "Backup Card" : "Change Card PIN");
|
||||
dialogPane.setHeaderText(backupOnly ? "Enter the current card PIN." : "Enter the current PIN, and then the new PIN twice. PIN must be between 6 and 32 digits.");
|
||||
dialogPane.getStylesheets().add(AppServices.class.getResource("general.css").toExternalForm());
|
||||
AppServices.setStageIcon(dialogPane.getScene().getWindow());
|
||||
dialogPane.getButtonTypes().addAll(ButtonType.CANCEL);
|
||||
dialogPane.setPrefWidth(380);
|
||||
dialogPane.setPrefHeight(260);
|
||||
dialogPane.setPrefHeight(backupOnly ? 135 : 260);
|
||||
AppServices.moveToActiveWindowScreen(this);
|
||||
|
||||
Glyph lock = new Glyph("FontAwesome", FontAwesome.Glyph.LOCK);
|
||||
|
@ -63,7 +68,12 @@ public class CardPinDialog extends Dialog<CardPinDialog.CardPinChange> {
|
|||
backupField.setText("Backup First:");
|
||||
backupField.getInputs().add(backupFirst);
|
||||
|
||||
fieldset.getChildren().addAll(currentField, newField, confirmField, backupField);
|
||||
if(backupOnly) {
|
||||
fieldset.getChildren().addAll(currentField);
|
||||
} else {
|
||||
fieldset.getChildren().addAll(currentField, newField, confirmField, backupField);
|
||||
}
|
||||
|
||||
form.getChildren().add(fieldset);
|
||||
dialogPane.setContent(form);
|
||||
|
||||
|
@ -75,7 +85,7 @@ public class CardPinDialog extends Dialog<CardPinDialog.CardPinChange> {
|
|||
validationSupport.registerValidator(newPinConfirm, (Control c, String newValue) -> ValidationResult.fromErrorIf(c, "PIN confirmation does not match", !newPinConfirm.getText().equals(newPin.getText())));
|
||||
});
|
||||
|
||||
okButtonType = new javafx.scene.control.ButtonType("Change", ButtonBar.ButtonData.OK_DONE);
|
||||
okButtonType = new javafx.scene.control.ButtonType(backupOnly ? "Backup" : "Change", ButtonBar.ButtonData.OK_DONE);
|
||||
dialogPane.getButtonTypes().addAll(okButtonType);
|
||||
Button okButton = (Button) dialogPane.lookupButton(okButtonType);
|
||||
okButton.setPrefWidth(130);
|
||||
|
|
|
@ -24,6 +24,7 @@ import javafx.scene.control.*;
|
|||
import javafx.scene.input.Clipboard;
|
||||
import javafx.scene.input.ClipboardContent;
|
||||
import javafx.scene.layout.StackPane;
|
||||
import org.controlsfx.control.SegmentedButton;
|
||||
import org.controlsfx.glyphfont.Glyph;
|
||||
import org.controlsfx.validation.ValidationResult;
|
||||
import org.controlsfx.validation.ValidationSupport;
|
||||
|
@ -68,7 +69,10 @@ public class KeystoreController extends WalletFormController implements Initiali
|
|||
private Button viewKeyButton;
|
||||
|
||||
@FXML
|
||||
private Button changePinButton;
|
||||
private ToggleGroup cardServiceToggleGroup;
|
||||
|
||||
@FXML
|
||||
private SegmentedButton cardServiceButtons;
|
||||
|
||||
@FXML
|
||||
private Button importButton;
|
||||
|
@ -137,7 +141,7 @@ public class KeystoreController extends WalletFormController implements Initiali
|
|||
exportButton.managedProperty().bind(exportButton.visibleProperty());
|
||||
viewSeedButton.managedProperty().bind(viewSeedButton.visibleProperty());
|
||||
viewKeyButton.managedProperty().bind(viewKeyButton.visibleProperty());
|
||||
changePinButton.managedProperty().bind(changePinButton.visibleProperty());
|
||||
cardServiceButtons.managedProperty().bind(cardServiceButtons.visibleProperty());
|
||||
scanXpubQR.managedProperty().bind(scanXpubQR.visibleProperty());
|
||||
displayXpubQR.managedProperty().bind(displayXpubQR.visibleProperty());
|
||||
displayXpubQR.visibleProperty().bind(scanXpubQR.visibleProperty().not());
|
||||
|
@ -294,7 +298,7 @@ public class KeystoreController extends WalletFormController implements Initiali
|
|||
exportButton.setVisible(showExport && getWalletForm().getWallet().getPolicyType() == PolicyType.MULTI);
|
||||
viewSeedButton.setVisible(keystore.getSource() == KeystoreSource.SW_SEED && keystore.hasSeed());
|
||||
viewKeyButton.setVisible(keystore.getSource() == KeystoreSource.SW_SEED && keystore.hasMasterPrivateExtendedKey());
|
||||
changePinButton.setVisible(keystore.getWalletModel().isCard());
|
||||
cardServiceButtons.setVisible(keystore.getWalletModel().isCard());
|
||||
|
||||
importButton.setText(keystore.getSource() == KeystoreSource.SW_WATCH ? "Import..." : "Replace...");
|
||||
importButton.setTooltip(new Tooltip(keystore.getSource() == KeystoreSource.SW_WATCH ? "Import a keystore from an external source" : "Replace this keystore with another source"));
|
||||
|
@ -432,12 +436,22 @@ public class KeystoreController extends WalletFormController implements Initiali
|
|||
}
|
||||
|
||||
public void changeCardPin(ActionEvent event) {
|
||||
cardServiceToggleGroup.selectToggle(null);
|
||||
changeCardPinOrBackup(false);
|
||||
}
|
||||
|
||||
public void backupCard(ActionEvent event) {
|
||||
cardServiceToggleGroup.selectToggle(null);
|
||||
changeCardPinOrBackup(true);
|
||||
}
|
||||
|
||||
public void changeCardPinOrBackup(boolean backupOnly) {
|
||||
if(!isReaderAvailable()) {
|
||||
AppServices.showErrorDialog("No card reader", "Connect a card reader to change the card PIN.");
|
||||
return;
|
||||
}
|
||||
|
||||
CardPinDialog cardPinDialog = new CardPinDialog();
|
||||
CardPinDialog cardPinDialog = new CardPinDialog(backupOnly);
|
||||
Optional<CardPinDialog.CardPinChange> optPinChange = cardPinDialog.showAndWait();
|
||||
if(optPinChange.isPresent()) {
|
||||
String currentPin = optPinChange.get().currentPin();
|
||||
|
@ -449,7 +463,7 @@ public class KeystoreController extends WalletFormController implements Initiali
|
|||
if(authDelayService != null) {
|
||||
authDelayService.setOnSucceeded(event1 -> {
|
||||
try {
|
||||
changeCardPin(newPin, backupFirst, cardApi);
|
||||
changeCardPin(newPin, backupFirst, backupOnly, cardApi);
|
||||
} catch(CardException e) {
|
||||
log.error("Error communicating with card", e);
|
||||
AppServices.showErrorDialog("Error communicating with card", e.getMessage());
|
||||
|
@ -464,7 +478,7 @@ public class KeystoreController extends WalletFormController implements Initiali
|
|||
AppServices.moveToActiveWindowScreen(serviceProgressDialog);
|
||||
authDelayService.start();
|
||||
} else {
|
||||
changeCardPin(newPin, backupFirst, cardApi);
|
||||
changeCardPin(newPin, backupFirst, backupOnly, cardApi);
|
||||
}
|
||||
} catch(CardException e) {
|
||||
log.error("Error communicating with card", e);
|
||||
|
@ -473,22 +487,24 @@ public class KeystoreController extends WalletFormController implements Initiali
|
|||
}
|
||||
}
|
||||
|
||||
private void changeCardPin(String newPin, boolean backupFirst, CardApi cardApi) throws CardException {
|
||||
private void changeCardPin(String newPin, boolean backupFirst, boolean backupOnly, CardApi cardApi) throws CardException {
|
||||
boolean requiresBackup = cardApi.requiresBackup();
|
||||
if(backupFirst || requiresBackup) {
|
||||
if(backupOnly || backupFirst || requiresBackup) {
|
||||
Service<String> backupService = cardApi.getBackupService();
|
||||
backupService.setOnSucceeded(event -> {
|
||||
String backup = backupService.getValue();
|
||||
String filename = fingerprint.getText() + ".aes";
|
||||
TextAreaDialog backupDialog = new TextAreaDialog(backup, false, filename, Base64.getDecoder().decode(backup));
|
||||
backupDialog.setTitle("Backup Private Key");
|
||||
backupDialog.getDialogPane().setHeaderText((requiresBackup ? "Please backup first by saving" : "Save") + " the following text in a safe place. It contains an encrypted copy of the card's private key, and can be decrypted using the backup key written on the back of the card.");
|
||||
backupDialog.getDialogPane().setHeaderText((requiresBackup && !backupOnly ? "Please backup first by saving" : "Save") + " the following text in a safe place. It contains an encrypted copy of the card's private key, and can be decrypted using the backup key written on the back of the card.");
|
||||
backupDialog.showAndWait();
|
||||
try {
|
||||
changePin(newPin, cardApi);
|
||||
} catch(Exception e) {
|
||||
log.error("Error communicating with card", e);
|
||||
AppServices.showErrorDialog("Error communicating with card", e.getMessage());
|
||||
if(!backupOnly) {
|
||||
try {
|
||||
changePin(newPin, cardApi);
|
||||
} catch(Exception e) {
|
||||
log.error("Error communicating with card", e);
|
||||
AppServices.showErrorDialog("Error communicating with card", e.getMessage());
|
||||
}
|
||||
}
|
||||
});
|
||||
backupService.setOnFailed(event -> {
|
||||
|
|
|
@ -41,14 +41,26 @@
|
|||
<Tooltip text="View master private key"/>
|
||||
</tooltip>
|
||||
</Button>
|
||||
<Button fx:id="changePinButton" text="Change Pin..." graphicTextGap="5" onAction="#changeCardPin">
|
||||
<graphic>
|
||||
<Glyph fontFamily="Font Awesome 5 Free Solid" fontSize="12" icon="WIFI" />
|
||||
</graphic>
|
||||
<tooltip>
|
||||
<Tooltip text="Change the PIN of current card"/>
|
||||
</tooltip>
|
||||
</Button>
|
||||
<SegmentedButton fx:id="cardServiceButtons">
|
||||
<toggleGroup>
|
||||
<ToggleGroup fx:id="cardServiceToggleGroup" />
|
||||
</toggleGroup>
|
||||
<buttons>
|
||||
<ToggleButton toggleGroup="$cardServiceToggleGroup" text="Change Pin" graphicTextGap="5" onAction="#changeCardPin">
|
||||
<graphic>
|
||||
<Glyph fontFamily="Font Awesome 5 Free Solid" fontSize="12" icon="WIFI" />
|
||||
</graphic>
|
||||
<tooltip>
|
||||
<Tooltip text="Change the PIN of the current card"/>
|
||||
</tooltip>
|
||||
</ToggleButton>
|
||||
<ToggleButton toggleGroup="$cardServiceToggleGroup" text="Backup" onAction="#backupCard">
|
||||
<tooltip>
|
||||
<Tooltip text="Backup the current card"/>
|
||||
</tooltip>
|
||||
</ToggleButton>
|
||||
</buttons>
|
||||
</SegmentedButton>
|
||||
<Button fx:id="exportButton" text="Export..." onAction="#export">
|
||||
<tooltip>
|
||||
<Tooltip text="Export this keystore as a signer for a multisig wallet"/>
|
||||
|
|
Loading…
Reference in a new issue