Compare commits
14 Commits
1c7069c737
...
master
Author | SHA1 | Date | |
---|---|---|---|
a5fd5444da | |||
b4df31a31a | |||
4881a135f2 | |||
ca502fd411 | |||
c8a1128e11 | |||
b9a2202c68 | |||
671844723f | |||
7a0ce063f1 | |||
62bfbb1923 | |||
2992572651 | |||
b25fea4549 | |||
a45ffdd864 | |||
c918d98a3c | |||
afb02dcb3d |
@ -1,52 +1,40 @@
|
||||
For sending secret messages and dummy messages regularly. It is meant to be used in conjunction with one-time pads. One-time pads provide perfect security for the message itself (if they are handled properly), but adversaries can still tell that messages are being sent, and when they are being sent. To avoid this, dummy messages are uploaded to a website on a regular basis. The messages can also be hidden using steganography.
|
||||
For sending secret messages and dummy messages regularly. It is meant to be used in conjunction with one-time pads. One-time pads provide perfect security for the message itself (if they are handled properly), but adversaries can still tell that messages are being sent, and when they are being sent. To avoid this, dummy messages are uploaded to a website on a regular basis.
|
||||
|
||||
This application should not be considered secure, and no sensitive information should be entered into it.
|
||||
|
||||
Baseline is that the number station will generate a dummy random message, optionally obscure it via steganography, then upload it to an (s)ftp/scp server.
|
||||
# Building
|
||||
|
||||
The random message generation actually happens last, so that, next time it is run, the existing message will be uploaded. This way a real message can be generated in the meantime and the next upload time the real message will be uploaded. Because the real message looks random to anyone without the corresponding one-time pad, it cannot be distinguished from the dummy messages.
|
||||
Building requires JDK 23.0.1 and javafx SDK 23.0.1, and Maven (I used version 3.9.9)
|
||||
|
||||
# Number Station Listener
|
||||
The JAVA_HOME environment variable must be set to the JDK installation directory e.g. `C:\Program Files\Java\jdk-23.0.1\bin\java.exe`. `$JAVA_HOME/bin` must be included in you PATH variable. PATH_TO_FX must be set to the JavaFX lib directory e.g. `$HOME/openjfx-23.0.1_windows-x64_bin-sdk/javafx-sdk-23.0.1/lib`.
|
||||
|
||||
This application periodically checks a site for numbers and stores them so the user can check whether the message matches any pads.
|
||||
To build, run `mvn package`, the output .jar should be in ./target
|
||||
|
||||
# Notes
|
||||
To run without installing: `java -jar target/numbersstation-1.0-SNAPSHOT-shaded.jar`
|
||||
|
||||
Should have sane defaults, but be built to be part of a more extensible system. Should be able to run other commands for message generation / upload.
|
||||
# Packaging
|
||||
|
||||
Need to be able to support multiple profiles for each.
|
||||
Packaging is done via jpackage, which is included with the JDK version used to build.
|
||||
|
||||
## Tech
|
||||
jpackage seems to pull in the entire working directory unnecessarily. To avoid bloat, packaging should be done in a clean subdirectory.
|
||||
|
||||
- Installers: JPackage
|
||||
- Notifications: https://github.com/sshtools/two-slices/blob/master/README.md
|
||||
- Post to wordpress: https://github.com/ashri/java-wordpress-api/tree/master
|
||||
## Windows
|
||||
|
||||
## Security considerations
|
||||
``` sh
|
||||
> mkdir packaging
|
||||
> cp target/numbersstation-1.0-SNAPSHOT-shaded.jar packaging
|
||||
> cd packaging
|
||||
> jpackage --input . --name "Numbers Station" --main-jar numbersstation-1.0-SNAPSHOT-shaded.jar --main-class name.nathanmcrae.numbersstation.MainRun --type exe --win-menu --win-per-user-install --win-shortcut --win-shortcut-prompt --win-upgrade-uuid 956c711b-01f1-46a2-9355-4a6b63ec1ec9 --icon "../icon.ico" --description "Tool to periodically upload encrypted messages to a website/blog"
|
||||
```
|
||||
|
||||
If someone were to take any part of the number station (this software, the server, or intercepting on the way to the recipient), then they could make sure no messages get through (though they couldn't spoof messages without access to the one-time pads).
|
||||
## Linux
|
||||
|
||||
This weakness is true of nearly all communication methods though. The only way to be certain a message was received is to receive an acknowledgement back.
|
||||
|
||||
# Settings/State Format
|
||||
|
||||
$XDG_CONFIG_HOME/numbers-station/main-settings.xml
|
||||
$XDG_CONFIG_HOME/numbers-station/listener-settings.xml
|
||||
$XDG_STATE_HOME/numbers-station/main.log
|
||||
$XDG_STATE_HOME/numbers-station/listener.log
|
||||
$XDG_STATE_HOME/numbers-station/<station-id>-main/next-message.txt
|
||||
$XDG_STATE_HOME/numbers-station/<station-id>-main/20250114T091633.txt
|
||||
$XDG_STATE_HOME/numbers-station/<station-id>-listener/20250114T091735.txt
|
||||
$XDG_STATE_HOME/numbers-station/<station-id>-listener/20250114T091748-read.txt
|
||||
|
||||
XDG dirs:
|
||||
https://superuser.com/a/1767882
|
||||
|
||||
On Windows:
|
||||
https://stackoverflow.com/questions/43853548/xdg-basedir-directories-for-windows
|
||||
|
||||
Library to use:
|
||||
https://github.com/dirs-dev/directories-jvm
|
||||
``` sh
|
||||
> mkdir packaging
|
||||
> cp target/numbersstation-1.0-SNAPSHOT.jar packaging
|
||||
> cd packaging
|
||||
> jpackage --input . --name numbers-station --main-jar numbersstation-1.0-SNAPSHOT.jar --main-class name.nathanmcrae.numbersstation.MainRun --type deb --icon ../icon.ico --description "Tool to periodically upload encrypted messages to a website/blog"
|
||||
```
|
||||
|
||||
# TODO
|
||||
|
||||
@ -67,15 +55,22 @@ https://github.com/dirs-dev/directories-jvm
|
||||
- [ ] Add tests for generateMessage()
|
||||
- [x] Load message from next-message
|
||||
- [x] When making changes to the message, show the changes as unsaved until saved.
|
||||
- [ ] Ensure all GUI elements have accessibility text
|
||||
- [ ] Embed versioning info
|
||||
- [x] Ensure all GUI elements have accessibility text
|
||||
- [x] Embed versioning info
|
||||
- [ ] Factor out scheduling into a wrapper class that handles all the os-specific stuff internally.
|
||||
- [ ] If a station name is run which doesn't exist in settings, but has associated files, then prompt the user to delete the files.
|
||||
- [ ] Fix behavior when settings file is empty
|
||||
- [ ] Store schedule time with time zone
|
||||
- [x] Store schedule time with time zone
|
||||
- [ ] Add tests for StationSettings.nextSendTime()
|
||||
- [ ] When changing number of digits for a station, we may want to regenerate a new message of the specified length. We'll need to prompt the user to overwrite the existing message (in case it's a real message).
|
||||
- [ ] Add a button to post message manually (With dialog warning)
|
||||
- Add description in help quickstart for how to use this
|
||||
- [ ] 'Next message will be sent' should reflect when external schedule management is turned on
|
||||
- [x] Have a way to show executable location (since you need to know that to manage schedule externally)
|
||||
- [ ] When launching help, re-navigate to help page
|
||||
- [x] When can't load settings, give option to re-initialize (with confirmation)
|
||||
|
||||
Note on jars and javafx: https://stackoverflow.com/a/23121897
|
||||
# Devlog
|
||||
|
||||
# 2025-01-27 JAR packaging
|
||||
|
||||
@ -137,7 +132,7 @@ java.io.IOException: Command [C:\Program Files (x86)\WiX Toolset v3.11\bin\candl
|
||||
|
||||
Did a clean clone and build and it worked.
|
||||
|
||||
jpackage --input . --name numbers-station --main-jar .\target\numbersstation-1.0-SNAPSHOT.jar --main-class name.nathanmcrae.numbersstation.MainRun --type exe --win-menu --win-per-user-install --win-shortcut --win-shortcut-prompt --win-upgrade-uuid 956c711b-01f1-46a2-9355-4a6b63ec1ec9 --icon "P:\personal_root\projects\numbers-station\icon.ico" --description "Tool to periodically upload encrypted messages to a website/blog"
|
||||
jpackage --input . --name "Numbers Station" --main-jar .\target\numbersstation-1.0-SNAPSHOT.jar --main-class name.nathanmcrae.numbersstation.MainRun --type exe --win-menu --win-per-user-install --win-shortcut --win-shortcut-prompt --win-upgrade-uuid 956c711b-01f1-46a2-9355-4a6b63ec1ec9 --icon "P:\personal_root\projects\numbers-station\icon.ico" --description "Tool to periodically upload encrypted messages to a website/blog"
|
||||
|
||||
---
|
||||
|
@ -25,6 +25,7 @@ import javafx.fxml.FXMLLoader;
|
||||
import javafx.fxml.Initializable;
|
||||
import javafx.scene.control.Alert;
|
||||
import javafx.scene.control.Alert.AlertType;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.ButtonType;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.TextArea;
|
||||
@ -183,9 +184,20 @@ public class MainController implements Initializable {
|
||||
|
||||
Result<MainSettings, Exception> result = MainSettings.load();
|
||||
if (!result.hasSuccess()) {
|
||||
Alert alert = new Alert(Alert.AlertType.ERROR, "Unable to load settings file. See log for details. Reinitialize settings? This may overwrite existing settings.", ButtonType.YES, ButtonType.NO);
|
||||
String logPath = Main.getStatePath().resolve("main.log").toString();
|
||||
String message = "Unable to load settings file. See log file at " + logPath + " for details. Reinitialize settings? This may overwrite existing settings.";
|
||||
Alert alert = new Alert(Alert.AlertType.ERROR, message, ButtonType.NO, ButtonType.YES);
|
||||
alert.setTitle("Settings load error");
|
||||
alert.setHeaderText(null);
|
||||
|
||||
//Deactivate Defaultbehavior for yes-Button:
|
||||
Button yesButton = (Button) alert.getDialogPane().lookupButton( ButtonType.YES );
|
||||
yesButton.setDefaultButton( false );
|
||||
|
||||
//Activate Defaultbehavior for no-Button:
|
||||
Button noButton = (Button) alert.getDialogPane().lookupButton( ButtonType.NO );
|
||||
noButton.setDefaultButton( true );
|
||||
|
||||
Optional<ButtonType> promptResult = alert.showAndWait();
|
||||
|
||||
if (!promptResult.isPresent()) {
|
||||
|
@ -138,14 +138,12 @@ public class StationSelectionController {
|
||||
while (change.next()) {
|
||||
if (change.wasAdded()) {
|
||||
for (StationSettings addedStation : change.getAddedSubList()) {
|
||||
System.out.println("Added: " + addedStation.getName());
|
||||
}
|
||||
}
|
||||
if (change.wasRemoved()) {
|
||||
for (StationSettings removedStation : change.getRemoved()) {
|
||||
System.out.println("Removed: " + removedStation.getName());
|
||||
|
||||
try {
|
||||
StationSettings.deleteStationData(removedStation.getName());
|
||||
removedStation.deleteDir();
|
||||
} catch (IOException e) {
|
||||
logger.log(Level.SEVERE, "Exception when removing station directory", e);
|
||||
@ -170,7 +168,6 @@ public class StationSelectionController {
|
||||
|
||||
if (selectedStation != null) {
|
||||
stage.setUserData(selectedStation.getName());
|
||||
System.out.println("Selected Station: " + selectedStation.getName());
|
||||
}
|
||||
stage.close();
|
||||
}
|
||||
|
@ -112,6 +112,10 @@ public class StationSettings {
|
||||
}
|
||||
|
||||
public void deleteDir() throws IOException {
|
||||
if (!Files.exists(stationPath())) {
|
||||
return;
|
||||
}
|
||||
|
||||
Files.walkFileTree(stationPath(), new SimpleFileVisitor<Path>() {
|
||||
@Override
|
||||
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
|
||||
|
@ -533,16 +533,6 @@ public class StationSettingsController {
|
||||
}
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void handleTestRegisterScheduleButtonPress() {
|
||||
WindowsScheduler.registerSchedule(settings);
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void handleTestRunScheduleButtonPress() {
|
||||
WindowsScheduler.runSchedule(settings);
|
||||
}
|
||||
|
||||
public StringProperty stationAddressProperty() {
|
||||
return stationAddress;
|
||||
}
|
||||
@ -565,7 +555,6 @@ public class StationSettingsController {
|
||||
messagePeriod.set(settings.getMessagePeriod());
|
||||
username.set(settings.getUsername());
|
||||
password.set(settings.getPassword());
|
||||
System.out.println(settings.getPrefixes());
|
||||
prefixListView.getItems().addAll(settings.getPrefixes());
|
||||
scheduleStartDate.set(settings.getScheduleStart().withZoneSameInstant(ZoneId.systemDefault()).toLocalDate());
|
||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm:ss");
|
||||
|
@ -437,7 +437,7 @@ public class WindowsScheduler {
|
||||
|
||||
/**
|
||||
* @return (stdout contents, stderr contents)
|
||||
* TODO: don't assume that process has exited yet. If it does we don't want to hang.
|
||||
* Note that caller should check that process has exited
|
||||
*/
|
||||
public static Pair<String, String> captureProcessOutput(Process process) throws IOException {
|
||||
StringBuilder output = new StringBuilder();
|
||||
|
@ -12,15 +12,15 @@
|
||||
<Font size="18.0" />
|
||||
</font>
|
||||
</Label>
|
||||
<Label layoutX="20.0" layoutY="110.0" text="Application executable: " AnchorPane.leftAnchor="20.0" AnchorPane.topAnchor="110.0" />
|
||||
<Label layoutX="20.0" layoutY="50.0" text="Homepage:" AnchorPane.leftAnchor="20.0" AnchorPane.topAnchor="50.0" />
|
||||
<Label layoutX="20.0" layoutY="140.0" text="Config directory: " AnchorPane.leftAnchor="20.0" AnchorPane.topAnchor="140.0" />
|
||||
<TextField fx:id="homepageURLTextField" accessibleText="Homepage URL field" editable="false" layoutX="89.0" layoutY="46.0" prefHeight="25.0" prefWidth="501.0" text="asefa" AnchorPane.leftAnchor="89.0" AnchorPane.rightAnchor="10.0" />
|
||||
<Label layoutX="20.0" layoutY="80.0" text="Version:" AnchorPane.leftAnchor="20.0" AnchorPane.topAnchor="80.0" />
|
||||
<TextField fx:id="versionTextField" editable="false" layoutX="72.0" layoutY="76.0" text="asefa" />
|
||||
<TextField fx:id="executableTextField" editable="false" layoutX="153.0" layoutY="106.0" prefHeight="25.0" prefWidth="403.0" text="sflejk" AnchorPane.leftAnchor="153.0" AnchorPane.rightAnchor="10.0" />
|
||||
<TextField fx:id="directoryTextField" editable="false" layoutX="118.0" layoutY="136.0" prefHeight="25.0" prefWidth="437.0" text="afseijl" AnchorPane.leftAnchor="118.0" AnchorPane.rightAnchor="10.0" />
|
||||
<TextField fx:id="versionTextField" accessibleText="Application version field" editable="false" layoutX="72.0" layoutY="76.0" text="asefa" AnchorPane.leftAnchor="89.0" AnchorPane.rightAnchor="10.0" />
|
||||
<Label layoutX="20.0" layoutY="110.0" text="Application executable: " AnchorPane.leftAnchor="20.0" AnchorPane.topAnchor="110.0" />
|
||||
<TextField fx:id="executableTextField" accessibleText="Application executable path field" editable="false" layoutX="153.0" layoutY="106.0" prefHeight="25.0" prefWidth="403.0" text="sflejk" AnchorPane.leftAnchor="153.0" AnchorPane.rightAnchor="10.0" />
|
||||
<Label layoutX="20.0" layoutY="140.0" text="Config directory: " AnchorPane.leftAnchor="20.0" AnchorPane.topAnchor="140.0" />
|
||||
<TextField fx:id="directoryTextField" accessibleText="Configuration directory path field" editable="false" layoutX="118.0" layoutY="136.0" prefHeight="25.0" prefWidth="437.0" text="afseijl" AnchorPane.leftAnchor="118.0" AnchorPane.rightAnchor="10.0" />
|
||||
<Label layoutX="20.0" layoutY="168.0" text="Log file: " AnchorPane.leftAnchor="20.0" AnchorPane.topAnchor="170.0" />
|
||||
<TextField fx:id="logPathTextField" editable="false" layoutX="70.0" layoutY="166.0" prefHeight="25.0" prefWidth="485.0" text="afseijl" AnchorPane.leftAnchor="70.0" AnchorPane.rightAnchor="10.0" />
|
||||
<TextField fx:id="homepageURLTextField" editable="false" layoutX="89.0" layoutY="46.0" prefHeight="25.0" prefWidth="501.0" text="asefa" AnchorPane.leftAnchor="89.0" AnchorPane.rightAnchor="10.0" />
|
||||
<TextField fx:id="logPathTextField" accessibleText="Log file path field" editable="false" layoutX="70.0" layoutY="166.0" prefHeight="25.0" prefWidth="485.0" text="afseijl" AnchorPane.leftAnchor="70.0" AnchorPane.rightAnchor="10.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
|
@ -11,13 +11,13 @@
|
||||
<children>
|
||||
<AnchorPane prefHeight="200.0" prefWidth="312.0">
|
||||
<children>
|
||||
<Button fx:id="okButton" layoutX="89.0" layoutY="67.0" mnemonicParsing="false" prefHeight="25.0" prefWidth="65.0" text="OK" AnchorPane.bottomAnchor="15.0" AnchorPane.rightAnchor="89.0" />
|
||||
<Button fx:id="cancelButton" layoutX="169.0" layoutY="67.0" mnemonicParsing="false" prefHeight="25.0" prefWidth="65.0" text="Cancel" AnchorPane.bottomAnchor="15.0" AnchorPane.rightAnchor="9.0" />
|
||||
<Label layoutX="14.0" layoutY="14.0" text="Enter a message prefix / identifier:">
|
||||
<font>
|
||||
<Font name="Liberation Sans" size="13.0" />
|
||||
</font></Label>
|
||||
<TextField fx:id="prefixField" layoutX="216.0" layoutY="10.0" prefHeight="25.0" prefWidth="86.0" AnchorPane.leftAnchor="216.0" AnchorPane.rightAnchor="10.0" />
|
||||
<TextField fx:id="prefixField" accessibleText="Prefix field" layoutX="216.0" layoutY="10.0" prefHeight="25.0" prefWidth="86.0" AnchorPane.leftAnchor="216.0" AnchorPane.rightAnchor="10.0" />
|
||||
<Button fx:id="okButton" layoutX="89.0" layoutY="67.0" mnemonicParsing="false" prefHeight="25.0" prefWidth="65.0" text="OK" AnchorPane.bottomAnchor="15.0" AnchorPane.rightAnchor="89.0" />
|
||||
<Button fx:id="cancelButton" layoutX="169.0" layoutY="67.0" mnemonicParsing="false" prefHeight="25.0" prefWidth="65.0" text="Cancel" AnchorPane.bottomAnchor="15.0" AnchorPane.rightAnchor="9.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
</children>
|
||||
|
@ -3,4 +3,4 @@
|
||||
<?import javafx.scene.web.WebView?>
|
||||
|
||||
|
||||
<WebView fx:id="webView" prefHeight="391.0" prefWidth="440.0" xmlns="http://javafx.com/javafx/23.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="name.nathanmcrae.numbersstation.HelpController" />
|
||||
<WebView fx:id="webView" prefHeight="597.0" prefWidth="652.0" xmlns="http://javafx.com/javafx/23.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="name.nathanmcrae.numbersstation.HelpController" />
|
||||
|
@ -65,7 +65,7 @@
|
||||
<children>
|
||||
<Button layoutX="228.0" layoutY="1.0" mnemonicParsing="false" onAction="#handleSelectStationButtonPress" text="Select Station" />
|
||||
<Label alignment="CENTER_RIGHT" layoutY="5.0" prefHeight="17.0" prefWidth="60.0" text="Station: " textAlignment="RIGHT" />
|
||||
<TextField fx:id="stationNameField" editable="false" layoutX="68.0" prefHeight="25.0" prefWidth="153.0" style="-fx-background-color: #EEEEEE; -fx-border-color: #AAAAAA;" text="My Station" />
|
||||
<TextField id="teststationnamefield" fx:id="stationNameField" accessibleText="Station name field" editable="false" layoutX="68.0" prefHeight="25.0" prefWidth="153.0" style="-fx-background-color: #EEEEEE; -fx-border-color: #AAAAAA;" text="My Station" />
|
||||
<Button layoutX="602.0" layoutY="1.0" mnemonicParsing="false" onAction="#handleHelpButtonPress" text="Help" AnchorPane.rightAnchor="0.0" />
|
||||
<Button layoutX="516.0" layoutY="1.0" mnemonicParsing="false" onAction="#handleAboutButtonPress" text="About" AnchorPane.rightAnchor="52.0" />
|
||||
</children>
|
||||
@ -90,7 +90,7 @@
|
||||
<items>
|
||||
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="100.0">
|
||||
<children>
|
||||
<TextArea fx:id="messageTextArea" prefHeight="270.0" text="0239 0480 2938 0928 3093 2298 3923 8933" wrapText="true" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<TextArea fx:id="messageTextArea" accessibleText="Next message editor" prefHeight="270.0" text="0239 0480 2938 0928 3093 2298 3923 8933" wrapText="true" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<font>
|
||||
<Font name="Liberation Mono" size="30.0" />
|
||||
</font>
|
||||
|
@ -40,18 +40,18 @@
|
||||
|
||||
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="250.0" prefWidth="395.0" stylesheets="@css/application.css" xmlns="http://javafx.com/javafx/23.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="name.nathanmcrae.numbersstation.NotificationController">
|
||||
<children>
|
||||
<Label fx:id="titleLabel" layoutX="86.0" layoutY="24.0" text="Notification title (this sure is a title)">
|
||||
<font>
|
||||
<Font name="Liberation Sans Bold" size="16.0" />
|
||||
</font>
|
||||
</Label>
|
||||
<Button fx:id="dismissButton" layoutX="325.0" layoutY="139.0" mnemonicParsing="false" onAction="#handleDismissButtonPressed" text="Dismiss" AnchorPane.bottomAnchor="14.0" AnchorPane.rightAnchor="14.0" />
|
||||
<Button fx:id="openButton" layoutX="270.0" layoutY="139.0" mnemonicParsing="false" onAction="#handleOpenButtonPressed" text="Open" visible="false" AnchorPane.bottomAnchor="14.0" AnchorPane.rightAnchor="79.5" />
|
||||
<Label fx:id="iconLabel" alignment="CENTER" contentDisplay="CENTER" layoutX="14.0" layoutY="5.0" prefHeight="60.0" prefWidth="65.0" text="⚠" textAlignment="CENTER" textFill="RED">
|
||||
<font>
|
||||
<Font size="42.0" />
|
||||
</font>
|
||||
</Label>
|
||||
<TextArea fx:id="descriptionTextArea" editable="false" layoutX="14.0" layoutY="67.0" prefHeight="62.0" prefWidth="367.0" style="-fx-background-color: EEEEEE;" text="Quidem repellendus perferendis quos ipsum. Nihil nobis esse aperiam. Modi optio quia repudiandae quaerat fugit accusamus. Qui sint qui cupiditate rerum quisquam aspernatur illum. Deleniti voluptatum nam alias fugiat.Ab in iste dolores. Ad nostrum quia quisquam deleniti dolorum sequi. Est ut id et enim.Repellat nemo velit modi sunt provident neque neque. Est consequatur est beatae voluptates tempore commodi voluptas. Dicta asperiores deserunt veritatis quia officia. Reiciendis et qui placeat est minus." wrapText="true" AnchorPane.bottomAnchor="49.0" AnchorPane.leftAnchor="14.0" AnchorPane.rightAnchor="14.0" AnchorPane.topAnchor="67.0" />
|
||||
<Label fx:id="titleLabel" layoutX="86.0" layoutY="24.0" text="Notification title (this sure is a title)">
|
||||
<font>
|
||||
<Font name="Liberation Sans Bold" size="16.0" />
|
||||
</font>
|
||||
</Label>
|
||||
<TextArea fx:id="descriptionTextArea" accessibleText="Notification text field" editable="false" layoutX="14.0" layoutY="67.0" prefHeight="62.0" prefWidth="367.0" style="-fx-background-color: EEEEEE;" text="Quidem repellendus perferendis quos ipsum. Nihil nobis esse aperiam. Modi optio quia repudiandae quaerat fugit accusamus. Qui sint qui cupiditate rerum quisquam aspernatur illum. Deleniti voluptatum nam alias fugiat.Ab in iste dolores. Ad nostrum quia quisquam deleniti dolorum sequi. Est ut id et enim.Repellat nemo velit modi sunt provident neque neque. Est consequatur est beatae voluptates tempore commodi voluptas. Dicta asperiores deserunt veritatis quia officia. Reiciendis et qui placeat est minus." wrapText="true" AnchorPane.bottomAnchor="49.0" AnchorPane.leftAnchor="14.0" AnchorPane.rightAnchor="14.0" AnchorPane.topAnchor="67.0" />
|
||||
<Button fx:id="openButton" layoutX="270.0" layoutY="139.0" mnemonicParsing="false" onAction="#handleOpenButtonPressed" text="Open" visible="false" AnchorPane.bottomAnchor="14.0" AnchorPane.rightAnchor="79.5" />
|
||||
<Button fx:id="dismissButton" layoutX="325.0" layoutY="139.0" mnemonicParsing="false" onAction="#handleDismissButtonPressed" text="Dismiss" AnchorPane.bottomAnchor="14.0" AnchorPane.rightAnchor="14.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
|
@ -13,9 +13,9 @@
|
||||
<Font size="20.0" />
|
||||
</font>
|
||||
</Label>
|
||||
<Button layoutX="358.0" layoutY="17.0" mnemonicParsing="false" onAction="#handleAddButtonPress" prefHeight="25.0" prefWidth="26.0" text="+" AnchorPane.rightAnchor="55.0" AnchorPane.topAnchor="17.0" />
|
||||
<Button layoutX="391.0" layoutY="17.0" mnemonicParsing="false" onAction="#handleRemoveButtonPress" prefHeight="25.0" prefWidth="25.0" text="-" AnchorPane.rightAnchor="21.0" AnchorPane.topAnchor="17.0" />
|
||||
<ListView fx:id="stationListView" layoutX="14.0" layoutY="57.0" prefHeight="301.0" prefWidth="409.0" AnchorPane.bottomAnchor="42.0" AnchorPane.leftAnchor="14.0" AnchorPane.rightAnchor="14.0" AnchorPane.topAnchor="57.0" />
|
||||
<Button accessibleText="Add new station button" layoutX="358.0" layoutY="17.0" mnemonicParsing="false" onAction="#handleAddButtonPress" prefHeight="25.0" prefWidth="26.0" text="+" AnchorPane.rightAnchor="55.0" AnchorPane.topAnchor="17.0" />
|
||||
<Button accessibleText="Remove selected station button" layoutX="391.0" layoutY="17.0" mnemonicParsing="false" onAction="#handleRemoveButtonPress" prefHeight="25.0" prefWidth="25.0" text="-" AnchorPane.rightAnchor="21.0" AnchorPane.topAnchor="17.0" />
|
||||
<ListView fx:id="stationListView" accessibleText="Station selection list" layoutX="14.0" layoutY="57.0" prefHeight="301.0" prefWidth="409.0" AnchorPane.bottomAnchor="42.0" AnchorPane.leftAnchor="14.0" AnchorPane.rightAnchor="14.0" AnchorPane.topAnchor="57.0" />
|
||||
<Button layoutX="293.0" layoutY="366.0" mnemonicParsing="false" onAction="#handleSelectButtonPress" text="Select" AnchorPane.bottomAnchor="10.0" AnchorPane.rightAnchor="85.0" />
|
||||
<Button layoutX="370.0" layoutY="365.0" mnemonicParsing="false" onAction="#handleCancelButtonPress" text="Cancel" AnchorPane.bottomAnchor="10.0" AnchorPane.rightAnchor="15.5" />
|
||||
</children>
|
||||
|
@ -27,7 +27,7 @@
|
||||
<FlowPane alignment="CENTER_LEFT" prefHeight="41.0" prefWidth="640.0">
|
||||
<children>
|
||||
<Label alignment="CENTER_RIGHT" prefHeight="17.0" prefWidth="58.0" text="Station: " />
|
||||
<TextField fx:id="stationNameField" style="-fx-border-color: #AAAAAA;" text="My Station">
|
||||
<TextField fx:id="stationNameField" accessibleText="Station name field" style="-fx-border-color: #AAAAAA;" text="My Station">
|
||||
<FlowPane.margin>
|
||||
<Insets right="10.0" />
|
||||
</FlowPane.margin>
|
||||
@ -47,7 +47,7 @@
|
||||
<Insets right="10.0" />
|
||||
</FlowPane.margin>
|
||||
</Label>
|
||||
<Spinner fx:id="digitsPerGroupSpinner" editable="true" prefHeight="25.0" prefWidth="96.0" />
|
||||
<Spinner fx:id="digitsPerGroupSpinner" accessibleText="Digit group size field" editable="true" prefHeight="25.0" prefWidth="96.0" />
|
||||
</children>
|
||||
</FlowPane>
|
||||
<FlowPane alignment="CENTER_LEFT" layoutX="244.0" layoutY="7.0" prefHeight="63.0" prefWidth="216.0">
|
||||
@ -57,7 +57,7 @@
|
||||
<Insets right="10.0" />
|
||||
</FlowPane.margin>
|
||||
</Label>
|
||||
<Spinner fx:id="messageLengthSpinner" editable="true" prefHeight="25.0" prefWidth="96.0" />
|
||||
<Spinner fx:id="messageLengthSpinner" accessibleText="Message length field" editable="true" prefHeight="25.0" prefWidth="96.0" />
|
||||
</children>
|
||||
</FlowPane>
|
||||
</children>
|
||||
@ -70,8 +70,8 @@
|
||||
<Font size="14.0" />
|
||||
</font>
|
||||
</Label>
|
||||
<Label layoutX="170.0" layoutY="39.0" text="Numbers station address:" />
|
||||
<TextField fx:id="stationAddressField" layoutX="188.0" layoutY="63.0" prefHeight="25.0" prefWidth="390.0" AnchorPane.leftAnchor="188.0" AnchorPane.rightAnchor="0.0" />
|
||||
<Label fx:id="connectionTestStatusLabel" accessibleText="Test connection result" alignment="CENTER_RIGHT" layoutX="136.0" layoutY="11.0" prefHeight="17.0" prefWidth="317.0" textAlignment="RIGHT" AnchorPane.leftAnchor="136.0" AnchorPane.rightAnchor="125.0" />
|
||||
<Button fx:id="testConnectionButton" layoutX="464.0" layoutY="7.0" mnemonicParsing="false" onAction="#handleTestConnectionButtonPress" text="Test connection" AnchorPane.rightAnchor="0.0" />
|
||||
<RadioButton fx:id="sftpRadioButton" layoutX="16.0" layoutY="42.0" mnemonicParsing="false" text="SFTP">
|
||||
<toggleGroup>
|
||||
<ToggleGroup fx:id="messageMethodGroup" />
|
||||
@ -87,13 +87,13 @@
|
||||
<fx:reference source="messageMethodGroup" />
|
||||
</toggleGroup>
|
||||
</RadioButton>
|
||||
<Label layoutX="170.0" layoutY="39.0" text="Numbers station address:" />
|
||||
<TextField fx:id="stationAddressField" accessibleText="Number station address field" layoutX="189.0" layoutY="63.0" prefHeight="25.0" prefWidth="390.0" AnchorPane.leftAnchor="189.0" AnchorPane.rightAnchor="-1.0" />
|
||||
<Label layoutX="182.0" layoutY="99.0" text="Username:" AnchorPane.rightAnchor="340.0" />
|
||||
<TextField fx:id="usernameField" accessibleText="Numbers station username field" layoutX="245.0" layoutY="95.0" prefHeight="25.0" prefWidth="124.0" AnchorPane.rightAnchor="209.0" />
|
||||
<Label layoutX="380.0" layoutY="99.0" text="Password:" AnchorPane.rightAnchor="142.0" />
|
||||
<TextField fx:id="usernameField" layoutX="245.0" layoutY="95.0" prefHeight="25.0" prefWidth="124.0" AnchorPane.rightAnchor="209.0" />
|
||||
<PasswordField fx:id="passwordField" layoutX="444.0" layoutY="95.0" prefHeight="25.0" prefWidth="135.0" AnchorPane.rightAnchor="0.0" />
|
||||
<TextField fx:id="externalProgramCommandField" layoutX="-2.0" layoutY="131.0" prefHeight="25.0" prefWidth="580.0" AnchorPane.leftAnchor="-2.0" AnchorPane.rightAnchor="0.0" />
|
||||
<Button fx:id="testConnectionButton" layoutX="464.0" layoutY="7.0" mnemonicParsing="false" onAction="#handleTestConnectionButtonPress" text="Test connection" AnchorPane.rightAnchor="0.0" />
|
||||
<Label fx:id="connectionTestStatusLabel" alignment="CENTER_RIGHT" layoutX="136.0" layoutY="11.0" prefHeight="17.0" prefWidth="317.0" textAlignment="RIGHT" AnchorPane.leftAnchor="136.0" AnchorPane.rightAnchor="125.0" />
|
||||
<PasswordField fx:id="passwordField" accessibleText="Numbers station password field" layoutX="444.0" layoutY="95.0" prefHeight="25.0" prefWidth="135.0" AnchorPane.rightAnchor="0.0" />
|
||||
<TextField fx:id="externalProgramCommandField" accessibleText="Numbers station external program field" layoutX="-2.0" layoutY="131.0" prefHeight="25.0" prefWidth="580.0" AnchorPane.leftAnchor="-2.0" AnchorPane.rightAnchor="0.0" />
|
||||
|
||||
</children>
|
||||
<VBox.margin>
|
||||
@ -108,14 +108,14 @@
|
||||
<Font size="14.0" />
|
||||
</font>
|
||||
</Label>
|
||||
<Button layoutX="520.5" layoutY="4.0" mnemonicParsing="false" onAction="#handleAddPrefixButtonPress" text="+" AnchorPane.rightAnchor="33.0" />
|
||||
<Button layoutX="552.0" layoutY="4.0" mnemonicParsing="false" onAction="#handleRemovePrefixButtonPress" prefHeight="25.0" prefWidth="25.0" text="-" AnchorPane.rightAnchor="1.0" />
|
||||
<Button accessibleText="Add prefix field" layoutX="520.5" layoutY="4.0" mnemonicParsing="false" onAction="#handleAddPrefixButtonPress" text="+" AnchorPane.rightAnchor="33.0" />
|
||||
<Button accessibleText="Remove selected prefix button" layoutX="552.0" layoutY="4.0" mnemonicParsing="false" onAction="#handleRemovePrefixButtonPress" prefHeight="25.0" prefWidth="25.0" text="-" AnchorPane.rightAnchor="1.0" />
|
||||
</children>
|
||||
<VBox.margin>
|
||||
<Insets bottom="10.0" />
|
||||
</VBox.margin>
|
||||
</AnchorPane>
|
||||
<ListView fx:id="prefixListView" prefHeight="103.0" prefWidth="578.0" />
|
||||
<ListView fx:id="prefixListView" accessibleText="Prefix list" prefHeight="103.0" prefWidth="578.0" />
|
||||
<Separator prefWidth="200.0">
|
||||
<VBox.margin>
|
||||
<Insets bottom="10.0" top="10.0" />
|
||||
@ -144,12 +144,9 @@
|
||||
<fx:reference source="messagePeriodGroup" />
|
||||
</toggleGroup>
|
||||
</RadioButton>
|
||||
<DatePicker fx:id="scheduleStartDatePicker" disable="${manageScheduleExternallyCheckBox.selected}" layoutX="115.0" layoutY="34.0" />
|
||||
<Label layoutX="115.0" layoutY="8.0" text="Starting from:" />
|
||||
<TextField fx:id="scheduleStartTimeField" disable="${manageScheduleExternallyCheckBox.selected}" layoutX="115.0" layoutY="64.0" text="23:24:49" />
|
||||
<Label layoutX="48.0" layoutY="102.0" text="TODO: Jitter" />
|
||||
<Button layoutX="377.0" layoutY="73.0" mnemonicParsing="false" onAction="#handleTestRegisterScheduleButtonPress" text="Test register scheduled task" />
|
||||
<Button layoutX="377.0" layoutY="107.0" mnemonicParsing="false" onAction="#handleTestRunScheduleButtonPress" text="Test running scheduled task" />
|
||||
<DatePicker fx:id="scheduleStartDatePicker" accessibleText="Message schedule start date" disable="${manageScheduleExternallyCheckBox.selected}" layoutX="115.0" layoutY="34.0" />
|
||||
<TextField fx:id="scheduleStartTimeField" accessibleText="Message schedule start time" disable="${manageScheduleExternallyCheckBox.selected}" layoutX="115.0" layoutY="64.0" text="23:24:49" />
|
||||
|
||||
</children>
|
||||
</AnchorPane>
|
||||
|
@ -108,7 +108,6 @@
|
||||
<li>
|
||||
Set other options (See application reference for details)
|
||||
</li>
|
||||
<li>TODO: test post</li>
|
||||
</ol>
|
||||
|
||||
<h3>
|
||||
|
Reference in New Issue
Block a user