Merge branch 'develop' into feature/window-debug-launcher

This commit is contained in:
Armin Schrenk
2025-06-17 13:59:33 +02:00
38 changed files with 475 additions and 199 deletions

View File

@@ -53,6 +53,4 @@ updates:
groups:
github-actions:
patterns:
- "*"
labels:
- "misc:ci"
- "*"

View File

@@ -8,6 +8,14 @@ on:
version:
description: 'Version'
required: false
push:
branches-ignore:
- 'dependabot/**'
paths:
- '.github/workflows/appimage.yml'
- 'dist/linux/appimage/**'
- 'dist/linux/common/**'
- 'dist/linux/resources/**'
env:
JAVA_DIST: 'temurin'
@@ -17,7 +25,7 @@ jobs:
get-version:
uses: ./.github/workflows/get-version.yml
with:
version: ${{ inputs.version }}
version: ${{ inputs.version }} #okay if not defined
build:
name: Build AppImage
@@ -29,12 +37,12 @@ jobs:
include:
- os: ubuntu-latest
appimage-suffix: x86_64
openjfx-url: 'https://download2.gluonhq.com/openjfx/23.0.2/openjfx-23.0.2_linux-x64_bin-jmods.zip'
openjfx-sha: '063baebc6922e4a89c94b9dfb7a4f53e59e8d6fec400d4e670b31bc2ab324dec'
openjfx-url: 'https://download2.gluonhq.com/openjfx/24.0.1/openjfx-24.0.1_linux-x64_bin-jmods.zip'
openjfx-sha: '425fac742b9fbd095b2ce868cff82d1024620f747c94a7144d0a4879e756146c'
- os: ubuntu-24.04-arm
appimage-suffix: aarch64
openjfx-url: 'https://download2.gluonhq.com/openjfx/23.0.2/openjfx-23.0.2_linux-aarch64_bin-jmods.zip'
openjfx-sha: '9bbedaeae1590b69e2b22237bda310936df33e344dbc243bea2e86acaab3a0d8'
openjfx-url: 'https://download2.gluonhq.com/openjfx/24.0.1/openjfx-24.0.1_linux-aarch64_bin-jmods.zip'
openjfx-sha: '7e02edd0f4ee5527a27c94b0bbba66fcaaff41009119e45d0eca0f96ddfb6e7b'
steps:
- uses: actions/checkout@v4
- name: Setup Java
@@ -109,7 +117,8 @@ jobs:
--copyright "(C) 2016 - 2025 Skymatic GmbH"
--app-version "${{ needs.get-version.outputs.semVerNum }}.${{ needs.get-version.outputs.revNum }}"
--java-options "--enable-preview"
--java-options "--enable-native-access=org.cryptomator.jfuse.linux.amd64,org.cryptomator.jfuse.linux.aarch64,org.purejava.appindicator"
--java-options "--enable-native-access=javafx.graphics,org.cryptomator.jfuse.linux.amd64,org.cryptomator.jfuse.linux.aarch64,org.purejava.appindicator"
--java-options "--sun-misc-unsafe-memory-access=allow"
--java-options "-Xss5m"
--java-options "-Xmx256m"
--java-options "-Dcryptomator.appVersion=\"${{ needs.get-version.outputs.semVerStr }}\""
@@ -160,7 +169,7 @@ jobs:
- name: Build AppImage
run: >
./squashfs-root/AppRun Cryptomator.AppDir cryptomator-${{ needs.get-version.outputs.semVerStr }}-${{ matrix.appimage-suffix }}.AppImage
-u 'gh-releases-zsync|cryptomator|cryptomator|latest|cryptomator-*-${{ matrix.appimage-suffix }}.AppImage.zsync'
-u "gh-releases-zsync|cryptomator|cryptomator|latest|cryptomator-*-${{ matrix.appimage-suffix }}.AppImage.zsync"
--sign --sign-key=615D449FE6E6A235
- name: Create detached GPG signatures
run: |

View File

@@ -76,7 +76,7 @@ jobs:
name: ${{ needs.download-file.outputs.fileName }}
path: upload
- name: Upload to Avast
uses: wlixcc/SFTP-Deploy-Action@v1.2.5
uses: wlixcc/SFTP-Deploy-Action@v1.2.6
with:
server: whitelisting.avast.com
port: 22

View File

@@ -2,6 +2,10 @@ name: Build
on:
push:
paths:
- '.github/workflows/build.yml'
- 'pom.xml'
- 'src/**'
pull_request_target:
types: [labeled]

View File

@@ -5,41 +5,52 @@ on:
inputs:
semver:
description: 'SemVer String (e.g. 1.7.0-beta1)'
required: true
ppaver:
description: 'Base PPA Version String (e.g. 1.6.16+1.7.0~beta1) without -0ppa1'
required: true
dput:
description: 'Upload to PPA'
required: true
default: false
type: boolean
push:
branches-ignore:
- 'dependabot/**'
paths:
- '.github/workflows/debian.yml'
- 'dist/linux/debian/**'
- 'dist/linux/common/**'
- 'dist/linux/resources/**'
env:
JAVA_DIST: 'temurin'
JAVA_VERSION: '24.0.1+9'
COFFEELIBS_JDK: 24
COFFEELIBS_JDK_VERSION: '24.0.1+9-0ppa3'
OPENJFX_JMODS_AMD64: 'https://download2.gluonhq.com/openjfx/23.0.2/openjfx-23.0.2_linux-x64_bin-jmods.zip'
OPENJFX_JMODS_AMD64_HASH: '063baebc6922e4a89c94b9dfb7a4f53e59e8d6fec400d4e670b31bc2ab324dec'
OPENJFX_JMODS_AARCH64: 'https://download2.gluonhq.com/openjfx/23.0.2/openjfx-23.0.2_linux-aarch64_bin-jmods.zip'
OPENJFX_JMODS_AARCH64_HASH: '9bbedaeae1590b69e2b22237bda310936df33e344dbc243bea2e86acaab3a0d8'
OPENJFX_JMODS_AMD64: 'https://download2.gluonhq.com/openjfx/24.0.1/openjfx-24.0.1_linux-x64_bin-jmods.zip'
OPENJFX_JMODS_AMD64_HASH: '425fac742b9fbd095b2ce868cff82d1024620f747c94a7144d0a4879e756146c'
OPENJFX_JMODS_AARCH64: 'https://download2.gluonhq.com/openjfx/24.0.1/openjfx-24.0.1_linux-aarch64_bin-jmods.zip'
OPENJFX_JMODS_AARCH64_HASH: '7e02edd0f4ee5527a27c94b0bbba66fcaaff41009119e45d0eca0f96ddfb6e7b'
jobs:
get-version:
uses: ./.github/workflows/get-version.yml
with:
version: ${{ inputs.semver }} #okay if not defined
build:
name: Build Debian Package
runs-on: ubuntu-22.04
needs: [get-version]
steps:
- uses: actions/checkout@v4
- id: versions
name: Get version information
- id: deb-version
name: Determine deb-version
run: |
SEM_VER_STR="${{ inputs.semver }}"
SEM_VER_NUM=`echo ${SEM_VER_STR} | sed -E 's/([0-9]+\.[0-9]+\.[0-9]+).*/\1/'`
REVCOUNT=`git rev-list --count HEAD`
echo "semVerStr=${SEM_VER_STR}" >> $GITHUB_OUTPUT
echo "semVerNum=${SEM_VER_NUM}" >> $GITHUB_OUTPUT
echo "revNum=${REVCOUNT}" >> $GITHUB_OUTPUT
if [ -n "${{inputs.ppaver}}" ]; then
echo "debVersion=${{inputs.ppaver }}" >> "$GITHUB_OUTPUT"
else
echo "debVersion=${{needs.get-version.outputs.semVerStr}}" >> "$GITHUB_OUTPUT"
fi
- name: Install build tools
run: |
sudo add-apt-repository ppa:coffeelibs/openjdk
@@ -94,7 +105,7 @@ jobs:
cp -r jmods pkgdir
cp -r dist/linux/common/ pkgdir
cp target/cryptomator-*.jar pkgdir/mods
tar -cJf cryptomator_${{ inputs.ppaver }}.orig.tar.xz -C pkgdir .
tar -cJf cryptomator_${{ steps.deb-version.outputs.debVersion }}.orig.tar.xz -C pkgdir .
- name: Patch and rename pkgdir
run: |
cp -r dist/linux/debian/ pkgdir
@@ -103,12 +114,12 @@ jobs:
envsubst '${SEMVER_STR} ${VERSION_NUM} ${REVISION_NUM} ${DISABLE_UPDATE_CHECK}' < dist/linux/debian/rules > pkgdir/debian/rules
envsubst '${PPA_VERSION} ${RFC2822_TIMESTAMP}' < dist/linux/debian/changelog > pkgdir/debian/changelog
find . -name "*.jar" >> pkgdir/debian/source/include-binaries
mv pkgdir cryptomator_${{ inputs.ppaver }}
mv pkgdir cryptomator_${{ steps.deb-version.outputs.debVersion }}
env:
SEMVER_STR: ${{ steps.versions.outputs.semVerStr }}
VERSION_NUM: ${{ steps.versions.outputs.semVerNum }}
REVISION_NUM: ${{ steps.versions.outputs.revNum }}
PPA_VERSION: ${{ inputs.ppaver }}-0ppa1
SEMVER_STR: ${{ needs.get-version.outputs.semVerStr }}
VERSION_NUM: ${{ needs.get-version.outputs.semVerNum }}
REVISION_NUM: ${{ needs.get-version.outputs.revNum }}
PPA_VERSION: ${{ steps.deb-version.outputs.debVersion }}-0ppa1
- name: Prepare GPG-Agent for signing with key 615D449FE6E6A235
run: |
echo "${GPG_PRIVATE_KEY}" | gpg --batch --quiet --import
@@ -124,7 +135,7 @@ jobs:
env:
DEBSIGN_PROGRAM: gpg --batch --pinentry-mode loopback
DEBSIGN_KEYID: 615D449FE6E6A235
working-directory: cryptomator_${{ inputs.ppaver }}
working-directory: cryptomator_${{ steps.deb-version.outputs.debVersion }}
- name: Create detached GPG signatures
run: |
gpg --batch --quiet --passphrase-fd 0 --pinentry-mode loopback -u 615D449FE6E6A235 --detach-sign -a cryptomator_*_amd64.deb
@@ -141,7 +152,7 @@ jobs:
cryptomator_*_amd64.deb
cryptomator_*.asc
- name: Publish on PPA
if: inputs.dput
if: inputs.dput && inputs.ppaver != ''
run: dput ppa:sebastian-stenzel/cryptomator-beta cryptomator_*_source.changes
# If ref is a tag, also upload to GitHub Releases:
- name: Publish Debian package on GitHub Releases

View File

@@ -44,8 +44,8 @@ jobs:
architecture: x64
output-suffix: x64
fuse-lib: macFUSE
openjfx-url: 'https://download2.gluonhq.com/openjfx/23.0.2/openjfx-23.0.2_osx-x64_bin-jmods.zip'
openjfx-sha: '5e6c65c065eea22430c0eab36f37a5985eb8ad99e19e8772262021740d338f68'
openjfx-url: 'https://download2.gluonhq.com/openjfx/24.0.1/openjfx-24.0.1_osx-x64_bin-jmods.zip'
openjfx-sha: '6e62a426d43c168a488521f904a523f3dd6ee2cf103e08136f2fd465c828a105'
steps:
- uses: actions/checkout@v4
- name: Setup Java
@@ -120,7 +120,8 @@ jobs:
--copyright "(C) 2016 - 2025 Skymatic GmbH"
--app-version "${{ needs.get-version.outputs.semVerNum }}"
--java-options "--enable-preview"
--java-options "--enable-native-access=org.cryptomator.jfuse.mac"
--java-options "--enable-native-access=javafx.graphics,org.cryptomator.jfuse.mac"
--java-options "--sun-misc-unsafe-memory-access=allow"
--java-options "-Xss5m"
--java-options "-Xmx256m"
--java-options "-Dfile.encoding=\"utf-8\""
@@ -240,6 +241,11 @@ jobs:
Cryptomator-${VERSION_NO}-${{ matrix.output-suffix }}.dmg dmg
env:
VERSION_NO: ${{ needs.get-version.outputs.semVerNum }}
- name: Codesign .dmg
run: |
codesign -s ${CODESIGN_IDENTITY} --timestamp Cryptomator-*.dmg
env:
CODESIGN_IDENTITY: ${{ secrets.MACOS_CODESIGN_IDENTITY }}
- name: Notarize .dmg
if: startsWith(github.ref, 'refs/tags/') || inputs.notarize
uses: cocoalibs/xcode-notarization-action@v1

View File

@@ -13,6 +13,12 @@ on:
required: true
default: false
type: boolean
push:
branches-ignore:
- 'dependabot/**'
paths:
- '.github/workflows/mac-dmg.yml'
- 'dist/mac/**'
env:
JAVA_DIST: 'temurin'
@@ -36,8 +42,8 @@ jobs:
architecture: aarch64
output-suffix: arm64
fuse-lib: FUSE-T
openjfx-url: 'https://download2.gluonhq.com/openjfx/23.0.2/openjfx-23.0.2_osx-aarch64_bin-jmods.zip'
openjfx-sha: 'c690cc642a3924cf56622951f478ba57aec9ce09063761f800c3319331bed3fc'
openjfx-url: 'https://download2.gluonhq.com/openjfx/24.0.1/openjfx-24.0.1_osx-aarch64_bin-jmods.zip'
openjfx-sha: 'b5a94a13077507003fa852512bfa33f4fb680bc8076d8002e4227a84c85171d4'
steps:
- uses: actions/checkout@v4
- name: Setup Java
@@ -112,7 +118,8 @@ jobs:
--copyright "(C) 2016 - 2025 Skymatic GmbH"
--app-version "${{ needs.get-version.outputs.semVerNum }}"
--java-options "--enable-preview"
--java-options "--enable-native-access=org.cryptomator.jfuse.mac"
--java-options "--enable-native-access=javafx.graphics,org.cryptomator.jfuse.mac"
--java-options "--sun-misc-unsafe-memory-access=allow"
--java-options "-Xss5m"
--java-options "-Xmx256m"
--java-options "-Dfile.encoding=\"utf-8\""
@@ -232,6 +239,11 @@ jobs:
Cryptomator-${VERSION_NO}-${{ matrix.output-suffix }}.dmg dmg
env:
VERSION_NO: ${{ needs.get-version.outputs.semVerNum }}
- name: Codesign .dmg
run: |
codesign -s ${CODESIGN_IDENTITY} --timestamp Cryptomator-*.dmg
env:
CODESIGN_IDENTITY: ${{ secrets.MACOS_CODESIGN_IDENTITY }}
- name: Notarize .dmg
if: startsWith(github.ref, 'refs/tags/') || inputs.notarize
uses: cocoalibs/xcode-notarization-action@v1

View File

@@ -12,14 +12,19 @@ on:
description: 'Build debug version with console output'
type: boolean
default: false
push:
branches-ignore:
- 'dependabot/**'
paths:
- '.github/workflows/win-exe.yml'
- 'dist/win/**'
env:
JAVA_DIST: 'zulu'
JAVA_VERSION: '24.0.1+9'
OPENJFX_JMODS_AMD64: 'https://download2.gluonhq.com/openjfx/23.0.1/openjfx-23.0.1_windows-x64_bin-jmods.zip'
OPENJFX_JMODS_AMD64_HASH: 'ee176dcee3bd78bde7910735bd67f67c792882f5b89626796ae06f7a1c0119d3'
WINFSP_MSI: 'https://github.com/winfsp/winfsp/releases/download/v2.0/winfsp-2.0.23075.msi'
OPENJFX_JMODS_AMD64: 'https://download2.gluonhq.com/openjfx/24.0.1/openjfx-24.0.1_windows-x64_bin-jmods.zip'
OPENJFX_JMODS_AMD64_HASH: 'f13d17c7caf88654fc835f1b4e75a9b0f34a888eb8abef381796c0002e63b03f'
WINFSP_MSI: 'https://github.com/winfsp/winfsp/releases/download/v2.1/winfsp-2.1.25156.msi'
WINFSP_MSI_HASH: '073a70e00f77423e34bed98b86e600def93393ba5822204fac57a29324db9f7a'
WINFSP_UNINSTALLER: 'https://github.com/cryptomator/winfsp-uninstaller/releases/latest/download/winfsp-uninstaller.exe'
defaults:
@@ -34,8 +39,21 @@ jobs:
build-msi:
name: Build .msi Installer
runs-on: windows-latest
needs: [get-version]
runs-on: ${{ matrix.os }}
needs: [ get-version ]
strategy:
matrix:
include:
- arch: x64
os: windows-latest
java-dist: 'zulu'
java-version: '24.0.1+9'
java-package: 'jdk'
- arch: arm64
os: windows-11-arm
java-dist: 'liberica'
java-version: '24.0.1+11'
java-package: 'jdk+fx' #This is needed, as liberica contains JFX 24 Jmods for Windows ARM64
env:
LOOPBACK_ALIAS: 'cryptomator-vault'
WIN_CONSOLE_FLAG: ''
@@ -44,8 +62,9 @@ jobs:
- name: Setup Java
uses: actions/setup-java@v4
with:
distribution: ${{ env.JAVA_DIST }}
java-version: ${{ env.JAVA_VERSION }}
distribution: ${{ matrix.java-dist }}
java-version: ${{ matrix.java-version }}
java-package: ${{ matrix.java-package }}
check-latest: true
cache: 'maven'
- name: Install wix and extensions
@@ -54,6 +73,7 @@ jobs:
wix.exe extension add WixToolset.UI.wixext/6.0.0 --global
wix.exe extension add WixToolset.Util.wixext/6.0.0 --global
- name: Download and extract JavaFX jmods from Gluon
if: matrix.arch == 'x64'
#In the last step we move all jmods files a dir level up because jmods are placed inside a directory in the zip
run: |
curl --output openjfx-jmods.zip -L "${{ env.OPENJFX_JMODS_AMD64 }}"
@@ -64,6 +84,7 @@ jobs:
Get-ChildItem -Path openjfx-jmods -Recurse -Filter "*.jmod" | ForEach-Object { Move-Item -Path $_ -Destination $_.Directory.Parent}
shell: pwsh
- name: Ensure major jfx version in pom and in jmods is the same
if: matrix.arch == 'x64'
run: |
JMOD_VERSION_AMD64=$(jmod describe openjfx-jmods/javafx.base.jmod | head -1)
JMOD_VERSION_AMD64=${JMOD_VERSION_AMD64#*@}
@@ -77,7 +98,7 @@ jobs:
exit 1
fi
- name: Set version
run : mvn versions:set -DnewVersion=${{ needs.get-version.outputs.semVerStr }}
run: mvn versions:set -DnewVersion=${{ needs.get-version.outputs.semVerStr }}
- name: Run maven
run: mvn -B clean package -Pwin -DskipTests -Djavafx.platform=win
- name: Patch target dir
@@ -93,7 +114,7 @@ jobs:
fi
echo "jmod_paths=${JMOD_PATHS}" >> "$GITHUB_OUTPUT"
- name: Run jlink
#Remark: no compression is applied for improved build compression later (here msi)
# Remark: no compression is applied for improved build compression later (here msi)
run: >
${JAVA_HOME}/bin/jlink
--verbose
@@ -127,7 +148,8 @@ jobs:
--copyright "(C) 2016 - 2025 Skymatic GmbH"
--app-version "${{ needs.get-version.outputs.semVerNum }}.${{ needs.get-version.outputs.revNum }}"
--java-options "--enable-preview"
--java-options "--enable-native-access=org.cryptomator.jfuse.win,org.cryptomator.integrations.win"
--java-options "--enable-native-access=javafx.graphics,org.cryptomator.jfuse.win,org.cryptomator.integrations.win"
--java-options "--sun-misc-unsafe-memory-access=allow"
--java-options "-Xss5m"
--java-options "-Xmx256m"
--java-options "-Dcryptomator.appVersion=\"${{ needs.get-version.outputs.semVerStr }}\""
@@ -144,6 +166,7 @@ jobs:
--java-options "-Dcryptomator.buildNumber=\"msi-${{ needs.get-version.outputs.revNum }}\""
--java-options "-Dcryptomator.integrationsWin.autoStartShellLinkName=\"Cryptomator\""
--java-options "-Dcryptomator.integrationsWin.keychainPaths=\"@{appdata}/Cryptomator/keychain.json;@{userhome}/AppData/Roaming/Cryptomator/keychain.json\""
--java-options "-Dcryptomator.integrationsWin.windowsHelloKeychainPaths=\"@{appdata}/Cryptomator/windowsHelloKeychain.json\""
--java-options "-Djavafx.verbose=${{ inputs.isDebug }}"
--resource-dir dist/win/resources
--icon dist/win/resources/Cryptomator.ico
@@ -256,8 +279,8 @@ jobs:
description: Cryptomator Installer
timestampUrl: 'http://timestamp.digicert.com'
folder: installer
- name: Add possible alpha/beta tags to installer name
run: mv installer/Cryptomator-*.msi Cryptomator-${{ needs.get-version.outputs.semVerStr }}-x64.msi
- name: Add possible alpha/beta tags and architecture to installer name
run: mv installer/Cryptomator-*.msi Cryptomator-${{ needs.get-version.outputs.semVerStr }}-${{ matrix.arch }}.msi
- name: Create detached GPG signature with key 615D449FE6E6A235
run: |
echo "${GPG_PRIVATE_KEY}" | gpg --batch --quiet --import
@@ -268,7 +291,7 @@ jobs:
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: msi
name: msi-${{ matrix.arch }}
path: |
Cryptomator-*.msi
Cryptomator-*.asc
@@ -276,8 +299,23 @@ jobs:
build-exe:
name: Build .exe installer
runs-on: windows-latest
needs: [get-version, build-msi]
runs-on: ${{ matrix.os }}
needs: [ get-version, build-msi ]
strategy:
matrix:
include:
- arch: x64
os: windows-latest
executable-suffix: x64
java-dist: 'zulu'
java-version: '24.0.1+9'
java-package: 'jdk'
- arch: arm64
os: windows-11-arm
executable-suffix: arm64
java-dist: 'liberica'
java-version: '24.0.1+11'
java-package: 'jdk+fx' #This is needed, as liberica contains JFX 24 Jmods for Windows ARM64
steps:
- uses: actions/checkout@v4
- name: Install wix and extensions
@@ -288,14 +326,16 @@ jobs:
- name: Download .msi
uses: actions/download-artifact@v4
with:
name: msi
name: msi-${{ matrix.arch }}
path: dist/win/bundle/resources
- name: Strip version info from msi file name
run: mv dist/win/bundle/resources/Cryptomator*.msi dist/win/bundle/resources/Cryptomator.msi
- uses: actions/setup-java@v4
- name: Setup Java
uses: actions/setup-java@v4
with:
distribution: ${{ env.JAVA_DIST }}
java-version: ${{ env.JAVA_VERSION }}
distribution: ${{ matrix.java-dist }}
java-version: ${{ matrix.java-version }}
java-package: ${{ matrix.java-package }}
check-latest: true
cache: 'maven'
- name: Generate license for exe
@@ -311,7 +351,13 @@ jobs:
shell: pwsh
- name: Download WinFsp
run: |
curl --output dist/win/bundle/resources/winfsp.msi -L ${{ env.WINFSP_MSI }}
curl --output $env:WINFSP_PATH -L ${{ env.WINFSP_MSI }}
$computedHash = (Get-FileHash -Path $env:WINFSP_PATH -Algorithm SHA256).Hash.ToLower()
if ($computedHash -ne "${{ env.WINFSP_MSI_HASH }}") {
throw "Checksum mismatch for $env:WINFSP_PATH (expected ${{ env.WINFSP_MSI_HASH }}, got $computedHash)."
}
env:
WINFSP_PATH: 'dist/win/bundle/resources/winfsp.msi'
shell: pwsh
- name: Download Legacy-WinFsp uninstaller
run: |
@@ -357,7 +403,7 @@ jobs:
timestampUrl: 'http://timestamp.digicert.com'
folder: installer
- name: Add possible alpha/beta tags to installer name
run: mv installer/Cryptomator-Installer.exe Cryptomator-${{ needs.get-version.outputs.semVerStr }}-x64.exe
run: mv installer/Cryptomator-Installer.exe Cryptomator-${{ needs.get-version.outputs.semVerStr }}-${{ matrix.executable-suffix }}.exe
- name: Create detached GPG signature with key 615D449FE6E6A235
run: |
echo "${GPG_PRIVATE_KEY}" | gpg --batch --quiet --import
@@ -368,7 +414,7 @@ jobs:
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: exe
name: exe-${{ matrix.executable-suffix }}
path: |
Cryptomator-*.exe
Cryptomator-*.asc
@@ -378,16 +424,18 @@ jobs:
name: Publish installers to the github release
if: startsWith(github.ref, 'refs/tags/') && github.event.action == 'published'
runs-on: ubuntu-latest
needs: [build-msi, build-exe]
needs: [ build-msi, build-exe ]
outputs:
download-url-msi: ${{ fromJSON(steps.publish.outputs.assets)[0].browser_download_url }}
download-url-exe: ${{ fromJSON(steps.publish.outputs.assets)[1].browser_download_url }}
download-url-msi-x64: ${{ fromJSON(steps.publish.outputs.assets)[0].browser_download_url }}
download-url-msi-arm64: ${{ fromJSON(steps.publish.outputs.assets)[1].browser_download_url }}
download-url-exe-x64: ${{ fromJSON(steps.publish.outputs.assets)[2].browser_download_url }}
download-url-exe-arm64: ${{ fromJSON(steps.publish.outputs.assets)[3].browser_download_url }}
steps:
- name: Download installers
uses: actions/download-artifact@v4
with:
merge-multiple: true
- name: Publish .msi on GitHub Releases
- name: Publish installers on GitHub Releases
id: publish
uses: softprops/action-gh-release@v2
with:
@@ -395,22 +443,38 @@ jobs:
token: ${{ secrets.CRYPTOBOT_RELEASE_TOKEN }}
# do not change ordering of filelist, required for correct job output
files: |
*.msi
*.exe
*x64.msi
*arm64.msi
*x64.exe
*arm64.exe
*.asc
allowlist-msi:
allowlist-msi-x64:
uses: ./.github/workflows/av-whitelist.yml
needs: [publish]
needs: [ publish ]
with:
url: ${{ needs.publish.outputs.download-url-msi }}
url: ${{ needs.publish.outputs.download-url-msi-x64 }}
secrets: inherit
allowlist-exe:
allowlist-msi-arm64:
uses: ./.github/workflows/av-whitelist.yml
needs: [publish, allowlist-msi]
needs: [ publish ]
with:
url: ${{ needs.publish.outputs.download-url-exe }}
url: ${{ needs.publish.outputs.download-url-msi-arm64 }}
secrets: inherit
allowlist-exe-x64:
uses: ./.github/workflows/av-whitelist.yml
needs: [ publish, allowlist-msi-x64 ]
with:
url: ${{ needs.publish.outputs.download-url-exe-x64 }}
secrets: inherit
allowlist-exe-arm64:
uses: ./.github/workflows/av-whitelist.yml
needs: [ publish, allowlist-msi-arm64 ]
with:
url: ${{ needs.publish.outputs.download-url-exe-arm64 }}
secrets: inherit
notify-winget:
@@ -427,7 +491,7 @@ jobs:
SLACK_ICON: false
SLACK_ICON_EMOJI: ':bot:'
SLACK_CHANNEL: 'cryptomator-desktop'
SLACK_TITLE: "MSI of ${{ github.event.repository.name }} ${{ github.event.release.tag_name }} published."
SLACK_MESSAGE: "Ready to <https://github.com/${{ github.repository }}/actions/workflows/winget.yml| release to winget>."
SLACK_TITLE: "MSI packages of ${{ github.event.repository.name }} ${{ github.event.release.tag_name }} published."
SLACK_MESSAGE: "Ready to <https://github.com/${{ github.repository }}/actions/workflows/winget.yml| release them to winget>."
SLACK_FOOTER: false
MSG_MINIMAL: true
MSG_MINIMAL: true

View File

@@ -23,5 +23,5 @@ jobs:
identifier: Cryptomator.Cryptomator
version: ${{ inputs.tag }}
release-tag: ${{ inputs.tag }}
installers-regex: '\.msi$'
installers-regex: '-x64\.msi$'
token: ${{ secrets.CRYPTOBOT_WINGET_TOKEN }}

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="-Dcryptomator.settingsPath=&quot;@{userhome}/.config/Cryptomator/settings.json&quot; -Dcryptomator.p12Path=&quot;@{userhome}/.config/Cryptomator/key.p12&quot; -Dcryptomator.ipcSocketPath=&quot;@{userhome}/.config/Cryptomator/ipc.socket&quot; -Dcryptomator.logDir=&quot;@{userhome}/.local/share/Cryptomator/logs&quot; -Dcryptomator.pluginDir=&quot;@{userhome}/.local/share/Cryptomator/plugins&quot; -Dcryptomator.mountPointsDir=&quot;@{userhome}/.local/share/Cryptomator/mnt&quot; -Dcryptomator.showTrayIcon=true -Xss20m -Xmx512m --enable-preview --enable-native-access=org.cryptomator.jfuse.linux.amd64,org.cryptomator.jfuse.linux.aarch64,org.purejava.appindicator" />
<option name="VM_PARAMETERS" value="-Dcryptomator.settingsPath=&quot;@{userhome}/.config/Cryptomator/settings.json&quot; -Dcryptomator.p12Path=&quot;@{userhome}/.config/Cryptomator/key.p12&quot; -Dcryptomator.ipcSocketPath=&quot;@{userhome}/.config/Cryptomator/ipc.socket&quot; -Dcryptomator.logDir=&quot;@{userhome}/.local/share/Cryptomator/logs&quot; -Dcryptomator.pluginDir=&quot;@{userhome}/.local/share/Cryptomator/plugins&quot; -Dcryptomator.mountPointsDir=&quot;@{userhome}/.local/share/Cryptomator/mnt&quot; -Dcryptomator.showTrayIcon=true -Xss20m -Xmx512m --enable-preview --enable-native-access=org.cryptomator.jfuse.linux.amd64,org.cryptomator.jfuse.linux.aarch64,org.purejava.appindicator,javafx.graphics" />
<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="-Dcryptomator.settingsPath=&quot;@{userhome}/.config/Cryptomator-Dev/settings.json&quot; -Dcryptomator.p12Path=&quot;@{userhome}/.config/Cryptomator-Dev/key.p12&quot; -Dcryptomator.ipcSocketPath=&quot;@{userhome}/.config/Cryptomator-Dev/ipc.socket&quot; -Dcryptomator.logDir=&quot;@{userhome}/.local/share/Cryptomator-Dev/logs&quot; -Dcryptomator.pluginDir=&quot;@{userhome}/.local/share/Cryptomator-Dev/plugins&quot; -Dcryptomator.mountPointsDir=&quot;@{userhome}/.local/share/Cryptomator-Dev/mnt&quot; -Dcryptomator.showTrayIcon=true -Dfuse.experimental=&quot;true&quot; -Xss20m -Xmx512m --enable-preview --enable-native-access=org.cryptomator.jfuse.linux.amd64,org.cryptomator.jfuse.linux.aarch64,org.purejava.appindicator" />
<option name="VM_PARAMETERS" value="-Dcryptomator.settingsPath=&quot;@{userhome}/.config/Cryptomator-Dev/settings.json&quot; -Dcryptomator.p12Path=&quot;@{userhome}/.config/Cryptomator-Dev/key.p12&quot; -Dcryptomator.ipcSocketPath=&quot;@{userhome}/.config/Cryptomator-Dev/ipc.socket&quot; -Dcryptomator.logDir=&quot;@{userhome}/.local/share/Cryptomator-Dev/logs&quot; -Dcryptomator.pluginDir=&quot;@{userhome}/.local/share/Cryptomator-Dev/plugins&quot; -Dcryptomator.mountPointsDir=&quot;@{userhome}/.local/share/Cryptomator-Dev/mnt&quot; -Dcryptomator.showTrayIcon=true -Dfuse.experimental=&quot;true&quot; -Xss20m -Xmx512m --enable-preview --enable-native-access=org.cryptomator.jfuse.linux.amd64,org.cryptomator.jfuse.linux.aarch64,org.purejava.appindicator,javafx.graphics" />
<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="-Dcryptomator.settingsPath=&quot;@{appdata}/Cryptomator/settings.json;@{userhome}/AppData/Roaming/Cryptomator/settings.json&quot; -Dcryptomator.ipcSocketPath=&quot;@{localappdata}/Cryptomator/ipc.socket&quot; -Dcryptomator.logDir=&quot;@{localappdata}/Cryptomator&quot; -Dcryptomator.pluginDir=&quot;@{appdata}/Cryptomator/Plugins&quot; -Dcryptomator.integrationsWin.keychainPaths=&quot;@{appdata}/Cryptomator/keychain.json;@{userhome}/AppData/Roaming/Cryptomator/keychain.json&quot; -Dcryptomator.p12Path=&quot;@{appdata}/Cryptomator/key.p12;@{userhome}/AppData/Roaming/Cryptomator/key.p12&quot; -Dcryptomator.mountPointsDir=&quot;@{userhome}/Cryptomator&quot; -Dcryptomator.showTrayIcon=true -Xss2m -Xmx512m --enable-preview --enable-native-access=org.cryptomator.jfuse.win,org.cryptomator.integrations.win" />
<option name="VM_PARAMETERS" value="-Dcryptomator.settingsPath=&quot;@{appdata}/Cryptomator/settings.json;@{userhome}/AppData/Roaming/Cryptomator/settings.json&quot; -Dcryptomator.ipcSocketPath=&quot;@{localappdata}/Cryptomator/ipc.socket&quot; -Dcryptomator.logDir=&quot;@{localappdata}/Cryptomator&quot; -Dcryptomator.pluginDir=&quot;@{appdata}/Cryptomator/Plugins&quot; -Dcryptomator.integrationsWin.keychainPaths=&quot;@{appdata}/Cryptomator/keychain.json;@{userhome}/AppData/Roaming/Cryptomator/keychain.json&quot; -Dcryptomator.integrationsWin.windowsHelloKeychainPaths=&quot;@{appdata}/Cryptomator/windowsHelloKeychain.json;@{userhome}/AppData/Roaming/Cryptomator/windowsHelloKeychain.json&quot; -Dcryptomator.p12Path=&quot;@{appdata}/Cryptomator/key.p12;@{userhome}/AppData/Roaming/Cryptomator/key.p12&quot; -Dcryptomator.mountPointsDir=&quot;@{userhome}/Cryptomator&quot; -Dcryptomator.showTrayIcon=true -Xss2m -Xmx512m --enable-preview --enable-native-access=org.cryptomator.jfuse.win,org.cryptomator.integrations.win,javafx.graphics" />
<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="-Dcryptomator.settingsPath=&quot;@{appdata}/Cryptomator-Dev/settings.json;@{userhome}/AppData/Roaming/Cryptomator-Dev/settings.json&quot; -Dcryptomator.ipcSocketPath=&quot;@{localappdata}/Cryptomator-Dev/ipc.socket&quot; -Dcryptomator.logDir=&quot;@{localappdata}/Cryptomator-Dev&quot; -Dcryptomator.pluginDir=&quot;@{appdata}/Cryptomator-Dev/Plugins&quot; -Dcryptomator.integrationsWin.keychainPaths=&quot;@{appdata}/Cryptomator-Dev/keychain.json;@{userhome}/AppData/Roaming/Cryptomator-Dev/keychain.json&quot; -Dcryptomator.p12Path=&quot;@{appdata}/Cryptomator-Dev/key.p12;@{userhome}/AppData/Roaming/Cryptomator-Dev/key.p12&quot; -Dcryptomator.mountPointsDir=&quot;@{userhome}/Cryptomator-Dev&quot; -Dcryptomator.showTrayIcon=true -Xss2m -Xmx512m --enable-preview --enable-native-access=org.cryptomator.jfuse.win,org.cryptomator.integrations.win" />
<option name="VM_PARAMETERS" value="-Dcryptomator.settingsPath=&quot;@{appdata}/Cryptomator-Dev/settings.json;@{userhome}/AppData/Roaming/Cryptomator-Dev/settings.json&quot; -Dcryptomator.ipcSocketPath=&quot;@{localappdata}/Cryptomator-Dev/ipc.socket&quot; -Dcryptomator.logDir=&quot;@{localappdata}/Cryptomator-Dev&quot; -Dcryptomator.pluginDir=&quot;@{appdata}/Cryptomator-Dev/Plugins&quot; -Dcryptomator.integrationsWin.keychainPaths=&quot;@{appdata}/Cryptomator-Dev/keychain.json;@{userhome}/AppData/Roaming/Cryptomator-Dev/keychain.json&quot; -Dcryptomator.integrationsWin.windowsHelloKeychainPaths=&quot;@{appdata}/Cryptomator-Dev/windowsHelloKeychain.json;@{userhome}/AppData/Roaming/Cryptomator-Dev/windowsHelloKeychain.json&quot; -Dcryptomator.p12Path=&quot;@{appdata}/Cryptomator-Dev/key.p12;@{userhome}/AppData/Roaming/Cryptomator-Dev/key.p12&quot; -Dcryptomator.mountPointsDir=&quot;@{userhome}/Cryptomator-Dev&quot; -Dcryptomator.showTrayIcon=true -Xss2m -Xmx512m --enable-preview --enable-native-access=org.cryptomator.jfuse.win,org.cryptomator.integrations.win,javafx.graphics" />
<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="-Dapple.awt.enableTemplateImages=true -Dcryptomator.settingsPath=&quot;@{userhome}/Library/Application Support/Cryptomator/settings.json&quot; -Dcryptomator.p12Path=&quot;@{userhome}/Library/Application Support/Cryptomator/key.p12&quot; -Dcryptomator.ipcSocketPath=&quot;@{userhome}/Library/Application Support/Cryptomator/ipc.socket&quot; -Dcryptomator.logDir=&quot;@{userhome}/Library/Logs/Cryptomator&quot; -Dcryptomator.pluginDir=&quot;@{userhome}/Library/Application Support/Cryptomator/Plugins&quot; -Dcryptomator.mountPointsDir=&quot;@{userhome}/Cryptomator&quot; -Dcryptomator.showTrayIcon=true -Dcryptomator.integrationsMac.keychainServiceName=Cryptomator -Xss2m -Xmx512m -ea --enable-preview --enable-native-access=org.cryptomator.jfuse.mac" />
<option name="VM_PARAMETERS" value="-Dapple.awt.enableTemplateImages=true -Dcryptomator.settingsPath=&quot;@{userhome}/Library/Application Support/Cryptomator/settings.json&quot; -Dcryptomator.p12Path=&quot;@{userhome}/Library/Application Support/Cryptomator/key.p12&quot; -Dcryptomator.ipcSocketPath=&quot;@{userhome}/Library/Application Support/Cryptomator/ipc.socket&quot; -Dcryptomator.logDir=&quot;@{userhome}/Library/Logs/Cryptomator&quot; -Dcryptomator.pluginDir=&quot;@{userhome}/Library/Application Support/Cryptomator/Plugins&quot; -Dcryptomator.mountPointsDir=&quot;@{userhome}/Cryptomator&quot; -Dcryptomator.showTrayIcon=true -Dcryptomator.integrationsMac.keychainServiceName=Cryptomator -Xss2m -Xmx512m -ea --enable-preview --enable-native-access=org.cryptomator.jfuse.mac,javafx.graphics" />
<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="-Dapple.awt.enableTemplateImages=true -Dcryptomator.settingsPath=&quot;@{userhome}/Library/Application Support/Cryptomator-Dev/settings.json&quot; -Dcryptomator.p12Path=&quot;@{userhome}/Library/Application Support/Cryptomator-Dev/key.p12&quot; -Dcryptomator.ipcSocketPath=&quot;@{userhome}/Library/Application Support/Cryptomator-Dev/ipc.socket&quot; -Dcryptomator.logDir=&quot;@{userhome}/Library/Logs/Cryptomator-Dev&quot; -Dcryptomator.pluginDir=&quot;@{userhome}/Library/Application Support/Cryptomator-Dev/Plugins&quot; -Dcryptomator.mountPointsDir=&quot;@{userhome}/Library/Application Support/Cryptomator-Dev/mnt&quot; -Dcryptomator.showTrayIcon=true -Dcryptomator.integrationsMac.keychainServiceName=Cryptomator -Xss2m -Xmx512m -ea --enable-preview --enable-native-access=org.cryptomator.jfuse.mac" />
<option name="VM_PARAMETERS" value="-Dapple.awt.enableTemplateImages=true -Dcryptomator.settingsPath=&quot;@{userhome}/Library/Application Support/Cryptomator-Dev/settings.json&quot; -Dcryptomator.p12Path=&quot;@{userhome}/Library/Application Support/Cryptomator-Dev/key.p12&quot; -Dcryptomator.ipcSocketPath=&quot;@{userhome}/Library/Application Support/Cryptomator-Dev/ipc.socket&quot; -Dcryptomator.logDir=&quot;@{userhome}/Library/Logs/Cryptomator-Dev&quot; -Dcryptomator.pluginDir=&quot;@{userhome}/Library/Application Support/Cryptomator-Dev/Plugins&quot; -Dcryptomator.mountPointsDir=&quot;@{userhome}/Library/Application Support/Cryptomator-Dev/mnt&quot; -Dcryptomator.showTrayIcon=true -Dcryptomator.integrationsMac.keychainServiceName=Cryptomator -Xss2m -Xmx512m -ea --enable-preview --enable-native-access=org.cryptomator.jfuse.mac,javafx.graphics" />
<method v="2">
<option name="Make" enabled="true" />
</method>

View File

@@ -78,7 +78,7 @@ For more information on the security details visit [cryptomator.org](https://doc
### Dependencies
* JDK 23 (e.g. temurin, zulu)
* JDK 24 (e.g. temurin, zulu)
* Maven 3
### Run Maven

View File

@@ -12,7 +12,7 @@ command -v unzip >/dev/null 2>&1 || { echo >&2 "unzip not found."; exit 1; }
VERSION=$(mvn -f ../../../pom.xml help:evaluate -Dexpression=project.version -q -DforceStdout)
SEMVER_STR=${VERSION}
CPU_ARCH=$(uname -p)
CPU_ARCH=$(uname -m)
if [[ ! "${CPU_ARCH}" =~ x86_64|aarch64 ]]; then echo "Platform ${CPU_ARCH} not supported"; exit 1; fi
@@ -23,12 +23,12 @@ mvn -B -f ../../../pom.xml clean package -Plinux -DskipTests -Djavafx.platform=l
cp ../../../LICENSE.txt ../../../target
cp ../../../target/cryptomator-*.jar ../../../target/mods
JAVAFX_VERSION=23.0.2
JAVAFX_VERSION=24.0.1
JAVAFX_ARCH="x64"
JAVAFX_JMODS_SHA256='063baebc6922e4a89c94b9dfb7a4f53e59e8d6fec400d4e670b31bc2ab324dec'
JAVAFX_JMODS_SHA256='425fac742b9fbd095b2ce868cff82d1024620f747c94a7144d0a4879e756146c'
if [ "${CPU_ARCH}" = "aarch64" ]; then
JAVAFX_ARCH="aarch64"
JAVAFX_JMODS_SHA256='9bbedaeae1590b69e2b22237bda310936df33e344dbc243bea2e86acaab3a0d8'
JAVAFX_JMODS_SHA256='7e02edd0f4ee5527a27c94b0bbba66fcaaff41009119e45d0eca0f96ddfb6e7b'
fi
# download javaFX jmods
@@ -81,7 +81,7 @@ ${JAVA_HOME}/bin/jpackage \
--name Cryptomator \
--vendor "Skymatic GmbH" \
--java-options "--enable-preview" \
--java-options "--enable-native-access=org.cryptomator.jfuse.linux.amd64,org.cryptomator.jfuse.linux.aarch64,org.purejava.appindicator" \
--java-options "--enable-native-access=javafx.graphics,org.cryptomator.jfuse.linux.amd64,org.cryptomator.jfuse.linux.aarch64,org.purejava.appindicator" \
--copyright "(C) 2016 - 2025 Skymatic GmbH" \
--java-options "-Xss5m" \
--java-options "-Xmx256m" \
@@ -128,7 +128,7 @@ chmod +x /tmp/appimagetool.AppImage
/tmp/appimagetool.AppImage \
Cryptomator.AppDir \
cryptomator-${SEMVER_STR}-${CPU_ARCH}.AppImage \
-u 'gh-releases-zsync|cryptomator|cryptomator|latest|cryptomator-*-${CPU_ARCH}.AppImage.zsync'
-u "gh-releases-zsync|cryptomator|cryptomator|latest|cryptomator-*-${CPU_ARCH}.AppImage.zsync"
echo ""
echo "Done. AppImage successfully created: cryptomator-${SEMVER_STR}-${CPU_ARCH}.AppImage"

View File

@@ -44,7 +44,8 @@ override_dh_auto_build:
--name cryptomator \
--vendor "Skymatic GmbH" \
--java-options "--enable-preview" \
--java-options "--enable-native-access=org.cryptomator.jfuse.linux.amd64,org.cryptomator.jfuse.linux.aarch64,org.purejava.appindicator" \
--java-options "--enable-native-access=javafx.graphics,org.cryptomator.jfuse.linux.amd64,org.cryptomator.jfuse.linux.aarch64,org.purejava.appindicator" \
--java-options "--sun-misc-unsafe-memory-access=allow" \
--copyright "(C) 2016 - 2025 Skymatic GmbH" \
--java-options "-Xss5m" \
--java-options "-Xmx256m" \

View File

@@ -32,15 +32,15 @@ REVISION_NO=`git rev-list --count HEAD`
VERSION_NO=`mvn -f../../../pom.xml help:evaluate -Dexpression=project.version -q -DforceStdout | sed -rn 's/.*([0-9]+\.[0-9]+\.[0-9]+).*/\1/p'`
FUSE_LIB="FUSE-T"
JAVAFX_VERSION=23.0.2
JAVAFX_VERSION=24.0.1
JAVAFX_ARCH="undefined"
JAVAFX_JMODS_SHA256="undefined"
if [ "$(machine)" = "arm64e" ]; then
JAVAFX_ARCH="aarch64"
JAVAFX_JMODS_SHA256="c690cc642a3924cf56622951f478ba57aec9ce09063761f800c3319331bed3fc"
JAVAFX_JMODS_SHA256="b5a94a13077507003fa852512bfa33f4fb680bc8076d8002e4227a84c85171d4"
else
JAVAFX_ARCH="x64"
JAVAFX_JMODS_SHA256="5e6c65c065eea22430c0eab36f37a5985eb8ad99e19e8772262021740d338f68"
JAVAFX_JMODS_SHA256="6e62a426d43c168a488521f904a523f3dd6ee2cf103e08136f2fd465c828a105"
fi
JAVAFX_JMODS_URL="https://download2.gluonhq.com/openjfx/${JAVAFX_VERSION}/openjfx-${JAVAFX_VERSION}_osx-${JAVAFX_ARCH}_bin-jmods.zip"
@@ -106,7 +106,7 @@ ${JAVA_HOME}/bin/jpackage \
--copyright "(C) ${COPYRIGHT_YEARS} ${VENDOR}" \
--app-version "${VERSION_NO}" \
--java-options "--enable-preview" \
--java-options "--enable-native-access=org.cryptomator.jfuse.mac" \
--java-options "--enable-native-access=javafx.graphics,org.cryptomator.jfuse.mac" \
--java-options "-Xss5m" \
--java-options "-Xmx256m" \
--java-options "-Dfile.encoding=\"utf-8\"" \

88
dist/win/build.ps1 vendored
View File

@@ -33,15 +33,15 @@ if ((Get-Command 'wix' -ErrorAction SilentlyContinue) -eq $null)
}
$wixExtensions = & wix.exe extension list --global | Out-String
if ($wixExtensions -notmatch 'WixToolset.UI.wixext') {
Write-Error 'UI wix extension missing. Please install it with: wix.exe extension add WixToolset.UI.wixext/6.0.0 --global)'
Write-Error 'Wix UI extension missing. Please install it with: wix.exe extension add WixToolset.UI.wixext/6.0.0 --global)'
exit 1
}
if ($wixExtensions -notmatch 'WixToolset.Util.wixext') {
Write-Error 'Util wix extension missing. Please install it with: wix.exe extension add WixToolset.Util.wixext/6.0.0 --global)'
Write-Error 'Wix Util extension missing. Please install it with: wix.exe extension add WixToolset.Util.wixext/6.0.0 --global)'
exit 1
}
if ($wixExtensions -notmatch 'WixToolset.BootstrapperApplications.wixext') {
Write-Error 'Util wix extension missing. Please install it with: wix.exe extension add WixToolset.BootstrapperApplications.wixext/6.0.0 --global)'
Write-Error 'Wix Bootstrapper extension missing. Please install it with: wix.exe extension add WixToolset.BootstrapperApplications.wixext/6.0.0 --global)'
exit 1
}
@@ -68,32 +68,60 @@ if ($clean -and (Test-Path -Path $runtimeImagePath)) {
Remove-Item -Path $runtimeImagePath -Force -Recurse
}
## download jfx jmods
$javaFxVersion='23.0.2'
$javaFxJmodsUrl = "https://download2.gluonhq.com/openjfx/${javaFxVersion}/openjfx-${javaFxVersion}_windows-x64_bin-jmods.zip"
$javaFxJmodsSHA256 = 'ee176dcee3bd78bde7910735bd67f67c792882f5b89626796ae06f7a1c0119d3'
$javaFxJmods = '.\resources\jfxJmods.zip'
if( !(Test-Path -Path $javaFxJmods) ) {
Write-Output "Downloading ${javaFxJmodsUrl}..."
Invoke-WebRequest $javaFxJmodsUrl -OutFile $javaFxJmods # redirects are followed by default
## download jfx jmods for X64, while they are part of the Arm64 JDK
$archCode = (Get-CimInstance Win32_Processor).Architecture
$archName = switch ($archCode) {
9 { "x64 (AMD64)" }
12 { "ARM64" }
default { "WMI Win32_Processor.Architecture code ($archCode)" }
}
$jmodsChecksumActual = $(Get-FileHash -Path $javaFxJmods -Algorithm SHA256).Hash.ToLower()
if( $jmodsChecksumActual -ne $javaFxJmodsSHA256 ) {
Write-Error "Checksum mismatch for jfxJmods.zip. Expected: $javaFxJmodsSHA256
, actual: $jmodsChecksumActual"
exit 1;
switch ($archName) {
'ARM64' {
$javafxBaseJmod = Join-Path $Env:JAVA_HOME "jmods\javafx.base.jmod"
if (!(Test-Path $javafxBaseJmod)) {
Write-Error "JavaFX module not found in JDK. Please ensure full JDK (including jmods) is installed."
exit 1
}
$jmodPaths = "$Env:JAVA_HOME/jmods"
}
'x64 (AMD64)' {
$javaFxVersion='24.0.1'
$javaFxJmodsUrl = "https://download2.gluonhq.com/openjfx/${javaFxVersion}/openjfx-${javaFxVersion}_windows-x64_bin-jmods.zip"
$javaFxJmodsSHA256 = 'f13d17c7caf88654fc835f1b4e75a9b0f34a888eb8abef381796c0002e63b03f'
$javaFxJmods = '.\resources\jfxJmods.zip'
if( !(Test-Path -Path $javaFxJmods) ) {
Write-Output "Downloading ${javaFxJmodsUrl}..."
Invoke-WebRequest $javaFxJmodsUrl -OutFile $javaFxJmods # redirects are followed by default
}
$jmodsChecksumActual = $(Get-FileHash -Path $javaFxJmods -Algorithm SHA256).Hash.ToLower()
if( $jmodsChecksumActual -ne $javaFxJmodsSHA256 ) {
Write-Error "Checksum mismatch for jfxJmods.zip. Expected: $javaFxJmodsSHA256
, actual: $jmodsChecksumActual"
exit 1;
}
Expand-Archive -Path $javaFxJmods -Force -DestinationPath ".\resources\"
Remove-Item -Recurse -Force -Path ".\resources\javafx-jmods" -ErrorAction Ignore
Move-Item -Force -Path ".\resources\javafx-jmods-*" -Destination ".\resources\javafx-jmods" -ErrorAction Stop
$jmodPaths="$buildDir/resources/javafx-jmods";
}
default {
Write-Error "Unsupported architecture: $arch"
exit 1
}
}
Expand-Archive -Path $javaFxJmods -Force -DestinationPath ".\resources\"
Remove-Item -Recurse -Force -Path ".\resources\javafx-jmods" -ErrorAction Ignore
Move-Item -Force -Path ".\resources\javafx-jmods-*" -Destination ".\resources\javafx-jmods" -ErrorAction Stop
## create custom runtime
### check for JEP 493
$jmodPaths="$buildDir/resources/javafx-jmods";
if ((& "$Env:JAVA_HOME\bin\jlink" --help | Select-String -Pattern "Linking from run-time image enabled" -SimpleMatch | Measure-Object).Count -eq 0 ) {
$jmodPaths="$Env:JAVA_HOME/jmods;" + $jmodPaths;
}
### create runtime
& "$Env:JAVA_HOME\bin\jlink" `
--verbose `
@@ -133,7 +161,7 @@ Set-Content -Path $buildDir\resources\${AppName}Debug.properties -Value $debugPr
--vendor $Vendor `
--copyright $copyright `
--java-options "--enable-preview" `
--java-options "--enable-native-access=org.cryptomator.jfuse.win,org.cryptomator.integrations.win" `
--java-options "--enable-native-access=javafx.graphics,org.cryptomator.jfuse.win,org.cryptomator.integrations.win" `
--java-options "-Xss5m" `
--java-options "-Xmx256m" `
--java-options "-Dcryptomator.appVersion=`"$semVerNo`"" `
@@ -149,6 +177,7 @@ Set-Content -Path $buildDir\resources\${AppName}Debug.properties -Value $debugPr
--java-options "-Dcryptomator.loopbackAlias=`"$LoopbackAlias`"" `
--java-options "-Dcryptomator.integrationsWin.autoStartShellLinkName=`"$AppName`"" `
--java-options "-Dcryptomator.integrationsWin.keychainPaths=`"@{appdata}/$AppName/keychain.json;@{userhome}/AppData/Roaming/$AppName/keychain.json`"" `
--java-options "-Dcryptomator.integrationsWin.windowsHelloKeychainPaths=`"@{appdata}/$AppName/windowsHelloKeychain.json`"" `
--java-options "-Dcryptomator.showTrayIcon=true" `
--java-options "-Dcryptomator.buildNumber=`"msi-$revisionNo`"" `
--resource-dir resources `
@@ -206,7 +235,6 @@ if ($LASTEXITCODE -ne 0) {
return 1;
}
#Create RTF license for bundle
&mvn -B -f $buildDir/../../pom.xml license:add-third-party "-Djavafx.platform=win" `
"-Dlicense.thirdPartyFilename=license.rtf" `
@@ -218,9 +246,19 @@ if ($LASTEXITCODE -ne 0) {
"-Dlicense.licenseMergesUrl=file:///$buildDir/../../license/merges"
# download Winfsp
$winfspMsiUrl= 'https://github.com/winfsp/winfsp/releases/download/v2.0/winfsp-2.0.23075.msi'
$winfspMsiUrl= 'https://github.com/winfsp/winfsp/releases/download/v2.1/winfsp-2.1.25156.msi'
$winfspMsiHash = '073A70E00F77423E34BED98B86E600DEF93393BA5822204FAC57A29324DB9F7A'
Write-Output "Downloading ${winfspMsiUrl}..."
Invoke-WebRequest $winfspMsiUrl -OutFile ".\bundle\resources\winfsp.msi" # redirects are followed by default
$computedHash = $(Get-FileHash -Path '.\bundle\resources\winfsp.msi' -Algorithm SHA256).Hash
if (! $computedHash.Equals($winfspMsiHash)) {
Write-Error -Category InvalidData -CategoryActivity "Data integrity check failed" -Message @"
Downloaded Winfsp Installer does not match stored SHA256 checksum.
Expected: $winfspMsiHash
Actual: $computedHash
"@
exit 1
}
# download legacy-winfsp uninstaller
$winfspUninstaller= 'https://github.com/cryptomator/winfsp-uninstaller/releases/latest/download/winfsp-uninstaller.exe'
@@ -242,4 +280,6 @@ Copy-Item ".\installer\$AppName-*.msi" -Destination ".\bundle\resources\$AppName
-ext "WixToolset.Util.wixext" `
-ext "WixToolset.BootstrapperApplications.wixext" `
.\bundle\bundleWithWinfsp.wxs `
-out "installer\$AppName-Installer.exe"
-out "installer\$AppName-Installer.exe"
Write-Output "Created EXE installer .\installer\$AppName-Installer.exe"

View File

@@ -6,9 +6,10 @@ java ^
-Dcryptomator.ipcSocketPath="~/AppData/Roaming/Cryptomator/ipc.socket" ^
-Dcryptomator.logDir="~/AppData/Roaming/Cryptomator" ^
-Dcryptomator.mountPointsDir="~/Cryptomator" ^
-Dcryptomator.keychainPath="~/AppData/Roaming/Cryptomator/keychain.json" ^
-Dcryptomator.integrationsWin.keychainPaths="~/AppData/Roaming/Cryptomator/keychain.json" ^
-Dcryptomator.integrationsWin.windowsHelloKeychainPaths="~/AppData/Roaming/Cryptomator/windowsHelloKeychain.json" ^
-Xss20m ^
-Xmx512m ^
--enable-preview `
--enable-native-access=org.cryptomator.jfuse.win `
-m org.cryptomator.desktop/org.cryptomator.launcher.Cryptomator
-m org.cryptomator.desktop/org.cryptomator.launcher.Cryptomator

24
pom.xml
View File

@@ -34,19 +34,19 @@
<!-- cryptomator dependencies -->
<cryptomator.cryptofs.version>2.9.0</cryptomator.cryptofs.version>
<cryptomator.integrations.version>1.5.1</cryptomator.integrations.version>
<cryptomator.integrations.win.version>1.3.0</cryptomator.integrations.win.version>
<cryptomator.integrations.mac.version>1.3.2</cryptomator.integrations.mac.version>
<cryptomator.integrations.linux.version>1.5.3</cryptomator.integrations.linux.version>
<cryptomator.integrations.version>1.6.0</cryptomator.integrations.version>
<cryptomator.integrations.win.version>1.5.0</cryptomator.integrations.win.version>
<cryptomator.integrations.mac.version>1.4.0</cryptomator.integrations.mac.version>
<cryptomator.integrations.linux.version>1.6.0</cryptomator.integrations.linux.version>
<cryptomator.fuse.version>5.0.5</cryptomator.fuse.version>
<cryptomator.webdav.version>2.0.10</cryptomator.webdav.version>
<!-- 3rd party dependencies -->
<commons-lang3.version>3.17.0</commons-lang3.version>
<dagger.version>2.56.1</dagger.version>
<dagger.version>2.56.2</dagger.version>
<easybind.version>2.2</easybind.version>
<jackson.version>2.18.3</jackson.version>
<javafx.version>23.0.2</javafx.version>
<jackson.version>2.19.1</jackson.version>
<javafx.version>24.0.1</javafx.version>
<jwt.version>4.5.0</jwt.version>
<nimbus-jose.version>9.37.3</nimbus-jose.version>
<logback.version>1.5.18</logback.version>
@@ -55,13 +55,13 @@
<zxcvbn.version>1.9.0</zxcvbn.version>
<!-- test dependencies -->
<junit.jupiter.version>5.12.2</junit.jupiter.version>
<mockito.version>5.17.0</mockito.version>
<junit.jupiter.version>5.13.1</junit.jupiter.version>
<mockito.version>5.18.0</mockito.version>
<hamcrest.version>3.0</hamcrest.version>
<!-- build-time dependencies -->
<jetbrains.annotations.version>26.0.2</jetbrains.annotations.version>
<dependency-check.version>12.1.1</dependency-check.version>
<dependency-check.version>12.1.3</dependency-check.version>
<jacoco.version>0.8.13</jacoco.version>
<license-generator.version>2.5.0</license-generator.version>
<junit-tree-reporter.version>1.4.0</junit-tree-reporter.version>
@@ -225,7 +225,7 @@
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
<version>3.2.0</version>
<version>3.2.1</version>
</dependency>
<!-- JUnit / Mockito / Hamcrest -->
<dependency>
@@ -358,7 +358,7 @@
<consoleOutputReporter>
<disable>true</disable>
</consoleOutputReporter>
<argLine>@{surefire.jacoco.args} -javaagent:${org.mockito:mockito-core:jar}</argLine>
<argLine>@{surefire.jacoco.args} -javaagent:${org.mockito:mockito-core:jar} --enable-native-access=javafx.graphics</argLine>
<statelessTestsetInfoReporter
implementation="org.apache.maven.plugin.surefire.extensions.junit5.JUnit5StatelessTestsetInfoTreeReporter">
</statelessTestsetInfoReporter>

View File

@@ -23,6 +23,7 @@ public class Environment {
private static final String SETTINGS_PATH_PROP_NAME = "cryptomator.settingsPath";
private static final String IPC_SOCKET_PATH_PROP_NAME = "cryptomator.ipcSocketPath";
private static final String KEYCHAIN_PATHS_PROP_NAME = "cryptomator.integrationsWin.keychainPaths";
private static final String WINDOWS_HELLO_KEYCHAIN_PATHS_PROP_NAME = "cryptomator.integrationsWin.windowsHelloKeychainPaths";
private static final String P12_PATH_PROP_NAME = "cryptomator.p12Path";
private static final String LOG_DIR_PROP_NAME = "cryptomator.logDir";
private static final String LOOPBACK_ALIAS_PROP_NAME = "cryptomator.loopbackAlias";
@@ -45,6 +46,7 @@ public class Environment {
logCryptomatorSystemProperty(SETTINGS_PATH_PROP_NAME);
logCryptomatorSystemProperty(IPC_SOCKET_PATH_PROP_NAME);
logCryptomatorSystemProperty(KEYCHAIN_PATHS_PROP_NAME);
logCryptomatorSystemProperty(WINDOWS_HELLO_KEYCHAIN_PATHS_PROP_NAME);
logCryptomatorSystemProperty(P12_PATH_PROP_NAME);
logCryptomatorSystemProperty(LOG_DIR_PROP_NAME);
logCryptomatorSystemProperty(LOOPBACK_ALIAS_PROP_NAME);
@@ -85,6 +87,10 @@ public class Environment {
return getPaths(KEYCHAIN_PATHS_PROP_NAME);
}
public Stream<Path> getWindowsHelloKeychainPath() {
return getPaths(WINDOWS_HELLO_KEYCHAIN_PATHS_PROP_NAME);
}
public Stream<Path> getP12Path() {
return getPaths(P12_PATH_PROP_NAME);
}

View File

@@ -42,25 +42,11 @@ public class KeychainManager implements KeychainAccessProvider {
return result;
}
@Override
public String displayName() {
return getClass().getName();
}
@Override
public void storePassphrase(String key, String displayName, CharSequence passphrase) throws KeychainAccessException {
storePassphrase(key, displayName, passphrase, true);
}
//TODO: remove ignored parameter once the API is fixed
@Override
public void storePassphrase(String key, String displayName, CharSequence passphrase, boolean ignored) throws KeychainAccessException {
try {
lock.writeLock().lock();
var kc = getKeychainOrFail();
//this is the only keychain actually using the parameter
var usesOSAuth = (kc.getClass().getName().equals("org.cryptomator.macos.keychain.TouchIdKeychainAccess"));
kc.storePassphrase(key, displayName, passphrase, usesOSAuth);
getKeychainOrFail().storePassphrase(key, displayName, passphrase);
} finally {
lock.writeLock().unlock();
}

View File

@@ -44,7 +44,7 @@ public class Settings {
@Deprecated // to be changed to "whatever is available" eventually
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";
"org.cryptomator.linux.keychain.GnomeKeyringKeychainAccess";
static final String DEFAULT_QUICKACCESS_SERVICE = SystemUtils.IS_OS_WINDOWS ? "org.cryptomator.windows.quickaccess.ExplorerQuickAccessService" : //
SystemUtils.IS_OS_LINUX ? "org.cryptomator.linux.quickaccess.NautilusBookmarks" : null;
@@ -147,6 +147,11 @@ public class Settings {
@SuppressWarnings("deprecation")
private void migrateLegacySettings(SettingsJson json) {
// migrate renamed keychainAccess
if(this.keychainProvider.getValueSafe().equals("org.cryptomator.linux.keychain.SecretServiceKeychainAccess")) {
this.keychainProvider.setValue("org.cryptomator.linux.keychain.GnomeKeyringKeychainAccess");
}
// implicit migration of 1.6.x legacy setting "preferredVolumeImpl":
if (this.mountService.get() == null && json.preferredVolumeImpl != null) {
this.mountService.set(switch (json.preferredVolumeImpl) {

View File

@@ -106,7 +106,7 @@ public class VaultListManager {
vaultList.addAll(vaults);
}
private Optional<Vault> get(Path vaultPath) {
public Optional<Vault> get(Path vaultPath) {
assert vaultPath.isAbsolute();
assert vaultPath.normalize().equals(vaultPath);
return vaultList.stream() //

View File

@@ -79,7 +79,7 @@ public class ReadmeGenerator {
} else if (c <= 0xFF) {
sb.append("\\'").append(String.format("%02X", c));
} else if (c < 0xFFFF) {
sb.append("\\uc1\\u").append(c);
sb.append("\\u").append(c);
}
});
}

View File

@@ -133,9 +133,9 @@ public class EventListCellController implements FxController {
eventMessage.setValue(resourceBundle.getString("eventView.entry.brokenFileNode.message"));
eventDescription.setValue(bfe.ciphertextPath().getFileName().toString());
if (revealService != null) {
addAction("eventView.entry.brokenFileNode.showEncrypted", () -> reveal(revealService, convertVaultPathToSystemPath(bfe.ciphertextPath())));
addAction("eventView.entry.brokenFileNode.showEncrypted", () -> reveal(revealService, bfe.ciphertextPath()));
} else {
addAction("eventView.entry.brokenFileNode.copyEncrypted", () -> copyToClipboard(convertVaultPathToSystemPath(bfe.ciphertextPath()).toString()));
addAction("eventView.entry.brokenFileNode.copyEncrypted", () -> copyToClipboard(bfe.ciphertextPath().toString()));
}
addAction("eventView.entry.brokenFileNode.copyDecrypted", () -> copyToClipboard(convertVaultPathToSystemPath(bfe.cleartextPath()).toString()));
}

View File

@@ -12,6 +12,7 @@ import javax.inject.Named;
import javafx.application.Platform;
import java.io.IOException;
import java.nio.file.Path;
import java.util.Optional;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
@@ -58,29 +59,30 @@ class AppLaunchEventHandler {
switch (event.type()) {
case REVEAL_APP -> appWindows.showMainWindow();
case OPEN_FILE -> Platform.runLater(() -> {
event.pathsToOpen().forEach(this::addOrRevealVault);
event.pathsToOpen().forEach(this::openPotentialVault);
});
default -> LOG.warn("Unsupported event type: {}", event.type());
}
}
// TODO deduplicate MainWindowController...
private void addOrRevealVault(Path potentialVaultPath) {
private void openPotentialVault(Path path) {
assert Platform.isFxApplicationThread();
try {
final Vault v;
if (potentialVaultPath.getFileName().toString().endsWith(CRYPTOMATOR_FILENAME_EXT)) {
v = vaultListManager.add(potentialVaultPath.getParent());
Path potentialVaultPath = path.getFileName().toString().endsWith(CRYPTOMATOR_FILENAME_EXT) ? path.getParent() : path;
final Optional<Vault> v = vaultListManager.get(potentialVaultPath);
if (v.isPresent()) {
if (v.get().isUnlocked()) {
vaultService.reveal(v.get());
} else if (v.get().isLocked()) {
appWindows.startUnlockWorkflow(v.get(), null);
}
} else {
v = vaultListManager.add(potentialVaultPath);
vaultListManager.add(potentialVaultPath);
LOG.debug("Added vault {}", potentialVaultPath);
}
if (v.isUnlocked()) {
vaultService.reveal(v);
}
LOG.debug("Added vault {}", potentialVaultPath);
} catch (IOException e) {
LOG.error("Failed to add vault " + potentialVaultPath, e);
LOG.error("Failed to add vault " + path, e);
}
}

View File

@@ -85,7 +85,7 @@ public class GeneralPreferencesController implements FxController {
var keychainSettingsConverter = new ServiceToSettingsConverter<>(keychainAccessProviders);
keychainBackendChoiceBox.getItems().addAll(keychainAccessProviders);
keychainBackendChoiceBox.setValue(keychainSettingsConverter.fromString(settings.keychainProvider.get()));
keychainBackendChoiceBox.setConverter(new KeychainProviderDisplayNameConverter());
keychainBackendChoiceBox.setConverter(new NamedServiceConverter<>());
Bindings.bindBidirectional(settings.keychainProvider, keychainBackendChoiceBox.valueProperty(), keychainSettingsConverter);
useKeychainCheckbox.selectedProperty().bindBidirectional(settings.useKeychain);
keychainBackendChoiceBox.disableProperty().bind(useKeychainCheckbox.selectedProperty().not());
@@ -106,13 +106,13 @@ public class GeneralPreferencesController implements FxController {
var idsAndNames = settings.directories.stream().collect(Collectors.toMap(vs -> vs.id, vs -> vs.displayName.getValue()));
if (!idsAndNames.isEmpty()) {
if (LOG.isDebugEnabled()) {
LOG.debug("Migrating keychain entries {} from {} to {}", idsAndNames.keySet(), oldProvider.displayName(), newProvider.displayName());
LOG.debug("Migrating keychain entries {} from {} to {}", idsAndNames.keySet(), oldProvider.getName(), newProvider.getName());
}
keychainMigrations = keychainMigrations.thenRunAsync(() -> {
try {
KeychainManager.migrate(oldProvider, newProvider, idsAndNames);
} catch (KeychainAccessException e) {
LOG.warn("Failed to migrate all entries from {} to {}", oldProvider.displayName(), newProvider.displayName(), e);
LOG.warn("Failed to migrate all entries from {} to {}", oldProvider.getName(), newProvider.getName(), e);
}
}, backgroundExecutor);
}
@@ -151,25 +151,6 @@ public class GeneralPreferencesController implements FxController {
}
/* Helper classes */
private static class KeychainProviderDisplayNameConverter extends StringConverter<KeychainAccessProvider> {
@Override
public String toString(KeychainAccessProvider provider) {
if (provider == null) {
return null;
} else {
return provider.displayName();
}
}
@Override
public KeychainAccessProvider fromString(String string) {
throw new UnsupportedOperationException();
}
}
private static class NamedServiceConverter<T extends NamedServiceProvider> extends StringConverter<T> {
@Override

View File

@@ -423,6 +423,7 @@ main.vaultDetail.stats=إحصائيات الخزنة
main.vaultDetail.locateEncryptedFileBtn=تحديد موقع الملف المشفر
main.vaultDetail.locateEncryptedFileBtn.tooltip=اختر ملف من خزانتك لتحديد مكان نظيره المشفر
main.vaultDetail.encryptedPathsCopied=تم نسخ مسارات الملفات إلى الحافظة!
main.vaultDetail.decryptName.buttonLabel=فك تشفير اسم الملف
### Missing
main.vaultDetail.missing.info=لم يتمكن Cryptomator من العثور على خزنة في هذا المسار.
main.vaultDetail.missing.recheck=إعادة الفحص

View File

@@ -616,7 +616,7 @@ eventView.entry.decryptionFailed.copyEncrypted=Pfad der verschlüsselten Datei k
eventView.entry.brokenDirFile.message=Ungültiger Verzeichnislink
eventView.entry.brokenDirFile.showEncrypted=Defekten, verschlüsselten Link anzeigen
eventView.entry.brokenDirFile.copyEncrypted=Pfad des ungültigen Links kopieren
eventView.entry.brokenFileNode.message=Fehlender Dateisystemknoten
eventView.entry.brokenFileNode.message=Beschädigter Dateisystemknoten
eventView.entry.brokenFileNode.showEncrypted=Beschädigten, verschlüsselten Knoten anzeigen
eventView.entry.brokenFileNode.copyEncrypted=Pfad des kaputten, verschlüsselten Knotens kopieren
eventView.entry.brokenFileNode.copyEncrypted=Pfad des beschädigten, verschlüsselten Knotens kopieren
eventView.entry.brokenFileNode.copyDecrypted=Pfad der entschlüsselten Datei kopieren

View File

@@ -177,6 +177,7 @@ hub.registerFailed.description.generic=Rekisteröinnissä tapahtui virhe. Löyd
hub.registerFailed.description.deviceAlreadyExists=Tämä laite on jo rekisteröity toiselle käyttäjälle. Yritä vaihtaa käyttäjätiliä tai käytää toista laitetta.
### Unauthorized
hub.unauthorized.message=Pääsy estetty
hub.unauthorized.description=Sinulla ei ole oikeutta avata tätä holvia. Ota yhteyttä holvin omistajaan pyytääksesi pääsyä.
### Requires Account Initialization
hub.requireAccountInit.message=Toimia vaaditaan
hub.requireAccountInit.description.0=Jatkaaksesi, ole hyvä ja suorita tarvittavat toimenpiteet
@@ -282,6 +283,7 @@ preferences.title=Asetukset
## General
preferences.general=Yleiset
preferences.general.startHidden=Piilota ikkuna kun Cryptomator käynnistyy
preferences.general.autoCloseVaults=Lukitse holvit kysymättä, kun ohjelma suljetaan
preferences.general.debugLogging=Ota virheloki käyttöön
preferences.general.debugDirectory=Näytä lokitiedostot
preferences.general.autoStart=Käynnistä Cryptomator järjestelmän käynnistyessä
@@ -330,6 +332,7 @@ preferences.updates.upToDate=Cryptomator on ajan tasalla.
## Contribution
preferences.contribute=Tue meitä
preferences.contribute.registeredFor=Tukijan sertifikaatti rekisteröity %s
preferences.contribute.noCertificate=Tue Cryptomatoria ja saa tukijasertifikaatti. Se on kuin lisenssiavain, mutta mahtaville ihmisille, jotka käyttävät vapaata ohjelmistoa. ;-)
preferences.contribute.getCertificate=Eikö sinulla ole sellaista? Lue lisää miten voit hankkia sellaisen.
preferences.contribute.promptText=Liitä tukijasertifikaatin koodi tähän
@@ -391,6 +394,7 @@ main.vaultlist.contextMenu.vaultoptions=Näytä holvin asetukset
main.vaultlist.contextMenu.reveal=Paljasta Asema
main.vaultlist.addVaultBtn.menuItemNew=Luo uusi holvi...
main.vaultlist.addVaultBtn.menuItemExisting=Avaa olemassa oleva holvi...
main.vaultlist.showEventsButton.tooltip=Avaa tapahtumanäkymä
##Notificaition
main.notification.updateAvailable=Päivitys on saatavilla.
main.notification.support=Tue Cryptomatoria.
@@ -419,6 +423,9 @@ main.vaultDetail.stats=Holvin tilastot
main.vaultDetail.locateEncryptedFileBtn=Etsi salattu tiedosto
main.vaultDetail.locateEncryptedFileBtn.tooltip=Valitse tiedosto holvistasi löytääksesi sen salatun vastineen
main.vaultDetail.encryptedPathsCopied=Polut kopioitu leikepöydälle!
main.vaultDetail.locateEncrypted.filePickerTitle=Valitse tiedosto holvin sisältä
main.vaultDetail.decryptName.buttonLabel=Pura tiedoston nimen salaus
main.vaultDetail.decryptName.tooltip=Valitse salattu tiedosto purkaaksesi nimen salauksen
### Missing
main.vaultDetail.missing.info=Cryptomator ei löytänyt täältä holvia.
main.vaultDetail.missing.recheck=Tarkista uudelleen
@@ -545,6 +552,10 @@ updateReminder.yesAutomatically=Kyllä, automaattisesti
dokanySupportEnd.preferencesBtn=Avaa asetukset
#Retry If Readonly
retryIfReadonly.title=Rajoitettu holvin pääsy
retryIfReadonly.message=Ei kirjoitusoikeuksia holvihakemistoon
retryIfReadonly.description=Cryptomator ei voi kirjoittaa holvihakemistoon. Voit vaihtaa holvin lukutilaan ja yrittää uudelleen. Tämä vaihtoehto voidaan poistaa käytöstä holvin asetuksissa.
retryIfReadonly.retry=Vaihda ja yritä uudelleen
# Share Vault
shareVault.title=Jaa holvi
@@ -554,14 +565,46 @@ shareVault.instruction.1=1. Jaa käyttöoikeus salattuun holvikansioon pilvipalv
shareVault.instruction.2=2. Jaa holvin salasana turvallisella tavalla.
shareVault.remarkBestPractices=Lisätietoja varten tutustu hyvien käytäntöjen suosituksiin dokumentaatiossamme.
shareVault.docsTooltip=Avaa dokumentaatio lukeaksesi lisää holvein jakamisesta.
shareVault.hubAd.description=Turvallinen tapa työskennellä tiimeissä
shareVault.hubAd.keyManagement=• Nollatieto avainten hallinta
shareVault.hubAd.authentication=• Vahva todennus
shareVault.hubAd.encryption=• Päästä päähän salaus
shareVault.visitHub=Käy Cryptomator Hubissa
shareVault.hub.message=Kuinka jakaa Hub -holvi
shareVault.hub.description=Jotta holvin sisältö voitaisiin jakaa toisen tiimin jäsenen kanssa, sinun on suoritettava kaksi vaihetta:
shareVault.hub.instruction.1=1. Jaa käyttöoikeus salattuun holvikansioon pilvipalvelun kautta.
shareVault.hub.instruction.2=2. Myönnä käyttöoikeus tiimin jäsenelle Cryptomator Hubissa.
shareVault.hub.openHub=Avaa Cryptomator Hub
# Decrypt File Names
decryptNames.title=Pura tiedostonimien salaus
decryptNames.filePicker.title=Valitse salattu tiedosto
decryptNames.dropZone.message=Pudota tiedostoja tai napsauta valitaksesi
decryptNames.dropZone.error.generic=Tiedostonimien salauksen purku epäonnistui
# Event View
eventView.title=Tapahtumat
eventView.filter.allVaults=Kaikki
eventView.clearListButton.tooltip=Tyhjennä luettelo
## event list entries
eventView.entry.vaultLocked.description=Avaa "%s" lisätietoja varten
eventView.entry.conflictResolved.message=Ratkaistu ristiriita
eventView.entry.conflictResolved.showDecrypted=Näytä purettu tiedosto
eventView.entry.conflictResolved.copyDecrypted=Kopioi purettu polku
eventView.entry.conflict.message=Ristiriidan ratkaisu epäonnistui
eventView.entry.conflict.showDecrypted=Näytä purettu, alkuperäinen tiedosto
eventView.entry.conflict.copyDecrypted=Näytä purettu, alkuperäinen polku
eventView.entry.conflict.showEncrypted=Näytä ristiriitainen, salattu tiedosto
eventView.entry.conflict.copyEncrypted=Kopioi ristiriitainen, salattu polku
eventView.entry.decryptionFailed.message=Salauksen purku epäonnistui
eventView.entry.decryptionFailed.showEncrypted=Näytä salattu tiedosto
eventView.entry.decryptionFailed.copyEncrypted=Kopioi salattu polku
eventView.entry.brokenDirFile.message=Virheellinen hakemiston linkki
eventView.entry.brokenDirFile.showEncrypted=Näytä virheellinen, salattu linkki
eventView.entry.brokenDirFile.copyEncrypted=Kopioi virheellisen polun linkki
eventView.entry.brokenFileNode.message=Virheellinen tiedostojärjestelmän solmu
eventView.entry.brokenFileNode.showEncrypted=Näytä virheellinen, salattu solmu
eventView.entry.brokenFileNode.copyEncrypted=Kopioi virheellisen, salatun solmun polku
eventView.entry.brokenFileNode.copyDecrypted=Kopioi purettu polku

View File

@@ -424,6 +424,9 @@ main.vaultDetail.stats=Vault 통계
main.vaultDetail.locateEncryptedFileBtn=암호화된 파일 위치
main.vaultDetail.locateEncryptedFileBtn.tooltip=암호화된 파일을 보기 위해 Vault에서 파일을 선택하십시오.
main.vaultDetail.encryptedPathsCopied=클립보드에 복사됨!
main.vaultDetail.locateEncrypted.filePickerTitle=Vault 내부에서 파일 선택
main.vaultDetail.decryptName.buttonLabel=파일명 복호화
main.vaultDetail.decryptName.tooltip=암호화된 볼트 파일을 선택해 파일 이름을 복호화
### Missing
main.vaultDetail.missing.info=Cryptomator가 이 경로에 있는 Vault를 찾지 못했습니다.
main.vaultDetail.missing.recheck=다시 시도
@@ -580,11 +583,21 @@ shareVault.hub.instruction.2=2. Cryptomator Hub에서 팀 구성원에 접근을
shareVault.hub.openHub=Cryptomator Hub 열기
# Decrypt File Names
decryptNames.title=파일명 복호화
decryptNames.filePicker.title=암호화된 파일 선택
decryptNames.filePicker.extensionDescription=Cryptomator로 암호화된 파일
decryptNames.copyTable.tooltip=테이블 복사
decryptNames.clearTable.tooltip=테이블 비우기
decryptNames.dropZone.message=파일을 여기에 드롭하거나 클릭하세요
decryptNames.dropZone.error.vaultInternalFiles=복호화 가능한 이름이 선택되지 않은 Vailt 내부 파일
decryptNames.dropZone.error.noDirIdBackup=선택된 파일 폴더에 dirId.c9r 파일이 포함되어 있지 않습니다
decryptNames.dropZone.error.generic=파일 이름 복호화 실패
# Event View
eventView.title=이벤트
eventView.filter.allVaults=전체
eventView.clearListButton.tooltip=목록 지우기
## event list entries
eventView.entry.vaultLocked.description="%s"를 잠금 해제하여 세부정보 보기
eventView.entry.conflictResolved.message=해결된 충돌

View File

@@ -1,6 +1,7 @@
# Locale Specific CSS files such as CJK, RTL,...
# Generics
generic.action.dismiss=Откажи
## Button
generic.button.apply=Примени
generic.button.back=Назад
@@ -13,6 +14,7 @@ generic.button.copied=Копирано!
generic.button.done=Прифати
generic.button.next=Продолжи
generic.button.print=Печати
generic.button.remove=Отстрани
# Error
error.message=Грешка
@@ -22,6 +24,8 @@ error.hyperlink.report=Пријави ја оваа грешка
error.technicalDetails=Детали:
error.existingSolutionDescription=Не очекуваше да се случи ова. Но најдовме постоечко решение за оваа грешка. Ве молиме погледнете го следниот линк.
error.hyperlink.solution=Пребарај решение
error.dismiss=Откажи
error.lookUpSolution=Пребарај решение
# Defaults
defaults.vault.vaultName=Сеф

View File

@@ -68,6 +68,7 @@ addvaultwizard.new.validCharacters.dashes=Dấu gạch ngang (%s) hoặc dấu g
### Expert Settings
addvaultwizard.new.expertSettings.enableExpertSettingsCheckbox="Bật các cài đặt chuyên gia"
addvaultwizard.new.expertSettings.shorteningThreshold.invalid=Nhập giá trị từ 36 đến 220 (mặc định 220)
addvaultwizard.new.expertSettings.shorteningThreshold.tooltip=Mở tài liệu để tìm hiểu thêm.
addvaultwizard.new.expertSettings.shorteningThreshold.title="Chiều dài tối đa của tên các file được mã hóa"
addvaultwizard.new.expertSettings.shorteningThreshold.valid="Hợp lệ"
### Password
@@ -138,7 +139,12 @@ unlock.error.customPath.message=Không thể gắn vault vào đường dẫn t
unlock.error.customPath.description.notSupported=Nếu bạn muốn tiếp tục sử dụng đường dẫn tuỳ chỉnh, vui lòng chuyển đến tuỳ chọn và chọn loại ổ đĩa hỗ trợ nó. Nếu không, hãy chuyển đến tuỳ chọn vault và chọn điểm gắn kết được hỗ trợ.
unlock.error.customPath.description.notExists=Đường dẫn gắn kết tuỳ chỉnh không tồn tại. Tạo nó trong hệ thống tệp cục bộ của bạn hoặc thay đổi nó trong các tuỳ chọn vault.
unlock.error.customPath.description.inUse="Ký hiệu ổ cứng hoặc đường dẫn tự gán "%s" đã bị chiếm dụng".
unlock.error.customPath.description.hideawayNotDir=Không thể xóa tệp tạm thời, tệp ẩn "%3$s" dùng để mở khóa. Vui lòng kiểm tra tệp này và xóa nó bằng tay.
unlock.error.customPath.description.couldNotBeCleaned=Vault của bạn không gắn được vào đường dẫn "%s". Vui lòng thử lại hoặc chọn một đường dẫn khác.
unlock.error.customPath.description.notEmptyDir=Đường dẫn tùy chỉnh "%s" không phải là một thư mục trống. Vui lòng chọn một thư mục trống và thử lại.
unlock.error.customPath.description.generic=Bạn đã chọn một đường dẫn gắn tùy chỉnh cho vault này, nhưng việc sử dụng nó đã thất bại với thông báo: %2$s
unlock.error.restartRequired.message=Không thể mở vault
unlock.error.restartRequired.description=Thay đổi loại ổ đĩa trong tùy chọn vault hoặc khởi động lại Cryptomator.
unlock.error.title=Mở khóa "%s" không thành công
## Hub
hub.noKeychain.message=Không thể truy cập khoá thiết bị
@@ -153,18 +159,30 @@ hub.receive.message=Đang xử lý phản hồi…
hub.receive.description=Cryptomator đang nhận và xử lý phản hồi từ Hub. Vui lòng chờ.
### Register Device
hub.register.message=Thiết bị mới
hub.register.description=Đây là lần đầu tiên truy cập Hub từ thiết bị này. Vui lòng đăng ký bằng Khóa Tài Khoản của bạn.
hub.register.nameLabel=Tên thiết bị
hub.register.invalidAccountKeyLabel=Khóa Tài Khoản không đúng
hub.register.registerBtn=Đăng ký
### Register Device Legacy
hub.register.legacy.occupiedMsg=Tên đã sử dụng
hub.register.legacy.description=Đây là lần đầu tiên truy cập Hub từ thiết bị này. Vui lòng đăng ký.
### Registration Success
hub.registerSuccess.message=Đã đăng ký thiết bị
hub.registerSuccess.description=Thiết bị của bạn đã được đăng ký thành công. Bạn có thể tiếp tục mở khóa vault.
hub.registerSuccess.unlockBtn=Mở khoá
hub.registerSuccess.legacy.description=Để truy cập vault, thiết bị của bạn cần được chủ sở hữu vault cấp phép.
### Registration Failed
hub.registerFailed.message=Đăng ký thiết bị thất bại
hub.registerFailed.description.generic=Đã xảy ra lỗi trong quá trình đăng ký. Để biết thêm chi tiết, vui lòng kiểm tra nhật ký ứng dụng.
hub.registerFailed.description.deviceAlreadyExists=Thiết bị này đã được đăng ký cho người dùng khác. Hãy thử tài khoản khác hoặc sử dụng một thiết bị khác.
### Unauthorized
hub.unauthorized.message=Truy cập bị từ chối
hub.unauthorized.description=Bạn không được phép mở vault này. Vui lòng liên hệ với chủ sở hữu vault để yêu cầu quyền truy cập.
### Requires Account Initialization
hub.requireAccountInit.message=Cần thực hiện hành động
hub.requireAccountInit.description.0=Để tiếp tục, vui lòng hoàn thành các bước yêu cầu trong
hub.requireAccountInit.description.1=Hồ sơ người dùng
hub.requireAccountInit.description.2=.
### License Exceeded
hub.invalidLicense.message=Giấy phép Hub không hợp lệ
hub.invalidLicense.description=Phiên bản Cryptomator Hub của bạn có giấy phép không hợp lệ. Vui lòng thông báo cho quản trị viên Hub để nâng cấp hoặc gia hạn giấy phép.
@@ -265,10 +283,12 @@ preferences.title=Tùy chỉnh
## General
preferences.general=Chung
preferences.general.startHidden=Ẩn cửa sổ khi khởi động Cryptomator
preferences.general.autoCloseVaults=Tự động khóa vaults khi thoát ứng dụng mà không cần xác nhận
preferences.general.debugLogging=Bật nhật kí gỡ lỗi
preferences.general.debugDirectory=Mở tệp nhật ký
preferences.general.autoStart=Khởi chạy Cryptomator khi khởi động hệ thống
preferences.general.keychainBackend=Lưu mật khẩu với
preferences.general.quickAccessService=Thêm các vault đã mở khóa vào khu vực truy cập nhanh
## Interface
preferences.interface=Giao diện
preferences.interface.theme=Cái nhìn và cảm nhận
@@ -282,8 +302,10 @@ preferences.interface.interfaceOrientation=Định hướng giao diện
preferences.interface.interfaceOrientation.ltr=Trái sang phải
preferences.interface.interfaceOrientation.rtl=Phải sang trái
preferences.interface.showTrayIcon=Hiển thị biểu tượng khay (yêu cầu khởi động lại)
preferences.interface.compactMode=Bật danh sách vault thu gọn
## Volume
preferences.volume=Ổ lưu trữ ảo
preferences.volume.type=Loại ổ đĩa mặc định
preferences.volume.type.automatic=Tự động
preferences.volume.docsTooltip=Mở tài liệu để tìm hiểu thêm về các loại ổ đĩa khác nhau.
preferences.volume.fuseRestartRequired=Để áp dụng các thay đổi, Cryptomator cần được khởi động lại.
@@ -300,10 +322,13 @@ preferences.updates.currentVersion=Phiên bản hiện tại: %s
preferences.updates.autoUpdateCheck=Tự động kiểm tra phiên bản mới
preferences.updates.checkNowBtn=Kiểm tra ngay
preferences.updates.updateAvailable=Có bản cập nhật lên phiên bản %s.
preferences.updates.lastUpdateCheck=Lần kiểm tra cuối: %s
preferences.updates.lastUpdateCheck.never=không bao giờ
preferences.updates.lastUpdateCheck.recently=gần đây
preferences.updates.lastUpdateCheck.daysAgo=%s ngày trước
preferences.updates.lastUpdateCheck.hoursAgo=%s giờ trước
preferences.updates.checkFailed=Không thể kiểm tra cập nhật. Vui lòng kiểm tra kết nối internet hoặc thử lại sau.
preferences.updates.upToDate=Cryptomator đã được cập nhật mới nhất.
## Contribution
preferences.contribute=Hỗ trợ chúng tôi
@@ -311,8 +336,14 @@ preferences.contribute.registeredFor=Chứng nhận Người Hỗ Trợ được
preferences.contribute.noCertificate=Hỗ trợ Cryptomator và lấy về cho bạn chứng nhận người hỗ trợ. Chứng nhận này giống như giấy phép sử dụng phần mềm, nhưng chỉ dành cho những con người tuyệt vời đang dùng phần mềm tự do. ;-)
preferences.contribute.getCertificate=Bạn chưa có? Tìm hiểu cách bạn có thể lấy được nó.
preferences.contribute.promptText=Vui lòng dán mã chứng nhận người hỗ trợ vào đây
preferences.contribute.thankYou=Cảm ơn bạn đã hỗ trợ phát triển mã nguồn mở của Cryptomator!
preferences.contribute.donate=Ủng Hộ
preferences.contribute.sponsor=Nhà tài trợ
### Remove License Key Dialog
removeCert.title=Xoá Chứng chỉ
removeCert.message=Xóa chứng chỉ người ủng hộ?
removeCert.description=Các tính năng chính của Cryptomator không bị ảnh hưởng bởi điều này. Việc truy cập vào các vault của bạn không bị hạn chế và mức độ bảo mật cũng không bị giảm.
#<-- Add entries for donations and code/translation/documentation contribution -->
## About
@@ -362,7 +393,12 @@ main.vaultlist.contextMenu.unlock=Mở khoá…
main.vaultlist.contextMenu.unlockNow=Mở khóa bây giờ
main.vaultlist.contextMenu.vaultoptions=Hiện tùy chọn vault
main.vaultlist.contextMenu.reveal=Hiển thị Ổ đĩa
main.vaultlist.addVaultBtn.menuItemNew=Tạo Vault Mới...
main.vaultlist.addVaultBtn.menuItemExisting=Mở Vault Hiện Có...
main.vaultlist.showEventsButton.tooltip=Mở xem sự kiện
##Notificaition
main.notification.updateAvailable=Có bản cập nhật mới.
main.notification.support=Hỗ trợ Cryptomator.
## Vault Detail
### Welcome
main.vaultDetail.welcomeOnboarding=Cảm ơn bạn đã chọn Cryptomator để bảo vệ tệp của bạn. Nếu bạn cần bất kỳ hỗ trợ nào, hãy xem hướng dẫn bắt đầu của chúng tôi:
@@ -388,6 +424,9 @@ main.vaultDetail.stats=Thống kê Vault
main.vaultDetail.locateEncryptedFileBtn=Định vị Tệp Đã mã hoá
main.vaultDetail.locateEncryptedFileBtn.tooltip=Chọn một tệp từ vaule của bạn để xác định vị trí đối tác được mã hoá của nó
main.vaultDetail.encryptedPathsCopied=Đường dẫn Đã sao chép vào Bảng tạm!
main.vaultDetail.locateEncrypted.filePickerTitle=Chọn tệp bên trong Vault
main.vaultDetail.decryptName.buttonLabel=Giải mã tên tệp
main.vaultDetail.decryptName.tooltip=Chọn một tệp vault đã được mã hóa để giải mã tên của nó
### Missing
main.vaultDetail.missing.info=Cryptomator không thể tìm thấy vault tại đường dẫn này.
main.vaultDetail.missing.recheck=Kiểm tra lại
@@ -426,6 +465,7 @@ vaultOptions.general.startHealthCheckBtn=Bắt đầu Kiểm tra sức khỏe
## Mount
vaultOptions.mount=Gắn kết
vaultOptions.mount.info=Mở phần tùy chọn ổ đĩa ảo để thay đổi các cài đặt mặc định.
vaultOptions.mount.readonly=Chỉ đọc
vaultOptions.mount.customMountFlags=Cờ gắn kết tuỳ chỉnh
vaultOptions.mount.winDriveLetterOccupied=đã bị chiếm
@@ -436,6 +476,7 @@ vaultOptions.mount.mountPoint.custom=Sử dụng thư mục đã chọn
vaultOptions.mount.mountPoint.directoryPickerButton=Chọn…
vaultOptions.mount.mountPoint.directoryPickerTitle=Chọn một thư mục
vaultOptions.mount.volumeType.default=Mặc định (%s)
vaultOptions.mount.volumeType.restartRequired=Để sử dụng loại ổ đĩa này, Cryptomator cần được khởi động lại.
vaultOptions.mount.volume.tcp.port=Cổng TCP
vaultOptions.mount.volume.type=Loại Ổ đĩa
## Master Key
@@ -504,25 +545,78 @@ quit.forced.forceAndQuitBtn=Bắt buộc và Thoát
# Update Reminder
updateReminder.title=Kiểm tra cập nhật
updateReminder.message=Kiểm tra cập nhật?
updateReminder.description=Luôn cập nhật các tính năng mới, sửa lỗi và cải tiến bảo mật. Chúng tôi khuyến nghị để tự động kiểm tra cập nhật.
updateReminder.notNow=Không phải bây giờ
updateReminder.yesOnce=Có, chỉ một lần
updateReminder.yesAutomatically=Có, tự động
#Dokany Support End
dokanySupportEnd.title=Thông báo ngừng phát triển
dokanySupportEnd.message=Kết thúc hỗ trợ cho Dokany
dokanySupportEnd.description=Loại ổ đĩa Dokany không còn được Cryptomator hỗ trợ. Cài đặt của bạn đã được điều chỉnh để sử dụng loại ổ đĩa mặc định. Bạn có thể xem loại mặc định trong phần tùy chọn.
dokanySupportEnd.preferencesBtn=Mở Tuỳ chọn
#Retry If Readonly
retryIfReadonly.title=Truy cập Vault bị giới hạn
retryIfReadonly.message=Không có quyền ghi vào thư mục vault
retryIfReadonly.description=Cryptomator không thể ghi vào thư mục vault. Bạn có thể chuyển vault sang chế độ chỉ đọc và thử lại. Tùy chọn này có thể được tắt trong phần tùy chọn vault.
retryIfReadonly.retry=Thay đổi và Thử lại
# Share Vault
shareVault.title=Chia sẻ Vault
shareVault.message=Bạn muốn chia sẻ vault của mình với người khác không?
shareVault.description=Luôn cẩn trọng khi chia sẻ vault của bạn với người khác. Tóm lại, hãy làm theo các bước sau:
shareVault.instruction.1=1. Chia sẻ quyền truy cập thư mục vault đã mã hóa qua dịch vụ lưu trữ đám mây.
shareVault.instruction.2=2. Chia sẻ mật khẩu vault một cách an toàn.
shareVault.remarkBestPractices=Để biết thêm thông tin, hãy tham khảo các gợi ý về phương pháp tốt nhất trong tài liệu của chúng tôi.
shareVault.docsTooltip=Mở tài liệu hướng dẫn để tìm hiểu thêm về việc chia sẻ vault.
shareVault.hubAd.description=Cách an toàn để làm việc theo nhóm
shareVault.hubAd.keyManagement=• Quản lý khóa Zero-knowledge
shareVault.hubAd.authentication=• Xác thực bảo mật cao
shareVault.hubAd.encryption=• Mã hóa đầu cuối
shareVault.visitHub=Truy cập Cryptomator Hub
shareVault.hub.message=Hướng dẫn chia sẻ vault trên Hub
shareVault.hub.description=Để chia sẻ nội dung vault với thành viên nhóm khác, bạn cần thực hiện hai bước sau:
shareVault.hub.instruction.1=1. Chia sẻ quyền truy cập thư mục vault đã mã hóa qua dịch vụ lưu trữ đám mây.
shareVault.hub.instruction.2=2. Cấp quyền truy cập cho thành viên nhóm trong Cryptomator Hub.
shareVault.hub.openHub=Mở Cryptomator Hub
# Decrypt File Names
decryptNames.title=Giải mã tên tệp
decryptNames.filePicker.title=Chọn tệp được mã hóa
decryptNames.filePicker.extensionDescription=Tệp mã hóa Cryptomator
decryptNames.copyTable.tooltip=Sao chép bảng
decryptNames.clearTable.tooltip=Xóa bảng
decryptNames.copyHint=Sao chép nội dung ô với %s
decryptNames.dropZone.message=Kéo thả tệp hoặc nhấp để chọn
decryptNames.dropZone.error.vaultInternalFiles=Đã chọn các tệp bên trong vault không có tên giải mã được
decryptNames.dropZone.error.foreignFiles=Các tệp không thuộc vault "%s"
decryptNames.dropZone.error.noDirIdBackup=Thư mục của các tệp đã chọn không chứa tệp dirId.c9r
decryptNames.dropZone.error.generic=Không thể giải mã tên tệp
# Event View
eventView.title=Sự kiện
eventView.filter.allVaults=Tất cả
eventView.clearListButton.tooltip=Xóa danh sách
## event list entries
eventView.entry.vaultLocked.description=Mở khóa "%s" để xem chi tiết
eventView.entry.conflictResolved.message=Đã xử lý xung đột
eventView.entry.conflictResolved.showDecrypted=Xem tệp đã giải mã
eventView.entry.conflictResolved.copyDecrypted=Sao chép đường dẫn giải mã
eventView.entry.conflict.message=Giải quyết xung đột thất bại
eventView.entry.conflict.showDecrypted=Xem tệp gốc đã giải mã
eventView.entry.conflict.copyDecrypted=Sao chép đường dẫn gốc đã giải mã
eventView.entry.conflict.showEncrypted=Hiển thị tệp bị xung đột, đã mã hóa
eventView.entry.conflict.copyEncrypted=Sao chép đường dẫn mã hóa bị xung đột
eventView.entry.decryptionFailed.message=Giải mã thất bại
eventView.entry.decryptionFailed.showEncrypted=Hiển thị tệp đã mã hóa
eventView.entry.decryptionFailed.copyEncrypted=Sao chép đường dẫn tệp đã mã hóa
eventView.entry.brokenDirFile.message=Liên kết thư mục hỏng
eventView.entry.brokenDirFile.showEncrypted=Hiển thị liên kết mã hóa bị hỏng
eventView.entry.brokenDirFile.copyEncrypted=Sao chép đường dẫn liên kết bị hỏng
eventView.entry.brokenFileNode.message=Nút tập tin bị hỏng
eventView.entry.brokenFileNode.showEncrypted=Hiển thị nút mã hóa bị hỏng
eventView.entry.brokenFileNode.copyEncrypted=Sao chép đường dẫn nút mã hóa bị hỏng
eventView.entry.brokenFileNode.copyDecrypted=Sao chép đường dẫn giải mã

View File

@@ -16,12 +16,7 @@ class MapKeychainAccess implements KeychainAccessProvider {
private final Map<String, char[]> map = new HashMap<>();
@Override
public String displayName() {
return getClass().getName();
}
@Override
public void storePassphrase(String key, String displayName,CharSequence passphrase, boolean ignored) {
public void storePassphrase(String key, String displayName,CharSequence passphrase) {
char[] pw = new char[passphrase.length()];
for (int i = 0; i < passphrase.length(); i++) {
pw[i] = passphrase.charAt(i);

View File

@@ -16,7 +16,7 @@ public class ReadMeGeneratorTest {
@CsvSource({ //
"test,test", //
"t\u00E4st,t\\'E4st", //
"t\uD83D\uDE09st,t\\uc1\\u55357\\uc1\\u56841st", //
"t\uD83D\uDE09st,t\\u55357\\u56841st", //
})
public void testEscapeNonAsciiChars(String input, String expectedResult) {
ReadmeGenerator readmeGenerator = new ReadmeGenerator(null);
@@ -40,7 +40,7 @@ public class ReadMeGeneratorTest {
MatcherAssert.assertThat(result, CoreMatchers.startsWith("{\\rtf1\\fbidis\\ansi\\uc0\\fs32"));
MatcherAssert.assertThat(result, CoreMatchers.containsString("{\\sa80 Dear User,}\\par"));
MatcherAssert.assertThat(result, CoreMatchers.containsString("{\\sa80 \\b please don't touch the \"d\" directory.}\\par "));
MatcherAssert.assertThat(result, CoreMatchers.containsString("{\\sa80 Thank you for your cooperation \\uc1\\u55357\\uc1\\u56841}\\par"));
MatcherAssert.assertThat(result, CoreMatchers.containsString("{\\sa80 Thank you for your cooperation \\u55357\\u56841}\\par"));
MatcherAssert.assertThat(result, CoreMatchers.endsWith("}"));
}