diff --git a/src/main/java/digital/slovensko/autogram/core/Autogram.java b/src/main/java/digital/slovensko/autogram/core/Autogram.java index 37ca78fa..bd5e91a3 100644 --- a/src/main/java/digital/slovensko/autogram/core/Autogram.java +++ b/src/main/java/digital/slovensko/autogram/core/Autogram.java @@ -14,6 +14,8 @@ import java.io.File; import java.util.List; +import java.util.Timer; +import java.util.TimerTask; import java.util.concurrent.ExecutorService; import java.util.concurrent.ScheduledExecutorService; import java.util.function.Consumer; @@ -24,6 +26,7 @@ public class Autogram { /** Current batch, should be null if no batch was started yet */ private Batch batch = null; private final PasswordManager passwordManager; + private Timer tokenSessionTimer = null; public Autogram(UI ui, UserSettings settings) { this.ui = ui; @@ -93,6 +96,8 @@ public void startVisualization(SigningJob job) { private void signCommonAndThen(SigningJob job, SigningKey signingKey, Consumer callback) { try { job.signWithKeyAndRespond(signingKey); + resetTokenSessionTimer(); + if (batch == null || batch.isEnded() || batch.isAllProcessed()) passwordManager.reset(); @@ -214,6 +219,7 @@ private void fetchKeysAndThen(TokenDriver driver, Consumer callback) try { var token = driver.createToken(passwordManager, settings); var keys = token.getKeys(); + resetTokenSessionTimer(); ui.onUIThreadDo( () -> ui.pickKeyAndThen(keys, driver, (privateKey) -> callback.accept(new SigningKey(token, privateKey)))); @@ -266,4 +272,27 @@ public TSPSource getTspSource() { public boolean isPlainXmlEnabled() { return settings.isPlainXmlEnabled(); } + + private void stopTokenSessionTimer() { + if (tokenSessionTimer == null) + return; + + tokenSessionTimer.cancel(); + } + + private void startTokenSessionTimer() { + var timerTask = new TimerTask() { + @Override + public void run() { + ui.resetSigningKey(); + } + }; + tokenSessionTimer = new Timer(); + tokenSessionTimer.schedule(timerTask, settings.getTokenSessionTimeout() * 60 * 1000); + } + + private void resetTokenSessionTimer() { + stopTokenSessionTimer(); + startTokenSessionTimer(); + } } diff --git a/src/main/java/digital/slovensko/autogram/core/UserSettings.java b/src/main/java/digital/slovensko/autogram/core/UserSettings.java index 7c55f57d..61c5687c 100644 --- a/src/main/java/digital/slovensko/autogram/core/UserSettings.java +++ b/src/main/java/digital/slovensko/autogram/core/UserSettings.java @@ -33,6 +33,7 @@ public class UserSettings implements PasswordManagerSettings, SignatureTokenSett private String customTsaServer; private boolean bulkEnabled; private int pdfDpi; + private long tokenSessionTimeout; public static UserSettings load() { var prefs = Preferences.userNodeForPackage(UserSettings.class); @@ -56,6 +57,7 @@ public static UserSettings load() { settings.setCustomTsaServer(prefs.get("CUSTOM_TSA_SERVER", "")); settings.setTsaEnabled(prefs.getBoolean("TSA_ENABLE", false)); settings.setPdfDpi(prefs.getInt("PDF_DPI", 100)); + settings.setTokenSessionTimeout(prefs.getLong("TOKEN_SESSION_TIMEOUT", 5)); return settings; } @@ -81,6 +83,7 @@ public void save() { prefs.put("CUSTOM_TSA_SERVER", customTsaServer); prefs.putBoolean("TSA_ENABLE", tsaEnabled); prefs.putInt("PDF_DPI", pdfDpi); + prefs.putLong("TOKEN_SESSION_TIMEOUT", tokenSessionTimeout); } private void setSignatureType(String signatureType) { @@ -285,4 +288,15 @@ public int getPdfDpi() { public void setPdfDpi(int value) { pdfDpi = value; } + + public long getTokenSessionTimeout() { + return tokenSessionTimeout; + } + + public void setTokenSessionTimeout(long value) { + if (value <= 0) + return; + + tokenSessionTimeout = value; + } } diff --git a/src/main/java/digital/slovensko/autogram/ui/UI.java b/src/main/java/digital/slovensko/autogram/ui/UI.java index 0f29eebe..c8caa154 100644 --- a/src/main/java/digital/slovensko/autogram/ui/UI.java +++ b/src/main/java/digital/slovensko/autogram/ui/UI.java @@ -60,4 +60,6 @@ public interface UI { char[] getContextSpecificPassword(); public void updateBatch(); + + void resetSigningKey(); } diff --git a/src/main/java/digital/slovensko/autogram/ui/cli/CliUI.java b/src/main/java/digital/slovensko/autogram/ui/cli/CliUI.java index 1bc721e1..fa21f292 100644 --- a/src/main/java/digital/slovensko/autogram/ui/cli/CliUI.java +++ b/src/main/java/digital/slovensko/autogram/ui/cli/CliUI.java @@ -280,4 +280,9 @@ public char[] getContextSpecificPassword() { public void updateBatch() { // TODO: no usage for this in CLI UI } + + @Override + public void resetSigningKey() { + activeKey = null; + } } diff --git a/src/main/java/digital/slovensko/autogram/ui/gui/GUI.java b/src/main/java/digital/slovensko/autogram/ui/gui/GUI.java index 79f00e41..4ad3aa49 100644 --- a/src/main/java/digital/slovensko/autogram/ui/gui/GUI.java +++ b/src/main/java/digital/slovensko/autogram/ui/gui/GUI.java @@ -15,7 +15,6 @@ import digital.slovensko.autogram.drivers.TokenDriver; import digital.slovensko.autogram.ui.BatchUiResult; import digital.slovensko.autogram.ui.UI; -import eu.europa.esig.dss.enumerations.KeyUsageBit; import eu.europa.esig.dss.token.DSSPrivateKeyEntry; import javafx.application.HostServices; import javafx.application.Platform; @@ -500,8 +499,12 @@ public void disableSigning() { batchController.disableSigning(); } + @Override public void resetSigningKey() { - setActiveSigningKeyAndThen(null, null); + onUIThreadDo(()->{ + setActiveSigningKeyAndThen(null, null); + refreshKeyOnAllJobs(); + }); } public void cancelJob(SigningJob job) { diff --git a/src/main/java/digital/slovensko/autogram/ui/gui/SettingsDialogController.java b/src/main/java/digital/slovensko/autogram/ui/gui/SettingsDialogController.java index 085191af..c06b6ef9 100644 --- a/src/main/java/digital/slovensko/autogram/ui/gui/SettingsDialogController.java +++ b/src/main/java/digital/slovensko/autogram/ui/gui/SettingsDialogController.java @@ -33,6 +33,8 @@ public class SettingsDialogController { @FXML private HBox plainXmlEnabledRadios; @FXML + private TextField tokenSessionTimeoutTextField; + @FXML private ChoiceBox driverChoiceBox; @FXML private VBox trustedCountriesList; @@ -76,6 +78,7 @@ public void initialize() { initializeBulkEnabledCheckbox(); initializeEn319132CheckBox(); initializePlainXmlEnabledCheckBox(); + initializeTokenSessionTimeoutTextField(); initializeCorrectDocumentDisplayCheckBox(); initializeSignatureValidationCheckBox(); initializeCheckPDFAComplianceCheckBox(); @@ -297,6 +300,15 @@ private void initializeCustomKeystoreSettings() { }); } + private void initializeTokenSessionTimeoutTextField() { + tokenSessionTimeoutTextField.setTextFormatter(new TextFormatter <> (change -> change.getControlNewText().matches("[0-9]*") ? change : null)); + tokenSessionTimeoutTextField.setText(String.valueOf(userSettings.getTokenSessionTimeout())); + tokenSessionTimeoutTextField.setOnKeyTyped((e) -> { + if (!tokenSessionTimeoutTextField.getText().isEmpty()) + userSettings.setTokenSessionTimeout(Long.parseLong(tokenSessionTimeoutTextField.getText())); + }); + } + public void onSaveButtonAction() { userSettings.save(); var stage = (Stage) saveButton.getScene().getWindow(); diff --git a/src/main/resources/digital/slovensko/autogram/ui/gui/idsk.css b/src/main/resources/digital/slovensko/autogram/ui/gui/idsk.css index 29da7ab4..7e1789e4 100644 --- a/src/main/resources/digital/slovensko/autogram/ui/gui/idsk.css +++ b/src/main/resources/digital/slovensko/autogram/ui/gui/idsk.css @@ -279,6 +279,10 @@ -fx-font-size: 1.1875em; } +.autogram-input--width-3 { + -fx-max-width: 3.75em; +} + .autogram-input:hover { -fx-cursor: text; } @@ -696,7 +700,6 @@ TextFlow.autogram-body-s { -fx-pref-width: 20.25em; } - .autogram-dropdown { -fx-cursor: hand; -fx-alignment: center-left; diff --git a/src/main/resources/digital/slovensko/autogram/ui/gui/settings-dialog.fxml b/src/main/resources/digital/slovensko/autogram/ui/gui/settings-dialog.fxml index 18b3b009..685495a3 100644 --- a/src/main/resources/digital/slovensko/autogram/ui/gui/settings-dialog.fxml +++ b/src/main/resources/digital/slovensko/autogram/ui/gui/settings-dialog.fxml @@ -150,19 +150,17 @@ - Použitie nového štandardu + Automatické odpojenie pri nečinnosti - Podpisovanie štandardom ETSI EN 319 132 a ETSI EN 319 122. - Pozor, systémy verejnej správy tento štandard väčšinou nepodporujú. + Po koľkých minútach nečinnosti bude s kartou zrušené spojenie. - - + + @@ -183,6 +181,25 @@ styleClass="autogram-smaller-radio-buttons" /> + + + + + Použitie nového štandardu + + + + + Podpisovanie štandardom ETSI EN 319 132 a ETSI EN 319 122. + Pozor, systémy verejnej správy tento štandard väčšinou nepodporujú. + + + + + + + diff --git a/src/test/java/digital/slovensko/autogram/AutogramTests.java b/src/test/java/digital/slovensko/autogram/AutogramTests.java index 11587f3b..5c712ab4 100644 --- a/src/test/java/digital/slovensko/autogram/AutogramTests.java +++ b/src/test/java/digital/slovensko/autogram/AutogramTests.java @@ -309,6 +309,11 @@ public void onSignatureCheckCompleted(ValidationReports wrapper) { public void updateBatch() { } + + @Override + public void resetSigningKey() { + + } } private class TestSettings extends UserSettings {