mirror of
https://github.com/cryptomator/cryptomator.git
synced 2026-05-17 10:11:27 +00:00
Merge branch 'develop' into feature/hub
This commit is contained in:
18
.github/workflows/release.yml
vendored
18
.github/workflows/release.yml
vendored
@@ -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: |
|
||||
|
||||
@@ -28,6 +28,14 @@ Cryptomator is provided free of charge as an open-source project despite the hig
|
||||
|
||||
### Silver Sponsors
|
||||
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><a href="https://mowcapital.com/"><img src="https://cryptomator.org/img/sponsors/mowcapital.svg" alt="Mow Capital" height="40"></a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
- [Jameson Lopp](https://www.lopp.net/)
|
||||
|
||||
---
|
||||
|
||||
2
dist/linux/debian/changelog
vendored
2
dist/linux/debian/changelog
vendored
@@ -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
|
||||
|
||||
|
||||
3
dist/mac/dmg/.gitignore
vendored
3
dist/mac/dmg/.gitignore
vendored
@@ -1,3 +1,4 @@
|
||||
# created during build
|
||||
runtime/
|
||||
*.app/
|
||||
dmg/
|
||||
*.dmg
|
||||
|
||||
28
dist/mac/dmg/build.sh
vendored
28
dist/mac/dmg/build.sh
vendored
@@ -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
|
||||
|
||||
3
dist/win/.gitignore
vendored
Normal file
3
dist/win/.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
runtime
|
||||
Cryptomator
|
||||
installer
|
||||
2
dist/win/build.bat
vendored
Normal file
2
dist/win/build.bat
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
@echo off
|
||||
powershell -NoExit -ExecutionPolicy Unrestricted -Command .\build.ps1
|
||||
91
dist/win/build.ps1
vendored
Normal file
91
dist/win/build.ps1
vendored
Normal file
@@ -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
|
||||
@@ -16,7 +16,11 @@ public class UserInteractionLock<E extends Enum> {
|
||||
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) {
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ abstract class LockModule {
|
||||
|
||||
enum ForceLockDecision {
|
||||
CANCEL,
|
||||
RETRY,
|
||||
FORCE;
|
||||
}
|
||||
|
||||
|
||||
@@ -51,20 +51,26 @@ public class LockWorkflow extends Task<Void> {
|
||||
|
||||
@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());
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -33,11 +33,11 @@
|
||||
</HBox>
|
||||
|
||||
<VBox alignment="BOTTOM_CENTER" VBox.vgrow="ALWAYS">
|
||||
<ButtonBar buttonMinWidth="120" buttonOrder="+CI">
|
||||
<ButtonBar buttonMinWidth="100" buttonOrder="+CIU">
|
||||
<buttons>
|
||||
<Button text="%generic.button.cancel" ButtonBar.buttonData="CANCEL_CLOSE" defaultButton="true" cancelButton="true" onAction="#cancel"/>
|
||||
<!-- TODO: third button with retry? -->
|
||||
<Button text="%lock.forced.confirmBtn" ButtonBar.buttonData="FINISH" onAction="#confirmForcedLock"/>
|
||||
<Button text="%lock.forced.retryBtn" ButtonBar.buttonData="FINISH" onAction="#retry"/>
|
||||
<Button text="%lock.forced.forceBtn" ButtonBar.buttonData="OTHER" onAction="#force" disable="${!controller.forceSupported}"/>
|
||||
</buttons>
|
||||
</ButtonBar>
|
||||
</VBox>
|
||||
|
||||
@@ -118,9 +118,10 @@ unlock.error.invalidMountPoint.existing=Mount point "%s" already exists or paren
|
||||
|
||||
# Lock
|
||||
## Force
|
||||
lock.forced.heading=Graceful lock failed
|
||||
lock.forced.heading=Lock failed
|
||||
lock.forced.message=Locking "%s" was blocked by pending operations or open files. You can force lock this vault, however interrupting I/O may result in the loss of unsaved data.
|
||||
lock.forced.confirmBtn=Force Lock
|
||||
lock.forced.retryBtn=Retry
|
||||
lock.forced.forceBtn=Force Lock
|
||||
## Failure
|
||||
lock.fail.heading=Locking vault failed.
|
||||
lock.fail.message=Vault "%s" could not be locked. Ensure unsaved work is saved elsewhere and important Read/Write operations are finished. In order to close the vault, kill the Cryptomator process.
|
||||
|
||||
Reference in New Issue
Block a user