Merge branch 'develop' into release/1.6.0

This commit is contained in:
Armin Schrenk
2021-08-16 14:33:07 +02:00
206 changed files with 4254 additions and 2823 deletions

View File

@@ -1,5 +1,6 @@
commit_message: "[ci skip]"
escape_special_characters: 0
commit_message: '[ci skip]'
files:
- source: /src/main/resources/i18n/strings.properties
translation: /src/main/resources/i18n/strings_%two_letters_code%.properties
escape_quotes: 0
escape_special_characters: 0

View File

@@ -22,7 +22,7 @@ include:
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or
* The use of sexual language or imagery and unwelcome sexual attention or
advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment

View File

@@ -1,56 +0,0 @@
---
name: "Bug Report"
about: "Create a report to help us improve"
labels: type:bug
---
<!--
Please make sure to:
- Comply with our code of conduct: https://github.com/cryptomator/cryptomator/blob/develop/.github/CODE_OF_CONDUCT.md
- Search for existing similar issues first: https://github.com/cryptomator/cryptomator/issues?q=
⚠️ IMPORTANT: If you don't stick to this template, the issue will get closed.
-->
### Description
[Summarize your problem.]
### System Setup
* Operating system and version: [Windows/macOS/Linux + Version ( + Desktop Environment, if Linux)]
* Cryptomator version: [Shown in the settings]
* Volume type: [Dokany/FUSE/WebDAV, shown in the settings]
### Steps to Reproduce
1. [First step]
2. [Second step]
3. [and so on…]
#### Expected Behavior
[What you expect to happen.]
#### Actual Behavior
[What actually happens.]
#### Reproducibility
[Always/Intermittent/Only once]
### Additional Information
[Any additional information, log files, screenshots, configuration, or data that might be necessary to reproduce the issue.]
<!--
If you want to add the log file or screenshots, please add them as attachments. If your log file seems empty and doesn't show any errors, you may enable the debug mode first. Here is how to do that: https://community.cryptomator.org/t/how-do-i-enable-debug-mode/36
Then reproduce the problem to ensure all important information is contained in there. You may use test data or redact sensitive information from the log file.
Log file location:
- Windows: %appdata%/Cryptomator
- macOS: ~/Library/Logs/Cryptomator
- Linux: ~/.local/share/Cryptomator/logs
-->

93
.github/ISSUE_TEMPLATE/bug.yml vendored Normal file
View File

@@ -0,0 +1,93 @@
name: Bug Report
description: Create a report to help us improve
labels: ["type:bug"]
body:
- type: checkboxes
id: terms
attributes:
label: Please agree to the following
options:
- label: I have searched [existing issues](https://github.com/cryptomator/cryptomator/issues?q=) for duplicates
required: true
- label: I agree to follow this project's [Code of Conduct](https://github.com/cryptomator/cryptomator/blob/develop/.github/CODE_OF_CONDUCT.md)
required: true
- type: input
id: summary
attributes:
label: Summary
placeholder: Please summarize your problem.
validations:
required: true
- type: textarea
id: software-versions
attributes:
label: What software is involved?
description: |
Examples:
- Operating System: Windows 10
- Cryptomator: 1.5.16
- LibreOffice: 7.1.4
value: |
- Operating System:
- Cryptomator:
- …
validations:
required: true
- type: dropdown
id: volume-type
attributes:
label: Volume Type
description: What is selected under Settings → Virtual Drive?
multiple: true
options:
- FUSE
- Dokany
- WebDAV
validations:
required: false
- type: textarea
id: reproduction-steps
attributes:
label: Steps to Reproduce
value: |
1. [First Step]
2. [Second Step]
3. …
validations:
required: true
- type: textarea
id: expected-behaviour
attributes:
label: Expected Behavior
placeholder: What you expect to happen.
validations:
required: true
- type: textarea
id: actual-behaviour
attributes:
label: Actual Behavior
placeholder: What actually happens.
validations:
required: true
- type: dropdown
id: reproducibility
attributes:
label: Reproducibility
description: How often does the described behaviour occur?
options:
- Always
- Intermittent
- Only once
validations:
required: true
- type: textarea
id: logs
attributes:
label: Relevant Log Output
description: Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks.
render: shell
- type: textarea
id: further-info
attributes:
label: Anything else?
description: Links? References? Screenshots? Configurations? Any data that might be necessary to reproduce the issue?

View File

@@ -1,27 +0,0 @@
---
name: "Feature Request"
about: "Suggest an idea for this project"
labels: type:feature-request
---
<!--
Please make sure to:
- Comply with our code of conduct: https://github.com/cryptomator/cryptomator/blob/develop/.github/CODE_OF_CONDUCT.md
- Search for existing similar issues first: https://github.com/cryptomator/cryptomator/issues?q=
-->
### Summary
[One paragraph explanation of the feature.]
### Motivation
[Why are we doing this? What use cases does it support? What is the expected outcome?]
### Considered Alternatives
[A clear and concise description of the alternative solutions you've considered.]
### Additional Context
[Add any other context or screenshots about the feature request here.]

37
.github/ISSUE_TEMPLATE/feature.yml vendored Normal file
View File

@@ -0,0 +1,37 @@
name: Feature Request
description: Suggest an idea for this project
labels: ["type:feature-request"]
body:
- type: checkboxes
id: terms
attributes:
label: Please agree to the following
options:
- label: I have searched [existing issues](https://github.com/cryptomator/cryptomator/issues?q=) for duplicates
required: true
- label: I agree to follow this project's [Code of Conduct](https://github.com/cryptomator/cryptomator/blob/develop/.github/CODE_OF_CONDUCT.md)
required: true
- type: input
id: summary
attributes:
label: Summary
placeholder: Please summarize your feature request.
validations:
required: true
- type: textarea
id: motivation
attributes:
label: Motivation
description: Who requires this feature? What problem does the user face? How would this feature solve the problem?
validations:
required: true
- type: textarea
id: alternatives
attributes:
label: Considered Alternatives
description: What current alternatives or workarounds have you considered? Is there a different way to solve the same problem?
- type: textarea
id: context
attributes:
label: Anything else?
description: Any context, suggestions, screenshots, or concepts you want to share?

2
.github/SUPPORT.md vendored
View File

@@ -14,5 +14,5 @@ For _everything else_, please visit our official [Cryptomator Community](https:/
- Discussions about the apps
- [Development discussions](https://community.cryptomator.org/c/development)
- General questions
- Discussions regarding our design decissions
- Discussions regarding our design decisions
- Our roadmap

View File

@@ -1,27 +1,31 @@
name: Build
on:
[push]
push:
env:
JAVA_VERSION: 16
defaults:
run:
shell: bash
jobs:
build:
name: Build and Test
test:
name: Compile and Test
runs-on: ubuntu-latest
if: "!contains(github.event.head_commit.message, '[ci skip]') && !contains(github.event.head_commit.message, '[skip ci]')"
steps:
- uses: actions/checkout@v2
- uses: actions/setup-java@v1
with:
java-version: 16
- uses: actions/cache@v1
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-
- 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/')
- name: Build and Test
run: mvn -B clean install jacoco:report -Pcoverage,dependency-check
- name: Upload code coverage report
@@ -29,102 +33,4 @@ jobs:
run: bash <(curl -Ls https://coverage.codacy.com/get.sh)
env:
CODACY_PROJECT_TOKEN: ${{ secrets.CODACY_PROJECT_TOKEN }}
continue-on-error: true
### TODO: move to matrix build:
- name: Assemble buildkit-linux.zip
run: mvn -B clean package -DskipTests -Plinux
- name: Upload buildkit-linux.zip
uses: actions/upload-artifact@v1
with:
name: buildkit-linux.zip
path: target/buildkit-linux.zip
- name: Assemble buildkit-mac.zip
run: mvn -B clean package -DskipTests -Pmac
- name: Upload buildkit-mac.zip
uses: actions/upload-artifact@v1
with:
name: buildkit-mac.zip
path: target/buildkit-mac.zip
- name: Assemble buildkit-win.zip
run: mvn -B clean package -DskipTests -Pwindows
- name: Upload buildkit-win.zip
uses: actions/upload-artifact@v1
with:
name: buildkit-win.zip
path: target/buildkit-win.zip
release:
name: Draft a Release on GitHub Releases
runs-on: ubuntu-latest
needs: build
if: startsWith(github.ref, 'refs/tags/') && github.repository == 'cryptomator/cryptomator'
steps:
- name: Download buildkit-linux.zip
uses: actions/download-artifact@v1
with:
name: buildkit-linux.zip
path: .
- name: Download buildkit-mac.zip
uses: actions/download-artifact@v1
with:
name: buildkit-mac.zip
path: .
- name: Download buildkit-win.zip
uses: actions/download-artifact@v1
with:
name: buildkit-win.zip
path: .
- name: Create Release
id: create_release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ github.ref }}
release_name: ${{ github.ref }}
body: |
:construction: Work in Progress
TODO:
* [ ] add Linux appimage, zsync file and signature file
* [ ] add Windows installer and signature file
* [ ] add MacOs disk image and signature file
## What's new
## Bugfixes
## Misc
---
:scroll: A complete list of closed issues is available [here](LINK)
draft: true
prerelease: false
- name: Upload buildkit-linux.zip to GitHub Releases
uses: actions/upload-release-asset@v1.0.1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: buildkit-linux.zip
asset_name: buildkit-linux.zip
asset_content_type: application/zip
- name: Upload buildkit-mac.zip to GitHub Releases
uses: actions/upload-release-asset@v1.0.1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: buildkit-mac.zip
asset_name: buildkit-mac.zip
asset_content_type: application/zip
- name: Upload buildkit-win.zip to GitHub Releases
uses: actions/upload-release-asset@v1.0.1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: buildkit-win.zip
asset_name: buildkit-win.zip
asset_content_type: application/zip
continue-on-error: true

529
.github/workflows/release.yml vendored Normal file
View File

@@ -0,0 +1,529 @@
name: Installers and Release
on:
workflow_dispatch:
push:
tags: # see https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#filter-pattern-cheat-sheet
- '[0-9]+.[0-9]+.[0-9]+'
- '[0-9]+.[0-9]+.[0-9]+-*'
env:
JAVA_VERSION: 16
defaults:
run:
shell: bash
jobs:
#
# Buildkit
#
buildkit:
name: Build ${{ matrix.profile }}-buildkit
runs-on: ${{ matrix.os }}
strategy:
fail-fast: true
matrix:
include:
- os: ubuntu-latest
profile: linux
- os: windows-latest
profile: win
- os: macos-latest
profile: mac
steps:
- uses: actions/checkout@v2
- uses: actions/setup-java@v1
with:
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-
- 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/')
- name: Build and Test
run: mvn -B clean package -Pdependency-check,${{ matrix.profile }}
- name: Patch buildkit
run: |
cp LICENSE.txt target
cp dist/${{ matrix.profile }}/launcher* target
cp target/cryptomator-*.jar target/mods
- name: Upload ${{ matrix.profile }}-buildkit
uses: actions/upload-artifact@v2
with:
name: ${{ matrix.profile }}-buildkit
path: |
target/libs
target/mods
target/LICENSE.txt
target/${{ matrix.launcher }}
if-no-files-found: error
#
# Release Metadata
#
metadata:
name: Determine Version Metadata
runs-on: ubuntu-latest
outputs:
versionStr: ${{ steps.versions.outputs.versionStr }}
versionNum: ${{ steps.versions.outputs.versionNum }}
revNum: ${{ steps.versions.outputs.revNum }}
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0
- id: versions
run: |
if [[ $GITHUB_REF == refs/tags/* ]]; then
VERSION_NUM=`echo ${GITHUB_REF##*/} | sed -E 's/([0-9]+\.[0-9]+\.[0-9]+).*/\1/'`
echo "::set-output name=versionStr::${GITHUB_REF##*/}"
echo "::set-output name=versionNum::${VERSION_NUM}"
else
echo "::set-output name=versionStr::SNAPSHOT"
echo "::set-output name=versionNum::99.0.0"
fi
echo "::set-output name=revNum::`git rev-list --count HEAD`"
#
# Application Directory
#
appdir:
name: Create ${{ matrix.profile }}-appdir
needs: [buildkit, metadata]
runs-on: ${{ matrix.os }}
strategy:
fail-fast: true
matrix:
include:
- os: ubuntu-latest
profile: linux
jpackageoptions: >
--app-version "${{ needs.metadata.outputs.versionNum }}.${{ needs.metadata.outputs.revNum }}"
--java-options "-Dfile.encoding=\"utf-8\""
--java-options "-Dcryptomator.logDir=\"~/.local/share/Cryptomator/logs\""
--java-options "-Dcryptomator.settingsPath=\"~/.config/Cryptomator/settings.json:~/.Cryptomator/settings.json\""
--java-options "-Dcryptomator.ipcSocketPath=\"~/.config/Cryptomator/ipc.socket\""
--java-options "-Dcryptomator.mountPointsDir=\"~/.local/share/Cryptomator/mnt\""
--java-options "-Dcryptomator.showTrayIcon=false"
--java-options "-Dcryptomator.buildNumber=\"appimage-${{ needs.metadata.outputs.revNum }}\""
--resource-dir dist/linux/resources
- os: windows-latest
profile: win
jpackageoptions: >
--app-version "${{ needs.metadata.outputs.versionNum }}.${{ needs.metadata.outputs.revNum }}"
--java-options "-Dfile.encoding=\"utf-8\""
--java-options "-Dcryptomator.logDir=\"~/AppData/Roaming/Cryptomator\""
--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-${{ needs.metadata.outputs.revNum }}\""
--resource-dir dist/win/resources
--icon dist/win/resources/Cryptomator.ico
- os: macos-latest
profile: mac
jpackageoptions: >
--app-version "${{ needs.metadata.outputs.versionNum }}"
--java-options "-Dfile.encoding=\"utf-8\""
--java-options "-Dcryptomator.logDir=\"~/Library/Logs/Cryptomator\""
--java-options "-Dcryptomator.settingsPath=\"~/Library/Application Support/Cryptomator/settings.json\""
--java-options "-Dcryptomator.ipcSocketPath=\"~/Library/Application Support/Cryptomator/ipc.socket\""
--java-options "-Dcryptomator.showTrayIcon=true"
--java-options "-Dcryptomator.buildNumber=\"dmg-${{ needs.metadata.outputs.revNum }}\""
--mac-package-identifier org.cryptomator
--resource-dir dist/mac/resources
steps:
- uses: actions/checkout@v2
- uses: actions/setup-java@v1
with:
java-version: ${{ env.JAVA_VERSION }}
- name: Download ${{ matrix.profile }}-buildkit
uses: actions/download-artifact@v2
with:
name: ${{ matrix.profile }}-buildkit
path: buildkit
- name: Create Runtime Image
run: >
${JAVA_HOME}/bin/jlink
--verbose
--output runtime
--module-path "${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
- name: Create App Directory
run: >
${JAVA_HOME}/bin/jpackage
--verbose
--type app-image
--runtime-image runtime
--input buildkit/libs
--module-path buildkit/mods
--module org.cryptomator.desktop/org.cryptomator.launcher.Cryptomator
--dest appdir
--name Cryptomator
--vendor "Skymatic GmbH"
--copyright "(C) 2016 - 2021 Skymatic GmbH"
--java-options "-Xss5m"
--java-options "-Xmx256m"
${{ matrix.jpackageoptions }}
- name: Create appdir.tar
run: tar -cvf appdir.tar appdir
- name: Upload ${{ matrix.profile }}-appdir
uses: actions/upload-artifact@v2
with:
name: ${{ matrix.profile }}-appdir
path: appdir.tar
if-no-files-found: error
#
# Linux Cryptomator.AppImage
#
linux-appimage:
name: Build Cryptomator.AppImage
runs-on: ubuntu-latest
needs: [appdir, metadata]
steps:
- uses: actions/checkout@v2
- name: Download linux-appdir
uses: actions/download-artifact@v2
with:
name: linux-appdir
- name: Untar appdir.tar
run: |
tar -xvf appdir.tar
- name: Patch Cryptomator.AppDir
run: |
mv appdir/Cryptomator Cryptomator.AppDir
cp -r dist/linux/appimage/resources/AppDir/* Cryptomator.AppDir/
envsubst '${REVISION_NO}' < dist/linux/appimage/resources/AppDir/bin/cryptomator.sh > Cryptomator.AppDir/bin/cryptomator.sh
ln -s usr/share/icons/hicolor/scalable/apps/org.cryptomator.Cryptomator.svg Cryptomator.AppDir/org.cryptomator.Cryptomator.svg
ln -s usr/share/icons/hicolor/scalable/apps/org.cryptomator.Cryptomator.svg Cryptomator.AppDir/Cryptomator.svg
ln -s usr/share/icons/hicolor/scalable/apps/org.cryptomator.Cryptomator.svg Cryptomator.AppDir/.DirIcon
ln -s usr/share/applications/org.cryptomator.Cryptomator.desktop Cryptomator.AppDir/Cryptomator.desktop
ln -s bin/cryptomator.sh Cryptomator.AppDir/AppRun
env:
REVISION_NO: ${{ needs.metadata.outputs.revNum }}
- name: Extract libjffi.so # workaround for https://github.com/cryptomator/cryptomator-linux/issues/27
run: |
JFFI_NATIVE_JAR=`ls lib/app/ | grep -e 'jffi-[1-9]\.[0-9]\{1,2\}.[0-9]\{1,2\}-native.jar'`
${JAVA_HOME}/bin/jar -xf lib/app/${JFFI_NATIVE_JAR} /jni/x86_64-Linux/
mv jni/x86_64-Linux/* lib/app/libjffi.so
working-directory: Cryptomator.AppDir
- name: Download AppImageKit
run: |
curl -L https://github.com/AppImage/AppImageKit/releases/download/13/appimagetool-x86_64.AppImage -o appimagetool.AppImage
chmod +x appimagetool.AppImage
./appimagetool.AppImage --appimage-extract
- name: Prepare GPG-Agent for signing with key 615D449FE6E6A235
run: |
echo "${GPG_PRIVATE_KEY}" | gpg --batch --quiet --import
echo "${GPG_PASSPHRASE}" | gpg --batch --quiet --passphrase-fd 0 --pinentry-mode loopback -u 615D449FE6E6A235 --dry-run --sign Cryptomator.AppDir/AppRun
env:
GPG_PRIVATE_KEY: ${{ secrets.RELEASES_GPG_PRIVATE_KEY }}
GPG_PASSPHRASE: ${{ secrets.RELEASES_GPG_PASSPHRASE }}
- name: Build AppImage
run: >
./squashfs-root/AppRun Cryptomator.AppDir cryptomator-${{ needs.metadata.outputs.versionStr }}-x86_64.AppImage
-u 'gh-releases-zsync|cryptomator|cryptomator|latest|cryptomator-*-x86_64.AppImage.zsync'
--sign --sign-key=615D449FE6E6A235 --sign-args="--batch --pinentry-mode loopback"
- name: Upload AppImage
uses: actions/upload-artifact@v2
with:
name: linux-appimage
path: |
cryptomator-*.AppImage
cryptomator-*.AppImage.zsync
if-no-files-found: error
#
# macOS Cryptomator.app
#
mac-app:
name: Build Cryptomator.app
runs-on: macos-latest
needs: [appdir, metadata]
steps:
- uses: actions/checkout@v2
- name: Download mac-appdir
uses: actions/download-artifact@v2
with:
name: mac-appdir
- name: Untar appdir.tar
run: tar -xvf appdir.tar
- name: Patch Cryptomator.app
run: |
mv appdir/Cryptomator.app Cryptomator.app
sed -i '' "s|###BUNDLE_SHORT_VERSION_STRING###|${VERSION_NO}|g" Cryptomator.app/Contents/Info.plist
sed -i '' "s|###BUNDLE_VERSION###|${REVISION_NO}|g" Cryptomator.app/Contents/Info.plist
env:
VERSION_NO: ${{ needs.metadata.outputs.versionNum }}
REVISION_NO: ${{ needs.metadata.outputs.revNum }}
- name: Install codesign certificate
env:
CODESIGN_P12_BASE64: ${{ secrets.MACOS_CODESIGN_P12_BASE64 }}
CODESIGN_P12_PW: ${{ secrets.MACOS_CODESIGN_P12_PW }}
CODESIGN_TMP_KEYCHAIN_PW: ${{ secrets.MACOS_CODESIGN_TMP_KEYCHAIN_PW }}
run: |
# create variables
CERTIFICATE_PATH=$RUNNER_TEMP/codesign.p12
KEYCHAIN_PATH=$RUNNER_TEMP/codesign.keychain-db
# import certificate and provisioning profile from secrets
echo -n "$CODESIGN_P12_BASE64" | base64 --decode --output $CERTIFICATE_PATH
# create temporary keychain
security create-keychain -p "$CODESIGN_TMP_KEYCHAIN_PW" $KEYCHAIN_PATH
security set-keychain-settings -lut 900 $KEYCHAIN_PATH
security unlock-keychain -p "$CODESIGN_TMP_KEYCHAIN_PW" $KEYCHAIN_PATH
# import certificate to keychain
security import $CERTIFICATE_PATH -P "$CODESIGN_P12_PW" -A -t cert -f pkcs12 -k $KEYCHAIN_PATH
security list-keychain -d user -s $KEYCHAIN_PATH
- name: Codesign
env:
CODESIGN_IDENTITY: ${{ secrets.MACOS_CODESIGN_IDENTITY }}
run: |
find Cryptomator.app/Contents/runtime/Contents/MacOS -name '*.dylib' -exec codesign --force -s ${CODESIGN_IDENTITY} {} \;
for JAR_PATH in `find Cryptomator.app -name "*.jar"`; do
if [[ `unzip -l ${JAR_PATH} | grep '.dylib\|.jnilib'` ]]; then
JAR_FILENAME=$(basename ${JAR_PATH})
OUTPUT_PATH=${JAR_PATH%.*}
echo "Codesigning libs in ${JAR_FILENAME}..."
unzip -q ${JAR_PATH} -d ${OUTPUT_PATH}
find ${OUTPUT_PATH} -name '*.dylib' -exec codesign -s ${CODESIGN_IDENTITY} {} \;
find ${OUTPUT_PATH} -name '*.jnilib' -exec codesign -s ${CODESIGN_IDENTITY} {} \;
rm ${JAR_PATH}
pushd ${OUTPUT_PATH} > /dev/null
zip -qr ../${JAR_FILENAME} *
popd > /dev/null
rm -r ${OUTPUT_PATH}
fi
done
echo "Codesigning Cryptomator.app..."
codesign --force --deep --entitlements dist/mac/Cryptomator.entitlements -o runtime -s ${CODESIGN_IDENTITY} Cryptomator.app
- name: Clean up codesign certificate
if: ${{ always() }}
run: security delete-keychain $RUNNER_TEMP/codesign.keychain-db
- name: Create app.tar
run: tar -cvf app.tar Cryptomator.app
- name: Upload mac-app
uses: actions/upload-artifact@v2
with:
name: mac-app
path: app.tar
if-no-files-found: error
#
# macOS Cryptomator.dmg
#
mac-dmg:
name: Build Cryptomator.dmg
runs-on: macos-11
needs: [mac-app, metadata]
steps:
- uses: actions/checkout@v2
- name: Download mac-appdir
uses: actions/download-artifact@v2
with:
name: mac-app
- name: Untar app.tar
run: tar -xvf app.tar
- name: Prepare .dmg contents
run: |
mkdir dmg
mv Cryptomator.app dmg
cp dist/mac/dmg/resources/macFUSE.webloc dmg
ls -l dmg
- name: Install create-dmg
run: |
brew install create-dmg
create-dmg --help
- name: Create .dmg
run: >
create-dmg
--volname Cryptomator
--volicon "dist/mac/dmg/resources/Cryptomator-Volume.icns"
--background "dist/mac/dmg/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 "dist/mac/dmg/resources/license.rtf"
--icon ".background" 128 758
--icon ".fseventsd" 320 758
--icon ".VolumeIcon.icns" 512 758
Cryptomator-${VERSION_NO}.dmg dmg
env:
VERSION_NO: ${{ needs.metadata.outputs.versionNum }}
- name: Install notarization credentials
env:
NOTARIZATION_KEYCHAIN_PROFILE: ${{ secrets.MACOS_NOTARIZATION_KEYCHAIN_PROFILE }}
NOTARIZATION_APPLE_ID: ${{ secrets.MACOS_NOTARIZATION_APPLE_ID }}
NOTARIZATION_PW: ${{ secrets.MACOS_NOTARIZATION_PW }}
NOTARIZATION_TEAM_ID: ${{ secrets.MACOS_NOTARIZATION_TEAM_ID }}
NOTARIZATION_TMP_KEYCHAIN_PW: ${{ secrets.MACOS_NOTARIZATION_TMP_KEYCHAIN_PW }}
run: |
# create temporary keychain
KEYCHAIN_PATH=$RUNNER_TEMP/notarization.keychain-db
security create-keychain -p "${NOTARIZATION_TMP_KEYCHAIN_PW}" ${KEYCHAIN_PATH}
security set-keychain-settings -lut 900 ${KEYCHAIN_PATH}
security unlock-keychain -p "${NOTARIZATION_TMP_KEYCHAIN_PW}" ${KEYCHAIN_PATH}
# import credentials from secrets
sudo xcode-select -s /Applications/Xcode_13.0.app
xcrun notarytool store-credentials "${NOTARIZATION_KEYCHAIN_PROFILE}" --apple-id "${NOTARIZATION_APPLE_ID}" --password "${NOTARIZATION_PW}" --team-id "${NOTARIZATION_TEAM_ID}" --keychain "${KEYCHAIN_PATH}"
- name: Notarize .dmg
env:
NOTARIZATION_KEYCHAIN_PROFILE: ${{ secrets.MACOS_NOTARIZATION_KEYCHAIN_PROFILE }}
run: |
KEYCHAIN_PATH=$RUNNER_TEMP/notarization.keychain-db
sudo xcode-select -s /Applications/Xcode_13.0.app
xcrun notarytool submit Cryptomator-*.dmg --keychain-profile "${NOTARIZATION_KEYCHAIN_PROFILE}" --keychain "${KEYCHAIN_PATH}" --wait
xcrun stapler staple Cryptomator-*.dmg
- name: Clean up notarization credentials
if: ${{ always() }}
run: security delete-keychain $RUNNER_TEMP/notarization.keychain-db
- name: Upload mac-dmg
uses: actions/upload-artifact@v2
with:
name: mac-dmg
path: Cryptomator-*.dmg
if-no-files-found: error
#
# MSI package
#
win-msi:
name: Build Cryptomator.msi
runs-on: windows-latest
needs: [appdir, metadata]
steps:
- uses: actions/checkout@v2
- name: Download win-appdir
uses: actions/download-artifact@v2
with:
name: win-appdir
- name: Untar appdir.tar
run: tar -xvf appdir.tar
- uses: actions/setup-java@v1
with:
java-version: ${{ env.JAVA_VERSION }}
- name: Patch Application Directory
run: |
cp dist/win/contrib/* appdir/Cryptomator
- name: Fix permissions
run: attrib -r appdir/Cryptomator/Cryptomator.exe
shell: pwsh
- name: Codesign
uses: skymatic/code-sign-action@v1
with:
certificate: ${{ secrets.WIN_CODESIGN_P12_BASE64 }}
password: ${{ secrets.WIN_CODESIGN_P12_PW }}
certificatesha1: FF52240075AD7D14AF25629FDF69635357C7D14B
description: Cryptomator
timestampUrl: 'http://timestamp.digicert.com'
folder: appdir/Cryptomator
recursive: true
- name: Create MSI
run: >
${JAVA_HOME}/bin/jpackage
--verbose
--type msi
--win-upgrade-uuid bda45523-42b1-4cae-9354-a45475ed4775
--app-image appdir/Cryptomator
--dest installer
--name Cryptomator
--vendor "Skymatic GmbH"
--copyright "(C) 2016 - 2021 Skymatic GmbH"
--app-version "${{ needs.metadata.outputs.versionNum }}"
--win-menu
--win-dir-chooser
--resource-dir dist/win/resources
--license-file dist/win/resources/license.rtf
--file-associations dist/win/resources/FAencryptedData.properties
--file-associations dist/win/resources/FAvaultFile.properties
env:
JP_WIXWIZARD_RESOURCES: ${{ github.workspace }}/dist/win/resources # requires abs path, used in resources/main.wxs
- name: Codesign MSI
uses: skymatic/code-sign-action@v1
with:
certificate: ${{ secrets.WIN_CODESIGN_P12_BASE64 }}
password: ${{ secrets.WIN_CODESIGN_P12_PW }}
certificatesha1: FF52240075AD7D14AF25629FDF69635357C7D14B
description: Cryptomator Installer
timestampUrl: 'http://timestamp.digicert.com'
folder: installer
- name: Upload win-msi
uses: actions/upload-artifact@v2
with:
name: win-msi
path: installer/*.msi
if-no-files-found: error
#
# Release
#
release:
name: Draft a release on Github
runs-on: ubuntu-latest
needs: [metadata,linux-appimage,mac-dmg,win-msi]
if: startsWith(github.ref, 'refs/tags/') && github.repository == 'cryptomator/cryptomator'
steps:
- uses: actions/checkout@v2
- name: Create tarball
run: git archive --prefix="cryptomator-${{ needs.metadata.outputs.versionStr }}/" -o "cryptomator-${{ needs.metadata.outputs.versionStr }}.tar.gz" ${{ github.ref }}
- name: Download linux appimage
uses: actions/download-artifact@v2
with:
name: linux-appimage
- name: Download macOS dmg
uses: actions/download-artifact@v2
with:
name: mac-dmg
- name: Download Windows msi
uses: actions/download-artifact@v2
with:
name: win-msi
- name: Create detached GPG signature for all release files with key 615D449FE6E6A235
run: |
echo "${GPG_PRIVATE_KEY}" | gpg --batch --quiet --import
for FILE in `find . -name "*.AppImage" -o -name "*.dmg" -o -name "*.msi" -o -name "*.zsync" -o -name "*.tar.gz"`; do
echo "${GPG_PASSPHRASE}" | gpg --batch --quiet --passphrase-fd 0 --pinentry-mode loopback -u 615D449FE6E6A235 --detach-sign -a ${FILE}
done
env:
GPG_PRIVATE_KEY: ${{ secrets.RELEASES_GPG_PRIVATE_KEY }}
GPG_PASSPHRASE: ${{ secrets.RELEASES_GPG_PASSPHRASE }}
- name: Create release draft
uses: softprops/action-gh-release@v1
with:
draft: true
fail_on_unmatched_files: true
discussion_category_name: releases
token: ${{ secrets.CRYPTOBOT_RELEASE_TOKEN }}
files: |
*.AppImage
*.zsync
*.asc
*.dmg
*.msi
body: |
:construction: Work in Progress
## What's new
## Bugfixes
## Misc
---
:scroll: A complete list of closed issues is available [here](LINK)

View File

@@ -1,37 +0,0 @@
name: Bug Report Triage
on:
issues:
types: [opened]
jobs:
closeTemplateViolation:
name: Validate bug report against issue template
runs-on: ubuntu-latest
if: contains(github.event.issue.labels.*.name, 'type:bug')
steps:
- name: Check "Description"
if: |
!contains(github.event.issue.body, env.MUST_CONTAIN)
|| contains(toJson(github.event.issue.body), env.MUST_NOT_CONTAIN)
run: exit 1
env:
MUST_CONTAIN: '### Description'
MUST_NOT_CONTAIN: '### Description\r\n\r\n[Summarize your problem.]\r\n\r\n### System Setup'
- name: Check "Steps to Reproduce"
if: |
!contains(github.event.issue.body, env.MUST_CONTAIN)
|| contains(toJson(github.event.issue.body), env.MUST_NOT_CONTAIN)
run: exit 1
env:
MUST_CONTAIN: '### Steps to Reproduce'
MUST_NOT_CONTAIN: '### Steps to Reproduce\r\n\r\n1. [First step]\r\n2. [Second step]\r\n3. [and so on…]\r\n\r\n#### Expected Behavior'
- name: Close issue if one of the checks failed
if: ${{ failure() }}
uses: peter-evans/close-issue@v1
with:
comment: |
This bug report did ignore our issue template. 😞
Auto-closing this issue, since it is most likely not useful.
_This decision was made by a bot. If you think the bot is wrong, let us know and we'll reopen this issue._

4
.gitignore vendored
View File

@@ -17,7 +17,9 @@ pom.xml.versionsBackup
# IntelliJ Settings Files (https://intellij-support.jetbrains.com/hc/en-us/articles/206544839-How-to-manage-projects-under-Version-Control-Systems) #
.idea/**/workspace.xml
.idea/**/tasks.xml
.idea/dictionaries
.idea/**/shelf
.idea/dictionaries/**
!.idea/dictionaries/dict_*
.idea/compiler.xml
.idea/encodings.xml
.idea/jarRepositories.xml

15
.idea/dictionaries/dict_de.xml generated Normal file
View File

@@ -0,0 +1,15 @@
<component name="ProjectDictionaryState">
<dictionary name="dict_de">
<words>
<w>tresorinhalt</w>
<w>tresorkonfigurationsdatei</w>
<w>tresorlaufwerk</w>
<w>tresorliste</w>
<w>tresorname</w>
<w>tresoroptionen</w>
<w>tresorstatistik</w>
<w>ungespeicherten</w>
<w>ungespeicherter</w>
</words>
</dictionary>
</component>

106
.idea/dictionaries/dict_project.xml generated Normal file
View File

@@ -0,0 +1,106 @@
<component name="ProjectDictionaryState">
<dictionary name="dict_project">
<words>
<w>addvault</w>
<w>addvaultwizard</w>
<w>adoptopenjdk</w>
<w>affero</w>
<w>aquafx</w>
<w>autolock</w>
<w>autolocked</w>
<w>autolocking</w>
<w>baos</w>
<w>bkup</w>
<w>buildkit</w>
<w>changepassword</w>
<w>checkerframework</w>
<w>crit</w>
<w>crowdin</w>
<w>cryptofs</w>
<w>cryptomator</w>
<w>cryptomator's</w>
<w>cryptor</w>
<w>csprng</w>
<w>dcryptomator</w>
<w>dfuse</w>
<w>dirid</w>
<w>djdk</w>
<w>dokany</w>
<w>dragboard</w>
<w>easybind</w>
<w>encr</w>
<w>errorprone</w>
<w>failureaccess</w>
<w>fbidis</w>
<w>fldinst</w>
<w>fldrslt</w>
<w>fontawesomefx</w>
<w>gdrive</w>
<w>gvfs</w>
<w>hmmss</w>
<w>httpcomponents</w>
<w>httpcore</w>
<w>iclouddrive</w>
<w>jensd</w>
<w>jffi</w>
<w>keyloading</w>
<w>kibs</w>
<w>listcell</w>
<w>listenablefuture</w>
<w>lopp</w>
<w>mainwindow</w>
<w>masterkey</w>
<w>masterkeyfile</w>
<w>mibs</w>
<w>mountpath</w>
<w>mpc's</w>
<w>needsmigration</w>
<w>noncommercially</w>
<w>noël</w>
<w>nulab</w>
<w>oatomic</w>
<w>oauto</w>
<w>objectgraph</w>
<w>odefault</w>
<w>ogid</w>
<w>onoappledouble</w>
<w>ordonly</w>
<w>ouid</w>
<w>ovolname</w>
<w>passthrough</w>
<w>patreon</w>
<w>pcloud</w>
<w>probot</w>
<w>recoverykey</w>
<w>relicensing</w>
<w>removevault</w>
<w>revealer</w>
<w>serceman</w>
<w>setolabs</w>
<w>skymatic</w>
<w>socio</w>
<w>spof</w>
<w>stenzel</w>
<w>styleclass</w>
<w>sublicenses</w>
<w>sublicensing</w>
<w>systemkeychain</w>
<w>tada</w>
<w>tidelift</w>
<w>tmpmountpoint</w>
<w>tobiasdiez</w>
<w>toggler</w>
<w>traymenu</w>
<w>unknownerror</w>
<w>unlockable</w>
<w>vaultconfig</w>
<w>vaultlist</w>
<w>vaultname</w>
<w>vaultoptions</w>
<w>wrongfilealert</w>
<w>xattr</w>
<w>zillmann</w>
<w>zxcvbn</w>
</words>
</dictionary>
</component>

View File

@@ -1,7 +1,7 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="SpellCheckingInspection" enabled="false" level="TYPO" enabled_by_default="false">
<inspection_tool class="SpellCheckingInspection" enabled="true" level="TYPO" enabled_by_default="true">
<option name="processCode" value="true" />
<option name="processLiterals" value="true" />
<option name="processComments" value="true" />

View File

@@ -2,7 +2,7 @@
<configuration default="false" name="Cryptomator Linux" type="Application" factoryName="Application">
<option name="MAIN_CLASS_NAME" value="org.cryptomator.launcher.Cryptomator" />
<module name="cryptomator" />
<option name="VM_PARAMETERS" value="-Djdk.gtk.version=2 -Duser.language=en -Dcryptomator.settingsPath=&quot;~/.config/Cryptomator/settings.json&quot; -Dcryptomator.ipcPortPath=&quot;~/.config/Cryptomator/ipcPort.bin&quot; -Dcryptomator.logDir=&quot;~/.local/share/Cryptomator/logs&quot; -Dcryptomator.mountPointsDir=&quot;~/.local/share/Cryptomator/mnt&quot; -Dcryptomator.showTrayIcon=true -Xss20m -Xmx512m" />
<option name="VM_PARAMETERS" value="-Djdk.gtk.version=2 -Duser.language=en -Dcryptomator.settingsPath=&quot;~/.config/Cryptomator/settings.json&quot; -Dcryptomator.ipcSocketPath=&quot;~/.config/Cryptomator/ipc.socket&quot; -Dcryptomator.logDir=&quot;~/.local/share/Cryptomator/logs&quot; -Dcryptomator.mountPointsDir=&quot;~/.local/share/Cryptomator/mnt&quot; -Dcryptomator.showTrayIcon=true -Xss20m -Xmx512m" />
<method v="2">
<option name="Make" enabled="true" />
</method>

View File

@@ -2,7 +2,7 @@
<configuration default="false" name="Cryptomator Linux Dev" type="Application" factoryName="Application">
<option name="MAIN_CLASS_NAME" value="org.cryptomator.launcher.Cryptomator" />
<module name="cryptomator" />
<option name="VM_PARAMETERS" value="-Djdk.gtk.version=2 -Duser.language=en -Dcryptomator.settingsPath=&quot;~/.config/Cryptomator-Dev/settings.json&quot; -Dcryptomator.ipcPortPath=&quot;~/.config/Cryptomator-Dev/ipcPort.bin&quot; -Dcryptomator.logDir=&quot;~/.local/share/Cryptomator-Dev/logs&quot; -Dcryptomator.mountPointsDir=&quot;~/.local/share/Cryptomator-Dev/mnt&quot; -Dcryptomator.showTrayIcon=true -Dfuse.experimental=&quot;true&quot; -Xss20m -Xmx512m" />
<option name="VM_PARAMETERS" value="-Djdk.gtk.version=2 -Duser.language=en -Dcryptomator.settingsPath=&quot;~/.config/Cryptomator-Dev/settings.json&quot; -Dcryptomator.ipcSocketPath=&quot;~/.config/Cryptomator-Dev/ipc.socket&quot; -Dcryptomator.logDir=&quot;~/.local/share/Cryptomator-Dev/logs&quot; -Dcryptomator.mountPointsDir=&quot;~/.local/share/Cryptomator-Dev/mnt&quot; -Dcryptomator.showTrayIcon=true -Dfuse.experimental=&quot;true&quot; -Xss20m -Xmx512m" />
<method v="2">
<option name="Make" enabled="true" />
</method>

View File

@@ -2,7 +2,7 @@
<configuration default="false" name="Cryptomator Windows" type="Application" factoryName="Application">
<option name="MAIN_CLASS_NAME" value="org.cryptomator.launcher.Cryptomator" />
<module name="cryptomator" />
<option name="VM_PARAMETERS" value="-Duser.language=en -Dcryptomator.settingsPath=&quot;~/AppData/Roaming/Cryptomator/settings.json&quot; -Dcryptomator.ipcPortPath=&quot;~/AppData/Roaming/Cryptomator/ipcPort.bin&quot; -Dcryptomator.logDir=&quot;~/AppData/Roaming/Cryptomator&quot; -Dcryptomator.keychainPath=&quot;~/AppData/Roaming/Cryptomator/keychain.json&quot; -Dcryptomator.mountPointsDir=&quot;~/Cryptomator&quot; -Dcryptomator.showTrayIcon=true -Xss2m -Xmx512m" />
<option name="VM_PARAMETERS" value="-Duser.language=en -Dcryptomator.settingsPath=&quot;~/AppData/Roaming/Cryptomator/settings.json&quot; -Dcryptomator.ipcSocketPath=&quot;~/AppData/Roaming/Cryptomator/ipc.socket&quot; -Dcryptomator.logDir=&quot;~/AppData/Roaming/Cryptomator&quot; -Dcryptomator.keychainPath=&quot;~/AppData/Roaming/Cryptomator/keychain.json&quot; -Dcryptomator.mountPointsDir=&quot;~/Cryptomator&quot; -Dcryptomator.showTrayIcon=true -Xss2m -Xmx512m" />
<method v="2">
<option name="Make" enabled="true" />
</method>

View File

@@ -2,7 +2,7 @@
<configuration default="false" name="Cryptomator Windows Dev" type="Application" factoryName="Application">
<option name="MAIN_CLASS_NAME" value="org.cryptomator.launcher.Cryptomator" />
<module name="cryptomator" />
<option name="VM_PARAMETERS" value="-Duser.language=en -Dcryptomator.settingsPath=&quot;~/AppData/Roaming/Cryptomator-Dev/settings.json&quot; -Dcryptomator.ipcPortPath=&quot;~/AppData/Roaming/Cryptomator-Dev/ipcPort.bin&quot; -Dcryptomator.logDir=&quot;~/AppData/Roaming/Cryptomator-Dev&quot; -Dcryptomator.keychainPath=&quot;~/AppData/Roaming/Cryptomator-Dev/keychain.json&quot; -Dcryptomator.mountPointsDir=&quot;~/Cryptomator-Dev&quot; -Dfuse.experimental=&quot;true&quot; -Dcryptomator.showTrayIcon=true -Xss2m -Xmx512m" />
<option name="VM_PARAMETERS" value="-Duser.language=en -Dcryptomator.settingsPath=&quot;~/AppData/Roaming/Cryptomator-Dev/settings.json&quot; -Dcryptomator.ipcSocketPath=&quot;~/AppData/Roaming/Cryptomator-Dev/ipc.socket&quot; -Dcryptomator.logDir=&quot;~/AppData/Roaming/Cryptomator-Dev&quot; -Dcryptomator.keychainPath=&quot;~/AppData/Roaming/Cryptomator-Dev/keychain.json&quot; -Dcryptomator.mountPointsDir=&quot;~/Cryptomator-Dev&quot; -Dfuse.experimental=&quot;true&quot; -Dcryptomator.showTrayIcon=true -Xss2m -Xmx512m" />
<method v="2">
<option name="Make" enabled="true" />
</method>

View File

@@ -5,7 +5,7 @@
</envs>
<option name="MAIN_CLASS_NAME" value="org.cryptomator.launcher.Cryptomator" />
<module name="cryptomator" />
<option name="VM_PARAMETERS" value="-Duser.language=en -Dcryptomator.settingsPath=&quot;~/Library/Application Support/Cryptomator/settings.json&quot; -Dcryptomator.ipcPortPath=&quot;~/Library/Application Support/Cryptomator/ipcPort.bin&quot; -Dcryptomator.logDir=&quot;~/Library/Logs/Cryptomator&quot; -Dcryptomator.showTrayIcon=true -Xss2m -Xmx512m -ea" />
<option name="VM_PARAMETERS" value="-Duser.language=en -Dcryptomator.settingsPath=&quot;~/Library/Application Support/Cryptomator/settings.json&quot; -Dcryptomator.ipcSocketPath=&quot;~/Library/Application Support/Cryptomator/ipc.socket&quot; -Dcryptomator.logDir=&quot;~/Library/Logs/Cryptomator&quot; -Dcryptomator.showTrayIcon=true -Xss2m -Xmx512m -ea" />
<method v="2">
<option name="Make" enabled="true" />
</method>

View File

@@ -5,7 +5,7 @@
</envs>
<option name="MAIN_CLASS_NAME" value="org.cryptomator.launcher.Cryptomator" />
<module name="cryptomator" />
<option name="VM_PARAMETERS" value="-Duser.language=en -Dcryptomator.settingsPath=&quot;~/Library/Application Support/Cryptomator-Dev/settings.json&quot; -Dcryptomator.ipcPortPath=&quot;~/Library/Application Support/Cryptomator-Dev/ipcPort.bin&quot; -Dcryptomator.logDir=&quot;~/Library/Logs/Cryptomator-Dev&quot; -Dcryptomator.showTrayIcon=true -Xss2m -Xmx512m -ea" />
<option name="VM_PARAMETERS" value="-Duser.language=en -Dcryptomator.settingsPath=&quot;~/Library/Application Support/Cryptomator-Dev/settings.json&quot; -Dcryptomator.ipcSocketPath=&quot;~/Library/Application Support/Cryptomator-Dev/ipc.socket&quot; -Dcryptomator.logDir=&quot;~/Library/Logs/Cryptomator-Dev&quot; -Dcryptomator.showTrayIcon=true -Xss2m -Xmx512m -ea" />
<method v="2">
<option name="Make" enabled="true" />
</method>

View File

@@ -1,7 +1,7 @@
[![cryptomator](cryptomator.png)](https://cryptomator.org/)
[![Build](https://github.com/cryptomator/cryptomator/workflows/Build/badge.svg)](https://github.com/cryptomator/cryptomator/actions?query=workflow%3ABuild)
[![Known Vulnerabilities](https://snyk.io/test/github/cryptomator/cryptomator/badge.svg?targetFile=main%2Fpom.xml)](https://snyk.io/test/github/cryptomator/cryptomator?targetFile=main%2Fpom.xml)
[![Known Vulnerabilities](https://snyk.io/test/github/cryptomator/cryptomator/badge.svg)](https://snyk.io/test/github/cryptomator/cryptomator)
[![Codacy Badge](https://app.codacy.com/project/badge/Grade/2a0adf3cec6a4143b91035d3924178f1)](https://www.codacy.com/gh/cryptomator/cryptomator/dashboard)
[![Twitter](https://img.shields.io/badge/twitter-@Cryptomator-blue.svg?style=flat)](http://twitter.com/Cryptomator)
[![Crowdin](https://badges.crowdin.net/cryptomator/localized.svg)](https://translate.cryptomator.org/)
@@ -28,14 +28,6 @@ Cryptomator is provided free of charge as an open-source project despite the hig
### Silver Sponsors
<table>
<tbody>
<tr>
<td><a href="https://thebestvpn.com/"><img src="https://cryptomator.org/img/sponsors/thebestvpn@2x.png" alt="TheBestVPN" height="64"></a></td>
</tr>
</tbody>
</table>
- [Jameson Lopp](https://www.lopp.net/)
---
@@ -56,7 +48,7 @@ Download native binaries of Cryptomator on [cryptomator.org](https://cryptomator
- File names get encrypted
- Folder structure gets obfuscated
- Use as many vaults in your Dropbox as you want, each having individual passwords
- Two thousand commits for the security of your data!! :tada:
- Three thousand commits for the security of your data!! :tada:
### Privacy
@@ -87,7 +79,6 @@ For more information on the security details visit [cryptomator.org](https://doc
### Run Maven
```
cd main
mvn clean install
# or mvn clean install -Pwindows
# or mvn clean install -Pmac

View File

@@ -1,47 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<assembly xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/ASSEMBLY/2.0.0"
xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.0.0 http://maven.apache.org/xsd/assembly-2.0.0.xsd">
<id>tarball</id>
<includeBaseDirectory>false</includeBaseDirectory>
<formats>
<format>zip</format>
</formats>
<fileSets>
<fileSet>
<directory>target/</directory>
<includes>
<include>version.txt</include>
</includes>
<outputDirectory>libs</outputDirectory>
</fileSet>
<fileSet>
<directory>target/</directory>
<includes>
<include>LICENSE.txt</include>
</includes>
<outputDirectory></outputDirectory>
</fileSet>
<fileSet>
<directory>target/</directory>
<includes>
<include>launcher-linux.sh</include>
</includes>
<outputDirectory></outputDirectory>
<fileMode>0755</fileMode>
</fileSet>
<fileSet>
<directory>target/</directory>
<includes>
<include>cryptomator-*.jar</include>
</includes>
<outputDirectory>libs</outputDirectory>
</fileSet>
<fileSet>
<directory>target/libs</directory>
<includes>
<include>*.jar</include>
</includes>
<outputDirectory>libs</outputDirectory>
</fileSet>
</fileSets>
</assembly>

View File

@@ -1,47 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<assembly xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/ASSEMBLY/2.0.0"
xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.0.0 http://maven.apache.org/xsd/assembly-2.0.0.xsd">
<id>tarball</id>
<includeBaseDirectory>false</includeBaseDirectory>
<formats>
<format>zip</format>
</formats>
<fileSets>
<fileSet>
<directory>target/</directory>
<includes>
<include>version.txt</include>
</includes>
<outputDirectory>libs</outputDirectory>
</fileSet>
<fileSet>
<directory>target/</directory>
<includes>
<include>LICENSE.txt</include>
</includes>
<outputDirectory></outputDirectory>
</fileSet>
<fileSet>
<directory>target/</directory>
<includes>
<include>launcher-mac.sh</include>
</includes>
<outputDirectory></outputDirectory>
<fileMode>0755</fileMode>
</fileSet>
<fileSet>
<directory>target/</directory>
<includes>
<include>cryptomator-*.jar</include>
</includes>
<outputDirectory>libs</outputDirectory>
</fileSet>
<fileSet>
<directory>target/libs</directory>
<includes>
<include>*.jar</include>
</includes>
<outputDirectory>libs</outputDirectory>
</fileSet>
</fileSets>
</assembly>

View File

@@ -1,47 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<assembly xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/ASSEMBLY/2.0.0"
xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.0.0 http://maven.apache.org/xsd/assembly-2.0.0.xsd">
<id>tarball</id>
<includeBaseDirectory>false</includeBaseDirectory>
<formats>
<format>zip</format>
</formats>
<fileSets>
<fileSet>
<directory>target/</directory>
<includes>
<include>version.txt</include>
</includes>
<outputDirectory>libs</outputDirectory>
</fileSet>
<fileSet>
<directory>target/</directory>
<includes>
<include>LICENSE.txt</include>
</includes>
<outputDirectory></outputDirectory>
</fileSet>
<fileSet>
<directory>target/</directory>
<includes>
<include>launcher-win.bat</include>
</includes>
<outputDirectory></outputDirectory>
<fileMode>0755</fileMode>
</fileSet>
<fileSet>
<directory>target/</directory>
<includes>
<include>cryptomator-*.jar</include>
</includes>
<outputDirectory>libs</outputDirectory>
</fileSet>
<fileSet>
<directory>target/libs</directory>
<includes>
<include>*.jar</include>
</includes>
<outputDirectory>libs</outputDirectory>
</fileSet>
</fileSets>
</assembly>

4
dist/linux/appimage/.gitignore vendored Normal file
View File

@@ -0,0 +1,4 @@
# created during build
Cryptomator.AppDir
*.AppImage
*.AppImage.zsync

73
dist/linux/appimage/build.sh vendored Executable file
View File

@@ -0,0 +1,73 @@
#!/bin/bash
cd $(dirname $0)
REVISION_NO=`git rev-list --count HEAD`
# 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 curl >/dev/null 2>&1 || { echo >&2 "curl not found."; exit 1; }
# compile
mvn -B -f../../pom.xml clean package -DskipTests -Plinux
# add runtime
${JAVA_HOME}/bin/jlink \
--output runtime \
--module-path "${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
${JAVA_HOME}/bin/jpackage \
--verbose \
--type app-image \
--runtime-image runtime \
--input buildkit/libs \
--module-path buildkit/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" \
--app-version "${{ needs.metadata.outputs.versionNum }}.${{ needs.metadata.outputs.revNum }}" \
--java-options "-Dfile.encoding=\"utf-8\"" \
--java-options "-Dcryptomator.logDir=\"~/.local/share/Cryptomator/logs\"" \
--java-options "-Dcryptomator.settingsPath=\"~/.config/Cryptomator/settings.json:~/.Cryptomator/settings.json\"" \
--java-options "-Dcryptomator.ipcSocketPath=\"~/.config/Cryptomator/ipc.socket\"" \
--java-options "-Dcryptomator.mountPointsDir=\"~/.local/share/Cryptomator/mnt\"" \
--java-options "-Dcryptomator.showTrayIcon=false" \
--java-options "-Dcryptomator.buildNumber=\"appimage-${{ needs.metadata.outputs.revNum }}\"" \
--resource-dir ../resources
# transform AppDir
mv Cryptomator Cryptomator.AppDir
cp -r dist/linux/appimage/resources/AppDir/* Cryptomator.AppDir/
chmod +x Cryptomator.AppDir/lib/runtime/bin/java
envsubst '${REVISION_NO}' < resources/AppDir/bin/cryptomator.sh > Cryptomator.AppDir/bin/cryptomator.sh
ln -s usr/share/icons/hicolor/scalable/apps/org.cryptomator.Cryptomator.svg Cryptomator.AppDir/org.cryptomator.Cryptomator.svg
ln -s usr/share/icons/hicolor/scalable/apps/org.cryptomator.Cryptomator.svg Cryptomator.AppDir/Cryptomator.svg
ln -s usr/share/icons/hicolor/scalable/apps/org.cryptomator.Cryptomator.svg Cryptomator.AppDir/.DirIcon
ln -s usr/share/applications/org.cryptomator.Cryptomator.desktop Cryptomator.AppDir/Cryptomator.desktop
ln -s bin/cryptomator.sh Cryptomator.AppDir/AppRun
# extract jffi
JFFI_NATIVE_JAR=`ls Cryptomator.AppDir/lib/app | grep -e 'jffi-[1-9]\.[0-9]\{1,2\}.[0-9]\{1,2\}-native.jar'`
${JAVA_HOME}/bin/jar -xf Cryptomator.AppDir/lib/app/${JFFI_NATIVE_JAR} /jni/x86_64-Linux/
mv jni/x86_64-Linux/* Cryptomator.AppDir/lib/app/libjffi.so
rm -r jni/x86_64-Linux
# load AppImageTool
curl -L https://github.com/AppImage/AppImageKit/releases/download/13/appimagetool-x86_64.AppImage -o /tmp/appimagetool.AppImage
chmod +x /tmp/appimagetool.AppImage
# create AppImage
/tmp/appimagetool.AppImage \
Cryptomator.AppDir \
cryptomator-SNAPSHOT-x86_64.AppImage \
-u 'gh-releases-zsync|cryptomator|cryptomator|latest|cryptomator-*-x86_64.AppImage.zsync'

View File

@@ -0,0 +1,37 @@
#!/bin/sh
cd $(dirname $0)
# determine GTK version
GTK2_PRESENT=1 # initially false
GTK3_PRESENT=0 # initially true
if command -v dpkg &> /dev/null; then # do stuff for debian based things
GTK2_PRESENT=`dpkg -l libgtk* | grep -e '\^ii' | grep -e 'libgtk2-*' &> /dev/null; echo $?`
GTK3_PRESENT=`dpkg -l libgtk* | grep -e '\^ii' | grep -e 'libgtk-3-*' &> /dev/null; echo $?`
elif command -v rpm &> /dev/null; then # do stuff for rpm based things (including yum/dnf)
GTK2_PRESENT=`rpm -qa | grep -e '\^gtk2-[0-9][0-9]*' &> /dev/null; echo $?`
GTK3_PRESENT=`rpm -qa | grep -e '\^gtk3-[0-9][0-9]*' &> /dev/null; echo $?`
elif command -v pacman &> /dev/null; then # don't forget arch
GTK2_PRESENT=`pacman -Qi gtk2 &> /dev/null; echo $?`
GTK3_PRESENT=`pacman -Qi gtk3 &> /dev/null; echo $?`
fi
if [ "$GTK2_PRESENT" -eq 0 ] && [ "$GTK3_PRESENT" -ne 0 ]; then
GTK_FLAG="-Djdk.gtk.version=2"
fi
# workaround for https://github.com/cryptomator/cryptomator-linux/issues/27
export LD_PRELOAD=lib/app/libjffi.so
# start Cryptomator
./lib/runtime/bin/java \
-p "lib/app/mods" \
-cp "lib/app/*" \
-Dcryptomator.logDir="~/.local/share/Cryptomator/logs" \
-Dcryptomator.mountPointsDir="~/.local/share/Cryptomator/mnt" \
-Dcryptomator.settingsPath="~/.config/Cryptomator/settings.json:~/.Cryptomator/settings.json" \
-Dcryptomator.ipcSocketPath="~/.config/Cryptomator/ipc.socket" \
-Dcryptomator.buildNumber="appimage-${REVISION_NO}" \
$GTK_FLAG \
-Xss2m \
-Xmx512m \
-m org.cryptomator.desktop/org.cryptomator.launcher.Cryptomator

View File

@@ -0,0 +1,10 @@
[Desktop Entry]
Name=Cryptomator
Comment=Cloud Storage Encryption Utility
Exec=cryptomator %F
Icon=org.cryptomator.Cryptomator
Terminal=false
Type=Application
Categories=Utility;Security;FileTools;
StartupWMClass=org.cryptomator.launcher.Cryptomator
MimeType=application/vnd.cryptomator.encrypted;application/x-vnd.cryptomator.vault-metadata;

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

View File

@@ -0,0 +1 @@
<svg width="512" height="512" viewBox="0 0 512 512" preserveAspectRatio="xMidYMid meet" xmlns="http://www.w3.org/2000/svg"><path d="m255.4 42.2c-76.9 0-119.4 65.3-119.4 129h238.7c.1-63.8-47.9-129-119.3-129z" fill="#cfcfcf"/><path d="m255.4 66.4c-62.5 0-97 53-97 104.8l97 11 97-11c0-51.8-39-104.8-97-104.8z" fill="#585e62"/><path d="m44.8 378.5c-5 0-9.1-4.1-9.1-9.1 0-4.6 3.5-8.6 8.1-9.1 10.7-1.2 18.4-10.8 17.2-21.5s-10.8-18.4-21.5-17.2-18.4 10.8-17.2 21.5c.3 2.5 1.1 5 2.3 7.3 2.3 4.5.5 10-4 12.2-4.3 2.1-9.4.6-11.9-3.4-10.1-18.2-3.4-41.1 14.8-51.2s41.1-3.4 51.2 14.8 3.4 41.2-14.8 51.2c-4.3 2.4-9.1 3.9-14 4.5-.4 0-.7 0-1.1 0z" fill="#585e62"/><path d="m82.6 258 2.4 1.2c11.1 5.7 15.4 19.2 9.8 30.2l-9.4 18.4c-5.7 11.1-19.2 15.4-30.2 9.8l-2.4-1.2c-11.1-5.7-15.4-19.2-9.8-30.2l9.4-18.4c5.6-11 19.2-15.4 30.2-9.8z" fill="#cfcfcf"/><path d="m86.6 221.3 25.4 13-19.6 38.3c-3.6 7-12.2 9.8-19.2 6.2-7-3.6-9.8-12.2-6.2-19.2z" fill="#585e62"/><circle cx="105.2" cy="218.4" fill="#cfcfcf" r="34.1"/><path d="m121.4 188.5c-13.7-7.6-30.8-4.8-41.5 6.7 18.8.9 33.4 16.8 32.5 35.7-.4 8.1-3.6 15.8-9.1 21.7 18.8.8 34.8-13.7 35.6-32.6.7-13-6.1-25.2-17.5-31.5z" fill="#b1b1b1"/><path d="m467.2 378.5c-.3 0-.7 0-1-.1-20.7-2.3-35.5-21-33.2-41.6 2.3-20.7 21-35.5 41.6-33.2 20.7 2.3 35.5 21 33.2 41.6-.6 4.9-2.1 9.7-4.5 14-2.3 4.5-7.7 6.3-12.2 4s-6.3-7.7-4-12.2c.1-.2.2-.4.3-.6 5.2-9.4 1.8-21.3-7.6-26.5s-21.3-1.8-26.5 7.6-1.8 21.3 7.6 26.5c2.2 1.2 4.7 2 7.2 2.3 5 .5 8.6 5 8 10-.4 4.8-4.3 8.3-8.9 8.2z" fill="#585e62"/><path d="m459.3 316.4-2.4 1.2c-11.1 5.7-24.6 1.3-30.2-9.8l-9.4-18.4c-5.7-11.1-1.3-24.6 9.8-30.2l2.4-1.2c11.1-5.7 24.6-1.3 30.2 9.8l9.4 18.4c5.6 11 1.2 24.6-9.8 30.2z" fill="#cfcfcf"/><path d="m438.8 278.9c-7 3.6-15.6.8-19.2-6.2l-19.6-38.3 25.4-13 19.6 38.3c3.6 7 .8 15.6-6.2 19.2z" fill="#585e62"/><circle cx="406.8" cy="218.4" fill="#cfcfcf" r="34.1"/><path d="m390.6 188.5c13.7-7.6 30.8-4.8 41.5 6.7-18.8.9-33.4 16.8-32.5 35.7.4 8.1 3.6 15.7 9.1 21.7-18.8.9-34.8-13.7-35.7-32.5-.6-13.1 6.2-25.3 17.6-31.6z" fill="#b1b1b1"/><path d="m117.2 469.8c-16.7 0-30.5-18.1-34.3-45.1-2.1-14.5-1-29.7 2.9-42.8 4.3-14.1 11.6-24.4 20.6-29 3.3-1.7 7-2.6 10.8-2.7h47.1v119.5z" fill="#585e62"/><path d="m163.8 469.8c-9.7 0-17.7-18.1-19.9-45.1-1.2-14.5-.6-29.7 1.7-42.8 2.5-14.1 6.7-24.4 11.9-29 2-1.8 4.1-2.7 6.2-2.7 2.2 0 4.2.9 6.3 2.6l22.6 19.9c7.9 7 10.6 29.1 9.2 46.4-1.1 13.3-4.5 23.7-9.2 27.9l-22.6 19.9c-1.9 2-4 2.9-6.2 2.9z" fill="#585e62"/><path d="m168 360.1 22.6 19.9c5.1 4.5 8.1 21.6 6.7 38.2-.9 11-3.6 19.1-6.7 21.9l-22.6 19.9c-8.5 7.5-17.2-8.8-19.5-36.4s2.7-56 11.2-63.5c2.8-2.4 5.7-2.3 8.3 0z" fill="#35393b"/><path d="m390.9 469.8c16.7 0 30.5-18.1 34.3-45.1 2.1-14.5 1-29.7-2.9-42.8-4.3-14.1-11.6-24.4-20.6-29-3.3-1.7-7-2.6-10.8-2.7h-47.1v119.5z" fill="#585e62"/><path d="m344.3 469.8c9.7 0 17.7-18.1 19.9-45.1 1.2-14.5.6-29.7-1.7-42.8-2.5-14.1-6.7-24.4-11.9-29-2-1.8-4.1-2.7-6.2-2.7s-4.2.9-6.3 2.6l-22.6 19.9c-7.9 7-10.6 29.1-9.2 46.4 1.1 13.3 4.5 23.7 9.2 27.9l22.6 19.9c1.9 2 4 2.9 6.2 2.9z" fill="#585e62"/><path d="m340.1 360.1-22.6 19.9c-5.1 4.5-8.1 21.6-6.7 38.1.9 11 3.6 19.1 6.7 21.9l22.6 19.9c8.5 7.5 17.2-8.8 19.5-36.4s-2.7-56-11.2-63.5c-2.8-2.3-5.7-2.2-8.3.1z" fill="#35393b"/><path d="m390 247.5c-2-6.8-2.1-13.9-.3-20.7 6.7-24.2 2.3-50.8 2.3-50.8-84.2-26.3-136.5-.2-136.5-.2s-52.2-26.2-136.5-.2c0 0-4.5 26.7 2.1 50.9 1.8 6.8 1.7 14-.3 20.7-2.3 8-4.9 20.2-4.9 35.8-.2 113.3 139.2 148.3 139.2 148.3s139.4-34.6 139.6-147.9c.1-15.7-2.4-27.9-4.7-35.9z" fill="#cfcfcf"/><path d="m255.2 410.1c-23.1-7.2-119-42.4-118.9-127.1 0-13.5 2.2-23.8 4.1-30.2 3.1-10.4 3.2-21.4.4-31.8-2.8-10.3-3.1-21.4-2.8-29.7 18.4-4.7 36.5-7 53.9-7 34.4.1 54.5 9.6 54.7 9.6l9.3 4.7 8.8-4.7c.1 0 20.2-9.4 54.6-9.4 17.4 0 35.4 2.4 53.8 7.1.3 8.3 0 19.4-2.9 29.7-2.8 10.4-2.7 21.5.3 31.8 1.8 6.3 4 16.7 4 30.2-.2 85.1-96.1 119.7-119.3 126.8z" fill="#49b04a"/><path d="m281.5 259.9c0-14.4-11.6-26.2-26.1-26.2s-26.2 11.6-26.2 26.1c0 12.2 8.4 22.8 20.4 25.5l-14.7 61.7 20.3 5.8 20.3-5.8-14.5-61.7c12-2.6 20.5-13.1 20.5-25.4z" fill="#35393b"/><g fill="#49b04a"><path d="m210.9 101.8c-15.2 0-27.6 12.3-27.6 27.6h55.2c0-15.2-12.3-27.6-27.6-27.6z"/><path d="m296.2 101.8c-15.2 0-27.6 12.3-27.6 27.6h55.2c0-15.2-12.4-27.6-27.6-27.6z"/><circle cx="223.8" cy="146.5" r="5.2"/><circle cx="244.4" cy="146.5" r="5.2"/><circle cx="265" cy="146.5" r="5.2"/><circle cx="285.6" cy="146.5" r="5.2"/></g></svg>

After

Width:  |  Height:  |  Size: 4.3 KiB

View File

@@ -0,0 +1,69 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Copyright 2018 Armin Schrenk <armin.schrenk@zoho.eu> -->
<component type="desktop-application">
<id>org.cryptomator.Cryptomator</id>
<metadata_license>FSFAP</metadata_license>
<project_license>GPL-3.0-or-later</project_license>
<name>Cryptomator</name>
<summary>Multi-platform client-side encryption tool optimized for cloud storages</summary>
<description>
<p>
Cryptomator offers multi-platform transparent client-side encryption of your files in the cloud.
</p>
<p>
Features:
<ul>
<li>Works with Dropbox, Google Drive, OneDrive, ownCloud, Nextcloud and any other cloud storage service which synchronizes with a local directory</li>
<li>Open Source means: No backdoors, control is better than trust</li>
<li>Client-side: No accounts, no data shared with any online service</li>
<li>Totally transparent: Just work on the virtual drive as if it were a USB flash drive</li>
<li>AES encryption with 256-bit key length</li>
<li>File names get encrypted</li>
<li>Folder structure gets obfuscated</li>
<li>Use as many vaults in your Dropbox as you want, each having individual passwords</li>
<li>One thousand commits for the security of your data!! :tada:</li>
</ul>
</p>
<p>
Privacy:
<ul>
<li>256-bit keys (unlimited strength policy bundled with native binaries)</li>
<li>Scrypt key derivation</li>
<li>Cryptographically secure random numbers for salts, IVs and the masterkey of course</li>
<li>Sensitive data is wiped from the heap asap</li>
<li>Lightweight: Complexity kills security</li>
</ul>
</p>
<p>
Consistency:
<ul>
<li>HMAC over file contents to recognize changed ciphertext before decryption</li>
<li>I/O operations are transactional and atomic, if the filesystems support it</li>
<li>Each file contains all information needed for decryption (except for the key of course), no common metadata means no Single Point of Failure</li>
</ul>
</p>
</description>
<categories>
<category>Office</category>
<category>Security</category>
<category>FileTools</category>
<category>Java</category>
</categories>
<url type="homepage">http://cryptomator.org</url>
<url type="bugtracker">https://github.com/cryptomator/cryptomator/issues</url>
<url type="faq">https://community.cryptomator.org/c/kb/faq</url>
<url type="help">https://community.cryptomator.org/</url>
<url type="donation">https://cryptomator.org/</url>
<content_rating type="oars-1.0">
<content_attribute id="violence-cartoon">none</content_attribute>
<content_attribute id="drugs-alcohol">none</content_attribute>
<content_attribute id="sex-nudity">none</content_attribute>
<content_attribute id="language-profanity">none</content_attribute>
<content_attribute id="social-info">mild</content_attribute> <!-- update checker conencts to https://api.cryptomator.org/updates/latestVersion.json -->
</content_rating>
<project_group>Cryptomator</project_group>
<provides>
<binary>cryptomator</binary>
</provides>
<launchable type="desktop-id">org.cryptomator.Cryptomator.desktop</launchable>
</component>

5
src/package/launcher-linux.sh → dist/linux/launcher.sh vendored Normal file → Executable file
View File

@@ -1,12 +1,13 @@
#!/bin/sh
cd $(dirname $0)
java \
-p "mods" \
-cp "libs/*" \
-Dcryptomator.settingsPath="~/.config/Cryptomator/settings.json" \
-Dcryptomator.ipcPortPath="~/.config/Cryptomator/ipcPort.bin" \
-Dcryptomator.ipcSocketPath="~/.config/Cryptomator/ipc.socket" \
-Dcryptomator.logDir="~/.local/share/Cryptomator/logs" \
-Dcryptomator.mountPointsDir="~/.local/share/Cryptomator/mnt" \
-Djdk.gtk.version=2 \
-Xss2m \
-Xmx512m \
org.cryptomator.launcher.Cryptomator
-m org.cryptomator.desktop/org.cryptomator.launcher.Cryptomator

BIN
dist/linux/resources/Cryptomator.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

16
dist/mac/Cryptomator.entitlements vendored Normal file
View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.cs.allow-dyld-environment-variables</key>
<true/>
<key>com.apple.security.cs.allow-jit</key>
<true/>
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
<true/>
<key>com.apple.security.cs.disable-executable-page-protection</key>
<true/>
<key>com.apple.security.cs.disable-library-validation</key>
<true/>
</dict>
</plist>

Binary file not shown.

Binary file not shown.

100
dist/mac/dmg/resources/license.rtf vendored Normal file
View File

@@ -0,0 +1,100 @@
{\rtf1\ansi\ansicpg1252\cocoartf2512
\cocoatextscaling0\cocoaplatform0{\fonttbl\f0\fswiss\fcharset0 Helvetica-Bold;\f1\fswiss\fcharset0 Helvetica;}
{\colortbl;\red255\green255\blue255;}
{\*\expandedcolortbl;;}
\paperw11900\paperh16840\vieww12000\viewh15840\viewkind0
\deftab720
\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardeftab720\partightenfactor0
\f0\b\fs24 \cf0 Cryptomator is distributed under the GPLv3 License, found below. Please see the bottom of this document for any other license applicable to code used within Cryptomator.
\f1\b0 \
\
\f0\b \'a9 2016 \'96 2021 Skymatic GmbH
\f1\b0 \
\
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.\
\
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.\
\
You should have received a copy of the GNU General Public License along with this program. If not, see {\field{\*\fldinst{HYPERLINK "http://www.gnu.org/licenses/"}}{\fldrslt http://www.gnu.org/licenses/}}.\
\
\f0\b Cryptomator uses 49 third-party dependencies under the following licenses:
\f1\b0 \
Apache License v2.0:\
- jffi (com.github.jnr:jffi:1.2.23 - {\field{\*\fldinst{HYPERLINK "http://github.com/jnr/jffi"}}{\fldrslt http://github.com/jnr/jffi}})\
- jnr-a64asm (com.github.jnr:jnr-a64asm:1.0.0 - {\field{\*\fldinst{HYPERLINK "http://nexus.sonatype.org/oss-repository-hosting.html/jnr-a64asm"}}{\fldrslt http://nexus.sonatype.org/oss-repository-hosting.html/jnr-a64asm}})\
- jnr-constants (com.github.jnr:jnr-constants:0.9.15 - {\field{\*\fldinst{HYPERLINK "http://github.com/jnr/jnr-constants"}}{\fldrslt http://github.com/jnr/jnr-constants}})\
- jnr-ffi (com.github.jnr:jnr-ffi:2.1.12 - {\field{\*\fldinst{HYPERLINK "http://github.com/jnr/jnr-ffi"}}{\fldrslt http://github.com/jnr/jnr-ffi}})\
- FindBugs-jsr305 (com.google.code.findbugs:jsr305:3.0.2 - {\field{\*\fldinst{HYPERLINK "http://findbugs.sourceforge.net/"}}{\fldrslt http://findbugs.sourceforge.net/}})\
- Gson (com.google.code.gson:gson:2.8.6 - {\field{\*\fldinst{HYPERLINK "https://github.com/google/gson/gson"}}{\fldrslt https://github.com/google/gson/gson}})\
- Dagger (com.google.dagger:dagger:2.29.1 - {\field{\*\fldinst{HYPERLINK "https://github.com/google/dagger"}}{\fldrslt https://github.com/google/dagger}})\
- error-prone annotations (com.google.errorprone:error_prone_annotations:2.3.4 - {\field{\*\fldinst{HYPERLINK "http://nexus.sonatype.org/oss-repository-hosting.html/error_prone_parent/error_prone_annotation"}}{\fldrslt http://nexus.sonatype.org/oss-repository-hosting.html/error_prone_parent/error_prone_annotation}} )\
- Guava InternalFutureFailureAccess and InternalFutures (com.google.guava:failureaccess:1.0.1 - {\field{\*\fldinst{HYPERLINK "https://github.com/google/guava/failureaccess"}}{\fldrslt https://github.com/google/guava/failureaccess}})\
- Guava: Google Core Libraries for Java (com.google.guava:guava:30.0-jre - {\field{\*\fldinst{HYPERLINK "https://github.com/google/guava/guava"}}{\fldrslt https://github.com/google/guava/guava}})\
- Guava ListenableFuture only (com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava - {\field{\*\fldinst{HYPERLINK "https://github.com/google/guava/listenablefuture"}}{\fldrslt https://github.com/google/guava/listenablefuture}})\
- J2ObjC Annotations (com.google.j2objc:j2objc-annotations:1.3 - {\field{\*\fldinst{HYPERLINK "https://github.com/google/j2objc/"}}{\fldrslt https://github.com/google/j2objc/}})\
- Apache Commons CLI (commons-cli:commons-cli:1.4 - {\field{\*\fldinst{HYPERLINK "http://commons.apache.org/proper/commons-cli/"}}{\fldrslt http://commons.apache.org/proper/commons-cli/}})\
- javax.inject (javax.inject:javax.inject:1 - {\field{\*\fldinst{HYPERLINK "http://code.google.com/p/atinject/"}}{\fldrslt http://code.google.com/p/atinject/}})\
- Java Native Access (net.java.dev.jna:jna:5.6.0 - {\field{\*\fldinst{HYPERLINK "https://github.com/java-native-access/jna"}}{\fldrslt https://github.com/java-native-access/jna}})\
- Java Native Access Platform (net.java.dev.jna:jna-platform:5.5.0 - {\field{\*\fldinst{HYPERLINK "https://github.com/java-native-access/jna"}}{\fldrslt https://github.com/java-native-access/jna}})\
- Apache Commons Lang (org.apache.commons:commons-lang3:3.11 - {\field{\*\fldinst{HYPERLINK "https://commons.apache.org/proper/commons-lang/"}}{\fldrslt https://commons.apache.org/proper/commons-lang/}})\
- Apache HttpCore (org.apache.httpcomponents:httpcore:4.4.13 - {\field{\*\fldinst{HYPERLINK "http://hc.apache.org/httpcomponents-core-ga"}}{\fldrslt http://hc.apache.org/httpcomponents-core-ga}})\
- Jackrabbit WebDAV Library (org.apache.jackrabbit:jackrabbit-webdav:2.21.3 - {\field{\*\fldinst{HYPERLINK "http://jackrabbit.apache.org/jackrabbit-webdav/"}}{\fldrslt http://jackrabbit.apache.org/jackrabbit-webdav/}})\
- Jetty :: Http Utility (org.eclipse.jetty:jetty-http:9.4.35.v20201120 - {\field{\*\fldinst{HYPERLINK "https://eclipse.org/jetty/jetty-http"}}{\fldrslt https://eclipse.org/jetty/jetty-http}})\
- Jetty :: IO Utility (org.eclipse.jetty:jetty-io:9.4.35.v20201120 - {\field{\*\fldinst{HYPERLINK "https://eclipse.org/jetty/jetty-io"}}{\fldrslt https://eclipse.org/jetty/jetty-io}})\
- Jetty :: Security (org.eclipse.jetty:jetty-security:9.4.35.v20201120 - {\field{\*\fldinst{HYPERLINK "https://eclipse.org/jetty/jetty-security"}}{\fldrslt https://eclipse.org/jetty/jetty-security}})\
- Jetty :: Server Core (org.eclipse.jetty:jetty-server:9.4.35.v20201120 - {\field{\*\fldinst{HYPERLINK "https://eclipse.org/jetty/jetty-server"}}{\fldrslt https://eclipse.org/jetty/jetty-server}})\
- Jetty :: Servlet Handling (org.eclipse.jetty:jetty-servlet:9.4.35.v20201120 - {\field{\*\fldinst{HYPERLINK "https://eclipse.org/jetty/jetty-servlet"}}{\fldrslt https://eclipse.org/jetty/jetty-servlet}})\
- Jetty :: Utilities (org.eclipse.jetty:jetty-util:9.4.35.v20201120 - {\field{\*\fldinst{HYPERLINK "https://eclipse.org/jetty/jetty-util"}}{\fldrslt https://eclipse.org/jetty/jetty-util}})\
- Jetty :: Utilities :: Ajax(JSON) (org.eclipse.jetty:jetty-util-ajax:9.4.35.v20201120 - {\field{\*\fldinst{HYPERLINK "https://eclipse.org/jetty/jetty-util-ajax"}}{\fldrslt https://eclipse.org/jetty/jetty-util-ajax}})\
- Jetty :: Webapp Application Support (org.eclipse.jetty:jetty-webapp:9.4.35.v20201120 - {\field{\*\fldinst{HYPERLINK "https://eclipse.org/jetty/jetty-webapp"}}{\fldrslt https://eclipse.org/jetty/jetty-webapp}})\
- Jetty :: XML utilities (org.eclipse.jetty:jetty-xml:9.4.35.v20201120 - {\field{\*\fldinst{HYPERLINK "https://eclipse.org/jetty/jetty-xml"}}{\fldrslt https://eclipse.org/jetty/jetty-xml}})\
BSD:\
- asm (org.ow2.asm:asm:7.1 - {\field{\*\fldinst{HYPERLINK "http://asm.ow2.org/"}}{\fldrslt http://asm.ow2.org/}})\
- asm-analysis (org.ow2.asm:asm-analysis:7.1 - {\field{\*\fldinst{HYPERLINK "http://asm.ow2.org/"}}{\fldrslt http://asm.ow2.org/}})\
- asm-commons (org.ow2.asm:asm-commons:7.1 - {\field{\*\fldinst{HYPERLINK "http://asm.ow2.org/"}}{\fldrslt http://asm.ow2.org/}})\
- asm-tree (org.ow2.asm:asm-tree:7.1 - {\field{\*\fldinst{HYPERLINK "http://asm.ow2.org/"}}{\fldrslt http://asm.ow2.org/}})\
- asm-util (org.ow2.asm:asm-util:7.1 - {\field{\*\fldinst{HYPERLINK "http://asm.ow2.org/"}}{\fldrslt http://asm.ow2.org/}})\
Eclipse Public License - Version 1.0:\
- Jetty :: Http Utility (org.eclipse.jetty:jetty-http:9.4.35.v20201120 - {\field{\*\fldinst{HYPERLINK "https://eclipse.org/jetty/jetty-http"}}{\fldrslt https://eclipse.org/jetty/jetty-http}})\
- Jetty :: IO Utility (org.eclipse.jetty:jetty-io:9.4.35.v20201120 - {\field{\*\fldinst{HYPERLINK "https://eclipse.org/jetty/jetty-io"}}{\fldrslt https://eclipse.org/jetty/jetty-io}})\
- Jetty :: Security (org.eclipse.jetty:jetty-security:9.4.35.v20201120 - {\field{\*\fldinst{HYPERLINK "https://eclipse.org/jetty/jetty-security"}}{\fldrslt https://eclipse.org/jetty/jetty-security}})\
- Jetty :: Server Core (org.eclipse.jetty:jetty-server:9.4.35.v20201120 - {\field{\*\fldinst{HYPERLINK "https://eclipse.org/jetty/jetty-server"}}{\fldrslt https://eclipse.org/jetty/jetty-server}})\
- Jetty :: Servlet Handling (org.eclipse.jetty:jetty-servlet:9.4.35.v20201120 - {\field{\*\fldinst{HYPERLINK "https://eclipse.org/jetty/jetty-servlet"}}{\fldrslt https://eclipse.org/jetty/jetty-servlet}})\
- Jetty :: Utilities (org.eclipse.jetty:jetty-util:9.4.35.v20201120 - {\field{\*\fldinst{HYPERLINK "https://eclipse.org/jetty/jetty-util"}}{\fldrslt https://eclipse.org/jetty/jetty-util}})\
- Jetty :: Utilities :: Ajax(JSON) (org.eclipse.jetty:jetty-util-ajax:9.4.35.v20201120 - {\field{\*\fldinst{HYPERLINK "https://eclipse.org/jetty/jetty-util-ajax"}}{\fldrslt https://eclipse.org/jetty/jetty-util-ajax}})\
- Jetty :: Webapp Application Support (org.eclipse.jetty:jetty-webapp:9.4.35.v20201120 - {\field{\*\fldinst{HYPERLINK "https://eclipse.org/jetty/jetty-webapp"}}{\fldrslt https://eclipse.org/jetty/jetty-webapp}})\
- Jetty :: XML utilities (org.eclipse.jetty:jetty-xml:9.4.35.v20201120 - {\field{\*\fldinst{HYPERLINK "https://eclipse.org/jetty/jetty-xml"}}{\fldrslt https://eclipse.org/jetty/jetty-xml}})\
Eclipse Public License - v 2.0:\
- jnr-posix (com.github.jnr:jnr-posix:3.0.54 - {\field{\*\fldinst{HYPERLINK "http://nexus.sonatype.org/oss-repository-hosting.html/jnr-posix"}}{\fldrslt http://nexus.sonatype.org/oss-repository-hosting.html/jnr-posix}})\
GPLv2:\
- jnr-posix (com.github.jnr:jnr-posix:3.0.54 - {\field{\*\fldinst{HYPERLINK "http://nexus.sonatype.org/oss-repository-hosting.html/jnr-posix"}}{\fldrslt http://nexus.sonatype.org/oss-repository-hosting.html/jnr-posix}})\
GPLv2+CE:\
- Java Servlet API (javax.servlet:javax.servlet-api:3.1.0 - {\field{\*\fldinst{HYPERLINK "http://servlet-spec.java.net"}}{\fldrslt http://servlet-spec.java.net}})\
- javafx-base (org.openjfx:javafx-base:15 - {\field{\*\fldinst{HYPERLINK "https://openjdk.java.net/projects/openjfx/javafx-base/"}}{\fldrslt https://openjdk.java.net/projects/openjfx/javafx-base/}})\
- javafx-controls (org.openjfx:javafx-controls:15 - {\field{\*\fldinst{HYPERLINK "https://openjdk.java.net/projects/openjfx/javafx-controls/"}}{\fldrslt https://openjdk.java.net/projects/openjfx/javafx-controls/}})\
- javafx-fxml (org.openjfx:javafx-fxml:15 - {\field{\*\fldinst{HYPERLINK "https://openjdk.java.net/projects/openjfx/javafx-fxml/"}}{\fldrslt https://openjdk.java.net/projects/openjfx/javafx-fxml/}})\
- javafx-graphics (org.openjfx:javafx-graphics:15 - {\field{\*\fldinst{HYPERLINK "https://openjdk.java.net/projects/openjfx/javafx-graphics/"}}{\fldrslt https://openjdk.java.net/projects/openjfx/javafx-graphics/}})\
LGPL 2.1:\
- jnr-posix (com.github.jnr:jnr-posix:3.0.54 - {\field{\*\fldinst{HYPERLINK "http://nexus.sonatype.org/oss-repository-hosting.html/jnr-posix"}}{\fldrslt http://nexus.sonatype.org/oss-repository-hosting.html/jnr-posix}})\
- Java Native Access (net.java.dev.jna:jna:5.6.0 - https://github.com/java-native-access/jna)\
- Java Native Access Platform (net.java.dev.jna:jna-platform:5.5.0 - {\field{\*\fldinst{HYPERLINK "https://github.com/java-native-access/jna"}}{\fldrslt https://github.com/java-native-access/jna}})\
MIT License:\
- java jwt (com.auth0:java-jwt:3.12.0 - {\field{\*\fldinst{HYPERLINK "https://github.com/auth0/java-jwt"}}{\fldrslt https://github.com/auth0/java-jwt}})\
- jnr-x86asm (com.github.jnr:jnr-x86asm:1.0.2 - {\field{\*\fldinst{HYPERLINK "http://github.com/jnr/jnr-x86asm"}}{\fldrslt http://github.com/jnr/jnr-x86asm}})\
- jnr-fuse (com.github.serceman:jnr-fuse:0.5.4 - no url defined)\
- zxcvbn4j (com.nulab-inc:zxcvbn:1.3.0 - {\field{\*\fldinst{HYPERLINK "https://github.com/nulab/zxcvbn4j"}}{\fldrslt https://github.com/nulab/zxcvbn4j}})\
- Checker Qual (org.checkerframework:checker-qual:3.5.0 - {\field{\*\fldinst{HYPERLINK "https://checkerframework.org"}}{\fldrslt https://checkerframework.org}})\
- SLF4J API Module (org.slf4j:slf4j-api:1.7.30 - {\field{\*\fldinst{HYPERLINK "http://www.slf4j.org"}}{\fldrslt http://www.slf4j.org}})\
The BSD 2-Clause License:\
- EasyBind (com.tobiasdiez:easybind:2.1.0 - {\field{\*\fldinst{HYPERLINK "https://github.com/tobiasdiez/EasyBind"}}{\fldrslt https://github.com/tobiasdiez/EasyBind}})\
\
\f0\b Cryptomator uses other third-party assets under the following licenses:
\f1\b0 \
SIL OFL 1.1 License:\
- Font Awesome 5.12.0 ({\field{\*\fldinst{HYPERLINK "https://fontawesome.com/"}}{\fldrslt https://fontawesome.com/}})\
\
}

8
dist/mac/dmg/resources/macFUSE.webloc vendored Normal file
View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>URL</key>
<string>https://osxfuse.github.io/</string>
</dict>
</plist>

5
src/package/launcher-mac.sh → dist/mac/launcher.sh vendored Normal file → Executable file
View File

@@ -1,11 +1,12 @@
#!/bin/sh
cd $(dirname $0)
java \
-p "mods" \
-cp "libs/*" \
-Dcryptomator.settingsPath="~/Library/Application Support/Cryptomator/settings.json" \
-Dcryptomator.ipcPortPath="~/Library/Application Support/Cryptomator/ipcPort.bin" \
-Dcryptomator.ipcSocketPath="~/Library/Application Support/Cryptomator/ipc.socket" \
-Dcryptomator.logDir="~/Library/Logs/Cryptomator" \
-Dcryptomator.mountPointsDir="/Volumes" \
-Xss20m \
-Xmx512m \
org.cryptomator.launcher.Cryptomator
-m org.cryptomator.desktop/org.cryptomator.launcher.Cryptomator

Binary file not shown.

BIN
dist/mac/resources/Cryptomator.icns vendored Normal file

Binary file not shown.

120
dist/mac/resources/Info.plist vendored Normal file
View File

@@ -0,0 +1,120 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>LSMinimumSystemVersion</key>
<string>10.13.0</string>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleAllowMixedLocalizations</key>
<true/>
<key>CFBundleExecutable</key>
<string>Cryptomator</string>
<key>CFBundleIconFile</key>
<string>Cryptomator.icns</string>
<key>CFBundleIdentifier</key>
<string>org.cryptomator</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>Cryptomator</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>###BUNDLE_SHORT_VERSION_STRING###</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>LSApplicationCategoryType</key>
<string>public.app-category.utilities</string>
<key>CFBundleVersion</key>
<string>###BUNDLE_VERSION###</string>
<key>NSHumanReadableCopyright</key>
<string>cryptomator.org</string>
<key>NSHighResolutionCapable</key>
<string>true</string>
<key>NSUbiquitousContainers</key>
<dict>
<key>iCloud.com.setolabs.Cryptomator</key>
<dict>
<key>NSUbiquitousContainerIsDocumentScopePublic</key>
<true/>
<key>NSUbiquitousContainerName</key>
<string>Cryptomator</string>
<key>NSUbiquitousContainerSupportedFolderLevels</key>
<string>Any</string>
</dict>
</dict>
<!-- register .cryptomator extension -->
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>LSItemContentTypes</key>
<array>
<string>org.cryptomator.vault-metadata</string>
</array>
<key>CFBundleTypeIconFile</key>
<string>Cryptomator-Vault.icns</string>
<key>CFBundleTypeName</key>
<string>Cryptomator Vault Metadata</string>
<key>LSHandlerRank</key>
<string>Owner</string>
<key>CFBundleTypeRole</key>
<string>Editor</string>
</dict>
</array>
<key>UTExportedTypeDeclarations</key>
<array>
<dict>
<key>UTTypeIdentifier</key>
<string>org.cryptomator.vault-metadata</string>
<key>UTTypeConformsTo</key>
<array>
<string>public.utf8-plain-text</string>
<string>public.json</string>
</array>
<key>UTTypeDescription</key>
<string>Cryptomator Vault Metadata</string>
<key>UTTypeIconFile</key>
<string>Cryptomator-Vault.icns</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>cryptomator</string>
</array>
<key>public.mime-type</key>
<array>
<string>application/x-vnd.cryptomator.vault-metadata</string>
</array>
</dict>
</dict>
<dict>
<key>UTTypeIdentifier</key>
<string>org.cryptomator.encrypted-data</string>
<key>UTTypeConformsTo</key>
<array>
<string>public.data</string>
</array>
<key>UTTypeDescription</key>
<string>Cryptomator Encrypted Data</string>
<key>UTTypeIconFile</key>
<string>Cryptomator-Vault.icns</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>c9r</string>
<string>c9s</string>
</array>
<key>public.mime-type</key>
<array>
<string>application/vnd.cryptomator.encrypted</string>
</array>
</dict>
</dict>
</array>
<!-- allow utilization of integrated GPU, see https://developer.apple.com/library/mac/qa/qa1734/_index.html -->
<key>NSSupportsAutomaticGraphicsSwitching</key>
<true/>
</dict>
</plist>

12
dist/win/contrib/cryptomator.bat vendored Normal file
View File

@@ -0,0 +1,12 @@
@echo off
java ^
-p "app/mods" ^
-cp "app/*" ^
-Dcryptomator.settingsPath="~/AppData/Roaming/Cryptomator/settings.json" ^
-Dcryptomator.ipcSocketPath="~/AppData/Roaming/Cryptomator/ipc.socket" ^
-Dcryptomator.logDir="~/AppData/Roaming/Cryptomator" ^
-Dcryptomator.mountPointsDir="~/Cryptomator" ^
-Dcryptomator.keychainPath="~/AppData/Roaming/Cryptomator/keychain.json" ^
-Xss20m ^
-Xmx512m ^
-m org.cryptomator.desktop/org.cryptomator.launcher.Cryptomator

BIN
dist/win/contrib/dokan1.dll vendored Executable file

Binary file not shown.

BIN
dist/win/contrib/jnidispatch.dll vendored Normal file

Binary file not shown.

View File

@@ -1,11 +1,12 @@
@echo off
java ^
-p "mods" ^
-cp "libs/*" ^
-Dcryptomator.settingsPath="~/AppData/Roaming/Cryptomator/settings.json" ^
-Dcryptomator.ipcPortPath="~/AppData/Roaming/Cryptomator/ipcPort.bin" ^
-Dcryptomator.ipcSocketPath="~/AppData/Roaming/Cryptomator/ipc.socket" ^
-Dcryptomator.logDir="~/AppData/Roaming/Cryptomator" ^
-Dcryptomator.mountPointsDir="~/Cryptomator" ^
-Dcryptomator.keychainPath="~/AppData/Roaming/Cryptomator/keychain.json" ^
-Xss20m ^
-Xmx512m ^
org.cryptomator.launcher.Cryptomator
-m org.cryptomator.desktop/org.cryptomator.launcher.Cryptomator

BIN
dist/win/resources/Cryptomator.ico vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 158 KiB

View File

@@ -0,0 +1,4 @@
mime-type=application/vnd.cryptomator.encrypted
extension=c9r,c9s
description=Cryptomator Encrypted Data
icon=resources/Cryptomator.ico

View File

@@ -0,0 +1,4 @@
mime-type=application/vnd.cryptomator.vault
extension=cryptomator
description=Cryptomator Vault File
icon=resources/Cryptomator.ico

BIN
dist/win/resources/background.bmp vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 601 KiB

BIN
dist/win/resources/banner.bmp vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB

89
dist/win/resources/customWizard.wxi vendored Normal file
View File

@@ -0,0 +1,89 @@
<?xml version="1.0" encoding="utf-8"?>
<Include>
<Fragment>
<!-- copy pasta from https://github.com/wixtoolset/wix3/blob/develop/src/ext/UIExtension/wixlib/WixUI_InstallDir.wxs with custom exit dialog-->
<UI Id="CustomWizard">
<TextStyle Id="WixUI_Font_Normal" FaceName="Tahoma" Size="8" />
<TextStyle Id="WixUI_Font_Bigger" FaceName="Tahoma" Size="12" />
<TextStyle Id="WixUI_Font_Title" FaceName="Tahoma" Size="9" Bold="yes" />
<Property Id="DefaultUIFont" Value="WixUI_Font_Normal" />
<Property Id="WixUI_Mode" Value="InstallDir" />
<DialogRef Id="BrowseDlg" />
<DialogRef Id="DiskCostDlg" />
<DialogRef Id="ErrorDlg" />
<DialogRef Id="FatalError" />
<DialogRef Id="FilesInUse" />
<DialogRef Id="MsiRMFilesInUse" />
<DialogRef Id="PrepareDlg" />
<DialogRef Id="ProgressDlg" />
<DialogRef Id="ResumeDlg" />
<DialogRef Id="UserExit" />
<Publish Dialog="BrowseDlg" Control="OK" Event="DoAction" Value="WixUIValidatePath" Order="3">1</Publish>
<Publish Dialog="BrowseDlg" Control="OK" Event="SpawnDialog" Value="InvalidDirDlg" Order="4"><![CDATA[NOT WIXUI_DONTVALIDATEPATH AND WIXUI_INSTALLDIR_VALID<>"1"]]></Publish>
<!-- custom end dialog -->
<Publish Dialog="MyExitDialog" Control="Finish" Event="EndDialog" Value="Return" Order="999">1</Publish>
<Publish Dialog="WelcomeDlg" Control="Next" Event="NewDialog" Value="LicenseAgreementDlg">NOT Installed</Publish>
<Publish Dialog="WelcomeDlg" Control="Next" Event="NewDialog" Value="VerifyReadyDlg">Installed AND PATCH</Publish>
<Publish Dialog="LicenseAgreementDlg" Control="Back" Event="NewDialog" Value="WelcomeDlg">1</Publish>
<Publish Dialog="LicenseAgreementDlg" Control="Next" Event="NewDialog" Value="InstallDirDlg">LicenseAccepted = "1"</Publish>
<Publish Dialog="InstallDirDlg" Control="Back" Event="NewDialog" Value="LicenseAgreementDlg">1</Publish>
<Publish Dialog="InstallDirDlg" Control="Next" Event="SetTargetPath" Value="[WIXUI_INSTALLDIR]" Order="1">1</Publish>
<Publish Dialog="InstallDirDlg" Control="Next" Event="DoAction" Value="WixUIValidatePath" Order="2">NOT WIXUI_DONTVALIDATEPATH</Publish>
<Publish Dialog="InstallDirDlg" Control="Next" Event="SpawnDialog" Value="InvalidDirDlg" Order="3"><![CDATA[NOT WIXUI_DONTVALIDATEPATH AND WIXUI_INSTALLDIR_VALID<>"1"]]></Publish>
<Publish Dialog="InstallDirDlg" Control="Next" Event="NewDialog" Value="VerifyReadyDlg" Order="4">WIXUI_DONTVALIDATEPATH OR WIXUI_INSTALLDIR_VALID="1"</Publish>
<Publish Dialog="InstallDirDlg" Control="ChangeFolder" Property="_BrowseProperty" Value="[WIXUI_INSTALLDIR]" Order="1">1</Publish>
<Publish Dialog="InstallDirDlg" Control="ChangeFolder" Event="SpawnDialog" Value="BrowseDlg" Order="2">1</Publish>
<Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="InstallDirDlg" Order="1">NOT Installed</Publish>
<Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="MaintenanceTypeDlg" Order="2">Installed AND NOT PATCH</Publish>
<Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="WelcomeDlg" Order="2">Installed AND PATCH</Publish>
<Publish Dialog="MaintenanceWelcomeDlg" Control="Next" Event="NewDialog" Value="MaintenanceTypeDlg">1</Publish>
<Publish Dialog="MaintenanceTypeDlg" Control="RepairButton" Event="NewDialog" Value="VerifyReadyDlg">1</Publish>
<Publish Dialog="MaintenanceTypeDlg" Control="RemoveButton" Event="NewDialog" Value="VerifyReadyDlg">1</Publish>
<Publish Dialog="MaintenanceTypeDlg" Control="Back" Event="NewDialog" Value="MaintenanceWelcomeDlg">1</Publish>
<Property Id="ARPNOMODIFY" Value="1" />
<!-- copy pasta from https://github.com/wixtoolset/wix3/blob/develop/src/ext/UIExtension/wixlib/ExitDialog.wxs with adjustments-->
<Dialog Id="MyExitDialog" Width="370" Height="270" Title="!(loc.ExitDialog_Title)">
<Control Id="Finish" Type="PushButton" X="236" Y="243" Width="56" Height="17" Default="yes" Cancel="yes" Text="!(loc.WixUIFinish)" />
<Control Id="Cancel" Type="PushButton" X="304" Y="243" Width="56" Height="17" Disabled="yes" Text="!(loc.WixUICancel)" />
<Control Id="Bitmap" Type="Bitmap" X="0" Y="0" Width="370" Height="234" TabSkip="no" Text="!(loc.ExitDialogBitmap)" />
<Control Id="Back" Type="PushButton" X="180" Y="243" Width="56" Height="17" Disabled="yes" Text="!(loc.WixUIBack)" />
<Control Id="BottomLine" Type="Line" X="0" Y="234" Width="370" Height="0" />
<Control Id="Description" Type="Text" X="135" Y="70" Width="220" Height="40" Transparent="yes" NoPrefix="yes" Text="!(loc.ExitDialogDescription)" />
<Control Id="Title" Type="Text" X="135" Y="20" Width="220" Height="60" Transparent="yes" NoPrefix="yes" Text="!(loc.ExitDialogTitle)" />
<!-- TODO: localize? -->
<Control Id="Suggestion" Type="Text" X="135" Y="100" Width="220" Height="60" Transparent="yes" NoPrefix="yes">
<Text>We recommend for the best user experience to download and install one of the following third party Windows drivers:</Text>
</Control>
<Control Id="WinFsp" Type="Hyperlink" X="140" Y="125" Width="220" Height="60" Transparent="yes">
<Text><![CDATA[• WinFsp (<a href="http://www.secfs.net/winfsp/rel/">Homepage</a>)]]></Text>
</Control>
<Control Id="Dokany" Type="Hyperlink" X="140" Y="137" Width="220" Height="60" Transparent="yes">
<Text><![CDATA[• Dokany (<a href="https://dokan-dev.github.io/">Homepage</a>)]]></Text>
</Control>
</Dialog>
<InstallUISequence>
<Show Dialog="MyExitDialog" Overridable="yes" OnExit="success"/>
</InstallUISequence>
<AdminUISequence>
<Show Dialog="MyExitDialog" Overridable="yes" OnExit="success"/>
</AdminUISequence>
</UI>
<UIRef Id="WixUI_Common" />
</Fragment>
</Include>

92
dist/win/resources/license.rtf vendored Normal file
View File

@@ -0,0 +1,92 @@
{\rtf1\ansi\ansicpg1252\deff0\nouicompat{\fonttbl{\f0\fnil\fcharset0 Arial;}}
{\colortbl ;\red0\green0\blue255;}
{\*\generator Riched20 10.0.17134}\viewkind4\uc1
\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\b\fs16\lang7 Cryptomator is distributed under the GPLv3 License, found below. Please see the bottom of this document for any other license applicable to code used within Cryptomator.\b0\par
\par
\b\'a9 2016 \endash 2021 Skymatic GmbH\b0\par
\par
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.\par
\par
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.\par
\par
You should have received a copy of the GNU General Public License along with this program. If not, see {{\field{\*\fldinst{HYPERLINK http://www.gnu.org/licenses/ }}{\fldrslt{http://www.gnu.org/licenses/\ul0\cf0}}}}\f0\fs16 .\par
\par
\b Cryptomator uses 49 third-party dependencies under the following licenses:\b0\par
\tab Apache License v2.0:\par
\tab\tab - HKDF-RFC5869 (at.favre.lib:hkdf:1.0.2 - {{\field{\*\fldinst{HYPERLINK https://github.com/patrickfav/hkdf }}{\fldrslt{https://github.com/patrickfav/hkdf\ul0\cf0}}}}\f0\fs16 )\par
\tab\tab - jffi (com.github.jnr:jffi:1.2.23 - {{\field{\*\fldinst{HYPERLINK http://github.com/jnr/jffi }}{\fldrslt{http://github.com/jnr/jffi\ul0\cf0}}}}\f0\fs16 )\par
\tab\tab - jnr-a64asm (com.github.jnr:jnr-a64asm:1.0.0 - {{\field{\*\fldinst{HYPERLINK http://nexus.sonatype.org/oss-repository-hosting.html/jnr-a64asm }}{\fldrslt{http://nexus.sonatype.org/oss-repository-hosting.html/jnr-a64asm\ul0\cf0}}}}\f0\fs16 )\par
\tab\tab - jnr-constants (com.github.jnr:jnr-constants:0.9.15 - {{\field{\*\fldinst{HYPERLINK http://github.com/jnr/jnr-constants }}{\fldrslt{http://github.com/jnr/jnr-constants\ul0\cf0}}}}\f0\fs16 )\par
\tab\tab - jnr-ffi (com.github.jnr:jnr-ffi:2.1.12 - {{\field{\*\fldinst{HYPERLINK http://github.com/jnr/jnr-ffi }}{\fldrslt{http://github.com/jnr/jnr-ffi\ul0\cf0}}}}\f0\fs16 )\par
\tab\tab - FindBugs-jsr305 (com.google.code.findbugs:jsr305:3.0.2 - {{\field{\*\fldinst{HYPERLINK http://findbugs.sourceforge.net/ }}{\fldrslt{http://findbugs.sourceforge.net/\ul0\cf0}}}}\f0\fs16 )\par
\tab\tab - Gson (com.google.code.gson:gson:2.8.6 - {{\field{\*\fldinst{HYPERLINK https://github.com/google/gson/gson }}{\fldrslt{https://github.com/google/gson/gson\ul0\cf0}}}}\f0\fs16 )\par
\tab\tab - Dagger (com.google.dagger:dagger:2.27 - {{\field{\*\fldinst{HYPERLINK https://github.com/google/dagger }}{\fldrslt{https://github.com/google/dagger\ul0\cf0}}}}\f0\fs16 )\par
\tab\tab - error-prone annotations (com.google.errorprone:error_prone_annotations:2.3.4 - {{\field{\*\fldinst{HYPERLINK http://nexus.sonatype.org/oss-repository-hosting.html/error_prone_parent/error_prone_annotations }}{\fldrslt{http://nexus.sonatype.org/oss-repository-hosting.html/error_prone_parent/error_prone_annotations\ul0\cf0}}}}\f0\fs16 )\par
\tab\tab - Guava InternalFutureFailureAccess and InternalFutures (com.google.guava:failureaccess:1.0.1 - {{\field{\*\fldinst{HYPERLINK https://github.com/google/guava/failureaccess }}{\fldrslt{https://github.com/google/guava/failureaccess\ul0\cf0}}}}\f0\fs16 )\par
\tab\tab - Guava: Google Core Libraries for Java (com.google.guava:guava:28.2-jre - {{\field{\*\fldinst{HYPERLINK https://github.com/google/guava/guava }}{\fldrslt{https://github.com/google/guava/guava\ul0\cf0}}}}\f0\fs16 )\par
\tab\tab - Guava ListenableFuture only (com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava - {{\field{\*\fldinst{HYPERLINK https://github.com/google/guava/listenablefuture }}{\fldrslt{https://github.com/google/guava/listenablefuture\ul0\cf0}}}}\f0\fs16 )\par
\tab\tab - J2ObjC Annotations (com.google.j2objc:j2objc-annotations:1.3 - {{\field{\*\fldinst{HYPERLINK https://github.com/google/j2objc/ }}{\fldrslt{https://github.com/google/j2objc/\ul0\cf0}}}}\f0\fs16 )\par
\tab\tab - Apache Commons CLI (commons-cli:commons-cli:1.4 - {{\field{\*\fldinst{HYPERLINK http://commons.apache.org/proper/commons-cli/ }}{\fldrslt{http://commons.apache.org/proper/commons-cli/\ul0\cf0}}}}\f0\fs16 )\par
\tab\tab - javax.inject (javax.inject:javax.inject:1 - {{\field{\*\fldinst{HYPERLINK http://code.google.com/p/atinject/ }}{\fldrslt{http://code.google.com/p/atinject/\ul0\cf0}}}}\f0\fs16 )\par
\tab\tab - Java Native Access (net.java.dev.jna:jna:5.1.0 - {{\field{\*\fldinst{HYPERLINK https://github.com/java-native-access/jna }}{\fldrslt{https://github.com/java-native-access/jna\ul0\cf0}}}}\f0\fs16 )\par
\tab\tab - Java Native Access Platform (net.java.dev.jna:jna-platform:5.1.0 - {{\field{\*\fldinst{HYPERLINK https://github.com/java-native-access/jna }}{\fldrslt{https://github.com/java-native-access/jna\ul0\cf0}}}}\f0\fs16 )\par
\tab\tab - Apache Commons Lang (org.apache.commons:commons-lang3:3.9 - {{\field{\*\fldinst{HYPERLINK http://commons.apache.org/proper/commons-lang/ }}{\fldrslt{http://commons.apache.org/proper/commons-lang/\ul0\cf0}}}}\f0\fs16 )\par
\tab\tab - Jackrabbit WebDAV Library (org.apache.jackrabbit:jackrabbit-webdav:2.19.0 - {{\field{\*\fldinst{HYPERLINK http://jackrabbit.apache.org/jackrabbit-webdav/ }}{\fldrslt{http://jackrabbit.apache.org/jackrabbit-webdav/\ul0\cf0}}}}\f0\fs16 )\par
\tab\tab - Jetty :: Http Utility (org.eclipse.jetty:jetty-http:9.4.17.v20190418 - {{\field{\*\fldinst{HYPERLINK http://www.eclipse.org/jetty }}{\fldrslt{http://www.eclipse.org/jetty\ul0\cf0}}}}\f0\fs16 )\par
\tab\tab - Jetty :: IO Utility (org.eclipse.jetty:jetty-io:9.4.17.v20190418 - {{\field{\*\fldinst{HYPERLINK http://www.eclipse.org/jetty }}{\fldrslt{http://www.eclipse.org/jetty\ul0\cf0}}}}\f0\fs16 )\par
\tab\tab - Jetty :: Security (org.eclipse.jetty:jetty-security:9.4.17.v20190418 - {{\field{\*\fldinst{HYPERLINK http://www.eclipse.org/jetty }}{\fldrslt{http://www.eclipse.org/jetty\ul0\cf0}}}}\f0\fs16 )\par
\tab\tab - Jetty :: Server Core (org.eclipse.jetty:jetty-server:9.4.17.v20190418 - {{\field{\*\fldinst{HYPERLINK http://www.eclipse.org/jetty }}{\fldrslt{http://www.eclipse.org/jetty\ul0\cf0}}}}\f0\fs16 )\par
\tab\tab - Jetty :: Servlet Handling (org.eclipse.jetty:jetty-servlet:9.4.17.v20190418 - {{\field{\*\fldinst{HYPERLINK http://www.eclipse.org/jetty }}{\fldrslt{http://www.eclipse.org/jetty\ul0\cf0}}}}\f0\fs16 )\par
\tab\tab - Jetty :: Utilities (org.eclipse.jetty:jetty-util:9.4.17.v20190418 - {{\field{\*\fldinst{HYPERLINK http://www.eclipse.org/jetty }}{\fldrslt{http://www.eclipse.org/jetty\ul0\cf0}}}}\f0\fs16 )\par
\tab\tab - Jetty :: Utilities :: Ajax(JSON) (org.eclipse.jetty:jetty-util-ajax:9.4.35.v20201120 - {{\field{\*\fldinst{HYPERLINK https://eclipse.org/jetty/jetty-util-ajax }}{\fldrslt{{\fldrslt{http://www.eclipse.org/jetty\ul0\cf0}}}}}\f0\fs16 )\par
\tab\tab - Jetty :: Webapp Application Support (org.eclipse.jetty:jetty-webapp:9.4.17.v20190418 - {{\field{\*\fldinst{HYPERLINK http://www.eclipse.org/jetty }}{\fldrslt{http://www.eclipse.org/jetty\ul0\cf0}}}}\f0\fs16 )\par
\tab\tab - Jetty :: XML utilities (org.eclipse.jetty:jetty-xml:9.4.17.v20190418 - {{\field{\*\fldinst{HYPERLINK http://www.eclipse.org/jetty }}{\fldrslt{http://www.eclipse.org/jetty\ul0\cf0}}}}\f0\fs16 )\par
\tab BSD:\par
\tab\tab - asm (org.ow2.asm:asm:7.1 - {{\field{\*\fldinst{HYPERLINK http://asm.ow2.org/ }}{\fldrslt{http://asm.ow2.org/\ul0\cf0}}}}\f0\fs16 )\par
\tab\tab - asm-analysis (org.ow2.asm:asm-analysis:7.1 - {{\field{\*\fldinst{HYPERLINK http://asm.ow2.org/ }}{\fldrslt{http://asm.ow2.org/\ul0\cf0}}}}\f0\fs16 )\par
\tab\tab - asm-commons (org.ow2.asm:asm-commons:7.1 - {{\field{\*\fldinst{HYPERLINK http://asm.ow2.org/ }}{\fldrslt{http://asm.ow2.org/\ul0\cf0}}}}\f0\fs16 )\par
\tab\tab - asm-tree (org.ow2.asm:asm-tree:7.1 - {{\field{\*\fldinst{HYPERLINK http://asm.ow2.org/ }}{\fldrslt{http://asm.ow2.org/\ul0\cf0}}}}\f0\fs16 )\par
\tab\tab - asm-util (org.ow2.asm:asm-util:7.1 - {{\field{\*\fldinst{HYPERLINK http://asm.ow2.org/ }}{\fldrslt{http://asm.ow2.org/\ul0\cf0}}}}\f0\fs16 )\par
\tab Eclipse Public License - Version 1.0:\par
\tab\tab - Jetty :: Http Utility (org.eclipse.jetty:jetty-http:9.4.17.v20190418 - {{\field{\*\fldinst{HYPERLINK http://www.eclipse.org/jetty }}{\fldrslt{http://www.eclipse.org/jetty\ul0\cf0}}}}\f0\fs16 )\par
\tab\tab - Jetty :: IO Utility (org.eclipse.jetty:jetty-io:9.4.17.v20190418 - {{\field{\*\fldinst{HYPERLINK http://www.eclipse.org/jetty }}{\fldrslt{http://www.eclipse.org/jetty\ul0\cf0}}}}\f0\fs16 )\par
\tab\tab - Jetty :: Security (org.eclipse.jetty:jetty-security:9.4.17.v20190418 - {{\field{\*\fldinst{HYPERLINK http://www.eclipse.org/jetty }}{\fldrslt{http://www.eclipse.org/jetty\ul0\cf0}}}}\f0\fs16 )\par
\tab\tab - Jetty :: Server Core (org.eclipse.jetty:jetty-server:9.4.17.v20190418 - {{\field{\*\fldinst{HYPERLINK http://www.eclipse.org/jetty }}{\fldrslt{http://www.eclipse.org/jetty\ul0\cf0}}}}\f0\fs16 )\par
\tab\tab - Jetty :: Servlet Handling (org.eclipse.jetty:jetty-servlet:9.4.17.v20190418 - {{\field{\*\fldinst{HYPERLINK http://www.eclipse.org/jetty }}{\fldrslt{http://www.eclipse.org/jetty\ul0\cf0}}}}\f0\fs16 )\par
\tab\tab - Jetty :: Utilities (org.eclipse.jetty:jetty-util:9.4.17.v20190418 - {{\field{\*\fldinst{HYPERLINK http://www.eclipse.org/jetty }}{\fldrslt{http://www.eclipse.org/jetty\ul0\cf0}}}}\f0\fs16 )\par
\tab\tab - Jetty :: Utilities :: Ajax(JSON) (org.eclipse.jetty:jetty-util-ajax:9.4.35.v20201120 - {{\field{\*\fldinst{HYPERLINK https://eclipse.org/jetty/jetty-util-ajax }}{\fldrslt{http://www.eclipse.org/jetty\ul0\cf0}}}}}\f0\fs16 )\par
\tab\tab - Jetty :: Webapp Application Support (org.eclipse.jetty:jetty-webapp:9.4.17.v20190418 - {{\field{\*\fldinst{HYPERLINK http://www.eclipse.org/jetty }}{\fldrslt{http://www.eclipse.org/jetty\ul0\cf0}}}}\f0\fs16 )\par
\tab\tab - Jetty :: XML utilities (org.eclipse.jetty:jetty-xml:9.4.17.v20190418 - {{\field{\*\fldinst{HYPERLINK http://www.eclipse.org/jetty }}{\fldrslt{http://www.eclipse.org/jetty\ul0\cf0}}}}\f0\fs16 )\par
\tab Eclipse Public License - v 2.0:\par
\tab\tab - jnr-posix (com.github.jnr:jnr-posix:3.0.54 - {{\field{\*\fldinst{HYPERLINK http://nexus.sonatype.org/oss-repository-hosting.html/jnr-posix }}{\fldrslt{http://nexus.sonatype.org/oss-repository-hosting.html/jnr-posix\ul0\cf0}}}}\f0\fs16 )\par
\tab GPLv2:\par
\tab\tab - jnr-posix (com.github.jnr:jnr-posix:3.0.54 - {{\field{\*\fldinst{HYPERLINK http://nexus.sonatype.org/oss-repository-hosting.html/jnr-posix }}{\fldrslt{http://nexus.sonatype.org/oss-repository-hosting.html/jnr-posix\ul0\cf0}}}}\f0\fs16 )\par
\tab GPLv2+CE:\par
\tab\tab - Java Servlet API (javax.servlet:javax.servlet-api:3.1.0 - {{\field{\*\fldinst{HYPERLINK http://servlet-spec.java.net }}{\fldrslt{http://servlet-spec.java.net\ul0\cf0}}}}\f0\fs16 )\par
\tab\tab - javafx-base (org.openjfx:javafx-base:14 - {{\field{\*\fldinst{HYPERLINK https://openjdk.java.net/projects/openjfx/javafx-base/ }}{\fldrslt{https://openjdk.java.net/projects/openjfx/javafx-base/\ul0\cf0}}}}\f0\fs16 )\par
\tab\tab - javafx-controls (org.openjfx:javafx-controls:14 - {{\field{\*\fldinst{HYPERLINK https://openjdk.java.net/projects/openjfx/javafx-controls/ }}{\fldrslt{https://openjdk.java.net/projects/openjfx/javafx-controls/\ul0\cf0}}}}\f0\fs16 )\par
\tab\tab - javafx-fxml (org.openjfx:javafx-fxml:14 - {{\field{\*\fldinst{HYPERLINK https://openjdk.java.net/projects/openjfx/javafx-fxml/ }}{\fldrslt{https://openjdk.java.net/projects/openjfx/javafx-fxml/\ul0\cf0}}}}\f0\fs16 )\par
\tab\tab - javafx-graphics (org.openjfx:javafx-graphics:14 - {{\field{\*\fldinst{HYPERLINK https://openjdk.java.net/projects/openjfx/javafx-graphics/ }}{\fldrslt{https://openjdk.java.net/projects/openjfx/javafx-graphics/\ul0\cf0}}}}\f0\fs16 )\par
\tab LGPL 2.1:\par
\tab\tab - dbus-java (com.github.hypfvieh:dbus-java:3.0.2 - {{\field{\*\fldinst{HYPERLINK https://github.com/hypfvieh/dbus-java/dbus-java }}{\fldrslt{https://github.com/hypfvieh/dbus-java/dbus-java\ul0\cf0}}}}\f0\fs16 )\par
\tab\tab - jnr-posix (com.github.jnr:jnr-posix:3.0.54 - {{\field{\*\fldinst{HYPERLINK http://nexus.sonatype.org/oss-repository-hosting.html/jnr-posix }}{\fldrslt{http://nexus.sonatype.org/oss-repository-hosting.html/jnr-posix\ul0\cf0}}}}\f0\fs16 )\par
\tab\tab - Java Native Access (net.java.dev.jna:jna:5.1.0 - {{\field{\*\fldinst{HYPERLINK https://github.com/java-native-access/jna }}{\fldrslt{https://github.com/java-native-access/jna\ul0\cf0}}}}\f0\fs16 )\par
\tab\tab - Java Native Access Platform (net.java.dev.jna:jna-platform:5.1.0 - {{\field{\*\fldinst{HYPERLINK https://github.com/java-native-access/jna }}{\fldrslt{https://github.com/java-native-access/jna\ul0\cf0}}}}\f0\fs16 )\par
\tab MIT License:\par
\tab\tab - java jwt (com.auth0:java-jwt:3.10.2 - {{\field{\*\fldinst{HYPERLINK https://github.com/auth0/java-jwt }}{\fldrslt{https://github.com/auth0/java-jwt\ul0\cf0}}}}\f0\fs16 )\par
\tab\tab - java-utils (com.github.hypfvieh:java-utils:1.0.5 - {{\field{\*\fldinst{HYPERLINK https://github.com/hypfvieh/java-utils }}{\fldrslt{https://github.com/hypfvieh/java-utils\ul0\cf0}}}}\f0\fs16 )\par
\tab\tab - jnr-x86asm (com.github.jnr:jnr-x86asm:1.0.2 - {{\field{\*\fldinst{HYPERLINK http://github.com/jnr/jnr-x86asm }}{\fldrslt{http://github.com/jnr/jnr-x86asm\ul0\cf0}}}}\f0\fs16 )\par
\tab\tab - jnr-fuse (com.github.serceman:jnr-fuse:0.5.4 - no url defined)\par
\tab\tab - zxcvbn4j (com.nulab-inc:zxcvbn:1.3.0 - {{\field{\*\fldinst{HYPERLINK https://github.com/nulab/zxcvbn4j }}{\fldrslt{https://github.com/nulab/zxcvbn4j\ul0\cf0}}}}\f0\fs16 )\par
\tab\tab - secret-service (de.swiesend:secret-service:1.0.0-RC.3 - {{\field{\*\fldinst{HYPERLINK https://github.com/swiesend/secret-service }}{\fldrslt{https://github.com/swiesend/secret-service\ul0\cf0}}}}\f0\fs16 )\par
\tab\tab - Checker Qual (org.checkerframework:checker-qual:2.10.0 - {{\field{\*\fldinst{HYPERLINK https://checkerframework.org }}{\fldrslt{https://checkerframework.org\ul0\cf0}}}}\f0\fs16 )\par
\tab\tab - SLF4J API Module (org.slf4j:slf4j-api:1.7.30 - {{\field{\*\fldinst{HYPERLINK http://www.slf4j.org }}{\fldrslt{http://www.slf4j.org\ul0\cf0}}}}\f0\fs16 )\par
\tab The BSD 2-Clause License:\par
\tab\tab - EasyBind (org.fxmisc.easybind:easybind:1.0.3 - {{\field{\*\fldinst{HYPERLINK http://www.fxmisc.org/easybind/ }}{\fldrslt{http://www.fxmisc.org/easybind/\ul0\cf0}}}}\f0\fs16 )\par
\par
\b Cryptomator uses other third-party assets under the following licenses:\b0\par
\tab SIL OFL 1.1 License:\par
\tab\tab - Font Awesome 5.12.0 ({{\field{\*\fldinst{HYPERLINK https://fontawesome.com/ }}{\fldrslt{https://fontawesome.com/\ul0\cf0}}}}\f0\fs16 )\par
\par
}

135
dist/win/resources/main.wxs vendored Normal file
View File

@@ -0,0 +1,135 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Cryptomator's Jpackage Wix installer file
Remark: Expressions like $(var.name) are preprocessor variables, see also https://wixtoolset.org/documentation/manual/v3/overview/preprocessor.html
-->
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
<?ifdef JpIsSystemWide ?>
<?define JpInstallScope="perMachine"?>
<?else?>
<?define JpInstallScope="perUser"?>
<?endif?>
<?define JpProductLanguage=1033 ?>
<?define JpInstallerVersion=200 ?>
<?define JpCompressedMsi=yes ?>
<?ifdef JpAllowUpgrades ?>
<?define JpUpgradeVersionOnlyDetectUpgrade="no"?>
<?else?>
<?define JpUpgradeVersionOnlyDetectUpgrade="yes"?>
<?endif?>
<?ifdef JpAllowDowngrades ?>
<?define JpUpgradeVersionOnlyDetectDowngrade="no"?>
<?else?>
<?define JpUpgradeVersionOnlyDetectDowngrade="yes"?>
<?endif?>
<?include $(var.JpConfigDir)/overrides.wxi ?>
<Product Id="$(var.JpProductCode)" Name="$(var.JpAppName)" Language="$(var.JpProductLanguage)" Version="$(var.JpAppVersion)" Manufacturer="$(var.JpAppVendor)" UpgradeCode="$(var.JpProductUpgradeCode)">
<Package Description="$(var.JpAppDescription)" Manufacturer="$(var.JpAppVendor)" InstallerVersion="$(var.JpInstallerVersion)" Compressed="$(var.JpCompressedMsi)" InstallScope="$(var.JpInstallScope)" Platform="x64" />
<Media Id="1" Cabinet="Data.cab" EmbedCab="yes" />
<Upgrade Id="$(var.JpProductUpgradeCode)">
<UpgradeVersion OnlyDetect="$(var.JpUpgradeVersionOnlyDetectUpgrade)" Property="JP_UPGRADABLE_FOUND" Maximum="$(var.JpAppVersion)" MigrateFeatures="yes" IncludeMaximum="$(var.JpUpgradeVersionOnlyDetectUpgrade)" />
<UpgradeVersion OnlyDetect="$(var.JpUpgradeVersionOnlyDetectDowngrade)" Property="JP_DOWNGRADABLE_FOUND" Minimum="$(var.JpAppVersion)" MigrateFeatures="yes" IncludeMinimum="$(var.JpUpgradeVersionOnlyDetectDowngrade)" />
</Upgrade>
<?ifndef JpAllowUpgrades ?>
<CustomAction Id="JpDisallowUpgrade" Error="!(loc.DisallowUpgradeErrorMessage)" />
<?endif?>
<?ifndef JpAllowDowngrades ?>
<CustomAction Id="JpDisallowDowngrade" Error="!(loc.DowngradeErrorMessage)" />
<?endif?>
<!-- Standard required root -->
<Directory Id="TARGETDIR" Name="SourceDir"/>
<Feature Id="DefaultFeature" Title="!(loc.MainFeatureTitle)" Level="1">
<ComponentGroupRef Id="Shortcuts"/>
<ComponentGroupRef Id="Files"/>
<ComponentGroupRef Id="FileAssociations"/>
</Feature>
<?ifdef JpInstallDirChooser ?>
<Binary Id="JpCaDll" SourceFile="wixhelper.dll"/>
<CustomAction Id="JpCheckInstallDir" BinaryKey="JpCaDll" DllEntry="CheckInstallDir" />
<?endif?>
<CustomAction Id="JpSetARPINSTALLLOCATION" Property="ARPINSTALLLOCATION" Value="[INSTALLDIR]" />
<?ifdef JpIcon ?>
<Property Id="ARPPRODUCTICON" Value="JpARPPRODUCTICON"/>
<Icon Id="JpARPPRODUCTICON" SourceFile="$(var.JpIcon)"/>
<?endif?>
<UI>
<?ifdef JpInstallDirChooser ?>
<Dialog Id="JpInvalidInstallDir" Width="300" Height="85" Title="[ProductName] Setup" NoMinimize="yes">
<Control Id="JpInvalidInstallDirYes" Type="PushButton" X="100" Y="55" Width="50" Height="15" Default="no" Cancel="no" Text="Yes">
<Publish Event="NewDialog" Value="VerifyReadyDlg">1</Publish>
</Control>
<Control Id="JpInvalidInstallDirNo" Type="PushButton" X="150" Y="55" Width="50" Height="15" Default="yes" Cancel="yes" Text="No">
<Publish Event="NewDialog" Value="InstallDirDlg">1</Publish>
</Control>
<Control Id="Text" Type="Text" X="25" Y="15" Width="250" Height="30" TabSkip="no">
<Text>!(loc.message.install.dir.exist)</Text>
</Control>
</Dialog>
<!--
Run our custom wizard in the default install directory.
-->
<Property Id="WIXUI_INSTALLDIR" Value="INSTALLDIR"/>
<!-- included at the end -->
<UIRef Id="CustomWizard" />
<Publish Dialog="InstallDirDlg" Control="Next" Event="DoAction" Value="JpCheckInstallDir" Order="3">1</Publish>
<Publish Dialog="InstallDirDlg" Control="Next" Event="NewDialog" Value="JpInvalidInstallDir" Order="5">INSTALLDIR_VALID="0"</Publish>
<Publish Dialog="InstallDirDlg" Control="Next" Event="NewDialog" Value="VerifyReadyDlg" Order="5">INSTALLDIR_VALID="1"</Publish>
<?ifndef JpLicenseRtf ?>
<!--
No license file provided.
Override the dialog sequence in built-in dialog set "WixUI_InstallDir"
to exclude license dialog.
-->
<Publish Dialog="WelcomeDlg" Control="Next" Event="NewDialog" Value="InstallDirDlg" Order="2">1</Publish>
<Publish Dialog="InstallDirDlg" Control="Back" Event="NewDialog" Value="WelcomeDlg" Order="2">1</Publish>
<?endif?>
<?else?>
<?ifdef JpLicenseRtf ?>
<UIRef Id="WixUI_Minimal" />
<?endif?>
<?endif?>
</UI>
<?ifdef JpLicenseRtf ?>
<WixVariable Id="WixUILicenseRtf" Value="$(var.JpLicenseRtf)"/>
<?endif?>
<InstallExecuteSequence>
<Custom Action="JpSetARPINSTALLLOCATION" After="CostFinalize">Not Installed</Custom>
<?ifndef JpAllowUpgrades ?>
<Custom Action="JpDisallowUpgrade" After="FindRelatedProducts">JP_UPGRADABLE_FOUND</Custom>
<?endif?>
<?ifndef JpAllowDowngrades ?>
<Custom Action="JpDisallowDowngrade" After="FindRelatedProducts">JP_DOWNGRADABLE_FOUND</Custom>
<?endif?>
<RemoveExistingProducts Before="CostInitialize"/>
</InstallExecuteSequence>
<WixVariable Id="WixUIBannerBmp" Value="$(env.JP_WIXWIZARD_RESOURCES)\banner.bmp" />
<WixVariable Id="WixUIDialogBmp" Value="$(env.JP_WIXWIZARD_RESOURCES)\background.bmp" />
</Product>
<?include $(env.JP_WIXWIZARD_RESOURCES)\customWizard.wxi ?>
</Wix>

242
pom.xml
View File

@@ -23,30 +23,34 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.jdk.version>16</project.jdk.version>
<!-- Group IDs of jars that need to stay on the class path for now -->
<nonModularGroupIds>com.github.serceman,com.github.jnr,org.ow2.asm,net.java.dev.jna,org.apache.jackrabbit,org.apache.httpcomponents,de.swiesend,org.purejava,com.github.hypfvieh</nonModularGroupIds>
<!-- cryptomator dependencies -->
<cryptomator.cryptofs.version>2.1.0-beta5</cryptomator.cryptofs.version>
<cryptomator.integrations.version>1.0.0-beta2</cryptomator.integrations.version>
<cryptomator.cryptofs.version>2.1.0-beta9</cryptomator.cryptofs.version>
<cryptomator.integrations.version>1.0.0-rc1</cryptomator.integrations.version>
<cryptomator.integrations.win.version>1.0.0-beta2</cryptomator.integrations.win.version>
<cryptomator.integrations.mac.version>1.0.0-beta2</cryptomator.integrations.mac.version>
<cryptomator.integrations.linux.version>1.0.0-beta1</cryptomator.integrations.linux.version>
<cryptomator.fuse.version>1.3.1</cryptomator.fuse.version>
<cryptomator.dokany.version>1.3.1</cryptomator.dokany.version>
<cryptomator.webdav.version>1.2.2</cryptomator.webdav.version>
<cryptomator.webdav.version>1.2.5</cryptomator.webdav.version>
<!-- 3rd party dependencies -->
<javafx.version>16</javafx.version>
<commons-lang3.version>3.11</commons-lang3.version>
<jwt.version>3.15.0</jwt.version>
<easybind.version>2.1.0</easybind.version>
<commons-lang3.version>3.12.0</commons-lang3.version>
<jwt.version>3.18.1</jwt.version>
<easybind.version>2.2</easybind.version>
<guava.version>30.1.1-jre</guava.version>
<dagger.version>2.35.1</dagger.version>
<gson.version>2.8.6</gson.version>
<slf4j.version>1.7.30</slf4j.version>
<dagger.version>2.37</dagger.version>
<gson.version>2.8.7</gson.version>
<zxcvbn.version>1.5.2</zxcvbn.version>
<slf4j.version>1.7.31</slf4j.version>
<logback.version>1.2.3</logback.version>
<!-- test dependencies -->
<junit.jupiter.version>5.7.1</junit.jupiter.version>
<mockito.version>3.9.0</mockito.version>
<junit.jupiter.version>5.7.2</junit.jupiter.version>
<mockito.version>3.11.2</mockito.version>
<hamcrest.version>2.2</hamcrest.version>
</properties>
@@ -142,7 +146,7 @@
<dependency>
<groupId>com.nulab-inc</groupId>
<artifactId>zxcvbn</artifactId>
<version>1.3.0</version>
<version>${zxcvbn.version}</version>
</dependency>
<!-- Google -->
@@ -150,6 +154,29 @@
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>${guava.version}</version>
<exclusions>
<!-- see https://github.com/google/guava/wiki/UseGuavaInYourBuild#what-about-guavas-own-dependencies -->
<exclusion>
<groupId>com.google.guava</groupId>
<artifactId>listenablefuture</artifactId>
</exclusion>
<exclusion>
<groupId>com.google.code.findbugs</groupId>
<artifactId>jsr305</artifactId>
</exclusion>
<exclusion>
<groupId>org.checkerframework</groupId>
<artifactId>checker-qual</artifactId>
</exclusion>
<exclusion>
<groupId>com.google.errorprone</groupId>
<artifactId>error_prone_annotations</artifactId>
</exclusion>
<exclusion>
<groupId>com.google.j2objc</groupId>
<artifactId>j2objc-annotations</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.google.dagger</groupId>
@@ -190,7 +217,7 @@
<dependency>
<groupId>com.google.jimfs</groupId>
<artifactId>jimfs</artifactId>
<version>1.1</version>
<version>1.2</version>
<scope>test</scope>
</dependency>
</dependencies>
@@ -211,17 +238,12 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.1.2</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.3.0</version>
<version>3.2.0</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.2</version>
<version>3.0.0-M5</version>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
@@ -236,12 +258,12 @@
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.6</version>
<version>0.8.7</version>
</plugin>
<plugin>
<groupId>org.owasp</groupId>
<artifactId>dependency-check-maven</artifactId>
<version>6.0.3</version>
<version>6.2.2</version>
</plugin>
</plugins>
</pluginManagement>
@@ -258,6 +280,10 @@
<version>${dagger.version}</version>
</path>
</annotationProcessorPaths>
<compilerArgs>
<arg>-Adagger.fastInit=enabled</arg>
<arg>-Adagger.formatGeneratedSource=enabled</arg>
</compilerArgs>
</configuration>
</plugin>
<plugin>
@@ -276,40 +302,22 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<executions>
<execution>
<id>copy-resources</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}</outputDirectory>
<resources>
<resource>
<directory>${project.basedir}/src/package</directory>
<includes>
<include>version.txt</include>
<include>ffi-version.txt</include>
<include>launcher-mac.sh</include>
<include>launcher-linux.sh</include>
<include>launcher-win.bat</include>
<include>LICENSE.txt</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-mods</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<includeScope>runtime</includeScope>
<outputDirectory>${project.build.directory}/mods</outputDirectory>
<excludeGroupIds>${nonModularGroupIds}</excludeGroupIds>
</configuration>
</execution>
<execution>
<id>copy-libs</id>
<phase>prepare-package</phase>
@@ -319,7 +327,7 @@
<configuration>
<includeScope>runtime</includeScope>
<outputDirectory>${project.build.directory}/libs</outputDirectory>
<excludeClassifiers>linux,mac,win</excludeClassifiers>
<includeGroupIds>${nonModularGroupIds}</includeGroupIds>
</configuration>
</execution>
</executions>
@@ -430,48 +438,6 @@
<version>${cryptomator.integrations.mac.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<id>assemble-mac</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptors>
<descriptor>assembly-mac.xml</descriptor>
</descriptors>
<appendAssemblyId>false</appendAssemblyId>
<finalName>buildkit-mac</finalName>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-mac-libs</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/libs</outputDirectory>
<includeGroupIds>org.openjfx</includeGroupIds>
<classifier>mac</classifier>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
@@ -492,52 +458,10 @@
<version>${cryptomator.integrations.linux.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<id>assemble-linux</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptors>
<descriptor>assembly-linux.xml</descriptor>
</descriptors>
<appendAssemblyId>false</appendAssemblyId>
<finalName>buildkit-linux</finalName>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-linux-libs</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/libs</outputDirectory>
<includeGroupIds>org.openjfx</includeGroupIds>
<classifier>linux</classifier>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>windows</id>
<id>win</id>
<activation>
<os>
<family>windows</family>
@@ -553,48 +477,6 @@
<version>${cryptomator.integrations.win.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<id>assemble-win</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptors>
<descriptor>assembly-win.xml</descriptor>
</descriptors>
<appendAssemblyId>false</appendAssemblyId>
<finalName>buildkit-win</finalName>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-win-libs</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/libs</outputDirectory>
<includeGroupIds>org.openjfx</includeGroupIds>
<classifier>win</classifier>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>

View File

@@ -0,0 +1,59 @@
import org.cryptomator.integrations.autostart.AutoStartProvider;
import org.cryptomator.integrations.keychain.KeychainAccessProvider;
import org.cryptomator.integrations.tray.TrayIntegrationProvider;
import org.cryptomator.integrations.uiappearance.UiAppearanceProvider;
module org.cryptomator.desktop {
requires org.cryptomator.cryptofs;
requires org.cryptomator.frontend.dokany;
requires org.cryptomator.frontend.fuse;
requires org.cryptomator.frontend.webdav;
requires org.cryptomator.integrations.api;
requires java.desktop;
requires java.net.http;
requires javafx.base;
requires javafx.graphics;
requires javafx.controls;
requires javafx.fxml;
requires com.tobiasdiez.easybind;
requires com.google.common;
requires com.google.gson;
requires com.nulabinc.zxcvbn;
requires org.slf4j;
requires org.apache.commons.lang3;
requires dagger;
requires com.auth0.jwt;
/* TODO: filename-based modules: */
requires static javax.inject; /* ugly dagger/guava crap */
requires logback.classic;
requires logback.core;
uses AutoStartProvider;
uses KeychainAccessProvider;
uses TrayIntegrationProvider;
uses UiAppearanceProvider;
opens org.cryptomator.common.settings to com.google.gson;
opens org.cryptomator.common to javafx.fxml;
opens org.cryptomator.common.vaults to javafx.fxml;
opens org.cryptomator.ui.addvaultwizard to javafx.fxml;
opens org.cryptomator.ui.changepassword to javafx.fxml;
opens org.cryptomator.ui.common to javafx.fxml;
opens org.cryptomator.ui.controls to javafx.fxml;
opens org.cryptomator.ui.forgetPassword to javafx.fxml;
opens org.cryptomator.ui.fxapp to javafx.fxml;
opens org.cryptomator.ui.health to javafx.fxml;
opens org.cryptomator.ui.keyloading.masterkeyfile to javafx.fxml;
opens org.cryptomator.ui.mainwindow to javafx.fxml;
opens org.cryptomator.ui.migration to javafx.fxml;
opens org.cryptomator.ui.preferences to javafx.fxml;
opens org.cryptomator.ui.quit to javafx.fxml;
opens org.cryptomator.ui.recoverykey to javafx.fxml;
opens org.cryptomator.ui.removevault to javafx.fxml;
opens org.cryptomator.ui.stats to javafx.fxml;
opens org.cryptomator.ui.unlock to javafx.fxml;
opens org.cryptomator.ui.vaultoptions to javafx.fxml;
opens org.cryptomator.ui.wrongfilealert to javafx.fxml;
}

View File

@@ -46,6 +46,7 @@ public abstract class CommonsModule {
private static final int NUM_CORE_BG_THREADS = 6;
private static final long BG_THREAD_KEEPALIVE_SECONDS = 60l;
@SuppressWarnings("SpellCheckingInspection")
@Provides
@Singleton
@Named("licensePublicKey")

View File

@@ -33,7 +33,7 @@ public class Environment {
LOG.debug("user.region: {}", System.getProperty("user.region"));
LOG.debug("logback.configurationFile: {}", System.getProperty("logback.configurationFile"));
LOG.debug("cryptomator.settingsPath: {}", System.getProperty("cryptomator.settingsPath"));
LOG.debug("cryptomator.ipcPortPath: {}", System.getProperty("cryptomator.ipcPortPath"));
LOG.debug("cryptomator.ipcSocketPath: {}", System.getProperty("cryptomator.ipcSocketPath"));
LOG.debug("cryptomator.keychainPath: {}", System.getProperty("cryptomator.keychainPath"));
LOG.debug("cryptomator.logDir: {}", System.getProperty("cryptomator.logDir"));
LOG.debug("cryptomator.mountPointsDir: {}", System.getProperty("cryptomator.mountPointsDir"));
@@ -51,8 +51,8 @@ public class Environment {
return getPaths("cryptomator.settingsPath");
}
public Stream<Path> getIpcPortPath() {
return getPaths("cryptomator.ipcPortPath");
public Stream<Path> ipcSocketPath() {
return getPaths("cryptomator.ipcSocketPath");
}
public Stream<Path> getKeychainPath() {
@@ -99,12 +99,12 @@ public class Environment {
}
// visible for testing
Path getHomeDir() {
public Path getHomeDir() {
return getPath("user.home").orElseThrow();
}
// visible for testing
Stream<Path> getPaths(String propertyName) {
public Stream<Path> getPaths(String propertyName) {
Stream<String> rawSettingsPaths = getRawList(propertyName, PATH_LIST_SEP);
return rawSettingsPaths.filter(Predicate.not(Strings::isNullOrEmpty)).map(Paths::get).map(this::replaceHomeDir);
}
@@ -123,8 +123,8 @@ public class Environment {
return Stream.empty();
} else {
Iterable<String> iter = Splitter.on(separator).split(value);
Spliterator<String> spliter = Spliterators.spliteratorUnknownSize(iter.iterator(), Spliterator.ORDERED | Spliterator.IMMUTABLE);
return StreamSupport.stream(spliter, false);
Spliterator<String> spliterator = Spliterators.spliteratorUnknownSize(iter.iterator(), Spliterator.ORDERED | Spliterator.IMMUTABLE);
return StreamSupport.stream(spliterator, false);
}
}
}

View File

@@ -0,0 +1,8 @@
package org.cryptomator.common;
/**
* Replacement for JSR-305 to avoid runtime dependencies. Used in Dagger components.
*/
public @interface Nullable {
}

View File

@@ -60,17 +60,17 @@ public class SemVerComparator implements Comparator<String> {
final int commonCompCount = Math.min(vComps1.length, vComps2.length);
for (int i = 0; i < commonCompCount; i++) {
int subversionComparisionResult = 0;
int subversionComparisonResult = 0;
try {
final int v1 = Integer.parseInt(vComps1[i]);
final int v2 = Integer.parseInt(vComps2[i]);
subversionComparisionResult = v1 - v2;
subversionComparisonResult = v1 - v2;
} catch (NumberFormatException ex) {
// ok, lets compare this fragment lexicographically
subversionComparisionResult = vComps1[i].compareTo(vComps2[i]);
subversionComparisonResult = vComps1[i].compareTo(vComps2[i]);
}
if (subversionComparisionResult != 0) {
return subversionComparisionResult;
if (subversionComparisonResult != 0) {
return subversionComparisonResult;
}
}

View File

@@ -59,8 +59,10 @@ public class KeychainManager implements KeychainAccessProvider {
@Override
public void changePassphrase(String key, CharSequence passphrase) throws KeychainAccessException {
getKeychainOrFail().changePassphrase(key, passphrase);
setPassphraseStored(key, true);
if (isPassphraseStored(key)) {
getKeychainOrFail().changePassphrase(key, passphrase);
setPassphraseStored(key, true);
}
}
@Override

View File

@@ -34,11 +34,11 @@ public class KeychainModule {
@Singleton
static ObjectExpression<KeychainAccessProvider> provideKeychainAccessProvider(Settings settings, Set<KeychainAccessProvider> providers) {
return Bindings.createObjectBinding(() -> {
var selectedProviderClass = settings.keychainBackend().get().getProviderClass();
var selectedProviderClass = settings.keychainProvider().get();
var selectedProvider = providers.stream().filter(provider -> provider.getClass().getName().equals(selectedProviderClass)).findAny();
var fallbackProvider = providers.stream().findAny().orElse(null);
return selectedProvider.orElse(fallbackProvider);
}, settings.keychainBackend());
}, settings.keychainProvider());
}
}

View File

@@ -1,6 +1,6 @@
package org.cryptomator.common.mountpoint;
import com.google.common.base.Preconditions;
import dagger.multibindings.IntKey;
import org.cryptomator.common.vaults.Volume;
import java.nio.file.Path;
@@ -12,13 +12,13 @@ import java.util.SortedSet;
* preparation of a mountpoint or an exception otherwise.<br>
* <p>All <i>MountPointChoosers (MPCs)</i> need to implement this class and must be added to
* the pool of possible MPCs by the {@link MountPointChooserModule MountPointChooserModule.}
* The MountPointChooserModule will sort them according to their {@link #getPriority() priority.}
* The MountPointChooserModule will sort them according to their {@link IntKey IntKey priority.}
* The priority must be defined by the developer to reflect a useful execution order.<br>
* A specific priority <b>must not</b> be assigned to more than one MPC at a time;
* the result of having two MPCs with equal priority is undefined.
*
* <p>MPCs are executed by a {@link Volume} in ascending order of their priority
* (smaller priorities are tried first) to find and prepare a suitable mountpoint for the volume.
* <p>MPCs are executed by a {@link Volume} in descending order of their priority
* (higher priorities are tried first) to find and prepare a suitable mountpoint for the volume.
* The volume has access to a {@link SortedSet} of MPCs in this specific order,
* that is provided by the Module. The Set contains all available Choosers, even if they
* are not {@link #isApplicable(Volume) applicable} for the Vault/Volume. The Volume must

View File

@@ -9,6 +9,7 @@ import dagger.multibindings.IntoMap;
import org.cryptomator.common.vaults.PerVault;
import javax.inject.Named;
import java.util.Comparator;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;
@@ -24,16 +25,22 @@ public abstract class MountPointChooserModule {
@Binds
@IntoMap
@IntKey(0)
@IntKey(1000)
@PerVault
public abstract MountPointChooser bindCustomMountPointChooser(CustomMountPointChooser chooser);
@Binds
@IntoMap
@IntKey(100)
@IntKey(900)
@PerVault
public abstract MountPointChooser bindCustomDriveLetterChooser(CustomDriveLetterChooser chooser);
@Binds
@IntoMap
@IntKey(800)
@PerVault
public abstract MountPointChooser bindAvailableDriveLetterChooser(AvailableDriveLetterChooser chooser);
@Binds
@IntoMap
@IntKey(101)
@@ -42,13 +49,7 @@ public abstract class MountPointChooserModule {
@Binds
@IntoMap
@IntKey(200)
@PerVault
public abstract MountPointChooser bindAvailableDriveLetterChooser(AvailableDriveLetterChooser chooser);
@Binds
@IntoMap
@IntKey(999)
@IntKey(100)
@PerVault
public abstract MountPointChooser bindTemporaryMountPointChooser(TemporaryMountPointChooser chooser);
@@ -56,7 +57,8 @@ public abstract class MountPointChooserModule {
@PerVault
@Named("orderedMountPointChoosers")
public static Iterable<MountPointChooser> provideOrderedMountPointChoosers(Map<Integer, MountPointChooser> choosers) {
SortedMap<Integer, MountPointChooser> sortedChoosers = new TreeMap<>(choosers);
SortedMap<Integer, MountPointChooser> sortedChoosers = new TreeMap<>(Comparator.reverseOrder());
sortedChoosers.putAll(choosers);
return Iterables.unmodifiableIterable(sortedChoosers.values());
}
}

View File

@@ -1,19 +0,0 @@
package org.cryptomator.common.settings;
public enum KeychainBackend {
GNOME("org.cryptomator.linux.keychain.SecretServiceKeychainAccess"),
KDE("org.cryptomator.linux.keychain.KDEWalletKeychainAccess"),
MAC_SYSTEM_KEYCHAIN("org.cryptomator.macos.keychain.MacSystemKeychainAccess"),
WIN_SYSTEM_KEYCHAIN("org.cryptomator.windows.keychain.WindowsProtectedKeychainAccess");
private final String providerClass;
KeychainBackend(String providerClass) {
this.providerClass = providerClass;
}
public String getProviderClass() {
return providerClass;
}
}

View File

@@ -30,7 +30,7 @@ public class Settings {
public static final int MIN_PORT = 1024;
public static final int MAX_PORT = 65535;
public static final boolean DEFAULT_ASKED_FOR_UPDATE_CHECK = false;
public static final boolean DEFAULT_CHECK_FOR_UDPATES = false;
public static final boolean DEFAULT_CHECK_FOR_UPDATES = false;
public static final boolean DEFAULT_START_HIDDEN = false;
public static final int DEFAULT_PORT = 42427;
public static final int DEFAULT_NUM_TRAY_NOTIFICATIONS = 3;
@@ -38,14 +38,15 @@ public class Settings {
public static final boolean DEFAULT_DEBUG_MODE = false;
public static final VolumeImpl DEFAULT_PREFERRED_VOLUME_IMPL = SystemUtils.IS_OS_WINDOWS ? VolumeImpl.DOKANY : VolumeImpl.FUSE;
public static final UiTheme DEFAULT_THEME = UiTheme.LIGHT;
public static final KeychainBackend DEFAULT_KEYCHAIN_BACKEND = SystemUtils.IS_OS_WINDOWS ? KeychainBackend.WIN_SYSTEM_KEYCHAIN : SystemUtils.IS_OS_MAC ? KeychainBackend.MAC_SYSTEM_KEYCHAIN : KeychainBackend.GNOME;
@Deprecated // to be changed to "whatever is available" eventually
public static final String DEFAULT_KEYCHAIN_PROVIDER = SystemUtils.IS_OS_WINDOWS ? "org.cryptomator.windows.keychain.WindowsProtectedKeychainAccess" : SystemUtils.IS_OS_MAC ? "org.cryptomator.macos.keychain.MacSystemKeychainAccess" : "org.cryptomator.linux.keychain.SecretServiceKeychainAccess";
public static final NodeOrientation DEFAULT_USER_INTERFACE_ORIENTATION = NodeOrientation.LEFT_TO_RIGHT;
public static final String DEFAULT_LICENSE_KEY = "";
public static final boolean DEFAULT_SHOW_MINIMIZE_BUTTON = false;
private final ObservableList<VaultSettings> directories = FXCollections.observableArrayList(VaultSettings::observables);
private final BooleanProperty askedForUpdateCheck = new SimpleBooleanProperty(DEFAULT_ASKED_FOR_UPDATE_CHECK);
private final BooleanProperty checkForUpdates = new SimpleBooleanProperty(DEFAULT_CHECK_FOR_UDPATES);
private final BooleanProperty checkForUpdates = new SimpleBooleanProperty(DEFAULT_CHECK_FOR_UPDATES);
private final BooleanProperty startHidden = new SimpleBooleanProperty(DEFAULT_START_HIDDEN);
private final IntegerProperty port = new SimpleIntegerProperty(DEFAULT_PORT);
private final IntegerProperty numTrayNotifications = new SimpleIntegerProperty(DEFAULT_NUM_TRAY_NOTIFICATIONS);
@@ -53,7 +54,7 @@ public class Settings {
private final BooleanProperty debugMode = new SimpleBooleanProperty(DEFAULT_DEBUG_MODE);
private final ObjectProperty<VolumeImpl> preferredVolumeImpl = new SimpleObjectProperty<>(DEFAULT_PREFERRED_VOLUME_IMPL);
private final ObjectProperty<UiTheme> theme = new SimpleObjectProperty<>(DEFAULT_THEME);
private final ObjectProperty<KeychainBackend> keychainBackend = new SimpleObjectProperty<>(DEFAULT_KEYCHAIN_BACKEND);
private final ObjectProperty<String> keychainProvider = new SimpleObjectProperty<>(DEFAULT_KEYCHAIN_PROVIDER);
private final ObjectProperty<NodeOrientation> userInterfaceOrientation = new SimpleObjectProperty<>(DEFAULT_USER_INTERFACE_ORIENTATION);
private final StringProperty licenseKey = new SimpleStringProperty(DEFAULT_LICENSE_KEY);
private final BooleanProperty showMinimizeButton = new SimpleBooleanProperty(DEFAULT_SHOW_MINIMIZE_BUTTON);
@@ -77,7 +78,7 @@ public class Settings {
debugMode.addListener(this::somethingChanged);
preferredVolumeImpl.addListener(this::somethingChanged);
theme.addListener(this::somethingChanged);
keychainBackend.addListener(this::somethingChanged);
keychainProvider.addListener(this::somethingChanged);
userInterfaceOrientation.addListener(this::somethingChanged);
licenseKey.addListener(this::somethingChanged);
showMinimizeButton.addListener(this::somethingChanged);
@@ -140,7 +141,7 @@ public class Settings {
return theme;
}
public ObjectProperty<KeychainBackend> keychainBackend() { return keychainBackend; }
public ObjectProperty<String> keychainProvider() { return keychainProvider; }
public ObjectProperty<NodeOrientation> userInterfaceOrientation() {
return userInterfaceOrientation;

View File

@@ -48,7 +48,7 @@ public class SettingsJsonAdapter extends TypeAdapter<Settings> {
out.name("preferredVolumeImpl").value(value.preferredVolumeImpl().get().name());
out.name("theme").value(value.theme().get().name());
out.name("uiOrientation").value(value.userInterfaceOrientation().get().name());
out.name("keychainBackend").value(value.keychainBackend().get().name());
out.name("keychainProvider").value(value.keychainProvider().get());
out.name("licenseKey").value(value.licenseKey().get());
out.name("showMinimizeButton").value(value.showMinimizeButton().get());
out.name("showTrayIcon").value(value.showTrayIcon().get());
@@ -82,7 +82,7 @@ public class SettingsJsonAdapter extends TypeAdapter<Settings> {
case "preferredVolumeImpl" -> settings.preferredVolumeImpl().set(parsePreferredVolumeImplName(in.nextString()));
case "theme" -> settings.theme().set(parseUiTheme(in.nextString()));
case "uiOrientation" -> settings.userInterfaceOrientation().set(parseUiOrientation(in.nextString()));
case "keychainBackend" -> settings.keychainBackend().set(parseKeychainBackend(in.nextString()));
case "keychainProvider" -> settings.keychainProvider().set(in.nextString());
case "licenseKey" -> settings.licenseKey().set(in.nextString());
case "showMinimizeButton" -> settings.showMinimizeButton().set(in.nextBoolean());
case "showTrayIcon" -> settings.showTrayIcon().set(in.nextBoolean());
@@ -124,15 +124,6 @@ public class SettingsJsonAdapter extends TypeAdapter<Settings> {
}
}
private KeychainBackend parseKeychainBackend(String backendName) {
try {
return KeychainBackend.valueOf(backendName.toUpperCase());
} catch (IllegalArgumentException e) {
LOG.warn("Invalid keychain backend {}. Defaulting to {}.", backendName, Settings.DEFAULT_KEYCHAIN_BACKEND);
return Settings.DEFAULT_KEYCHAIN_BACKEND;
}
}
private NodeOrientation parseUiOrientation(String uiOrientationName) {
try {
return NodeOrientation.valueOf(uiOrientationName.toUpperCase());

View File

@@ -101,7 +101,7 @@ public class SettingsProvider implements Supplier<Settings> {
if (settings == null) {
return;
}
final Optional<Path> settingsPath = env.getSettingsPath().findFirst(); // alway save to preferred (first) path
final Optional<Path> settingsPath = env.getSettingsPath().findFirst(); // always save to preferred (first) path
settingsPath.ifPresent(path -> {
Runnable saveCommand = () -> this.save(settings, path);
ScheduledFuture<?> scheduledTask = scheduler.schedule(saveCommand, SAVE_DELAY_MS, TimeUnit.MILLISECONDS);

View File

@@ -31,7 +31,7 @@ import java.util.Random;
public class VaultSettings {
public static final boolean DEFAULT_UNLOCK_AFTER_STARTUP = false;
public static final boolean DEFAULT_REAVEAL_AFTER_MOUNT = true;
public static final boolean DEFAULT_REVEAL_AFTER_MOUNT = true;
public static final boolean DEFAULT_USES_INDIVIDUAL_MOUNTPATH = false;
public static final boolean DEFAULT_USES_READONLY_MODE = false;
public static final String DEFAULT_MOUNT_FLAGS = "";
@@ -43,11 +43,11 @@ public class VaultSettings {
private static final Random RNG = new Random();
private final String id;
private final ObjectProperty<Path> path = new SimpleObjectProperty();
private final ObjectProperty<Path> path = new SimpleObjectProperty<>();
private final StringProperty displayName = new SimpleStringProperty();
private final StringProperty winDriveLetter = new SimpleStringProperty();
private final BooleanProperty unlockAfterStartup = new SimpleBooleanProperty(DEFAULT_UNLOCK_AFTER_STARTUP);
private final BooleanProperty revealAfterMount = new SimpleBooleanProperty(DEFAULT_REAVEAL_AFTER_MOUNT);
private final BooleanProperty revealAfterMount = new SimpleBooleanProperty(DEFAULT_REVEAL_AFTER_MOUNT);
private final BooleanProperty useCustomMountPath = new SimpleBooleanProperty(DEFAULT_USES_INDIVIDUAL_MOUNTPATH);
private final StringProperty customMountPath = new SimpleStringProperty();
private final BooleanProperty usesReadOnlyMode = new SimpleBooleanProperty(DEFAULT_USES_READONLY_MODE);

View File

@@ -44,7 +44,7 @@ class VaultSettingsJsonAdapter {
String customMountPath = null;
String winDriveLetter = null;
boolean unlockAfterStartup = VaultSettings.DEFAULT_UNLOCK_AFTER_STARTUP;
boolean revealAfterMount = VaultSettings.DEFAULT_REAVEAL_AFTER_MOUNT;
boolean revealAfterMount = VaultSettings.DEFAULT_REVEAL_AFTER_MOUNT;
boolean useCustomMountPath = VaultSettings.DEFAULT_USES_INDIVIDUAL_MOUNTPATH;
boolean usesReadOnlyMode = VaultSettings.DEFAULT_USES_READONLY_MODE;
String mountFlags = VaultSettings.DEFAULT_MOUNT_FLAGS;

View File

@@ -19,6 +19,7 @@ import org.cryptomator.cryptofs.CryptoFileSystemProperties.FileSystemFlags;
import org.cryptomator.cryptofs.CryptoFileSystemProvider;
import org.cryptomator.cryptofs.VaultConfig;
import org.cryptomator.cryptofs.VaultConfig.UnverifiedVaultConfig;
import org.cryptomator.cryptofs.VaultConfigLoadException;
import org.cryptomator.cryptofs.common.FileSystemCapabilityChecker;
import org.cryptomator.cryptolib.api.CryptoException;
import org.cryptomator.cryptolib.api.MasterkeyLoader;
@@ -327,6 +328,14 @@ public class Vault {
return stats;
}
/**
* Attempts to read the vault config file and parse it without verifying its integrity.
*
* @return an unverified vault config
* @throws VaultConfigLoadException if the read file cannot be properly parsed
* @throws IOException if reading the file fails
*
*/
public UnverifiedVaultConfig getUnverifiedVaultConfig() throws IOException {
Path configPath = getPath().resolve(org.cryptomator.common.Constants.VAULTCONFIG_FILENAME);
String token = Files.readString(configPath, StandardCharsets.US_ASCII);

View File

@@ -7,10 +7,10 @@ package org.cryptomator.common.vaults;
import dagger.BindsInstance;
import dagger.Subcomponent;
import org.cryptomator.common.Nullable;
import org.cryptomator.common.mountpoint.MountPointChooserModule;
import org.cryptomator.common.settings.VaultSettings;
import javax.annotation.Nullable;
import javax.inject.Named;
@PerVault

View File

@@ -8,6 +8,7 @@ package org.cryptomator.common.vaults;
import dagger.Module;
import dagger.Provides;
import org.apache.commons.lang3.SystemUtils;
import org.cryptomator.common.Nullable;
import org.cryptomator.common.settings.Settings;
import org.cryptomator.common.settings.VaultSettings;
import org.cryptomator.common.settings.VolumeImpl;
@@ -15,7 +16,6 @@ import org.cryptomator.cryptofs.CryptoFileSystem;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.Nullable;
import javax.inject.Named;
import javafx.beans.binding.Bindings;
import javafx.beans.binding.StringBinding;
@@ -138,7 +138,7 @@ public class VaultModule {
// see https://github.com/billziss-gh/winfsp/blob/5d0b10d0b643652c00ebb4704dc2bb28e7244973/src/dll/fuse/fuse_main.c#L53-L62 for syntax guide
// see https://github.com/billziss-gh/winfsp/blob/5d0b10d0b643652c00ebb4704dc2bb28e7244973/src/dll/fuse/fuse.c#L295-L319 for options (-o <...>)
// see https://github.com/billziss-gh/winfsp/wiki/Frequently-Asked-Questions/5ba00e4be4f5e938eaae6ef1500b331de12dee77 (FUSE 4.) on why the given defaults were choosen
// see https://github.com/billziss-gh/winfsp/wiki/Frequently-Asked-Questions/5ba00e4be4f5e938eaae6ef1500b331de12dee77 (FUSE 4.) on why the given defaults were chosen
private String getWindowsFuseDefaultMountFlags(StringBinding mountName, ReadOnlyBooleanProperty readOnly) {
assert SystemUtils.IS_OS_WINDOWS;
StringBuilder flags = new StringBuilder();

View File

@@ -46,7 +46,7 @@ public class VaultState extends ObservableValueBase<VaultState.Value> implements
UNLOCKED,
/**
* Unknown state due to preceeding unrecoverable exceptions.
* Unknown state due to preceding unrecoverable exceptions.
*/
ERROR;
}

View File

@@ -35,8 +35,8 @@ public class VaultStats {
private final LongProperty bytesPerSecondEncrypted = new SimpleLongProperty();
private final LongProperty bytesPerSecondDecrypted = new SimpleLongProperty();
private final DoubleProperty cacheHitRate = new SimpleDoubleProperty();
private final LongProperty toalBytesRead = new SimpleLongProperty();
private final LongProperty toalBytesWritten = new SimpleLongProperty();
private final LongProperty totalBytesRead = new SimpleLongProperty();
private final LongProperty totalBytesWritten = new SimpleLongProperty();
private final LongProperty totalBytesEncrypted = new SimpleLongProperty();
private final LongProperty totalBytesDecrypted = new SimpleLongProperty();
private final LongProperty filesRead = new SimpleLongProperty();
@@ -75,8 +75,8 @@ public class VaultStats {
cacheHitRate.set(stats.map(this::getCacheHitRate).orElse(0.0));
bytesPerSecondDecrypted.set(stats.map(CryptoFileSystemStats::pollBytesDecrypted).orElse(0L));
bytesPerSecondEncrypted.set(stats.map(CryptoFileSystemStats::pollBytesEncrypted).orElse(0L));
toalBytesRead.set(stats.map(CryptoFileSystemStats::pollTotalBytesRead).orElse(0L));
toalBytesWritten.set(stats.map(CryptoFileSystemStats::pollTotalBytesWritten).orElse(0L));
totalBytesRead.set(stats.map(CryptoFileSystemStats::pollTotalBytesRead).orElse(0L));
totalBytesWritten.set(stats.map(CryptoFileSystemStats::pollTotalBytesWritten).orElse(0L));
totalBytesEncrypted.set(stats.map(CryptoFileSystemStats::pollTotalBytesEncrypted).orElse(0L));
totalBytesDecrypted.set(stats.map(CryptoFileSystemStats::pollTotalBytesDecrypted).orElse(0L));
var oldAccessCount = filesRead.get() + filesWritten.get();
@@ -146,7 +146,7 @@ public class VaultStats {
return bytesPerSecondEncrypted;
}
public long getBytesPerSecondEnrypted() {
public long getBytesPerSecondEncrypted() {
return bytesPerSecondEncrypted.get();
}
@@ -164,13 +164,13 @@ public class VaultStats {
return cacheHitRate.get();
}
public LongProperty toalBytesReadProperty() {return toalBytesRead;}
public LongProperty totalBytesReadProperty() {return totalBytesRead;}
public long getTotalBytesRead() { return toalBytesRead.get();}
public long getTotalBytesRead() { return totalBytesRead.get();}
public LongProperty toalBytesWrittenProperty() {return toalBytesWritten;}
public LongProperty totalBytesWrittenProperty() {return totalBytesWritten;}
public long getTotalBytesWritten() { return toalBytesWritten.get();}
public long getTotalBytesWritten() { return totalBytesWritten.get();}
public LongProperty totalBytesEncryptedProperty() {return totalBytesEncrypted;}

View File

@@ -12,7 +12,7 @@ import java.util.function.Consumer;
import java.util.stream.Stream;
/**
* Takes a Volume and usess it to mount an unlocked vault
* Takes a Volume and uses it to mount an unlocked vault
*/
public interface Volume {
@@ -24,7 +24,7 @@ public interface Volume {
boolean isSupported();
/**
* Gets the coresponding enum type of the {@link VolumeImpl volume implementation ("VolumeImpl")} that is implemented by this Volume.
* Gets the corresponding enum type of the {@link VolumeImpl volume implementation ("VolumeImpl")} that is implemented by this Volume.
*
* @return the type of implementation as defined by the {@link VolumeImpl VolumeImpl enum}
*/

View File

@@ -67,7 +67,7 @@ public class WebDavVolume implements Volume {
throw new IllegalStateException("Mounting requires unlocked WebDAV servlet.");
}
//on windows, prevent an automatic drive letter selection in the upstream library. Either we choose already a specifc one or there is no free.
//on windows, prevent an automatic drive letter selection in the upstream library. Either we choose already a specific one or there is no free.
Supplier<String> driveLetterSupplier;
if (System.getProperty("os.name").toLowerCase().contains("windows") && vaultSettings.winDriveLetter().isEmpty().get()) {
driveLetterSupplier = () -> windowsDriveLetters.getAvailableDriveLetter().orElse(null);

View File

@@ -0,0 +1,65 @@
package org.cryptomator.ipc;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.net.UnixDomainSocketAddress;
import java.nio.channels.SocketChannel;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.concurrent.Executor;
class Client implements IpcCommunicator {
private static final Logger LOG = LoggerFactory.getLogger(Client.class);
private final SocketChannel socketChannel;
private Client(SocketChannel socketChannel) {
this.socketChannel = socketChannel;
}
public static Client create(Path socketPath) throws IOException {
var address = UnixDomainSocketAddress.of(socketPath);
var socketChannel = SocketChannel.open(address);
LOG.info("Connected to IPC server on socket {}", socketPath);
return new Client(socketChannel);
}
@Override
public boolean isClient() {
return true;
}
@Override
public void listen(IpcMessageListener listener, Executor executor) {
executor.execute(() -> {
try {
while (socketChannel.isConnected()) {
var msg = IpcMessage.receive(socketChannel);
listener.handleMessage(msg);
}
} catch (IOException e) {
LOG.error("Failed to read IPC message", e);
}
});
}
@Override
public void send(IpcMessage message, Executor executor) {
executor.execute(() -> {
try {
message.send(socketChannel);
} catch (IOException e) {
LOG.error("Failed to send IPC message", e);
}
});
}
@Override
public void close() throws IOException {
socketChannel.close();
}
}

View File

@@ -0,0 +1,30 @@
package org.cryptomator.ipc;
import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.List;
record HandleLaunchArgsMessage(List<String> args) implements IpcMessage {
private static final char DELIMITER = '\n';
public static HandleLaunchArgsMessage decode(ByteBuffer encoded) {
var str = StandardCharsets.UTF_8.decode(encoded).toString();
var args = Splitter.on(DELIMITER).omitEmptyStrings().splitToList(str);
return new HandleLaunchArgsMessage(args);
}
@Override
public MessageType getMessageType() {
return MessageType.HANDLE_LAUNCH_ARGS;
}
@Override
public ByteBuffer encodePayload() {
var str = Joiner.on(DELIMITER).join(args);
return StandardCharsets.UTF_8.encode(str);
}
}

View File

@@ -0,0 +1,96 @@
package org.cryptomator.ipc;
import com.google.common.base.Preconditions;
import com.google.common.util.concurrent.MoreExecutors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.Closeable;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.concurrent.Future;
public interface IpcCommunicator extends Closeable {
Logger LOG = LoggerFactory.getLogger(IpcCommunicator.class);
/**
* Attempts to establish a socket connection via one of the given paths.
* <p>
* If no connection to an existing sockets can be established, a new socket is created for the first given path.
* <p>
* If this fails as well, a fallback communicator is returned that allows process-internal communication mocking the API
* that would have been used for IPC.
*
* @param socketPaths The socket path(s)
* @return A communicator object that allows sending and receiving messages
*/
static IpcCommunicator create(Iterable<Path> socketPaths) {
Preconditions.checkArgument(socketPaths.iterator().hasNext(), "socketPaths must contain at least one element");
for (var p : socketPaths) {
try {
var attr = Files.readAttributes(p, BasicFileAttributes.class);
if (attr.isOther()) {
return Client.create(p);
}
} catch (IOException e) {
// attempt next socket path
}
}
// Didn't get any connection yet? I.e. we're the first app instance, so let's launch a server:
try {
return Server.create(socketPaths.iterator().next());
} catch (IOException e) {
LOG.warn("Failed to create IPC server", e);
return new LoopbackCommunicator();
}
}
boolean isClient();
/**
* Listens to incoming messages until the connection gets closed.
* @param listener The listener that should be notified of incoming messages
* @param executor An executor on which to listen. Listening will block, so you might want to use a background thread.
* @return
*/
void listen(IpcMessageListener listener, Executor executor);
/**
* Sends the given message.
*
* @param message The message to send
* @param executor An executor used to send the message. Sending will block, so you might want to use a background thread.
*/
void send(IpcMessage message, Executor executor);
default void sendRevealRunningApp() {
send(new RevealRunningAppMessage(), MoreExecutors.directExecutor());
}
default void sendHandleLaunchargs(List<String> args) {
send(new HandleLaunchArgsMessage(args), MoreExecutors.directExecutor());
}
/**
* Clean up resources.
*
* @implSpec Must be idempotent
* @throws IOException In case of I/O errors.
*/
@Override
void close() throws IOException;
default void closeUnchecked() throws UncheckedIOException {
try {
close();
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
}

View File

@@ -0,0 +1,68 @@
package org.cryptomator.ipc;
import org.cryptomator.cryptolib.common.ByteBuffers;
import java.io.EOFException;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel;
import java.util.function.Function;
// TODO make sealed, remove enum
interface IpcMessage {
enum MessageType {
REVEAL_RUNNING_APP(RevealRunningAppMessage::decode),
HANDLE_LAUNCH_ARGS(HandleLaunchArgsMessage::decode);
private final Function<ByteBuffer, IpcMessage> decoder;
MessageType(Function<ByteBuffer, IpcMessage> decoder) {
this.decoder = decoder;
}
static MessageType forOrdinal(int ordinal) {
try {
return values()[ordinal];
} catch (IndexOutOfBoundsException e) {
throw new IllegalArgumentException("No such message type: " + ordinal, e);
}
}
IpcMessage decodePayload(ByteBuffer payload) {
return decoder.apply(payload);
}
}
MessageType getMessageType();
ByteBuffer encodePayload();
static IpcMessage receive(ReadableByteChannel channel) throws IOException {
var header = ByteBuffer.allocate(2 * Integer.BYTES);
if (ByteBuffers.fill(channel, header) < header.capacity()) {
throw new EOFException();
}
header.flip();
int typeNo = header.getInt();
int length = header.getInt();
MessageType type = MessageType.forOrdinal(typeNo);
var payload = ByteBuffer.allocate(length);
ByteBuffers.fill(channel, payload);
payload.flip();
return type.decodePayload(payload);
}
default void send(WritableByteChannel channel) throws IOException {
var payload = encodePayload();
var buf = ByteBuffer.allocate(2 * Integer.BYTES + payload.remaining());
buf.putInt(getMessageType().ordinal()); // message type
buf.putInt(payload.remaining()); // message length
buf.put(payload); // message
buf.flip();
while (buf.hasRemaining()) {
channel.write(buf);
}
}
}

View File

@@ -0,0 +1,19 @@
package org.cryptomator.ipc;
import java.util.List;
public interface IpcMessageListener {
default void handleMessage(IpcMessage message) {
if (message instanceof RevealRunningAppMessage) {
revealRunningApp();
} else if (message instanceof HandleLaunchArgsMessage m) {
handleLaunchArgs(m.args());
}
}
void revealRunningApp();
void handleLaunchArgs(List<String> args);
}

View File

@@ -0,0 +1,50 @@
package org.cryptomator.ipc;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.concurrent.Executor;
import java.util.concurrent.LinkedTransferQueue;
import java.util.concurrent.TransferQueue;
class LoopbackCommunicator implements IpcCommunicator {
private static final Logger LOG = LoggerFactory.getLogger(LoopbackCommunicator.class);
private final TransferQueue<IpcMessage> transferQueue = new LinkedTransferQueue<>();
@Override
public boolean isClient() {
return false;
}
@Override
public void listen(IpcMessageListener listener, Executor executor) {
executor.execute(() -> {
try {
var msg = transferQueue.take();
listener.handleMessage(msg);
} catch (InterruptedException e) {
LOG.error("Failed to read IPC message", e);
Thread.currentThread().interrupt();
}
});
}
@Override
public void send(IpcMessage message, Executor executor) {
executor.execute(() -> {
try {
transferQueue.put(message);
} catch (InterruptedException e) {
LOG.error("Failed to send IPC message", e);
Thread.currentThread().interrupt();
}
});
}
@Override
public void close() {
// no-op
}
}

View File

@@ -0,0 +1,20 @@
package org.cryptomator.ipc;
import java.nio.ByteBuffer;
public record RevealRunningAppMessage() implements IpcMessage {
static RevealRunningAppMessage decode(ByteBuffer ignored) {
return new RevealRunningAppMessage();
}
@Override
public MessageType getMessageType() {
return MessageType.REVEAL_RUNNING_APP;
}
@Override
public ByteBuffer encodePayload() {
return ByteBuffer.allocate(0);
}
}

View File

@@ -0,0 +1,82 @@
package org.cryptomator.ipc;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.EOFException;
import java.io.IOException;
import java.net.StandardProtocolFamily;
import java.net.UnixDomainSocketAddress;
import java.nio.channels.AsynchronousCloseException;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.ServerSocketChannel;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.concurrent.Executor;
class Server implements IpcCommunicator {
private static final Logger LOG = LoggerFactory.getLogger(Server.class);
private final ServerSocketChannel serverSocketChannel;
private final Path socketPath;
private Server(ServerSocketChannel serverSocketChannel, Path socketPath) {
this.serverSocketChannel = serverSocketChannel;
this.socketPath = socketPath;
}
public static Server create(Path socketPath) throws IOException {
var address = UnixDomainSocketAddress.of(socketPath);
var serverSocketChannel = ServerSocketChannel.open(StandardProtocolFamily.UNIX);
serverSocketChannel.bind(address);
LOG.info("Spawning IPC server listening on socket {}", socketPath);
return new Server(serverSocketChannel, socketPath);
}
@Override
public boolean isClient() {
return false;
}
@Override
public void listen(IpcMessageListener listener, Executor executor) {
executor.execute(() -> {
while (serverSocketChannel.isOpen()) {
try (var ch = serverSocketChannel.accept()) {
while (ch.isConnected()) {
var msg = IpcMessage.receive(ch);
listener.handleMessage(msg);
}
} catch (AsynchronousCloseException e) {
return; // serverSocketChannel closed or listener interrupted
} catch (EOFException | ClosedChannelException e) {
// continue with next connected client
} catch (IOException e) {
LOG.error("Failed to read IPC message", e);
}
}
});
}
@Override
public void send(IpcMessage message, Executor executor) {
executor.execute(() -> {
try (var ch = serverSocketChannel.accept()) {
message.send(ch);
} catch (IOException e) {
LOG.error("Failed to send IPC message", e);
}
});
}
@Override
public void close() throws IOException {
try {
serverSocketChannel.close();
} finally {
Files.deleteIfExists(socketPath);
LOG.debug("IPC server closed");
}
}
}

View File

@@ -5,7 +5,12 @@
*******************************************************************************/
package org.cryptomator.launcher;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import dagger.Lazy;
import org.apache.commons.lang3.SystemUtils;
import org.cryptomator.common.Environment;
import org.cryptomator.common.ShutdownHook;
import org.cryptomator.ipc.IpcCommunicator;
import org.cryptomator.logging.DebugMode;
import org.cryptomator.logging.LoggerConfiguration;
import org.cryptomator.ui.launcher.UiLauncher;
@@ -16,8 +21,10 @@ import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import java.io.IOException;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executors;
@Singleton
public class Cryptomator {
@@ -29,23 +36,28 @@ public class Cryptomator {
private final LoggerConfiguration logConfig;
private final DebugMode debugMode;
private final IpcFactory ipcFactory;
private final Environment env;
private final Lazy<IpcMessageHandler> ipcMessageHandler;
private final Optional<String> applicationVersion;
private final CountDownLatch shutdownLatch;
private final UiLauncher uiLauncher;
private final ShutdownHook shutdownHook;
private final Lazy<UiLauncher> uiLauncher;
@Inject
Cryptomator(LoggerConfiguration logConfig, DebugMode debugMode, IpcFactory ipcFactory, @Named("applicationVersion") Optional<String> applicationVersion, @Named("shutdownLatch") CountDownLatch shutdownLatch, UiLauncher uiLauncher) {
Cryptomator(LoggerConfiguration logConfig, DebugMode debugMode, Environment env, Lazy<IpcMessageHandler> ipcMessageHandler, @Named("applicationVersion") Optional<String> applicationVersion, @Named("shutdownLatch") CountDownLatch shutdownLatch, ShutdownHook shutdownHook, Lazy<UiLauncher> uiLauncher) {
this.logConfig = logConfig;
this.debugMode = debugMode;
this.ipcFactory = ipcFactory;
this.env = env;
this.ipcMessageHandler = ipcMessageHandler;
this.applicationVersion = applicationVersion;
this.shutdownLatch = shutdownLatch;
this.shutdownHook = shutdownHook;
this.uiLauncher = uiLauncher;
}
public static void main(String[] args) {
int exitCode = CRYPTOMATOR_COMPONENT.application().run(args);
LOG.info("Exit {}", exitCode);
System.exit(exitCode); // end remaining non-daemon threads.
}
@@ -64,19 +76,24 @@ public class Cryptomator {
* Attempts to create an IPC connection to a running Cryptomator instance and sends it the given args.
* If no external process could be reached, the args will be handled by the loopback IPC endpoint.
*/
try (IpcFactory.IpcEndpoint endpoint = ipcFactory.create()) {
endpoint.getRemote().handleLaunchArgs(args); // if we are the server, getRemote() returns self.
if (endpoint.isConnectedToRemote()) {
endpoint.getRemote().revealRunningApp();
try (var communicator = IpcCommunicator.create(env.ipcSocketPath().toList())) {
if (communicator.isClient()) {
communicator.sendHandleLaunchargs(List.of(args));
communicator.sendRevealRunningApp();
LOG.info("Found running application instance. Shutting down...");
return 2;
} else {
shutdownHook.runOnShutdown(communicator::closeUnchecked);
var executor = Executors.newSingleThreadExecutor(new ThreadFactoryBuilder().setNameFormat("IPC-%d").build());
var msgHandler = ipcMessageHandler.get();
msgHandler.handleLaunchArgs(List.of(args));
communicator.listen(msgHandler, executor);
LOG.debug("Did not find running application instance. Launching GUI...");
return runGuiApplication();
}
} catch (IOException e) {
LOG.error("Failed to initiate inter-process communication.", e);
return runGuiApplication();
} catch (Throwable e) {
LOG.error("Running application failed", e);
return 1;
}
}
@@ -88,7 +105,7 @@ public class Cryptomator {
*/
private int runGuiApplication() {
try {
uiLauncher.launch();
uiLauncher.get().launch();
shutdownLatch.await();
LOG.info("UI shut down");
return 0;
@@ -98,5 +115,4 @@ public class Cryptomator {
}
}
}

View File

@@ -22,6 +22,7 @@ import java.nio.file.InvalidPathException;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.BlockingQueue;
import java.util.stream.Collectors;
@@ -46,13 +47,13 @@ class FileOpenRequestHandler {
tryToEnqueueFileOpenRequest(launchEvent);
}
public void handleLaunchArgs(String[] args) {
public void handleLaunchArgs(List<String> args) {
handleLaunchArgs(FileSystems.getDefault(), args);
}
// visible for testing
void handleLaunchArgs(FileSystem fs, String[] args) {
Collection<Path> pathsToOpen = Arrays.stream(args).map(str -> {
void handleLaunchArgs(FileSystem fs, List<String> args) {
Collection<Path> pathsToOpen = args.stream().map(str -> {
try {
return fs.getPath(str);
} catch (InvalidPathException e) {

View File

@@ -1,258 +0,0 @@
/*******************************************************************************
* Copyright (c) 2017 Skymatic UG (haftungsbeschränkt).
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the accompanying LICENSE file.
*******************************************************************************/
package org.cryptomator.launcher;
import com.google.common.io.MoreFiles;
import org.cryptomator.common.Environment;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.io.Closeable;
import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.rmi.NotBoundException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.RMIClientSocketFactory;
import java.rmi.server.RMIServerSocketFactory;
import java.rmi.server.RMISocketFactory;
import java.rmi.server.UnicastRemoteObject;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
/**
* First running application on a machine opens a server socket. Further processes will connect as clients.
*/
@Singleton
class IpcFactory {
private static final Logger LOG = LoggerFactory.getLogger(IpcFactory.class);
private static final String RMI_NAME = "Cryptomator";
private final List<Path> portFilePaths;
private final IpcProtocolImpl ipcHandler;
@Inject
public IpcFactory(Environment env, IpcProtocolImpl ipcHandler) {
this.portFilePaths = env.getIpcPortPath().collect(Collectors.toUnmodifiableList());
this.ipcHandler = ipcHandler;
}
public IpcEndpoint create() {
if (portFilePaths.isEmpty()) {
LOG.warn("No IPC port file path specified.");
return new SelfEndpoint(ipcHandler);
} else {
System.setProperty("java.rmi.server.hostname", "localhost");
return attemptClientConnection().or(this::createServerEndpoint).orElseGet(() -> new SelfEndpoint(ipcHandler));
}
}
private Optional<IpcEndpoint> attemptClientConnection() {
for (Path portFilePath : portFilePaths) {
try {
int port = readPort(portFilePath);
LOG.debug("[Client] Connecting to port {}...", port);
Registry registry = LocateRegistry.getRegistry("localhost", port, new ClientSocketFactory());
IpcProtocol remoteInterface = (IpcProtocol) registry.lookup(RMI_NAME);
return Optional.of(new ClientEndpoint(remoteInterface));
} catch (NotBoundException | IOException e) {
LOG.debug("[Client] Failed to connect.");
// continue with next portFilePath...
}
}
return Optional.empty();
}
private int readPort(Path portFilePath) throws IOException {
try (ReadableByteChannel ch = Files.newByteChannel(portFilePath, StandardOpenOption.READ)) {
LOG.debug("[Client] Reading IPC port from {}", portFilePath);
ByteBuffer buf = ByteBuffer.allocate(Integer.BYTES);
if (ch.read(buf) == Integer.BYTES) {
buf.flip();
return buf.getInt();
} else {
throw new IOException("Invalid IPC port file.");
}
}
}
private Optional<IpcEndpoint> createServerEndpoint() {
assert !portFilePaths.isEmpty();
Path portFilePath = portFilePaths.get(0);
try {
ServerSocket socket = new ServerSocket(0, Byte.MAX_VALUE, InetAddress.getByName("localhost"));
RMIClientSocketFactory csf = RMISocketFactory.getDefaultSocketFactory();
SingletonServerSocketFactory ssf = new SingletonServerSocketFactory(socket);
Registry registry = LocateRegistry.createRegistry(0, csf, ssf);
UnicastRemoteObject.exportObject(ipcHandler, 0);
registry.rebind(RMI_NAME, ipcHandler);
writePort(portFilePath, socket.getLocalPort());
return Optional.of(new ServerEndpoint(ipcHandler, socket, registry, portFilePath));
} catch (IOException e) {
LOG.warn("[Server] Failed to create IPC server.", e);
return Optional.empty();
}
}
private void writePort(Path portFilePath, int port) throws IOException {
ByteBuffer buf = ByteBuffer.allocate(Integer.BYTES);
buf.putInt(port);
buf.flip();
MoreFiles.createParentDirectories(portFilePath);
try (WritableByteChannel ch = Files.newByteChannel(portFilePath, StandardOpenOption.WRITE, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING)) {
if (ch.write(buf) != Integer.BYTES) {
throw new IOException("Did not write expected number of bytes.");
}
}
LOG.debug("[Server] Wrote IPC port {} to {}", port, portFilePath);
}
interface IpcEndpoint extends Closeable {
boolean isConnectedToRemote();
IpcProtocol getRemote();
}
static class SelfEndpoint implements IpcEndpoint {
protected final IpcProtocol remoteObject;
SelfEndpoint(IpcProtocol remoteObject) {
this.remoteObject = remoteObject;
}
@Override
public boolean isConnectedToRemote() {
return false;
}
@Override
public IpcProtocol getRemote() {
return remoteObject;
}
@Override
public void close() {
// no-op
}
}
static class ClientEndpoint implements IpcEndpoint {
private final IpcProtocol remoteInterface;
public ClientEndpoint(IpcProtocol remoteInterface) {
this.remoteInterface = remoteInterface;
}
public IpcProtocol getRemote() {
return remoteInterface;
}
@Override
public boolean isConnectedToRemote() {
return true;
}
@Override
public void close() {
// no-op
}
}
class ServerEndpoint extends SelfEndpoint {
private final ServerSocket socket;
private final Registry registry;
private final Path portFilePath;
private ServerEndpoint(IpcProtocol remoteObject, ServerSocket socket, Registry registry, Path portFilePath) {
super(remoteObject);
this.socket = socket;
this.registry = registry;
this.portFilePath = portFilePath;
}
@Override
public void close() {
try {
registry.unbind(RMI_NAME);
UnicastRemoteObject.unexportObject(remoteObject, true);
socket.close();
Files.deleteIfExists(portFilePath);
LOG.debug("[Server] Shut down");
} catch (NotBoundException | IOException e) {
LOG.warn("[Server] Error shutting down:", e);
}
}
}
/**
* Always returns the same pre-constructed server socket.
*/
private static class SingletonServerSocketFactory implements RMIServerSocketFactory {
private final ServerSocket socket;
public SingletonServerSocketFactory(ServerSocket socket) {
this.socket = socket;
}
@Override
public synchronized ServerSocket createServerSocket(int port) throws IOException {
if (port != 0) {
throw new IllegalArgumentException("This factory doesn't support specific ports.");
}
return this.socket;
}
}
/**
* Creates client sockets with short timeouts.
*/
private static class ClientSocketFactory implements RMIClientSocketFactory {
@Override
public Socket createSocket(String host, int port) throws IOException {
return new SocketWithFixedTimeout(host, port, 1000);
}
}
private static class SocketWithFixedTimeout extends Socket {
public SocketWithFixedTimeout(String host, int port, int timeoutInMs) throws UnknownHostException, IOException {
super(host, port);
super.setSoTimeout(timeoutInMs);
}
@Override
public synchronized void setSoTimeout(int timeout) throws SocketException {
// do nothing, timeout is fixed
}
}
}

View File

@@ -1,5 +1,6 @@
package org.cryptomator.launcher;
import org.cryptomator.ipc.IpcMessageListener;
import org.cryptomator.ui.launcher.AppLaunchEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -7,20 +8,20 @@ import org.slf4j.LoggerFactory;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.BlockingQueue;
@Singleton
class IpcProtocolImpl implements IpcProtocol {
class IpcMessageHandler implements IpcMessageListener {
private static final Logger LOG = LoggerFactory.getLogger(IpcProtocolImpl.class);
private static final Logger LOG = LoggerFactory.getLogger(IpcMessageHandler.class);
private final FileOpenRequestHandler fileOpenRequestHandler;
private final BlockingQueue<AppLaunchEvent> launchEventQueue;
@Inject
public IpcProtocolImpl(FileOpenRequestHandler fileOpenRequestHandler, @Named("launchEventQueue") BlockingQueue<AppLaunchEvent> launchEventQueue) {
public IpcMessageHandler(FileOpenRequestHandler fileOpenRequestHandler, @Named("launchEventQueue") BlockingQueue<AppLaunchEvent> launchEventQueue) {
this.fileOpenRequestHandler = fileOpenRequestHandler;
this.launchEventQueue = launchEventQueue;
}
@@ -31,8 +32,8 @@ class IpcProtocolImpl implements IpcProtocol {
}
@Override
public void handleLaunchArgs(String... args) {
LOG.debug("Received launch args: {}", Arrays.stream(args).reduce((a, b) -> a + ", " + b).orElse(""));
public void handleLaunchArgs(List<String> args) {
LOG.debug("Received launch args: {}", args.stream().reduce((a, b) -> a + ", " + b).orElse(""));
fileOpenRequestHandler.handleLaunchArgs(args);
}

View File

@@ -1,17 +0,0 @@
/*******************************************************************************
* Copyright (c) 2017 Skymatic UG (haftungsbeschränkt).
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the accompanying LICENSE file.
*******************************************************************************/
package org.cryptomator.launcher;
import java.rmi.Remote;
import java.rmi.RemoteException;
interface IpcProtocol extends Remote {
void revealRunningApp() throws RemoteException;
void handleLaunchArgs(String... args) throws RemoteException;
}

View File

@@ -11,12 +11,12 @@ import java.io.File;
*
* @param <E> Event type the policy possibly reacts to
*/
public class LaunchAndSizeBasedTriggerinPolicy<E> extends TriggeringPolicyBase<E> {
public class LaunchAndSizeBasedTriggeringPolicy<E> extends TriggeringPolicyBase<E> {
LaunchBasedTriggeringPolicy<E> launchBasedTriggeringPolicy;
SizeBasedTriggeringPolicy<E> sizeBasedTriggeringPolicy;
public LaunchAndSizeBasedTriggerinPolicy(FileSize threshold) {
public LaunchAndSizeBasedTriggeringPolicy(FileSize threshold) {
this.launchBasedTriggeringPolicy = new LaunchBasedTriggeringPolicy<>();
this.sizeBasedTriggeringPolicy = new SizeBasedTriggeringPolicy<>();
sizeBasedTriggeringPolicy.setMaxFileSize(threshold);

View File

@@ -85,7 +85,7 @@ public class LoggerModule {
appender.setContext(context);
appender.setFile(logDir.resolve(LOGFILE_NAME).toString());
appender.setEncoder(encoder);
LaunchAndSizeBasedTriggerinPolicy triggeringPolicy = new LaunchAndSizeBasedTriggerinPolicy(FileSize.valueOf(LOG_MAX_SIZE));
LaunchAndSizeBasedTriggeringPolicy triggeringPolicy = new LaunchAndSizeBasedTriggeringPolicy(FileSize.valueOf(LOG_MAX_SIZE));
triggeringPolicy.setContext(context);
triggeringPolicy.start();
appender.setTriggeringPolicy(triggeringPolicy);

View File

@@ -5,8 +5,8 @@ import org.cryptomator.common.vaults.Vault;
import org.cryptomator.common.vaults.VaultListManager;
import org.cryptomator.cryptofs.CryptoFileSystemProperties;
import org.cryptomator.cryptofs.CryptoFileSystemProvider;
import org.cryptomator.cryptofs.VaultCipherCombo;
import org.cryptomator.cryptolib.api.CryptoException;
import org.cryptomator.cryptolib.api.CryptorProvider;
import org.cryptomator.cryptolib.api.Masterkey;
import org.cryptomator.cryptolib.api.MasterkeyLoader;
import org.cryptomator.cryptolib.common.MasterkeyFileAccess;
@@ -76,6 +76,7 @@ public class CreateNewVaultPasswordController implements FxController {
private final BooleanProperty readyToCreateVault;
private final ObjectBinding<ContentDisplay> createVaultButtonState;
/* FXML */
public ToggleGroup recoveryKeyChoice;
public Toggle showRecoveryKey;
public Toggle skipRecoveryKey;
@@ -106,7 +107,7 @@ public class CreateNewVaultPasswordController implements FxController {
@FXML
public void initialize() {
readyToCreateVault.bind(newPasswordSceneController.passwordsMatchAndSufficientProperty().and(recoveryKeyChoice.selectedToggleProperty().isNotNull()).and(processing.not()));
readyToCreateVault.bind(newPasswordSceneController.goodPasswordProperty().and(recoveryKeyChoice.selectedToggleProperty().isNotNull()).and(processing.not()));
window.setOnHiding(event -> {
newPasswordSceneController.passwordField.wipe();
newPasswordSceneController.reenterField.wipe();
@@ -182,7 +183,7 @@ public class CreateNewVaultPasswordController implements FxController {
// 2. initialize vault:
try {
MasterkeyLoader loader = ignored -> masterkey.clone();
CryptoFileSystemProperties fsProps = CryptoFileSystemProperties.cryptoFileSystemProperties().withCipherCombo(VaultCipherCombo.SIV_CTRMAC).withKeyLoader(loader).build();
CryptoFileSystemProperties fsProps = CryptoFileSystemProperties.cryptoFileSystemProperties().withCipherCombo(CryptorProvider.Scheme.SIV_CTRMAC).withKeyLoader(loader).build();
CryptoFileSystemProvider.initialize(path, fsProps, DEFAULT_KEY_ID);
// 3. write vault-internal readme file:

View File

@@ -62,7 +62,7 @@ public class ChangePasswordController implements FxController {
public void initialize() {
BooleanBinding checkboxNotConfirmed = finalConfirmationCheckbox.selectedProperty().not();
BooleanBinding oldPasswordFieldEmpty = oldPasswordField.textProperty().isEmpty();
finishButton.disableProperty().bind(checkboxNotConfirmed.or(oldPasswordFieldEmpty).or(newPasswordController.passwordsMatchAndSufficientProperty().not()));
finishButton.disableProperty().bind(checkboxNotConfirmed.or(oldPasswordFieldEmpty).or(newPasswordController.goodPasswordProperty().not()));
window.setOnHiding(event -> {
oldPasswordField.wipe();
newPasswordController.passwordField.wipe();

View File

@@ -1,11 +1,17 @@
package org.cryptomator.ui.common;
import javafx.animation.Animation;
import javafx.animation.Interpolator;
import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.RotateTransition;
import javafx.animation.SequentialTransition;
import javafx.animation.Timeline;
import javafx.beans.value.WritableValue;
import javafx.scene.Node;
import javafx.stage.Window;
import javafx.util.Duration;
import java.util.stream.IntStream;
public class Animations {
@@ -33,4 +39,19 @@ public class Animations {
);
}
public static SequentialTransition createDiscrete360Rotation(Node toAnimate) {
var animation = new SequentialTransition(IntStream.range(0, 8).mapToObj(i -> Animations.createDiscrete45Rotation()).toArray(Animation[]::new));
animation.setCycleCount(Animation.INDEFINITE);
animation.setNode(toAnimate);
return animation;
}
private static RotateTransition createDiscrete45Rotation() {
var animation = new RotateTransition(Duration.millis(100));
animation.setInterpolator(Interpolator.DISCRETE);
animation.setByAngle(45);
animation.setCycleCount(1);
return animation;
}
}

View File

@@ -0,0 +1,84 @@
package org.cryptomator.ui.common;
import com.tobiasdiez.easybind.EasyBind;
import com.tobiasdiez.easybind.Subscription;
import javafx.animation.Animation;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.value.ObservableValue;
/**
* Animation which starts and stops automatically based on an observable condition.
* <p>
* During creation the consumer can optionally define actions to be executed everytime before the animation starts and after it stops.
*/
public class AutoAnimator<T extends Animation> {
private final T animation;
private final ObservableValue<Boolean> condition;
private final Runnable beforeStart;
private final Runnable afterStop;
private final Subscription sub;
AutoAnimator(T animation, ObservableValue<Boolean> condition, Runnable beforeStart, Runnable afterStop) {
this.animation = animation;
this.condition = condition;
this.beforeStart = beforeStart;
this.afterStop = afterStop;
this.sub = EasyBind.subscribe(condition, this::togglePlay);
}
public void playFromStart() {
beforeStart.run();
animation.playFromStart();
}
public void stop() {
animation.stop();
afterStop.run();
}
private void togglePlay(boolean play) {
if (play) {
this.playFromStart();
} else {
this.stop();
}
}
public static Builder animate(Animation animation) {
return new Builder(animation);
}
public static class Builder {
private Animation animation;
private ObservableValue<Boolean> condition = new SimpleBooleanProperty(true);
private Runnable beforeStart = () -> {};
private Runnable afterStop = () -> {};
private Builder(Animation animation) {
this.animation = animation;
}
public Builder onCondition(ObservableValue<Boolean> condition) {
this.condition = condition;
return this;
}
public Builder beforeStart(Runnable beforeStart) {
this.beforeStart = beforeStart;
return this;
}
public Builder afterStop(Runnable afterStop) {
this.afterStop = afterStop;
return this;
}
public AutoAnimator build() {
return new AutoAnimator(animation, condition, beforeStart, afterStop);
}
}
}

View File

@@ -2,8 +2,8 @@ package org.cryptomator.ui.common;
import dagger.BindsInstance;
import dagger.Subcomponent;
import org.cryptomator.common.Nullable;
import javax.annotation.Nullable;
import javafx.application.Platform;
import javafx.scene.Scene;
import javafx.stage.Stage;

View File

@@ -1,6 +1,7 @@
package org.cryptomator.ui.common;
import javax.annotation.Nullable;
import org.cryptomator.common.Nullable;
import javax.inject.Inject;
import javax.inject.Named;
import javafx.fxml.FXML;

View File

@@ -12,6 +12,7 @@ public enum FxmlFile {
ERROR("/fxml/error.fxml"), //
FORGET_PASSWORD("/fxml/forget_password.fxml"), //
HEALTH_START("/fxml/health_start.fxml"), //
HEALTH_START_FAIL("/fxml/health_start_fail.fxml"), //
HEALTH_CHECK_LIST("/fxml/health_check_list.fxml"), //
LOCK_FORCED("/fxml/lock_forced.fxml"), //
LOCK_FAILED("/fxml/lock_failed.fxml"), //

Some files were not shown because too many files have changed in this diff Show More