diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 4547fb8df..a4670277a 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -3,7 +3,7 @@ ## Did you find a bug? - Ensure you're running the latest version of Cryptomator. -- Ensure the bug is related to the desktop version of Cryptomator. Bugs concerning the Cryptomator iOS and Android app can be reported on the [Cryptomator for iOS issues list](https://github.com/cryptomator/cryptomator-ios/issues) and [Cryptomator for Android issues list](https://github.com/cryptomator/cryptomator-android/issues) respectively. +- Ensure the bug is related to the desktop version of Cryptomator. Bugs concerning the Cryptomator iOS and Android app can be reported on the [Cryptomator for iOS issues list](https://github.com/cryptomator/ios/issues) and [Cryptomator for Android issues list](https://github.com/cryptomator/android/issues) respectively. - Ensure the bug was not [already reported](https://github.com/cryptomator/cryptomator/issues). You can also check out our [FAQ](https://community.cryptomator.org/c/kb/faq). - If you're unable to find an open issue addressing the problem, [submit a new one](https://github.com/cryptomator/cryptomator/issues/new/choose). diff --git a/.github/workflows/appimage.yml b/.github/workflows/appimage.yml index 1b0b34435..f7888fdc3 100644 --- a/.github/workflows/appimage.yml +++ b/.github/workflows/appimage.yml @@ -11,7 +11,7 @@ on: env: JAVA_DIST: 'zulu' - JAVA_VERSION: '22.0.2+9' + JAVA_VERSION: '23.0.1+11' jobs: get-version: @@ -116,7 +116,6 @@ jobs: --java-options "-Dcryptomator.showTrayIcon=true" --java-options "-Dcryptomator.integrationsLinux.trayIconsDir=\"@{appdir}/usr/share/icons/hicolor/symbolic/apps\"" --java-options "-Dcryptomator.buildNumber=\"appimage-${{ needs.get-version.outputs.revNum }}\"" - --add-launcher Cryptomator-gtk2=launcher-gtk2.properties --resource-dir dist/linux/resources - name: Patch Cryptomator.AppDir run: | diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f07eecae7..79ca42d22 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -7,7 +7,7 @@ on: env: JAVA_DIST: 'zulu' - JAVA_VERSION: 22 + JAVA_VERSION: 23 defaults: run: diff --git a/.github/workflows/check-jdk-updates.yml b/.github/workflows/check-jdk-updates.yml index c73546994..c05fbf351 100644 --- a/.github/workflows/check-jdk-updates.yml +++ b/.github/workflows/check-jdk-updates.yml @@ -1,56 +1,75 @@ -name: Checks JDK version for minor updates +name: Check JDK for non-major updates on: schedule: - cron: '0 0 1 * *' # run once a month at the first day of month + workflow_dispatch: env: - JDK_VERSION: '22.0.1+8' + JDK_VERSION: '23.0.1+11' JDK_VENDOR: zulu + RUNTIME_VERSION_HELPER: > + public class Test { + public static void main(String[] args) { + System.out.println(Runtime.version()); + } + } jobs: - jdk-current: - name: Check out current version - runs-on: ubuntu-latest - outputs: - jdk-date: ${{ steps.get-data.outputs.jdk-date}} - steps: - - uses: actions/setup-java@v4 - with: - java-version: ${{ env.JDK_VERSION }} - distribution: ${{ env.JDK_VENDOR }} - check-latest: false - - name: Read JAVA_VERSION_DATE and store in env variable - id: get-data - run: | - date=$(cat ${JAVA_HOME}/release | grep "JAVA_VERSION_DATE=\"" | awk -F'=' '{print $2}' | tr -d '"') - echo "jdk-date=${date}" >> "$GITHUB_OUTPUT" - jdk-latest: + check-version: name: Checkout latest jdk version runs-on: ubuntu-latest - outputs: - jdk-date: ${{ steps.get-data.outputs.jdk-date}} - jdk-version: ${{ steps.get-data.outputs.jdk-version}} + env: + JDK_MAJOR_VERSION: 'toBeFilled' steps: - - uses: actions/setup-java@v4 + - name: Determine current major version + run: echo 'JDK_MAJOR_VERSION=${{ env.JDK_VERSION }}'.substring(0,20) >> "$env:GITHUB_ENV" + shell: pwsh + - name: Checkout latest JDK ${{ env.JDK_MAJOR_VERSION }} + uses: actions/setup-java@v4 with: - java-version: 21 + java-version: ${{ env.JDK_MAJOR_VERSION}} distribution: ${{ env.JDK_VENDOR }} check-latest: true - - name: Read JAVA_VERSION_DATE and store in env variable - id: get-data + - name: Determine if update is available + id: determine + shell: pwsh run: | - date=$(cat ${JAVA_HOME}/release | grep "JAVA_VERSION_DATE=\"" | awk -F'=' '{print $2}' | tr -d '"') - echo "jdk-date=${date}" >> "$GITHUB_OUTPUT" - version=$(cat ${JAVA_HOME}/release | grep "JAVA_RUNTIME_VERSION=\"" | awk -F'=' '{print $2}' | tr -d '"') - echo "jdk-version=${version}" >> "$GITHUB_OUTPUT" - notify: - name: Notifies for jdk update - runs-on: ubuntu-latest - needs: [jdk-current, jdk-latest] - if: ${{ needs.jdk-latest.outputs.jdk-date }} > ${{ needs.jdk-current.outputs.jdk-date }} - steps: - - name: Slack Notification + $latestVersion = 0,0,0,0 #INTERIM, UPDATE, PATCH and BUILD + $currentVersion = 0,0,0,0 + + # Get the latest JDK runtime version + "${env:RUNTIME_VERSION_HELPER}" | Set-Content -Path "GetRuntimeVersion.java" + $latestVersionString = & java GetRuntimeVersion.java + $runtimeVersionAndBuild = $latestVersionString.Split('+') + if($runtimeVersionAndBuild.Length -eq 2) { + $latestVersion[3]=$runtimeVersionAndBuild[1]; + } + $tmp=$runtimeVersionAndBuild[0].Split('.') + for($i=0;$i -lt $latestVersion.Length; $i++) { + $latestVersion[$i]=$tmp[$i+1]; + } + + # Get the current JDK version + $runtimeVersionAndBuild = '${{ env.JDK_VERSION}}'.Split('+') + if($runtimeVersionAndBuild.Length -eq 2) { + $currentVersion[3]=$runtimeVersionAndBuild[1]; + } + $tmp=$runtimeVersionAndBuild[0].Split('.') + for($i=0;$i -lt $currentVersion.Length; $i++) { + $currentVersion[$i]=$tmp[$i+1]; + } + + # compare + for($i=0; $i -lt $currentVersion.Length ; $i++) { + if($latestVersion[$i] -gt $currentVersion[$i]){ + echo 'UPDATE_AVAILABLE=true' >> "$env:GITHUB_OUTPUT" + echo "LATEST_JDK_VERSION='${latestVersionString}'" >> "$env:GITHUB_OUTPUT" + return 0; + } + } + - name: Notify + if: steps.determine.outputs.UPDATE_AVAILABLE == 'true' uses: rtCamp/action-slack-notify@v2 env: SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }} @@ -59,6 +78,6 @@ jobs: SLACK_ICON_EMOJI: ':bot:' SLACK_CHANNEL: 'cryptomator-desktop' SLACK_TITLE: "JDK update available" - SLACK_MESSAGE: "Cryptomator-CI JDK can be upgraded to ${{ needs.jdk-latest.outputs.jdk-version }}. See https://github.com/cryptomator/cryptomator/wiki/How-to-update-the-build-JDK for instructions." + SLACK_MESSAGE: "Cryptomator-CI JDK can be upgraded to ${{ steps.determine.outputs.LATEST_JDK_VERSION }}. Check the Nextcloud collective for instructions." SLACK_FOOTER: false - MSG_MINIMAL: true + MSG_MINIMAL: true \ No newline at end of file diff --git a/.github/workflows/debian.yml b/.github/workflows/debian.yml index 7ab8cc7ea..edd87b44b 100644 --- a/.github/workflows/debian.yml +++ b/.github/workflows/debian.yml @@ -17,9 +17,9 @@ on: env: JAVA_DIST: 'zulu' - JAVA_VERSION: '22.0.2+9' - COFFEELIBS_JDK: 22 - COFFEELIBS_JDK_VERSION: '22.0.2+9-0ppa1' + JAVA_VERSION: '23.0.1+11' + COFFEELIBS_JDK: 23 + COFFEELIBS_JDK_VERSION: '23.0.1+11-0ppa1' OPENJFX_JMODS_AMD64: 'https://download2.gluonhq.com/openjfx/22.0.2/openjfx-22.0.2_linux-x64_bin-jmods.zip' OPENJFX_JMODS_AMD64_HASH: 'd44bff3b94d5668fdee18a938d7b1269026d663d44765f02d29a9bdfd3fa1eb0' OPENJFX_JMODS_AARCH64: 'https://download2.gluonhq.com/openjfx/22.0.2/openjfx-22.0.2_linux-aarch64_bin-jmods.zip' diff --git a/.github/workflows/dependency-check.yml b/.github/workflows/dependency-check.yml index 40dfe97fa..00e30c984 100644 --- a/.github/workflows/dependency-check.yml +++ b/.github/workflows/dependency-check.yml @@ -11,7 +11,7 @@ jobs: with: runner-os: 'ubuntu-latest' java-distribution: 'temurin' - java-version: 22 + java-version: 23 check-command: 'mvn -B validate -Pdependency-check -Djavafx.platform=linux' secrets: nvd-api-key: ${{ secrets.NVD_API_KEY }} diff --git a/.github/workflows/get-version.yml b/.github/workflows/get-version.yml index 7dc22462f..be2a6dd36 100644 --- a/.github/workflows/get-version.yml +++ b/.github/workflows/get-version.yml @@ -23,7 +23,7 @@ on: env: JAVA_DIST: 'zulu' - JAVA_VERSION: 22 + JAVA_VERSION: 23 jobs: determine-version: diff --git a/.github/workflows/mac-dmg-x64.yml b/.github/workflows/mac-dmg-x64.yml new file mode 100644 index 000000000..0ee2b3d28 --- /dev/null +++ b/.github/workflows/mac-dmg-x64.yml @@ -0,0 +1,264 @@ +name: Build macOS .dmg for x64 + +####################################### +# STOP! DO NOT EDIT THIS FILE! +# +# It is a copy of mac-dmg.yml with tiny adjustements (mainly lines 42 to 47) +# It was made necessary, since Github does not offer free macos intel runners for macos 15 and above. +# This workflow can only be triggered by a release. +# +####################################### + +on: + release: + types: [published] + +env: + JAVA_DIST: 'zulu' + JAVA_VERSION: '23.0.1+11' + +jobs: + get-version: + uses: ./.github/workflows/get-version.yml + with: + version: ${{ inputs.version }} + + build-arm: + name: Build Cryptomator.app for ${{ matrix.output-suffix }} + runs-on: ${{ matrix.os }} + needs: [get-version] + strategy: + fail-fast: false + matrix: + include: + - os: macos-15-large + architecture: x64 + output-suffix: x64 + fuse-lib: macFUSE + openjfx-url: 'https://download2.gluonhq.com/openjfx/22.0.2/openjfx-22.0.2_osx-x64_bin-jmods.zip' + openjfx-sha: '115cb08bb59d880cfff6e51e0bf0dcc45785ed9d456b8b8425597b04da6ab3d4' + steps: + - uses: actions/checkout@v4 + - name: Setup Java + uses: actions/setup-java@v4 + with: + distribution: ${{ env.JAVA_DIST }} + java-version: ${{ env.JAVA_VERSION }} + architecture: ${{ matrix.architecture }} + check-latest: true + cache: 'maven' + - name: Download OpenJFX jmods + id: download-jmods + run: | + curl -L ${{ matrix.openjfx-url }} -o openjfx-jmods.zip + echo "${{ matrix.openjfx-sha }} *openjfx-jmods.zip" | shasum -a256 --check + mkdir -p openjfx-jmods/ + unzip -jo openjfx-jmods.zip \*/javafx.base.jmod \*/javafx.controls.jmod \*/javafx.fxml.jmod \*/javafx.graphics.jmod -d openjfx-jmods + - name: Ensure major jfx version in pom and in jmods is the same + run: | + JMOD_VERSION=$(jmod describe openjfx-jmods/javafx.base.jmod | head -1) + JMOD_VERSION=${JMOD_VERSION#*@} + JMOD_VERSION=${JMOD_VERSION%%.*} + POM_JFX_VERSION=$(mvn help:evaluate "-Dexpression=javafx.version" -q -DforceStdout) + POM_JFX_VERSION=${POM_JFX_VERSION#*@} + POM_JFX_VERSION=${POM_JFX_VERSION%%.*} + + if [ "${POM_JFX_VERSION}" -ne "${JMOD_VERSION}" ]; then + >&2 echo "Major JavaFX version in pom.xml (${POM_JFX_VERSION}) != jmod version (${JMOD_VERSION})" + exit 1 + fi + - name: Set version + run : mvn versions:set -DnewVersion=${{ needs.get-version.outputs.semVerStr }} + - name: Run maven + run: mvn -B -Djavafx.platform=mac clean package -Pmac -DskipTests + - name: Patch target dir + run: | + cp LICENSE.txt target + cp target/cryptomator-*.jar target/mods + - name: Run jlink + #Remark: no compression is applied for improved build compression later (here dmg) + run: > + ${JAVA_HOME}/bin/jlink + --verbose + --output runtime + --module-path "${JAVA_HOME}/jmods:openjfx-jmods" + --add-modules java.base,java.desktop,java.instrument,java.logging,java.naming,java.net.http,java.scripting,java.sql,java.xml,javafx.base,javafx.graphics,javafx.controls,javafx.fxml,jdk.unsupported,jdk.accessibility,jdk.management.jfr,java.compiler + --strip-native-commands + --no-header-files + --no-man-pages + --strip-debug + --compress zip-0 + - name: Run jpackage + run: > + ${JAVA_HOME}/bin/jpackage + --verbose + --type app-image + --runtime-image runtime + --input target/libs + --module-path target/mods + --module org.cryptomator.desktop/org.cryptomator.launcher.Cryptomator + --dest appdir + --name Cryptomator + --vendor "Skymatic GmbH" + --copyright "(C) 2016 - 2024 Skymatic GmbH" + --app-version "${{ needs.get-version.outputs.semVerNum }}" + --java-options "--enable-preview" + --java-options "--enable-native-access=org.cryptomator.jfuse.mac" + --java-options "-Xss5m" + --java-options "-Xmx256m" + --java-options "-Dfile.encoding=\"utf-8\"" + --java-options "-Djava.net.useSystemProxies=true" + --java-options "-Dapple.awt.enableTemplateImages=true" + --java-options "-Dsun.java2d.metal=true" + --java-options "-Dcryptomator.appVersion=\"${{ needs.get-version.outputs.semVerStr }}\"" + --java-options "-Dcryptomator.logDir=\"@{userhome}/Library/Logs/Cryptomator\"" + --java-options "-Dcryptomator.pluginDir=\"@{userhome}/Library/Application Support/Cryptomator/Plugins\"" + --java-options "-Dcryptomator.settingsPath=\"@{userhome}/Library/Application Support/Cryptomator/settings.json\"" + --java-options "-Dcryptomator.p12Path=\"@{userhome}/Library/Application Support/Cryptomator/key.p12\"" + --java-options "-Dcryptomator.ipcSocketPath=\"@{userhome}/Library/Application Support/Cryptomator/ipc.socket\"" + --java-options "-Dcryptomator.integrationsMac.keychainServiceName=\"Cryptomator\"" + --java-options "-Dcryptomator.mountPointsDir=\"@{userhome}/Library/Application Support/Cryptomator/mnt\"" + --java-options "-Dcryptomator.showTrayIcon=true" + --java-options "-Dcryptomator.buildNumber=\"dmg-${{ needs.get-version.outputs.revNum }}\"" + --mac-package-identifier org.cryptomator + --resource-dir dist/mac/resources + - name: Patch Cryptomator.app + run: | + mv appdir/Cryptomator.app Cryptomator.app + mv dist/mac/resources/Cryptomator-Vault.icns Cryptomator.app/Contents/Resources/ + 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 + echo -n "$PROVISIONING_PROFILE_BASE64" | base64 --decode --output Cryptomator.app/Contents/embedded.provisionprofile + env: + VERSION_NO: ${{ needs.get-version.outputs.semVerNum }} + REVISION_NO: ${{ needs.get-version.outputs.revNum }} + PROVISIONING_PROFILE_BASE64: ${{ secrets.MACOS_PROVISIONING_PROFILE_BASE64 }} + - name: Generate license for dmg + run: > + mvn -B -Djavafx.platform=mac license:add-third-party + -Dlicense.thirdPartyFilename=license.rtf + -Dlicense.outputDirectory=dist/mac/dmg/resources + -Dlicense.fileTemplate=dist/mac/dmg/resources/licenseTemplate.ftl + -Dlicense.includedScopes=compile + -Dlicense.excludedGroups=^org\.cryptomator + -Dlicense.failOnMissing=true + -Dlicense.licenseMergesUrl=file://${{ github.workspace }}/license/merges + - name: Install codesign certificate + 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 + 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 }} + - name: Codesign + run: | + echo "Codesigning jdk files..." + find Cryptomator.app/Contents/runtime/Contents/Home/lib/ -name '*.dylib' -exec codesign --force -s ${CODESIGN_IDENTITY} {} \; + find Cryptomator.app/Contents/runtime/Contents/Home/lib/ \( -name 'jspawnhelper' -o -name 'pauseengine' -o -name 'simengine' \) -exec codesign --force -o runtime -s ${CODESIGN_IDENTITY} {} \; + echo "Codesigning jar contents..." + 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 --force -s ${CODESIGN_IDENTITY} {} \; + find ${OUTPUT_PATH} -name '*.jnilib' -exec codesign --force -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..." + sed -i '' "s|###APP_IDENTIFIER_PREFIX###|${TEAM_IDENTIFIER}.|g" dist/mac/Cryptomator.entitlements + sed -i '' "s|###TEAM_IDENTIFIER###|${TEAM_IDENTIFIER}|g" dist/mac/Cryptomator.entitlements + codesign --force --deep --entitlements dist/mac/Cryptomator.entitlements -o runtime -s ${CODESIGN_IDENTITY} Cryptomator.app + env: + CODESIGN_IDENTITY: ${{ secrets.MACOS_CODESIGN_IDENTITY }} + TEAM_IDENTIFIER: ${{ secrets.MACOS_TEAM_IDENTIFIER }} + - name: Prepare .dmg contents + run: | + mkdir dmg + mv Cryptomator.app dmg + cp dist/mac/dmg/resources/${{ matrix.fuse-lib }}.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-${{ matrix.fuse-lib }}-background.tiff" + --window-pos 400 100 + --window-size 640 694 + --icon-size 128 + --icon "Cryptomator.app" 128 245 + --hide-extension "Cryptomator.app" + --icon "${{ matrix.fuse-lib }}.webloc" 320 501 + --hide-extension "${{ matrix.fuse-lib }}.webloc" + --app-drop-link 512 245 + --eula "dist/mac/dmg/resources/license.rtf" + --icon ".background" 128 758 + --icon ".VolumeIcon.icns" 512 758 + Cryptomator-${VERSION_NO}-${{ matrix.output-suffix }}.dmg dmg + env: + VERSION_NO: ${{ needs.get-version.outputs.semVerNum }} + - name: Notarize .dmg + if: startsWith(github.ref, 'refs/tags/') || inputs.notarize + uses: cocoalibs/xcode-notarization-action@v1 + with: + app-path: 'Cryptomator-*.dmg' + apple-id: ${{ secrets.MACOS_NOTARIZATION_APPLE_ID }} + password: ${{ secrets.MACOS_NOTARIZATION_PW }} + team-id: ${{ secrets.MACOS_NOTARIZATION_TEAM_ID }} + xcode-path: '/Applications/Xcode_16.app' + - name: Add possible alpha/beta tags to installer name + run: mv Cryptomator-*.dmg Cryptomator-${{ needs.get-version.outputs.semVerStr }}-${{ matrix.output-suffix }}.dmg + - name: Create detached GPG signature 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 --detach-sign -a Cryptomator-*.dmg + env: + GPG_PRIVATE_KEY: ${{ secrets.RELEASES_GPG_PRIVATE_KEY }} + GPG_PASSPHRASE: ${{ secrets.RELEASES_GPG_PASSPHRASE }} + - name: Clean up codesign certificate + if: ${{ always() }} + run: security delete-keychain $RUNNER_TEMP/codesign.keychain-db + continue-on-error: true + - name: Upload artifacts + uses: actions/upload-artifact@v4 + with: + name: dmg-${{ matrix.output-suffix }} + path: | + Cryptomator-*.dmg + Cryptomator-*.asc + if-no-files-found: error + - name: Publish dmg on GitHub Releases + if: startsWith(github.ref, 'refs/tags/') && github.event.action == 'published' + uses: softprops/action-gh-release@v2 + with: + fail_on_unmatched_files: true + token: ${{ secrets.CRYPTOBOT_RELEASE_TOKEN }} + files: | + Cryptomator-*.dmg + Cryptomator-*.asc diff --git a/.github/workflows/mac-dmg.yml b/.github/workflows/mac-dmg.yml index 8bb6347bc..544d681e6 100644 --- a/.github/workflows/mac-dmg.yml +++ b/.github/workflows/mac-dmg.yml @@ -1,4 +1,4 @@ -name: Build macOS .dmg +name: Build macOS .dmg for arm64 on: release: @@ -16,7 +16,7 @@ on: env: JAVA_DIST: 'zulu' - JAVA_VERSION: '22.0.2+9' + JAVA_VERSION: '23.0.1+11' jobs: get-version: @@ -32,12 +32,6 @@ jobs: fail-fast: false matrix: include: - - os: macos-15-large - architecture: x64 - output-suffix: x64 - fuse-lib: macFUSE - openjfx-url: 'https://download2.gluonhq.com/openjfx/22.0.2/openjfx-22.0.2_osx-x64_bin-jmods.zip' - openjfx-sha: '115cb08bb59d880cfff6e51e0bf0dcc45785ed9d456b8b8425597b04da6ab3d4' - os: macos-15 architecture: aarch64 output-suffix: arm64 diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index e6512a52e..1d2d3e28e 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -5,7 +5,7 @@ on: env: JAVA_DIST: 'zulu' - JAVA_VERSION: 22 + JAVA_VERSION: 23 defaults: run: diff --git a/.github/workflows/release-check.yml b/.github/workflows/release-check.yml index 0454dc08d..b7e2b14be 100644 --- a/.github/workflows/release-check.yml +++ b/.github/workflows/release-check.yml @@ -12,7 +12,7 @@ defaults: env: JAVA_DIST: 'zulu' - JAVA_VERSION: 22 + JAVA_VERSION: 23 jobs: check-preconditions: diff --git a/.github/workflows/win-exe.yml b/.github/workflows/win-exe.yml index 2209de339..92da78e11 100644 --- a/.github/workflows/win-exe.yml +++ b/.github/workflows/win-exe.yml @@ -16,7 +16,7 @@ on: env: JAVA_DIST: 'zulu' - JAVA_VERSION: '22.0.2+9' + JAVA_VERSION: '23.0.1+11' OPENJFX_JMODS_AMD64: 'https://download2.gluonhq.com/openjfx/22.0.2/openjfx-22.0.2_windows-x64_bin-jmods.zip' OPENJFX_JMODS_AMD64_HASH: 'f9376d200f5c5b85327d575c1ec1482e6455f19916577f7e2fc9be2f48bb29b6' WINFSP_MSI: 'https://github.com/winfsp/winfsp/releases/download/v2.0/winfsp-2.0.23075.msi' diff --git a/.idea/misc.xml b/.idea/misc.xml index 3bcfa174b..09accc25b 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -8,7 +8,7 @@ - + \ No newline at end of file diff --git a/dist/linux/common/org.cryptomator.Cryptomator.metainfo.xml b/dist/linux/common/org.cryptomator.Cryptomator.metainfo.xml index ded761dbb..b15ba0356 100644 --- a/dist/linux/common/org.cryptomator.Cryptomator.metainfo.xml +++ b/dist/linux/common/org.cryptomator.Cryptomator.metainfo.xml @@ -74,6 +74,9 @@ + + https://github.com/cryptomator/cryptomator/releases/1.14.2 + https://github.com/cryptomator/cryptomator/releases/1.14.0 diff --git a/dist/linux/debian/rules b/dist/linux/debian/rules index 81d14f66a..6c2063d21 100755 --- a/dist/linux/debian/rules +++ b/dist/linux/debian/rules @@ -4,7 +4,7 @@ # Uncomment this to turn on verbose mode. #export DH_VERBOSE=1 -JAVA_HOME = /usr/lib/jvm/java-22-coffeelibs +JAVA_HOME = /usr/lib/jvm/java-23-coffeelibs DEB_BUILD_ARCH ?= $(shell dpkg-architecture -qDEB_BUILD_ARCH) ifeq ($(DEB_BUILD_ARCH),amd64) JMODS_PATH = jmods/amd64:${JAVA_HOME}/jmods diff --git a/pom.xml b/pom.xml index dc305726a..0812419af 100644 --- a/pom.xml +++ b/pom.xml @@ -26,18 +26,18 @@ UTF-8 - 22 + 23 org.ow2.asm,org.apache.jackrabbit,org.apache.httpcomponents - 2.7.0 + 2.7.1 1.4.0 1.3.0 1.2.4 - 1.5.0 + 1.5.1 5.0.2 2.0.7 diff --git a/src/main/java/org/cryptomator/common/locationpresets/GoogleDriveMacLocationPresetsProvider.java b/src/main/java/org/cryptomator/common/locationpresets/GoogleDriveMacLocationPresetsProvider.java index 9cb428d1b..a1d4d0c0e 100644 --- a/src/main/java/org/cryptomator/common/locationpresets/GoogleDriveMacLocationPresetsProvider.java +++ b/src/main/java/org/cryptomator/common/locationpresets/GoogleDriveMacLocationPresetsProvider.java @@ -67,7 +67,7 @@ public final class GoogleDriveMacLocationPresetsProvider implements LocationPres */ private String getDriveLocationString(Path accountPath) { String accountName = accountPath.getFileName().toString().replace("GoogleDrive-", ""); - return STR."Google Drive - \{accountName}"; + return "Google Drive - " + accountName; } /** diff --git a/src/main/java/org/cryptomator/common/mount/Mounter.java b/src/main/java/org/cryptomator/common/mount/Mounter.java index 6ca067305..89f8fb782 100644 --- a/src/main/java/org/cryptomator/common/mount/Mounter.java +++ b/src/main/java/org/cryptomator/common/mount/Mounter.java @@ -160,7 +160,7 @@ public class Mounter { var mountService = mountProviders.stream().filter(s -> s.getClass().getName().equals(vaultSettings.mountService.getValue())).findFirst().orElse(defaultMountService.getValue()); if (isConflictingMountService(mountService)) { - var msg = STR."\{mountService.getClass()} unavailable due to conflict with either of \{CONFLICTING_MOUNT_SERVICES.get(mountService.getClass().getName())}"; + var msg = mountService.getClass() + " unavailable due to conflict with either of " + CONFLICTING_MOUNT_SERVICES.get(mountService.getClass().getName()); throw new ConflictingMountServiceException(msg); } diff --git a/src/main/java/org/cryptomator/ui/error/ErrorComponent.java b/src/main/java/org/cryptomator/ui/error/ErrorComponent.java index 554aa65f1..47798c920 100644 --- a/src/main/java/org/cryptomator/ui/error/ErrorComponent.java +++ b/src/main/java/org/cryptomator/ui/error/ErrorComponent.java @@ -20,6 +20,8 @@ public interface ErrorComponent { default Stage show() { Stage stage = window(); stage.setScene(scene()); + stage.setMinWidth(420); + stage.setMinHeight(300); stage.show(); return stage; } diff --git a/src/main/java/org/cryptomator/ui/health/HealthCheckComponent.java b/src/main/java/org/cryptomator/ui/health/HealthCheckComponent.java index aa69e0828..3903734c9 100644 --- a/src/main/java/org/cryptomator/ui/health/HealthCheckComponent.java +++ b/src/main/java/org/cryptomator/ui/health/HealthCheckComponent.java @@ -25,6 +25,8 @@ public interface HealthCheckComponent { default Stage showHealthCheckWindow() { Stage stage = window(); stage.setScene(startScene().get()); + stage.setMinWidth(420); + stage.setMinHeight(300); stage.show(); return stage; } diff --git a/src/main/java/org/cryptomator/ui/keyloading/hub/HubConfig.java b/src/main/java/org/cryptomator/ui/keyloading/hub/HubConfig.java index eefad55a2..4697864f7 100644 --- a/src/main/java/org/cryptomator/ui/keyloading/hub/HubConfig.java +++ b/src/main/java/org/cryptomator/ui/keyloading/hub/HubConfig.java @@ -20,7 +20,7 @@ public class HubConfig { public String devicesResourceUrl; /** - * A collection of String template processors to construct URIs related to this Hub instance. + * A collection of functions to construct URIs related to this Hub instance. */ @JsonIgnore public final URIProcessors URIs = new URIProcessors(); @@ -49,14 +49,20 @@ public class HubConfig { public class URIProcessors { + public final URIProcessor API = this::fromApiEndpoint; + /** * Resolves paths relative to the /api/ endpoint of this Hub instance. */ - public final StringTemplate.Processor API = template -> { - var path = template.interpolate(); + public URI fromApiEndpoint(String path) { var relPath = path.startsWith("/") ? path.substring(1) : path; return getApiBaseUrl().resolve(relPath); - }; + } + } + @FunctionalInterface + public interface URIProcessor { + + URI resolve(String path); } } diff --git a/src/main/java/org/cryptomator/ui/keyloading/hub/ReceiveKeyController.java b/src/main/java/org/cryptomator/ui/keyloading/hub/ReceiveKeyController.java index 3bfb4ec8e..aa56a22e7 100644 --- a/src/main/java/org/cryptomator/ui/keyloading/hub/ReceiveKeyController.java +++ b/src/main/java/org/cryptomator/ui/keyloading/hub/ReceiveKeyController.java @@ -88,7 +88,7 @@ public class ReceiveKeyController implements FxController { * STEP 0 (Request): GET /api/config */ private void requestApiConfig() { - var configUri = hubConfig.URIs.API."config"; + var configUri = hubConfig.URIs.API.resolve("config"); var request = HttpRequest.newBuilder(configUri) // .GET() // .timeout(REQ_TIMEOUT) // @@ -122,7 +122,7 @@ public class ReceiveKeyController implements FxController { * STEP 1 (Request): GET user key for this device */ private void requestDeviceData() { - var deviceUri = hubConfig.URIs.API."devices/\{deviceId}"; + var deviceUri = hubConfig.URIs.API.resolve("devices/" + deviceId); var request = HttpRequest.newBuilder(deviceUri) // .header("Authorization", "Bearer " + bearerToken) // .GET() // @@ -162,7 +162,7 @@ public class ReceiveKeyController implements FxController { * STEP 2 (Request): GET vault key for this user */ private void requestVaultMasterkey(String encryptedUserKey) { - var vaultKeyUri = hubConfig.URIs.API."vaults/\{vaultId}/access-token"; + var vaultKeyUri = hubConfig.URIs.API.resolve("vaults/" + vaultId + "/access-token"); var request = HttpRequest.newBuilder(vaultKeyUri) // .header("Authorization", "Bearer " + bearerToken) // .GET() // @@ -205,7 +205,7 @@ public class ReceiveKeyController implements FxController { */ @Deprecated private void requestLegacyAccessToken() { - var legacyAccessTokenUri = hubConfig.URIs.API."vaults/\{vaultId}/keys/\{deviceId}"; + var legacyAccessTokenUri = hubConfig.URIs.API.resolve("vaults/" + vaultId + "/keys/" + deviceId); var request = HttpRequest.newBuilder(legacyAccessTokenUri) // .header("Authorization", "Bearer " + bearerToken) // .GET() // diff --git a/src/main/java/org/cryptomator/ui/keyloading/hub/RegisterDeviceController.java b/src/main/java/org/cryptomator/ui/keyloading/hub/RegisterDeviceController.java index b00d49874..186d06208 100644 --- a/src/main/java/org/cryptomator/ui/keyloading/hub/RegisterDeviceController.java +++ b/src/main/java/org/cryptomator/ui/keyloading/hub/RegisterDeviceController.java @@ -115,7 +115,7 @@ public class RegisterDeviceController implements FxController { workInProgress.set(true); - var userReq = HttpRequest.newBuilder(hubConfig.URIs.API."users/me") // + var userReq = HttpRequest.newBuilder(hubConfig.URIs.API.resolve("users/me")) // .GET() // .timeout(REQ_TIMEOUT) // .header("Authorization", "Bearer " + bearerToken) // @@ -143,7 +143,7 @@ public class RegisterDeviceController implements FxController { var now = Instant.now().toString(); var dto = new CreateDeviceDto(deviceId, deviceNameField.getText(), BaseEncoding.base64().encode(deviceKeyPair.getPublic().getEncoded()), "DESKTOP", jwe.serialize(), now); var json = toJson(dto); - var deviceUri = hubConfig.URIs.API."devices/\{deviceId}"; + var deviceUri = hubConfig.URIs.fromApiEndpoint("devices/" + deviceId); var putDeviceReq = HttpRequest.newBuilder(deviceUri) // .PUT(HttpRequest.BodyPublishers.ofString(json, StandardCharsets.UTF_8)) // .timeout(REQ_TIMEOUT) // @@ -164,7 +164,7 @@ public class RegisterDeviceController implements FxController { private void migrateLegacyDevices(ECPublicKey userPublicKey) { try { // GET legacy access tokens - var getUri = hubConfig.URIs.API."devices/\{deviceId}/legacy-access-tokens"; + var getUri = hubConfig.URIs.API.resolve("devices/" + deviceId + "/legacy-access-tokens"); var getReq = HttpRequest.newBuilder(getUri).GET().timeout(REQ_TIMEOUT).header("Authorization", "Bearer " + bearerToken).build(); var getRes = httpClient.send(getReq, HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8)); if (getRes.statusCode() != 200) { @@ -185,12 +185,12 @@ public class RegisterDeviceController implements FxController { LOG.warn("Failed to decrypt legacy access token for vault {}. Skipping migration.", entry.getKey()); } }).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); - var postUri = hubConfig.URIs.API."users/me/access-tokens"; + var postUri = hubConfig.URIs.fromApiEndpoint("users/me/access-tokens"); var postBody = JSON.writer().writeValueAsString(newAccessTokens); var postReq = HttpRequest.newBuilder(postUri).POST(HttpRequest.BodyPublishers.ofString(postBody)).timeout(REQ_TIMEOUT).header("Authorization", "Bearer " + bearerToken).build(); var postRes = httpClient.send(postReq, HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8)); if (postRes.statusCode() != 200) { - throw new IOException(STR."Unexpected response from POST \{postUri}: \{postRes.statusCode()}"); + throw new IOException("Unexpected response from POST " + postUri + ": " + postRes.statusCode()); } } catch (IOException e) { // log and ignore: this is merely a best-effort attempt of migrating legacy devices. Failure is uncritical as this is merely a convenience feature. diff --git a/src/main/java/org/cryptomator/ui/mainwindow/VaultListController.java b/src/main/java/org/cryptomator/ui/mainwindow/VaultListController.java index 1919d66ac..e353fe8ed 100644 --- a/src/main/java/org/cryptomator/ui/mainwindow/VaultListController.java +++ b/src/main/java/org/cryptomator/ui/mainwindow/VaultListController.java @@ -113,6 +113,10 @@ public class VaultListController implements FxController { vaultList.setItems(vaults); vaultList.setCellFactory(cellFactory); + vaultList.prefHeightProperty().bind( + vaultList.fixedCellSizeProperty().multiply(Bindings.size(vaultList.getItems())) + ); + selectedVault.bind(vaultList.getSelectionModel().selectedItemProperty()); vaults.addListener((ListChangeListener.Change c) -> { while (c.next()) { diff --git a/src/main/java/org/cryptomator/ui/vaultoptions/GeneralVaultOptionsController.java b/src/main/java/org/cryptomator/ui/vaultoptions/GeneralVaultOptionsController.java index 59a52adf2..5fe6746d7 100644 --- a/src/main/java/org/cryptomator/ui/vaultoptions/GeneralVaultOptionsController.java +++ b/src/main/java/org/cryptomator/ui/vaultoptions/GeneralVaultOptionsController.java @@ -57,9 +57,14 @@ public class GeneralVaultOptionsController implements FxController { } private void trimVaultNameOnFocusLoss(Observable observable, Boolean wasFocussed, Boolean isFocussed) { + var displayNameSetting = vault.getVaultSettings().displayName; if (!isFocussed) { var trimmed = vaultName.getText().trim(); - vault.getVaultSettings().displayName.set(trimmed); + if (!trimmed.isEmpty()) { + displayNameSetting.set(trimmed); //persist changes + } else { + vaultName.setText(displayNameSetting.get()); //revert changes + } } } diff --git a/src/main/resources/fxml/health_start.fxml b/src/main/resources/fxml/health_start.fxml index cc65aaaaa..56c38f740 100644 --- a/src/main/resources/fxml/health_start.fxml +++ b/src/main/resources/fxml/health_start.fxml @@ -25,8 +25,8 @@ - - + + diff --git a/src/main/resources/fxml/preferences_about.fxml b/src/main/resources/fxml/preferences_about.fxml index 1555de504..55577426f 100644 --- a/src/main/resources/fxml/preferences_about.fxml +++ b/src/main/resources/fxml/preferences_about.fxml @@ -17,8 +17,8 @@ - - + + diff --git a/src/main/resources/fxml/vault_detail_missing.fxml b/src/main/resources/fxml/vault_detail_missing.fxml index 6f78b8064..8721496f5 100644 --- a/src/main/resources/fxml/vault_detail_missing.fxml +++ b/src/main/resources/fxml/vault_detail_missing.fxml @@ -9,7 +9,7 @@ xmlns="http://javafx.com/javafx" fx:controller="org.cryptomator.ui.mainwindow.VaultDetailMissingVaultController" alignment="TOP_CENTER" - spacing="24"> + spacing="9"> diff --git a/src/main/resources/fxml/vault_detail_welcome.fxml b/src/main/resources/fxml/vault_detail_welcome.fxml index 8fdcf85eb..132ec33fc 100644 --- a/src/main/resources/fxml/vault_detail_welcome.fxml +++ b/src/main/resources/fxml/vault_detail_welcome.fxml @@ -8,10 +8,10 @@ xmlns="http://javafx.com/javafx" fx:controller="org.cryptomator.ui.mainwindow.WelcomeController" alignment="CENTER" - spacing="24"> + spacing="9"> - - + + diff --git a/src/main/resources/fxml/vault_list.fxml b/src/main/resources/fxml/vault_list.fxml index ae0905d4e..267148d3e 100644 --- a/src/main/resources/fxml/vault_list.fxml +++ b/src/main/resources/fxml/vault_list.fxml @@ -18,11 +18,14 @@ minWidth="206"> - - - - - + + + + + + + +