diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ea7d5fd42..8ea663cc1 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -39,15 +39,11 @@ jobs: profile: mac steps: - uses: actions/checkout@v2 - - uses: actions/setup-java@v1 + - uses: actions/setup-java@v2 with: + distribution: 'temurin' java-version: ${{ env.JAVA_VERSION }} - - uses: actions/cache@v2 - with: - path: ~/.m2/repository - key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} - restore-keys: | - ${{ runner.os }}-maven- + cache: 'maven' - name: Ensure to use tagged version run: mvn versions:set -DnewVersion=${GITHUB_REF##*/} # use shell parameter expansion to strip of 'refs/tags' if: startsWith(github.ref, 'refs/tags/') @@ -159,8 +155,9 @@ jobs: --resource-dir dist/mac/resources steps: - uses: actions/checkout@v2 - - uses: actions/setup-java@v1 + - uses: actions/setup-java@v2 with: + distribution: 'temurin' java-version: ${{ env.JAVA_VERSION }} - name: Download ${{ matrix.profile }}-buildkit uses: actions/download-artifact@v2 @@ -210,7 +207,7 @@ jobs: ppa: name: Upload source package to PPA needs: [buildkit, metadata] - runs-on: ubuntu-latest + runs-on: ubuntu-18.04 steps: - uses: actions/checkout@v2 - name: install build tools @@ -505,8 +502,9 @@ jobs: name: win-appdir - name: Untar appdir.tar run: tar -xvf appdir.tar - - uses: actions/setup-java@v1 + - uses: actions/setup-java@v2 with: + distribution: 'temurin' java-version: ${{ env.JAVA_VERSION }} - name: Patch Application Directory run: | diff --git a/README.md b/README.md index 4e29763ba..7ffb1fba1 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,14 @@ Cryptomator is provided free of charge as an open-source project despite the hig ### Silver Sponsors + + + + + + +
Mow Capital
+ - [Jameson Lopp](https://www.lopp.net/) --- diff --git a/dist/linux/debian/changelog b/dist/linux/debian/changelog index 84a9756f9..2c7606733 100644 --- a/dist/linux/debian/changelog +++ b/dist/linux/debian/changelog @@ -1,4 +1,4 @@ -cryptomator (${PPA_VERSION}) focal; urgency=low +cryptomator (${PPA_VERSION}) bionic; urgency=low * Full changelog can be found on https://github.com/cryptomator/cryptomator/releases diff --git a/dist/mac/dmg/.gitignore b/dist/mac/dmg/.gitignore index 738927994..c186170c9 100644 --- a/dist/mac/dmg/.gitignore +++ b/dist/mac/dmg/.gitignore @@ -1,3 +1,4 @@ # created during build runtime/ -*.app/ +dmg/ +*.dmg diff --git a/dist/mac/dmg/build.sh b/dist/mac/dmg/build.sh index 6051e6f4c..b8d17cbe0 100755 --- a/dist/mac/dmg/build.sh +++ b/dist/mac/dmg/build.sh @@ -16,13 +16,14 @@ shift "$((OPTIND-1))" # prepare working dir and variables cd $(dirname $0) -rm -rf runtime *.app +rm -rf runtime dmg REVISION_NO=`git rev-list --count HEAD` VERSION_NO=`mvn -f../../../pom.xml help:evaluate -Dexpression=project.version -q -DforceStdout | sed -rn 's/.*([0-9]+\.[0-9]+\.[0-9]+).*/\1/p'` # check preconditions if [ -z "${JAVA_HOME}" ]; then echo "JAVA_HOME not set. Run using JAVA_HOME=/path/to/jdk ./build.sh"; exit 1; fi command -v mvn >/dev/null 2>&1 || { echo >&2 "mvn not found."; exit 1; } +command -v create-dmg >/dev/null 2>&1 || { echo >&2 "create-dmg not found."; exit 1; } if [ -n "${CODESIGN_IDENTITY}" ]; then command -v codesign >/dev/null 2>&1 || { echo >&2 "codesign not found. Fix by 'xcode-select --install'."; exit 1; } if [[ ! `security find-identity -v -p codesigning | grep -w "${CODESIGN_IDENTITY}"` ]]; then echo "Given codesign identity is invalid."; exit 1; fi @@ -59,6 +60,7 @@ ${JAVA_HOME}/bin/jpackage \ --java-options "-Dcryptomator.appVersion=\"${VERSION_NO}\"" \ --app-version "${VERSION_NO}" \ --java-options "-Dfile.encoding=\"utf-8\"" \ + --java-options "-Dapple.awt.enableTemplateImages=true" \ --java-options "-Dcryptomator.logDir=\"~/Library/Logs/Cryptomator\"" \ --java-options "-Dcryptomator.pluginDir=\"~/Library/Application Support/Cryptomator/Plugins\"" \ --java-options "-Dcryptomator.settingsPath=\"~/Library/Application Support/Cryptomator/settings.json\"" \ @@ -94,3 +96,27 @@ if [ -n "${CODESIGN_IDENTITY}" ]; then echo "Codesigning Cryptomator.app..." codesign --force --deep --entitlements ../Cryptomator.entitlements -o runtime -s ${CODESIGN_IDENTITY} Cryptomator.app fi + +# prepare dmg contents +mkdir dmg +mv Cryptomator.app dmg +cp resources/macFUSE.webloc dmg + +# create dmg +create-dmg \ + --volname Cryptomator \ + --volicon "resources/Cryptomator-Volume.icns" \ + --background "resources/Cryptomator-background.tiff" \ + --window-pos 400 100 \ + --window-size 640 694 \ + --icon-size 128 \ + --icon "Cryptomator.app" 128 245 \ + --hide-extension "Cryptomator.app" \ + --icon "macFUSE.webloc" 320 501 \ + --hide-extension "macFUSE.webloc" \ + --app-drop-link 512 245 \ + --eula "resources/license.rtf" \ + --icon ".background" 128 758 \ + --icon ".fseventsd" 320 758 \ + --icon ".VolumeIcon.icns" 512 758 \ + Cryptomator-${VERSION_NO}.dmg dmg diff --git a/dist/win/.gitignore b/dist/win/.gitignore new file mode 100644 index 000000000..2b66ddbed --- /dev/null +++ b/dist/win/.gitignore @@ -0,0 +1,3 @@ +runtime +Cryptomator +installer \ No newline at end of file diff --git a/dist/win/build.bat b/dist/win/build.bat new file mode 100644 index 000000000..ebfe2aa0b --- /dev/null +++ b/dist/win/build.bat @@ -0,0 +1,2 @@ +@echo off +powershell -NoExit -ExecutionPolicy Unrestricted -Command .\build.ps1 \ No newline at end of file diff --git a/dist/win/build.ps1 b/dist/win/build.ps1 new file mode 100644 index 000000000..e4024d46d --- /dev/null +++ b/dist/win/build.ps1 @@ -0,0 +1,91 @@ +# check preconditions +if ((Get-Command "git" -ErrorAction SilentlyContinue) -eq $null) +{ + Write-Host "Unable to find git.exe in your PATH (try: choco install git)" + exit 1 +} +if ((Get-Command "mvn" -ErrorAction SilentlyContinue) -eq $null) +{ + Write-Host "Unable to find mvn.cmd in your PATH (try: choco install maven)" + exit 1 +} + +$buildDir = Split-Path -Parent $PSCommandPath +$version = $(mvn -f $buildDir/../../pom.xml help:evaluate -Dexpression="project.version" -q -DforceStdout) +$semVerNo = $version -replace '(\d\.\d\.\d).*','$1' +$revisionNo = $(git rev-list --count HEAD) + +Write-Output "`$version=$version" +Write-Output "`$semVerNo=$semVerNo" +Write-Output "`$revisionNo=$revisionNo" +Write-Output "`$buildDir=$buildDir" +Write-Output "`$Env:JAVA_HOME=$Env:JAVA_HOME" + +# compile +&mvn -B -f $buildDir/../../pom.xml clean package -DskipTests -Pwin +Copy-Item "$buildDir\..\..\target\cryptomator-*.jar" -Destination "$buildDir\..\..\target\mods" + +# add runtime +& "$Env:JAVA_HOME\bin\jlink" ` + --verbose ` + --output runtime ` + --module-path "$Env:JAVA_HOME/jmods" ` + --add-modules java.base,java.desktop,java.logging,java.naming,java.net.http,java.scripting,java.sql,java.xml,jdk.unsupported,jdk.crypto.ec,jdk.accessibility ` + --no-header-files ` + --no-man-pages ` + --strip-debug ` + --compress=1 + +# create app dir +& "$Env:JAVA_HOME\bin\jpackage" ` + --verbose ` + --type app-image ` + --runtime-image runtime ` + --input ../../target/libs ` + --module-path ../../target/mods ` + --module org.cryptomator.desktop/org.cryptomator.launcher.Cryptomator ` + --dest . ` + --name Cryptomator ` + --vendor "Skymatic GmbH" ` + --copyright "(C) 2016 - 2021 Skymatic GmbH" ` + --java-options "-Xss5m" ` + --java-options "-Xmx256m" ` + --java-options "-Dcryptomator.appVersion=`"$semVerNo`"" ` + --app-version "$semVerNo.$revisionNo" ` + --java-options "-Dfile.encoding=`"utf-8`"" ` + --java-options "-Dcryptomator.logDir=`"~/AppData/Roaming/Cryptomator`"" ` + --java-options "-Dcryptomator.pluginDir=`"~/AppData/Roaming/Cryptomator/Plugins`"" ` + --java-options "-Dcryptomator.settingsPath=`"~/AppData/Roaming/Cryptomator/settings.json`"" ` + --java-options "-Dcryptomator.ipcSocketPath=`"~/AppData/Roaming/Cryptomator/ipc.socket`"" ` + --java-options "-Dcryptomator.keychainPath=`"~/AppData/Roaming/Cryptomator/keychain.json`"" ` + --java-options "-Dcryptomator.mountPointsDir=`"~/Cryptomator`"" ` + --java-options "-Dcryptomator.showTrayIcon=true" ` + --java-options "-Dcryptomator.buildNumber=`"msi-$revisionNo`"" ` + --resource-dir resources ` + --icon resources/Cryptomator.ico + +# patch app dir +Copy-Item "contrib\*" -Destination "Cryptomator" +attrib -r "Cryptomator\Cryptomator.exe" + + +# create .msi bundle +$Env:JP_WIXWIZARD_RESOURCES = "$buildDir\resources" +& "$Env:JAVA_HOME\bin\jpackage" ` + --verbose ` + --type msi ` + --win-upgrade-uuid bda45523-42b1-4cae-9354-a45475ed4775 ` + --app-image Cryptomator ` + --dest installer ` + --name Cryptomator ` + --vendor "Skymatic GmbH" ` + --copyright "(C) 2016 - 2021 Skymatic GmbH" ` + --app-version "$semVerNo" ` + --win-menu ` + --win-dir-chooser ` + --win-shortcut-prompt ` + --win-update-url "https:\\cryptomator.org" ` + --win-menu-group Cryptomator ` + --resource-dir resources ` + --license-file resources/license.rtf ` + --file-associations resources/FAvaultFile.properties \ No newline at end of file diff --git a/src/main/java/org/cryptomator/ui/common/UserInteractionLock.java b/src/main/java/org/cryptomator/ui/common/UserInteractionLock.java index f0c199648..4eba62552 100644 --- a/src/main/java/org/cryptomator/ui/common/UserInteractionLock.java +++ b/src/main/java/org/cryptomator/ui/common/UserInteractionLock.java @@ -16,7 +16,11 @@ public class UserInteractionLock { private volatile E state; public UserInteractionLock(E initialValue) { - state = initialValue; + this.state = initialValue; + } + + public synchronized void reset(E value) { + this.state = value; } public void interacted(E result) { diff --git a/src/main/java/org/cryptomator/ui/lock/LockForcedController.java b/src/main/java/org/cryptomator/ui/lock/LockForcedController.java index 8d4ce32d3..c3a452acc 100644 --- a/src/main/java/org/cryptomator/ui/lock/LockForcedController.java +++ b/src/main/java/org/cryptomator/ui/lock/LockForcedController.java @@ -35,7 +35,13 @@ public class LockForcedController implements FxController { } @FXML - public void confirmForcedLock() { + public void retry() { + forceLockDecisionLock.interacted(LockModule.ForceLockDecision.RETRY); + window.close(); + } + + @FXML + public void force() { forceLockDecisionLock.interacted(LockModule.ForceLockDecision.FORCE); window.close(); } @@ -54,4 +60,8 @@ public class LockForcedController implements FxController { return vault.getDisplayName(); } + public boolean isForceSupported() { + return vault.supportsForcedUnmount(); + } + } diff --git a/src/main/java/org/cryptomator/ui/lock/LockModule.java b/src/main/java/org/cryptomator/ui/lock/LockModule.java index 160dcf6fb..d1eb5f189 100644 --- a/src/main/java/org/cryptomator/ui/lock/LockModule.java +++ b/src/main/java/org/cryptomator/ui/lock/LockModule.java @@ -28,6 +28,7 @@ abstract class LockModule { enum ForceLockDecision { CANCEL, + RETRY, FORCE; } diff --git a/src/main/java/org/cryptomator/ui/lock/LockWorkflow.java b/src/main/java/org/cryptomator/ui/lock/LockWorkflow.java index 73b4844b9..00b25c507 100644 --- a/src/main/java/org/cryptomator/ui/lock/LockWorkflow.java +++ b/src/main/java/org/cryptomator/ui/lock/LockWorkflow.java @@ -51,20 +51,26 @@ public class LockWorkflow extends Task { @Override protected Void call() throws Volume.VolumeException, InterruptedException, LockNotCompletedException { - try { - vault.lock(false); - } catch (Volume.VolumeException | LockNotCompletedException e) { - LOG.debug("Regular lock of {} failed.", vault.getDisplayName(), e); - var decision = askUserForAction(); - switch (decision) { - case FORCE -> vault.lock(true); - case CANCEL -> cancel(false); - } - } + lock(false); return null; } + private void lock(boolean forced) throws InterruptedException { + try { + vault.lock(forced); + } catch (Volume.VolumeException | LockNotCompletedException e) { + LOG.info("Locking {} failed (forced: {}).", vault.getDisplayName(), forced, e); + var decision = askUserForAction(); + switch (decision) { + case RETRY -> lock(false); + case FORCE -> lock(true); + case CANCEL -> cancel(false); + } + } + } + private LockModule.ForceLockDecision askUserForAction() throws InterruptedException { + forceLockDecisionLock.reset(null); // show forcedLock dialogue ... Platform.runLater(() -> { lockWindow.setScene(lockForcedScene.get()); diff --git a/src/main/java/org/cryptomator/ui/preferences/SupporterCertificateController.java b/src/main/java/org/cryptomator/ui/preferences/SupporterCertificateController.java index 02b8bab91..db2554d67 100644 --- a/src/main/java/org/cryptomator/ui/preferences/SupporterCertificateController.java +++ b/src/main/java/org/cryptomator/ui/preferences/SupporterCertificateController.java @@ -34,10 +34,10 @@ public class SupporterCertificateController implements FxController { public void initialize() { supporterCertificateField.setText(licenseHolder.getLicenseKey().orElse(null)); supporterCertificateField.textProperty().addListener(this::registrationKeyChanged); - supporterCertificateField.setTextFormatter(new TextFormatter<>(this::checkVaultNameLength)); + supporterCertificateField.setTextFormatter(new TextFormatter<>(this::removeWhitespaces)); } - private TextFormatter.Change checkVaultNameLength(TextFormatter.Change change) { + private TextFormatter.Change removeWhitespaces(TextFormatter.Change change) { if (change.isContentChange()) { var strippedText = CharMatcher.whitespace().removeFrom(change.getText()); change.setText(strippedText); diff --git a/src/main/java/org/cryptomator/ui/vaultoptions/GeneralVaultOptionsController.java b/src/main/java/org/cryptomator/ui/vaultoptions/GeneralVaultOptionsController.java index a35b108d9..633797820 100644 --- a/src/main/java/org/cryptomator/ui/vaultoptions/GeneralVaultOptionsController.java +++ b/src/main/java/org/cryptomator/ui/vaultoptions/GeneralVaultOptionsController.java @@ -47,7 +47,7 @@ public class GeneralVaultOptionsController implements FxController { public void initialize() { vaultName.textProperty().set(vault.getVaultSettings().displayName().get()); vaultName.focusedProperty().addListener(this::trimVaultNameOnFocusLoss); - vaultName.setTextFormatter(new TextFormatter<>(this::removeWhitespaces)); + vaultName.setTextFormatter(new TextFormatter<>(this::checkVaultNameLength)); unlockOnStartupCheckbox.selectedProperty().bindBidirectional(vault.getVaultSettings().unlockAfterStartup()); actionAfterUnlockChoiceBox.getItems().addAll(WhenUnlocked.values()); actionAfterUnlockChoiceBox.valueProperty().bindBidirectional(vault.getVaultSettings().actionAfterUnlock()); @@ -63,7 +63,7 @@ public class GeneralVaultOptionsController implements FxController { } } - private TextFormatter.Change removeWhitespaces(TextFormatter.Change change) { + private TextFormatter.Change checkVaultNameLength(TextFormatter.Change change) { if (change.isContentChange() && change.getControlNewText().length() > VAULTNAME_TRUNCATE_THRESHOLD) { return null; // reject any change that would lead to a text exceeding threshold } else { diff --git a/src/main/resources/fxml/lock_forced.fxml b/src/main/resources/fxml/lock_forced.fxml index 4596af119..b0b5baa63 100644 --- a/src/main/resources/fxml/lock_forced.fxml +++ b/src/main/resources/fxml/lock_forced.fxml @@ -33,11 +33,11 @@ - +