Compare commits

..
32 changed files with 80 additions and 505 deletions
+3 -1
View File
@@ -53,4 +53,6 @@ updates:
groups: groups:
github-actions: github-actions:
patterns: patterns:
- "*" - "*"
labels:
- "misc:ci"
+2 -67
View File
@@ -52,6 +52,7 @@ jobs:
java-version: ${{ env.JAVA_VERSION }} java-version: ${{ env.JAVA_VERSION }}
check-latest: true check-latest: true
cache: 'maven' cache: 'maven'
- name: Download OpenJFX jmods - name: Download OpenJFX jmods
id: download-jmods id: download-jmods
run: | run: |
@@ -117,7 +118,6 @@ jobs:
--app-version "${{ needs.get-version.outputs.semVerNum }}.${{ needs.get-version.outputs.revNum }}" --app-version "${{ needs.get-version.outputs.semVerNum }}.${{ needs.get-version.outputs.revNum }}"
--java-options "--enable-preview" --java-options "--enable-preview"
--java-options "--enable-native-access=javafx.graphics,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 "-Xss5m"
--java-options "-Xmx256m" --java-options "-Xmx256m"
--java-options "-Dcryptomator.appVersion=\"${{ needs.get-version.outputs.semVerStr }}\"" --java-options "-Dcryptomator.appVersion=\"${{ needs.get-version.outputs.semVerStr }}\""
@@ -168,7 +168,7 @@ jobs:
- name: Build AppImage - name: Build AppImage
run: > run: >
./squashfs-root/AppRun Cryptomator.AppDir cryptomator-${{ needs.get-version.outputs.semVerStr }}-${{ matrix.appimage-suffix }}.AppImage ./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 --sign --sign-key=615D449FE6E6A235
- name: Create detached GPG signatures - name: Create detached GPG signatures
run: | run: |
@@ -193,68 +193,3 @@ jobs:
cryptomator-*.AppImage cryptomator-*.AppImage
cryptomator-*.zsync cryptomator-*.zsync
cryptomator-*.asc cryptomator-*.asc
create-aur-bin-pr:
name: Create PR for aur-bin repo
needs: [build, get-version]
runs-on: ubuntu-latest
if: github.event_name == 'release'
steps:
- name: Download AppImages
uses: actions/download-artifact@v4
with:
path: downloads/
merge-multiple: true
- name: Compute sha256 hash of AppImages
id: checksums
run: |
X64_SHA256=$(sha256sum downloads/cryptomator-*-x86_64.AppImage | cut -d ' ' -f1)
echo "x64-sha256sum=${X64_SHA256}" >> "$GITHUB_OUTPUT"
AARCH64_SHA256=$(sha256sum downloads/cryptomator-*-aarch64.AppImage | cut -d ' ' -f1)
echo "aarch64-sha256sum=${AARCH64_SHA256}" >> "$GITHUB_OUTPUT"
- uses: actions/checkout@v4
with:
repository: 'cryptomator/aur-bin'
token: ${{ secrets.CRYPTOBOT_PR_TOKEN }}
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get -y install makepkg pacman-package-manager
- name: Checkout release branch
run: |
git checkout -b release/${{ needs.get-version.outputs.semVerStr }}
- name: Update build file
run: |
sed -i -e 's|^pkgver=.*$|pkgver=${{ needs.get-version.outputs.semVerStr }}|' PKGBUILD
sed -i -e 's|^pkgrel=.*$|pkgrel=1|' PKGBUILD
sed -i -e "s|^sha256sums_x86_64=.*$|sha256sums_x86_64=('${{ steps.checksums.outputs.x64-sha256sum }}'|" PKGBUILD
sed -i -e "s|^sha256sums_aarch64=.*$|sha256sums_aarch64=('${{ steps.checksums.outputs.aarch64-sha256sum}}'|" PKGBUILD
makepkg --printsrcinfo > .SRCINFO
- name: Commit and push
run: |
git config user.name "${{ github.actor }}"
git config user.email "${{ github.actor_id }}+${{ github.actor }}@users.noreply.github.com"
git config push.autoSetupRemote true
git stage .
git commit -m "Prepare release ${{needs.get-version.outputs.semVerStr}}"
git push
- name: Create pull request
id: create-pr
run: |
printf "> [!IMPORTANT]\n> Todos:\n> - [ ] Update build instructions\n> - [ ] Check for JDK update\n> - [ ] Check for JFX update" > pr_body.md
URL=$(gh pr create --title "Release ${{ needs.get-version.outputs.semVerStr }}" --body-file pr_body.md)
echo "PR_URL=$URL" >> "$GITHUB_OUTPUT"
env:
GH_TOKEN: ${{ secrets.CRYPTOBOT_PR_TOKEN }}
- name: Slack Notification
uses: rtCamp/action-slack-notify@v2
env:
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }}
SLACK_USERNAME: 'Cryptobot'
SLACK_ICON: false
SLACK_ICON_EMOJI: ':bot:'
SLACK_CHANNEL: 'cryptomator-desktop'
SLACK_TITLE: "AUR-bin release PR for ${{ github.event.repository.name }} ${{ github.event.release.tag_name }} created."
SLACK_MESSAGE: "See <${{ steps.create-pr.outputs.PR_URL }}|PR> on how to proceed."
SLACK_FOOTER: false
MSG_MINIMAL: true
-93
View File
@@ -1,93 +0,0 @@
name: Create PR for AUR
on:
release:
types: [published]
workflow_dispatch:
inputs:
tag:
description: 'Release tag'
required: true
jobs:
get-version:
uses: ./.github/workflows/get-version.yml
with:
version: ${{ inputs.tag }}
tarball:
name: Determines tarball url and compute checksum
runs-on: ubuntu-latest
needs: [get-version]
if: github.event_name == 'workflow_dispatch' || needs.get-version.outputs.versionType == 'stable'
outputs:
url: ${{ steps.url.outputs.url}}
sha256: ${{ steps.sha256.outputs.sha256}}
steps:
- name: Determine tarball url
id: url
run: |
URL="";
if [[ -n "${{ inputs.tag }}" ]]; then
URL="https://github.com/cryptomator/cryptomator/archive/refs/tags/${{ inputs.tag }}.tar.gz"
else
URL="https://github.com/cryptomator/cryptomator/archive/refs/tags/${{ github.event.release.tag_name }}.tar.gz"
fi
echo "url=${URL}" >> "$GITHUB_OUTPUT"
- name: Download source tarball and compute checksum
id: sha256
run: |
curl --silent --fail-with-body -L -H "Accept: application/vnd.github+json" ${{ steps.url.outputs.url }} --output cryptomator.tar.gz
TARBALL_SHA256=$(sha256sum cryptomator.tar.gz | cut -d ' ' -f1)
echo "sha256=${TARBALL_SHA256}" >> "$GITHUB_OUTPUT"
aur:
name: Create PR for AUR
runs-on: ubuntu-latest
needs: [tarball, get-version]
env:
AUR_PR_URL: tbd
steps:
- uses: actions/checkout@v4
with:
repository: 'cryptomator/aur'
token: ${{ secrets.CRYPTOBOT_PR_TOKEN }}
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install makepkg pacman-package-manager
- name: Checkout release branch
run: |
git checkout -b release/${{ needs.get-version.outputs.semVerStr }}
- name: Update build file
run: |
sed -i -e 's|^pkgver=.*$|pkgver=${{ needs.get-version.outputs.semVerStr }}|' PKGBUILD
sed -i -e 's|^pkgrel=.*$|pkgrel=1|' PKGBUILD
sed -i -e "s|^sha256sums=.*$|sha256sums=('${{ needs.tarball.outputs.sha256 }}'|" PKGBUILD
makepkg --printsrcinfo > .SRCINFO
- name: Commit and push
run: |
git config user.name "${{ github.actor }}"
git config user.email "${{ github.actor_id }}+${{ github.actor }}@users.noreply.github.com"
git config push.autoSetupRemote true
git stage .
git commit -m "Prepare release ${{needs.get-version.outputs.semVerStr}}"
git push
- name: Create pull request
run: |
printf "> [!IMPORTANT]\n> Todos:\n> - [ ] Update build instructions\n> - [ ] Check for JDK update\n> - [ ] Check for JFX update" > pr_body.md
PR_URL=$(gh pr create --title "Release ${{ needs.get-version.outputs.semVerStr }}" --body-file pr_body.md)
echo "AUR_PR_URL=$PR_URL" >> "$GITHUB_ENV"
env:
GH_TOKEN: ${{ secrets.CRYPTOBOT_PR_TOKEN }}
- name: Slack Notification
uses: rtCamp/action-slack-notify@v2
if: github.event_name == 'release'
env:
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }}
SLACK_USERNAME: 'Cryptobot'
SLACK_ICON: false
SLACK_ICON_EMOJI: ':bot:'
SLACK_CHANNEL: 'cryptomator-desktop'
SLACK_TITLE: "AUR release PR created for ${{ github.event.repository.name }} ${{ github.event.release.tag_name }} created."
SLACK_MESSAGE: "See <${{ env.AUR_PR_URL }}|PR> on how to proceed."
SLACK_FOOTER: false
MSG_MINIMAL: true
+1 -1
View File
@@ -76,7 +76,7 @@ jobs:
name: ${{ needs.download-file.outputs.fileName }} name: ${{ needs.download-file.outputs.fileName }}
path: upload path: upload
- name: Upload to Avast - name: Upload to Avast
uses: wlixcc/SFTP-Deploy-Action@v1.2.6 uses: wlixcc/SFTP-Deploy-Action@v1.2.5
with: with:
server: whitelisting.avast.com server: whitelisting.avast.com
port: 22 port: 22
+2 -2
View File
@@ -49,7 +49,7 @@ jobs:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
with: with:
repository: 'flathub/org.cryptomator.Cryptomator' repository: 'flathub/org.cryptomator.Cryptomator'
token: ${{ secrets.CRYPTOBOT_PR_TOKEN }} token: ${{ secrets.CRYPTOBOT_WINGET_TOKEN }}
- name: Checkout release branch - name: Checkout release branch
run: | run: |
git checkout -b release/${{ needs.get-version.outputs.semVerStr }} git checkout -b release/${{ needs.get-version.outputs.semVerStr }}
@@ -72,7 +72,7 @@ jobs:
PR_URL=$(gh pr create --title "Release ${{ needs.get-version.outputs.semVerStr }}" --body-file pr_body.md) PR_URL=$(gh pr create --title "Release ${{ needs.get-version.outputs.semVerStr }}" --body-file pr_body.md)
echo "FLATHUB_PR_URL=$PR_URL" >> "$GITHUB_ENV" echo "FLATHUB_PR_URL=$PR_URL" >> "$GITHUB_ENV"
env: env:
GH_TOKEN: ${{ secrets.CRYPTOBOT_PR_TOKEN }} GH_TOKEN: ${{ secrets.CRYPTOBOT_WINGET_TOKEN }}
- name: Slack Notification - name: Slack Notification
uses: rtCamp/action-slack-notify@v2 uses: rtCamp/action-slack-notify@v2
if: github.event_name == 'release' if: github.event_name == 'release'
-6
View File
@@ -121,7 +121,6 @@ jobs:
--app-version "${{ needs.get-version.outputs.semVerNum }}" --app-version "${{ needs.get-version.outputs.semVerNum }}"
--java-options "--enable-preview" --java-options "--enable-preview"
--java-options "--enable-native-access=javafx.graphics,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 "-Xss5m"
--java-options "-Xmx256m" --java-options "-Xmx256m"
--java-options "-Dfile.encoding=\"utf-8\"" --java-options "-Dfile.encoding=\"utf-8\""
@@ -241,11 +240,6 @@ jobs:
Cryptomator-${VERSION_NO}-${{ matrix.output-suffix }}.dmg dmg Cryptomator-${VERSION_NO}-${{ matrix.output-suffix }}.dmg dmg
env: env:
VERSION_NO: ${{ needs.get-version.outputs.semVerNum }} 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 - name: Notarize .dmg
if: startsWith(github.ref, 'refs/tags/') || inputs.notarize if: startsWith(github.ref, 'refs/tags/') || inputs.notarize
uses: cocoalibs/xcode-notarization-action@v1 uses: cocoalibs/xcode-notarization-action@v1
-6
View File
@@ -119,7 +119,6 @@ jobs:
--app-version "${{ needs.get-version.outputs.semVerNum }}" --app-version "${{ needs.get-version.outputs.semVerNum }}"
--java-options "--enable-preview" --java-options "--enable-preview"
--java-options "--enable-native-access=javafx.graphics,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 "-Xss5m"
--java-options "-Xmx256m" --java-options "-Xmx256m"
--java-options "-Dfile.encoding=\"utf-8\"" --java-options "-Dfile.encoding=\"utf-8\""
@@ -239,11 +238,6 @@ jobs:
Cryptomator-${VERSION_NO}-${{ matrix.output-suffix }}.dmg dmg Cryptomator-${VERSION_NO}-${{ matrix.output-suffix }}.dmg dmg
env: env:
VERSION_NO: ${{ needs.get-version.outputs.semVerNum }} 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 - name: Notarize .dmg
if: startsWith(github.ref, 'refs/tags/') || inputs.notarize if: startsWith(github.ref, 'refs/tags/') || inputs.notarize
uses: cocoalibs/xcode-notarization-action@v1 uses: cocoalibs/xcode-notarization-action@v1
+4 -14
View File
@@ -23,8 +23,7 @@ on:
env: env:
OPENJFX_JMODS_AMD64: 'https://download2.gluonhq.com/openjfx/24.0.1/openjfx-24.0.1_windows-x64_bin-jmods.zip' 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' OPENJFX_JMODS_AMD64_HASH: 'f13d17c7caf88654fc835f1b4e75a9b0f34a888eb8abef381796c0002e63b03f'
WINFSP_MSI: 'https://github.com/winfsp/winfsp/releases/download/v2.1/winfsp-2.1.25156.msi' WINFSP_MSI: 'https://github.com/winfsp/winfsp/releases/download/v2.0/winfsp-2.0.23075.msi'
WINFSP_MSI_HASH: '073a70e00f77423e34bed98b86e600def93393ba5822204fac57a29324db9f7a'
WINFSP_UNINSTALLER: 'https://github.com/cryptomator/winfsp-uninstaller/releases/latest/download/winfsp-uninstaller.exe' WINFSP_UNINSTALLER: 'https://github.com/cryptomator/winfsp-uninstaller/releases/latest/download/winfsp-uninstaller.exe'
defaults: defaults:
@@ -145,7 +144,6 @@ jobs:
--app-version "${{ needs.get-version.outputs.semVerNum }}.${{ needs.get-version.outputs.revNum }}" --app-version "${{ needs.get-version.outputs.semVerNum }}.${{ needs.get-version.outputs.revNum }}"
--java-options "--enable-preview" --java-options "--enable-preview"
--java-options "--enable-native-access=javafx.graphics,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 "-Xss5m"
--java-options "-Xmx256m" --java-options "-Xmx256m"
--java-options "-Dcryptomator.appVersion=\"${{ needs.get-version.outputs.semVerStr }}\"" --java-options "-Dcryptomator.appVersion=\"${{ needs.get-version.outputs.semVerStr }}\""
@@ -345,13 +343,7 @@ jobs:
shell: pwsh shell: pwsh
- name: Download WinFsp - name: Download WinFsp
run: | run: |
curl --output $env:WINFSP_PATH -L ${{ env.WINFSP_MSI }} curl --output dist/win/bundle/resources/winfsp.msi -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 shell: pwsh
- name: Download Legacy-WinFsp uninstaller - name: Download Legacy-WinFsp uninstaller
run: | run: |
@@ -437,10 +429,8 @@ jobs:
token: ${{ secrets.CRYPTOBOT_RELEASE_TOKEN }} token: ${{ secrets.CRYPTOBOT_RELEASE_TOKEN }}
# do not change ordering of filelist, required for correct job output # do not change ordering of filelist, required for correct job output
files: | files: |
*x64.msi *.msi
*arm64.msi *.exe
*x64.exe
*arm64.exe
*.asc *.asc
allowlist-msi-x64: allowlist-msi-x64:
+2 -2
View File
@@ -16,7 +16,7 @@ jobs:
run: | run: |
gh repo sync cryptomator/winget-pkgs -b master --force gh repo sync cryptomator/winget-pkgs -b master --force
env: env:
GH_TOKEN: ${{ secrets.CRYPTOBOT_PR_TOKEN }} GH_TOKEN: ${{ secrets.CRYPTOBOT_WINGET_TOKEN }}
- name: Submit package - name: Submit package
uses: vedantmgoyal2009/winget-releaser@main uses: vedantmgoyal2009/winget-releaser@main
with: with:
@@ -24,4 +24,4 @@ jobs:
version: ${{ inputs.tag }} version: ${{ inputs.tag }}
release-tag: ${{ inputs.tag }} release-tag: ${{ inputs.tag }}
installers-regex: '-x64\.msi$' installers-regex: '-x64\.msi$'
token: ${{ secrets.CRYPTOBOT_PR_TOKEN }} token: ${{ secrets.CRYPTOBOT_WINGET_TOKEN }}
+2 -2
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) VERSION=$(mvn -f ../../../pom.xml help:evaluate -Dexpression=project.version -q -DforceStdout)
SEMVER_STR=${VERSION} SEMVER_STR=${VERSION}
CPU_ARCH=$(uname -m) CPU_ARCH=$(uname -p)
if [[ ! "${CPU_ARCH}" =~ x86_64|aarch64 ]]; then echo "Platform ${CPU_ARCH} not supported"; exit 1; fi if [[ ! "${CPU_ARCH}" =~ x86_64|aarch64 ]]; then echo "Platform ${CPU_ARCH} not supported"; exit 1; fi
@@ -128,7 +128,7 @@ chmod +x /tmp/appimagetool.AppImage
/tmp/appimagetool.AppImage \ /tmp/appimagetool.AppImage \
Cryptomator.AppDir \ Cryptomator.AppDir \
cryptomator-${SEMVER_STR}-${CPU_ARCH}.AppImage \ 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 ""
echo "Done. AppImage successfully created: cryptomator-${SEMVER_STR}-${CPU_ARCH}.AppImage" echo "Done. AppImage successfully created: cryptomator-${SEMVER_STR}-${CPU_ARCH}.AppImage"
@@ -83,12 +83,6 @@
</content_rating> </content_rating>
<releases> <releases>
<release date="2025-07-08" version="1.17.1">
<url type="details">https://github.com/cryptomator/cryptomator/releases/1.17.1</url>
</release>
<release date="2025-06-24" version="1.17.0">
<url type="details">https://github.com/cryptomator/cryptomator/releases/1.17.0</url>
</release>
<release date="2025-05-15" version="1.16.2"> <release date="2025-05-15" version="1.16.2">
<url type="details">https://github.com/cryptomator/cryptomator/releases/1.16.2</url> <url type="details">https://github.com/cryptomator/cryptomator/releases/1.16.2</url>
</release> </release>
-1
View File
@@ -45,7 +45,6 @@ override_dh_auto_build:
--vendor "Skymatic GmbH" \ --vendor "Skymatic GmbH" \
--java-options "--enable-preview" \ --java-options "--enable-preview" \
--java-options "--enable-native-access=javafx.graphics,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" \ --copyright "(C) 2016 - 2025 Skymatic GmbH" \
--java-options "-Xss5m" \ --java-options "-Xss5m" \
--java-options "-Xmx256m" \ --java-options "-Xmx256m" \
+1 -11
View File
@@ -235,19 +235,9 @@ if ($LASTEXITCODE -ne 0) {
"-Dlicense.licenseMergesUrl=file:///$buildDir/../../license/merges" "-Dlicense.licenseMergesUrl=file:///$buildDir/../../license/merges"
# download Winfsp # download Winfsp
$winfspMsiUrl= 'https://github.com/winfsp/winfsp/releases/download/v2.1/winfsp-2.1.25156.msi' $winfspMsiUrl= 'https://github.com/winfsp/winfsp/releases/download/v2.0/winfsp-2.0.23075.msi'
$winfspMsiHash = '073A70E00F77423E34BED98B86E600DEF93393BA5822204FAC57A29324DB9F7A'
Write-Output "Downloading ${winfspMsiUrl}..." Write-Output "Downloading ${winfspMsiUrl}..."
Invoke-WebRequest $winfspMsiUrl -OutFile ".\bundle\resources\winfsp.msi" # redirects are followed by default 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 # download legacy-winfsp uninstaller
$winfspUninstaller= 'https://github.com/cryptomator/winfsp-uninstaller/releases/latest/download/winfsp-uninstaller.exe' $winfspUninstaller= 'https://github.com/cryptomator/winfsp-uninstaller/releases/latest/download/winfsp-uninstaller.exe'
+7 -7
View File
@@ -3,7 +3,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>org.cryptomator</groupId> <groupId>org.cryptomator</groupId>
<artifactId>cryptomator</artifactId> <artifactId>cryptomator</artifactId>
<version>1.17.1</version> <version>1.17.0-SNAPSHOT</version>
<name>Cryptomator Desktop App</name> <name>Cryptomator Desktop App</name>
<organization> <organization>
@@ -43,9 +43,9 @@
<!-- 3rd party dependencies --> <!-- 3rd party dependencies -->
<commons-lang3.version>3.17.0</commons-lang3.version> <commons-lang3.version>3.17.0</commons-lang3.version>
<dagger.version>2.56.2</dagger.version> <dagger.version>2.56.1</dagger.version>
<easybind.version>2.2</easybind.version> <easybind.version>2.2</easybind.version>
<jackson.version>2.19.1</jackson.version> <jackson.version>2.18.3</jackson.version>
<javafx.version>24.0.1</javafx.version> <javafx.version>24.0.1</javafx.version>
<jwt.version>4.5.0</jwt.version> <jwt.version>4.5.0</jwt.version>
<nimbus-jose.version>9.37.3</nimbus-jose.version> <nimbus-jose.version>9.37.3</nimbus-jose.version>
@@ -55,13 +55,13 @@
<zxcvbn.version>1.9.0</zxcvbn.version> <zxcvbn.version>1.9.0</zxcvbn.version>
<!-- test dependencies --> <!-- test dependencies -->
<junit.jupiter.version>5.13.1</junit.jupiter.version> <junit.jupiter.version>5.12.2</junit.jupiter.version>
<mockito.version>5.18.0</mockito.version> <mockito.version>5.17.0</mockito.version>
<hamcrest.version>3.0</hamcrest.version> <hamcrest.version>3.0</hamcrest.version>
<!-- build-time dependencies --> <!-- build-time dependencies -->
<jetbrains.annotations.version>26.0.2</jetbrains.annotations.version> <jetbrains.annotations.version>26.0.2</jetbrains.annotations.version>
<dependency-check.version>12.1.3</dependency-check.version> <dependency-check.version>12.1.1</dependency-check.version>
<jacoco.version>0.8.13</jacoco.version> <jacoco.version>0.8.13</jacoco.version>
<license-generator.version>2.5.0</license-generator.version> <license-generator.version>2.5.0</license-generator.version>
<junit-tree-reporter.version>1.4.0</junit-tree-reporter.version> <junit-tree-reporter.version>1.4.0</junit-tree-reporter.version>
@@ -225,7 +225,7 @@
<dependency> <dependency>
<groupId>com.github.ben-manes.caffeine</groupId> <groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId> <artifactId>caffeine</artifactId>
<version>3.2.1</version> <version>3.2.0</version>
</dependency> </dependency>
<!-- JUnit / Mockito / Hamcrest --> <!-- JUnit / Mockito / Hamcrest -->
<dependency> <dependency>
@@ -25,8 +25,6 @@ import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections; import javafx.collections.FXCollections;
import javafx.collections.ObservableList; import javafx.collections.ObservableList;
import javafx.geometry.NodeOrientation; import javafx.geometry.NodeOrientation;
import java.nio.file.Path;
import java.time.Instant; import java.time.Instant;
import java.util.function.Consumer; import java.util.function.Consumer;
@@ -77,7 +75,6 @@ public class Settings {
public final BooleanProperty checkForUpdates; public final BooleanProperty checkForUpdates;
public final ObjectProperty<Instant> lastUpdateCheckReminder; public final ObjectProperty<Instant> lastUpdateCheckReminder;
public final ObjectProperty<Instant> lastSuccessfulUpdateCheck; public final ObjectProperty<Instant> lastSuccessfulUpdateCheck;
public final ObjectProperty<Path> previouslyUsedVaultDirectory;
private Consumer<Settings> saveCmd; private Consumer<Settings> saveCmd;
@@ -117,7 +114,6 @@ public class Settings {
this.checkForUpdates = new SimpleBooleanProperty(this, "checkForUpdates", json.checkForUpdatesEnabled); this.checkForUpdates = new SimpleBooleanProperty(this, "checkForUpdates", json.checkForUpdatesEnabled);
this.lastUpdateCheckReminder = new SimpleObjectProperty<>(this, "lastUpdateCheckReminder", json.lastReminderForUpdateCheck); this.lastUpdateCheckReminder = new SimpleObjectProperty<>(this, "lastUpdateCheckReminder", json.lastReminderForUpdateCheck);
this.lastSuccessfulUpdateCheck = new SimpleObjectProperty<>(this, "lastSuccessfulUpdateCheck", json.lastSuccessfulUpdateCheck); this.lastSuccessfulUpdateCheck = new SimpleObjectProperty<>(this, "lastSuccessfulUpdateCheck", json.lastSuccessfulUpdateCheck);
this.previouslyUsedVaultDirectory = new SimpleObjectProperty<>(this, "previouslyUsedVaultDirectory", json.previouslyUsedVaultDirectory);
this.directories.addAll(json.directories.stream().map(VaultSettings::new).toList()); this.directories.addAll(json.directories.stream().map(VaultSettings::new).toList());
@@ -147,14 +143,13 @@ public class Settings {
checkForUpdates.addListener(this::somethingChanged); checkForUpdates.addListener(this::somethingChanged);
lastUpdateCheckReminder.addListener(this::somethingChanged); lastUpdateCheckReminder.addListener(this::somethingChanged);
lastSuccessfulUpdateCheck.addListener(this::somethingChanged); lastSuccessfulUpdateCheck.addListener(this::somethingChanged);
previouslyUsedVaultDirectory.addListener(this::somethingChanged);
} }
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
private void migrateLegacySettings(SettingsJson json) { private void migrateLegacySettings(SettingsJson json) {
// migrate renamed keychainAccess // migrate renamed keychainAccess
if(this.keychainProvider.getValueSafe().equals("org.cryptomator.linux.keychain.SecretServiceKeychainAccess")) { if(this.keychainProvider.getValueSafe().equals("org.cryptomator.linux.SecretServiceKeychainAccess")) {
this.keychainProvider.setValue("org.cryptomator.linux.keychain.GnomeKeyringKeychainAccess"); this.keychainProvider.setValue("org.cryptomator.linux.GnomeKeyringKeychainAccess");
} }
// implicit migration of 1.6.x legacy setting "preferredVolumeImpl": // implicit migration of 1.6.x legacy setting "preferredVolumeImpl":
@@ -209,7 +204,6 @@ public class Settings {
json.checkForUpdatesEnabled = checkForUpdates.get(); json.checkForUpdatesEnabled = checkForUpdates.get();
json.lastReminderForUpdateCheck = lastUpdateCheckReminder.get(); json.lastReminderForUpdateCheck = lastUpdateCheckReminder.get();
json.lastSuccessfulUpdateCheck = lastSuccessfulUpdateCheck.get(); json.lastSuccessfulUpdateCheck = lastSuccessfulUpdateCheck.get();
json.previouslyUsedVaultDirectory = previouslyUsedVaultDirectory.get();
return json; return json;
} }
@@ -5,7 +5,6 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import java.nio.file.Path;
import java.time.Instant; import java.time.Instant;
import java.util.List; import java.util.List;
@@ -93,7 +92,4 @@ class SettingsJson {
@JsonProperty("quickAccessService") @JsonProperty("quickAccessService")
String quickAccessService = Settings.DEFAULT_QUICKACCESS_SERVICE; String quickAccessService = Settings.DEFAULT_QUICKACCESS_SERVICE;
@JsonProperty("previouslyUsedVaultDirectory")
Path previouslyUsedVaultDirectory;
} }
@@ -9,13 +9,13 @@
package org.cryptomator.common.vaults; package org.cryptomator.common.vaults;
import org.apache.commons.lang3.SystemUtils; import org.apache.commons.lang3.SystemUtils;
import org.cryptomator.common.Constants;
import org.cryptomator.common.settings.Settings; import org.cryptomator.common.settings.Settings;
import org.cryptomator.common.settings.VaultSettings; import org.cryptomator.common.settings.VaultSettings;
import org.cryptomator.cryptofs.CryptoFileSystemProvider; import org.cryptomator.cryptofs.CryptoFileSystemProvider;
import org.cryptomator.cryptofs.DirStructure; import org.cryptomator.cryptofs.DirStructure;
import org.cryptomator.cryptofs.migration.Migrators; import org.cryptomator.cryptofs.migration.Migrators;
import org.cryptomator.integrations.mount.MountService; import org.cryptomator.integrations.mount.MountService;
import org.cryptomator.ui.keyloading.masterkeyfile.MasterkeyFileLoadingStrategy;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -106,7 +106,7 @@ public class VaultListManager {
vaultList.addAll(vaults); vaultList.addAll(vaults);
} }
public Optional<Vault> get(Path vaultPath) { private Optional<Vault> get(Path vaultPath) {
assert vaultPath.isAbsolute(); assert vaultPath.isAbsolute();
assert vaultPath.normalize().equals(vaultPath); assert vaultPath.normalize().equals(vaultPath);
return vaultList.stream() // return vaultList.stream() //
@@ -125,7 +125,7 @@ public class VaultListManager {
vaultSettings.lastKnownKeyLoader.set(keyIdScheme); vaultSettings.lastKnownKeyLoader.set(keyIdScheme);
} }
} else if (vaultState == NEEDS_MIGRATION) { } else if (vaultState == NEEDS_MIGRATION) {
vaultSettings.lastKnownKeyLoader.set(MasterkeyFileLoadingStrategy.SCHEME); vaultSettings.lastKnownKeyLoader.set(Constants.DEFAULT_KEY_ID.toString());
} }
return vaultComponentFactory.create(vaultSettings, wrapper, vaultState, null).vault(); return vaultComponentFactory.create(vaultSettings, wrapper, vaultState, null).vault();
} catch (IOException e) { } catch (IOException e) {
@@ -90,9 +90,6 @@ public class LogbackConfigurator extends ContextAwareBase implements Configurato
// configure fuse file locking logger: // configure fuse file locking logger:
Logger fuseLocking = context.getLogger("org.cryptomator.frontend.fuse.locks"); Logger fuseLocking = context.getLogger("org.cryptomator.frontend.fuse.locks");
fuseLocking.setLevel(Level.OFF); fuseLocking.setLevel(Level.OFF);
//deactivate kwallet unsettling message
Logger kdeWallet = context.getLogger("org.purejava.kwallet.freedesktop.dbus.handlers");
kdeWallet.setLevel(Level.OFF);
} }
return ExecutionStatus.DO_NOT_INVOKE_NEXT_IF_ANY; return ExecutionStatus.DO_NOT_INVOKE_NEXT_IF_ANY;
} }
@@ -26,7 +26,7 @@ public class CreateNewVaultExpertSettingsController implements FxController {
public static final int MAX_SHORTENING_THRESHOLD = 220; public static final int MAX_SHORTENING_THRESHOLD = 220;
public static final int MIN_SHORTENING_THRESHOLD = 36; public static final int MIN_SHORTENING_THRESHOLD = 36;
private static final String DOCS_NAME_SHORTENING_URL = "https://docs.cryptomator.org/security/vault/#name-shortening"; private static final String DOCS_NAME_SHORTENING_URL = "https://docs.cryptomator.org/security/architecture/#name-shortening";
private final Stage window; private final Stage window;
private final Lazy<Application> application; private final Lazy<Application> application;
@@ -4,7 +4,6 @@ import dagger.Lazy;
import org.cryptomator.common.ObservableUtil; import org.cryptomator.common.ObservableUtil;
import org.cryptomator.common.locationpresets.LocationPreset; import org.cryptomator.common.locationpresets.LocationPreset;
import org.cryptomator.common.locationpresets.LocationPresetsProvider; import org.cryptomator.common.locationpresets.LocationPresetsProvider;
import org.cryptomator.common.settings.Settings;
import org.cryptomator.ui.common.FxController; import org.cryptomator.ui.common.FxController;
import org.cryptomator.ui.common.FxmlFile; import org.cryptomator.ui.common.FxmlFile;
import org.cryptomator.ui.common.FxmlScene; import org.cryptomator.ui.common.FxmlScene;
@@ -39,7 +38,6 @@ import javafx.stage.WindowEvent;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.InvalidPathException;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.util.Optional; import java.util.Optional;
@@ -66,7 +64,6 @@ public class CreateNewVaultLocationController implements FxController {
private final BooleanProperty loadingPresetLocations = new SimpleBooleanProperty(false); private final BooleanProperty loadingPresetLocations = new SimpleBooleanProperty(false);
private final ObservableList<Node> radioButtons; private final ObservableList<Node> radioButtons;
private final ObservableList<Node> sortedRadioButtons; private final ObservableList<Node> sortedRadioButtons;
private final Settings settings;
private Path customVaultPath = DEFAULT_CUSTOM_VAULT_PATH; private Path customVaultPath = DEFAULT_CUSTOM_VAULT_PATH;
@@ -85,7 +82,6 @@ public class CreateNewVaultLocationController implements FxController {
@FxmlScene(FxmlFile.ADDVAULT_NEW_EXPERT_SETTINGS) Lazy<Scene> chooseExpertSettingsScene, // @FxmlScene(FxmlFile.ADDVAULT_NEW_EXPERT_SETTINGS) Lazy<Scene> chooseExpertSettingsScene, //
ObjectProperty<Path> vaultPath, // ObjectProperty<Path> vaultPath, //
@Named("vaultName") StringProperty vaultName, // @Named("vaultName") StringProperty vaultName, //
Settings settings, //
ExecutorService backgroundExecutor, ResourceBundle resourceBundle) { ExecutorService backgroundExecutor, ResourceBundle resourceBundle) {
this.window = window; this.window = window;
this.chooseNameScene = chooseNameScene; this.chooseNameScene = chooseNameScene;
@@ -100,18 +96,6 @@ public class CreateNewVaultLocationController implements FxController {
this.usePresetPath = new SimpleBooleanProperty(); this.usePresetPath = new SimpleBooleanProperty();
this.radioButtons = FXCollections.observableArrayList(); this.radioButtons = FXCollections.observableArrayList();
this.sortedRadioButtons = radioButtons.sorted(this::compareLocationPresets); this.sortedRadioButtons = radioButtons.sorted(this::compareLocationPresets);
this.settings = settings;
Path previouslyUsedDirectory = settings.previouslyUsedVaultDirectory.get();
if (previouslyUsedDirectory != null) {
try {
if (Files.exists(previouslyUsedDirectory) && Files.isDirectory(previouslyUsedDirectory) && isActuallyWritable(previouslyUsedDirectory)) {
this.customVaultPath = previouslyUsedDirectory;
}
} catch (InvalidPathException | NullPointerException e) {
LOG.warn("Invalid previously used vault directory path: {}", previouslyUsedDirectory, e);
}
}
} }
private VaultPathStatus validatePath(Path p) throws NullPointerException { private VaultPathStatus validatePath(Path p) throws NullPointerException {
@@ -212,12 +196,6 @@ public class CreateNewVaultLocationController implements FxController {
@FXML @FXML
public void next() { public void next() {
if (validVaultPath.getValue()) { if (validVaultPath.getValue()) {
if (this.getVaultPath() != null) {
Path parentPath = this.getVaultPath().getParent();
if (parentPath != null) {
this.settings.previouslyUsedVaultDirectory.setValue(parentPath);
}
}
window.setScene(chooseExpertSettingsScene.get()); window.setScene(chooseExpertSettingsScene.get());
} }
} }
@@ -79,7 +79,7 @@ public class ReadmeGenerator {
} else if (c <= 0xFF) { } else if (c <= 0xFF) {
sb.append("\\'").append(String.format("%02X", c)); sb.append("\\'").append(String.format("%02X", c));
} else if (c < 0xFFFF) { } else if (c < 0xFFFF) {
sb.append("\\u").append(c); sb.append("\\uc1\\u").append(c);
} }
}); });
} }
@@ -12,7 +12,6 @@ import javax.inject.Named;
import javafx.application.Platform; import javafx.application.Platform;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.Optional;
import java.util.concurrent.BlockingQueue; import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
@@ -59,30 +58,29 @@ class AppLaunchEventHandler {
switch (event.type()) { switch (event.type()) {
case REVEAL_APP -> appWindows.showMainWindow(); case REVEAL_APP -> appWindows.showMainWindow();
case OPEN_FILE -> Platform.runLater(() -> { case OPEN_FILE -> Platform.runLater(() -> {
event.pathsToOpen().forEach(this::openPotentialVault); event.pathsToOpen().forEach(this::addOrRevealVault);
}); });
default -> LOG.warn("Unsupported event type: {}", event.type()); default -> LOG.warn("Unsupported event type: {}", event.type());
} }
} }
// TODO deduplicate MainWindowController... // TODO deduplicate MainWindowController...
private void openPotentialVault(Path path) { private void addOrRevealVault(Path potentialVaultPath) {
assert Platform.isFxApplicationThread(); assert Platform.isFxApplicationThread();
try { try {
Path potentialVaultPath = path.getFileName().toString().endsWith(CRYPTOMATOR_FILENAME_EXT) ? path.getParent() : path; final Vault v;
final Optional<Vault> v = vaultListManager.get(potentialVaultPath); if (potentialVaultPath.getFileName().toString().endsWith(CRYPTOMATOR_FILENAME_EXT)) {
if (v.isPresent()) { v = vaultListManager.add(potentialVaultPath.getParent());
if (v.get().isUnlocked()) {
vaultService.reveal(v.get());
} else if (v.get().isLocked()) {
appWindows.startUnlockWorkflow(v.get(), null);
}
} else { } else {
vaultListManager.add(potentialVaultPath); v = vaultListManager.add(potentialVaultPath);
LOG.debug("Added vault {}", potentialVaultPath);
} }
if (v.isUnlocked()) {
vaultService.reveal(v);
}
LOG.debug("Added vault {}", potentialVaultPath);
} catch (IOException e) { } catch (IOException e) {
LOG.error("Failed to add vault " + path, e); LOG.error("Failed to add vault " + potentialVaultPath, e);
} }
} }
@@ -46,16 +46,15 @@ public interface KeyLoadingStrategy extends MasterkeyLoader {
/** /**
* Determines whether the provided key loader scheme corresponds to a Masterkey File Vault. * Determines whether the provided key loader scheme corresponds to a Masterkey File Vault.
* <p> * <p>
* This method checks if the {@code keyLoader} parameter starts with the known Masterkey File Vault scheme * This method checks if the {@code keyLoader} parameter matches the known Masterkey File Vault scheme
* {@link MasterkeyFileLoadingStrategy#SCHEME}. * {@link MasterkeyFileLoadingStrategy#SCHEME}.
* This allows identifying not only exact matches but also variants or extended schemes based on the Masterkey scheme.
* </p> * </p>
* *
* @param keyLoader A string representing the key loader scheme to be checked. * @param keyLoader A string representing the key loader scheme to be checked.
* @return {@code true} if the given key loader scheme starts with the Masterkey File Vault scheme; {@code false} otherwise. * @return {@code true} if the given key loader scheme represents a Masterkey File Vault; {@code false} otherwise.
*/ */
static boolean isMasterkeyFileVault(String keyLoader) { static boolean isMasterkeyFileVault(String keyLoader) {
return keyLoader.startsWith(MasterkeyFileLoadingStrategy.SCHEME); return MasterkeyFileLoadingStrategy.SCHEME.equals(keyLoader);
} }
/** /**
@@ -19,7 +19,7 @@ public class ShareVaultController implements FxController {
private static final String SCHEME_PREFIX = "hub+"; private static final String SCHEME_PREFIX = "hub+";
private static final String VISIT_HUB_URL = "https://cryptomator.org/hub/"; private static final String VISIT_HUB_URL = "https://cryptomator.org/hub/";
private static final String BEST_PRACTICES_URL = "https://docs.cryptomator.org/security/best-practices/#sharing-of-vaults"; private static final String BEST_PRACTICES_URL = "https://docs.cryptomator.org/en/latest/security/best-practices/#sharing-of-vaults";
private final Stage window; private final Stage window;
private final Lazy<Application> application; private final Lazy<Application> application;
+5 -42
View File
@@ -62,9 +62,9 @@ addvaultwizard.new.locationIsOk=الموقع المناسب للمخزن الخ
addvaultwizard.new.invalidName=اسم المخزن غير صالح addvaultwizard.new.invalidName=اسم المخزن غير صالح
addvaultwizard.new.validName=اسم المخزن صالح addvaultwizard.new.validName=اسم المخزن صالح
addvaultwizard.new.validCharacters.message=قد يحتوي اسم المخزن على الأحرف التالية: addvaultwizard.new.validCharacters.message=قد يحتوي اسم المخزن على الأحرف التالية:
addvaultwizard.new.validCharacters.chars=أحرف لكن دون علامات (#, $, !, @...) addvaultwizard.new.validCharacters.chars=أحرف الكلمات (أمثلة: a, ж, )
addvaultwizard.new.validCharacters.numbers=الأرقام addvaultwizard.new.validCharacters.numbers=الأعداد
addvaultwizard.new.validCharacters.dashes=ناقص (%s) أو شِرْطَةٌ سفلية (%s) addvaultwizard.new.validCharacters.dashes=الشرطة (%s) أو الشرطة السفلية (%s)
### Expert Settings ### Expert Settings
addvaultwizard.new.expertSettings.enableExpertSettingsCheckbox=تمكين إعدادات الخبراء addvaultwizard.new.expertSettings.enableExpertSettingsCheckbox=تمكين إعدادات الخبراء
addvaultwizard.new.expertSettings.shorteningThreshold.invalid=أدخل قيمة بين 36 و 220 (الافتراضي 220) addvaultwizard.new.expertSettings.shorteningThreshold.invalid=أدخل قيمة بين 36 و 220 (الافتراضي 220)
@@ -319,7 +319,7 @@ preferences.volume.feature.readOnly=تحميل للقراءة فقط
## Updates ## Updates
preferences.updates=تحديثات preferences.updates=تحديثات
preferences.updates.currentVersion=الإصدار الحالي: %s preferences.updates.currentVersion=الإصدار الحالي: %s
preferences.updates.autoUpdateCheck=التحقق من وجود تحديثات تلقائياً preferences.updates.autoUpdateCheck=تحقق من التحديثات اوتوماتيكيا
preferences.updates.checkNowBtn=تحقق الان preferences.updates.checkNowBtn=تحقق الان
preferences.updates.updateAvailable=التحديث إلى الإصدار %s متاح. preferences.updates.updateAvailable=التحديث إلى الإصدار %s متاح.
preferences.updates.lastUpdateCheck=آخر فحص: %s preferences.updates.lastUpdateCheck=آخر فحص: %s
@@ -395,7 +395,6 @@ main.vaultlist.contextMenu.vaultoptions=إظهار خيارات المخزن
main.vaultlist.contextMenu.reveal=اظهار القرص main.vaultlist.contextMenu.reveal=اظهار القرص
main.vaultlist.addVaultBtn.menuItemNew=إنشاء مخزن جديد... main.vaultlist.addVaultBtn.menuItemNew=إنشاء مخزن جديد...
main.vaultlist.addVaultBtn.menuItemExisting=افتح مخزن موجود... main.vaultlist.addVaultBtn.menuItemExisting=افتح مخزن موجود...
main.vaultlist.showEventsButton.tooltip=عرض الإشعارات
##Notificaition ##Notificaition
main.notification.updateAvailable=هناك تحديث متاح. main.notification.updateAvailable=هناك تحديث متاح.
main.notification.support=دعم Cryptomator. main.notification.support=دعم Cryptomator.
@@ -424,9 +423,6 @@ main.vaultDetail.stats=إحصائيات الخزنة
main.vaultDetail.locateEncryptedFileBtn=تحديد موقع الملف المشفر main.vaultDetail.locateEncryptedFileBtn=تحديد موقع الملف المشفر
main.vaultDetail.locateEncryptedFileBtn.tooltip=اختر ملف من خزانتك لتحديد مكان نظيره المشفر main.vaultDetail.locateEncryptedFileBtn.tooltip=اختر ملف من خزانتك لتحديد مكان نظيره المشفر
main.vaultDetail.encryptedPathsCopied=تم نسخ مسارات الملفات إلى الحافظة! main.vaultDetail.encryptedPathsCopied=تم نسخ مسارات الملفات إلى الحافظة!
main.vaultDetail.locateEncrypted.filePickerTitle=اختر الملَف من الخزنة
main.vaultDetail.decryptName.buttonLabel=فك تشفير اسم الملف
main.vaultDetail.decryptName.tooltip=اختر ملَف مشفر لفك تشفير اسمه
### Missing ### Missing
main.vaultDetail.missing.info=لم يتمكن Cryptomator من العثور على خزنة في هذا المسار. main.vaultDetail.missing.info=لم يتمكن Cryptomator من العثور على خزنة في هذا المسار.
main.vaultDetail.missing.recheck=إعادة الفحص main.vaultDetail.missing.recheck=إعادة الفحص
@@ -476,7 +472,7 @@ vaultOptions.mount.mountPoint.custom=استخدام المجلد المختار
vaultOptions.mount.mountPoint.directoryPickerButton=اختر… vaultOptions.mount.mountPoint.directoryPickerButton=اختر…
vaultOptions.mount.mountPoint.directoryPickerTitle=إختر مجلد vaultOptions.mount.mountPoint.directoryPickerTitle=إختر مجلد
vaultOptions.mount.volumeType.default=الافتراضي (%s) vaultOptions.mount.volumeType.default=الافتراضي (%s)
vaultOptions.mount.volumeType.restartRequired=لاستخدام هذا النوع من وحدة التخزين يحتاج Cryptomator إلى إعادة تشغيل. vaultOptions.mount.volumeType.restartRequired=لاستخدام هذا النوع من وحدة التخزين يحتاج Cryptomator إلى إعادة تشغيله.
vaultOptions.mount.volume.tcp.port=منفذ TCP vaultOptions.mount.volume.tcp.port=منفذ TCP
vaultOptions.mount.volume.type=‮نوع وحدة التخزين vaultOptions.mount.volume.type=‮نوع وحدة التخزين
## Master Key ## Master Key
@@ -583,40 +579,7 @@ shareVault.hub.instruction.2=2. امنح الوصول لعضو الفريق في
shareVault.hub.openHub=زيارة Cryptomator Hub shareVault.hub.openHub=زيارة Cryptomator Hub
# Decrypt File Names # Decrypt File Names
decryptNames.title=فك تشفير اسم الملَف
decryptNames.filePicker.title=اختر ملَف مشفر
decryptNames.filePicker.extensionDescription=ملف مشفر
decryptNames.copyTable.tooltip=نسخ الجدول
decryptNames.clearTable.tooltip=مسح الجدول
decryptNames.copyHint=نسخ محتوى الخلية مع %s
decryptNames.dropZone.message=إسقاط الملفات أو انقر لتحديد
decryptNames.dropZone.error.vaultInternalFiles=مخزن الملفات الداخلية مع عدم تحديد اسم قابل للتشفير
decryptNames.dropZone.error.foreignFiles=الملفات لا تنتمي إلى مخزن "%s"
decryptNames.dropZone.error.noDirIdBackup=مسار الملفات المحددة لا يحتوي على ملَف dirId.c9r
decryptNames.dropZone.error.generic=فشل فك تشفير أسماء الملفات
# Event View # Event View
eventView.title=أحداث
eventView.filter.allVaults=الكل
eventView.clearListButton.tooltip=تفريغ القائمة
## event list entries ## event list entries
eventView.entry.vaultLocked.description=فتح "%s" للحصول على التفاصيل
eventView.entry.conflictResolved.message=تم حل التضارب
eventView.entry.conflictResolved.showDecrypted=إظهار الملف غير المشفر
eventView.entry.conflictResolved.copyDecrypted=نسخ المسار غير المشفر
eventView.entry.conflict.message=فشل حل التضارب
eventView.entry.conflict.showDecrypted=إظهار الملَف غير المشفر الأصلي
eventView.entry.conflict.copyDecrypted=نسخ المسار غير المشفر والأصلي
eventView.entry.conflict.showEncrypted=إظهار ملف متضارب ومشفر
eventView.entry.conflict.copyEncrypted=نسخ مسار التشفير المتعارض
eventView.entry.decryptionFailed.message=فشل فك التشفير
eventView.entry.decryptionFailed.showEncrypted=عرض ملَف المشفر
eventView.entry.decryptionFailed.copyEncrypted=نسخ مسار المشفر
eventView.entry.brokenDirFile.message=رابط الدليل المكسور
eventView.entry.brokenDirFile.showEncrypted=إظهار الرابط المكسور، المشفر
eventView.entry.brokenDirFile.copyEncrypted=نسخ مسار الرابط المكسور
eventView.entry.brokenFileNode.message=عقدة ملفات النظام التافلة
eventView.entry.brokenFileNode.showEncrypted=عرض العقدة المشفّرة التافلة
eventView.entry.brokenFileNode.copyEncrypted=نسخ مسار العقدة المشفّرة التافلة
eventView.entry.brokenFileNode.copyDecrypted=نسخ المسار غير المشفر
@@ -616,7 +616,7 @@ eventView.entry.decryptionFailed.copyEncrypted=Pfad der verschlüsselten Datei k
eventView.entry.brokenDirFile.message=Ungültiger Verzeichnislink eventView.entry.brokenDirFile.message=Ungültiger Verzeichnislink
eventView.entry.brokenDirFile.showEncrypted=Defekten, verschlüsselten Link anzeigen eventView.entry.brokenDirFile.showEncrypted=Defekten, verschlüsselten Link anzeigen
eventView.entry.brokenDirFile.copyEncrypted=Pfad des ungültigen Links kopieren eventView.entry.brokenDirFile.copyEncrypted=Pfad des ungültigen Links kopieren
eventView.entry.brokenFileNode.message=Beschädigter Dateisystemknoten eventView.entry.brokenFileNode.message=Fehlender Dateisystemknoten
eventView.entry.brokenFileNode.showEncrypted=Beschädigten, verschlüsselten Knoten anzeigen eventView.entry.brokenFileNode.showEncrypted=Beschädigten, verschlüsselten Knoten anzeigen
eventView.entry.brokenFileNode.copyEncrypted=Pfad des beschädigten, verschlüsselten Knotens kopieren eventView.entry.brokenFileNode.copyEncrypted=Pfad des kaputten, verschlüsselten Knotens kopieren
eventView.entry.brokenFileNode.copyDecrypted=Pfad der entschlüsselten Datei kopieren eventView.entry.brokenFileNode.copyDecrypted=Pfad der entschlüsselten Datei kopieren
@@ -177,7 +177,6 @@ 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. 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 ### Unauthorized
hub.unauthorized.message=Pääsy estetty 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 ### Requires Account Initialization
hub.requireAccountInit.message=Toimia vaaditaan hub.requireAccountInit.message=Toimia vaaditaan
hub.requireAccountInit.description.0=Jatkaaksesi, ole hyvä ja suorita tarvittavat toimenpiteet hub.requireAccountInit.description.0=Jatkaaksesi, ole hyvä ja suorita tarvittavat toimenpiteet
@@ -283,7 +282,6 @@ preferences.title=Asetukset
## General ## General
preferences.general=Yleiset preferences.general=Yleiset
preferences.general.startHidden=Piilota ikkuna kun Cryptomator käynnistyy 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.debugLogging=Ota virheloki käyttöön
preferences.general.debugDirectory=Näytä lokitiedostot preferences.general.debugDirectory=Näytä lokitiedostot
preferences.general.autoStart=Käynnistä Cryptomator järjestelmän käynnistyessä preferences.general.autoStart=Käynnistä Cryptomator järjestelmän käynnistyessä
@@ -332,7 +330,6 @@ preferences.updates.upToDate=Cryptomator on ajan tasalla.
## Contribution ## Contribution
preferences.contribute=Tue meitä 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.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.getCertificate=Eikö sinulla ole sellaista? Lue lisää miten voit hankkia sellaisen.
preferences.contribute.promptText=Liitä tukijasertifikaatin koodi tähän preferences.contribute.promptText=Liitä tukijasertifikaatin koodi tähän
@@ -394,7 +391,6 @@ main.vaultlist.contextMenu.vaultoptions=Näytä holvin asetukset
main.vaultlist.contextMenu.reveal=Paljasta Asema main.vaultlist.contextMenu.reveal=Paljasta Asema
main.vaultlist.addVaultBtn.menuItemNew=Luo uusi holvi... main.vaultlist.addVaultBtn.menuItemNew=Luo uusi holvi...
main.vaultlist.addVaultBtn.menuItemExisting=Avaa olemassa oleva holvi... main.vaultlist.addVaultBtn.menuItemExisting=Avaa olemassa oleva holvi...
main.vaultlist.showEventsButton.tooltip=Avaa tapahtumanäkymä
##Notificaition ##Notificaition
main.notification.updateAvailable=Päivitys on saatavilla. main.notification.updateAvailable=Päivitys on saatavilla.
main.notification.support=Tue Cryptomatoria. main.notification.support=Tue Cryptomatoria.
@@ -423,9 +419,6 @@ main.vaultDetail.stats=Holvin tilastot
main.vaultDetail.locateEncryptedFileBtn=Etsi salattu tiedosto main.vaultDetail.locateEncryptedFileBtn=Etsi salattu tiedosto
main.vaultDetail.locateEncryptedFileBtn.tooltip=Valitse tiedosto holvistasi löytääksesi sen salatun vastineen main.vaultDetail.locateEncryptedFileBtn.tooltip=Valitse tiedosto holvistasi löytääksesi sen salatun vastineen
main.vaultDetail.encryptedPathsCopied=Polut kopioitu leikepöydälle! 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 ### Missing
main.vaultDetail.missing.info=Cryptomator ei löytänyt täältä holvia. main.vaultDetail.missing.info=Cryptomator ei löytänyt täältä holvia.
main.vaultDetail.missing.recheck=Tarkista uudelleen main.vaultDetail.missing.recheck=Tarkista uudelleen
@@ -442,7 +435,6 @@ main.vaultDetail.error.windowTitle=Virhe ladatessa holvia
# Wrong File Alert # Wrong File Alert
wrongFileAlert.title=Kuinka tiedostoja salataan wrongFileAlert.title=Kuinka tiedostoja salataan
wrongFileAlert.message=Yritkö salata nämä tiedostot? wrongFileAlert.message=Yritkö salata nämä tiedostot?
wrongFileAlert.description=Tätä varten Cryptomator luo levyn järjestelmäsi tiedostonhallintaan.
wrongFileAlert.instruction.0=Salaa tiedostot seuraavasti: wrongFileAlert.instruction.0=Salaa tiedostot seuraavasti:
wrongFileAlert.instruction.1=1. Avaa holvisi. wrongFileAlert.instruction.1=1. Avaa holvisi.
wrongFileAlert.instruction.2=2. Klikkaa "Paljasta" avataksesi aseman tiedostoselaimessasi. wrongFileAlert.instruction.2=2. Klikkaa "Paljasta" avataksesi aseman tiedostoselaimessasi.
@@ -553,10 +545,6 @@ updateReminder.yesAutomatically=Kyllä, automaattisesti
dokanySupportEnd.preferencesBtn=Avaa asetukset dokanySupportEnd.preferencesBtn=Avaa asetukset
#Retry If Readonly #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 # Share Vault
shareVault.title=Jaa holvi shareVault.title=Jaa holvi
@@ -566,46 +554,14 @@ shareVault.instruction.1=1. Jaa käyttöoikeus salattuun holvikansioon pilvipalv
shareVault.instruction.2=2. Jaa holvin salasana turvallisella tavalla. shareVault.instruction.2=2. Jaa holvin salasana turvallisella tavalla.
shareVault.remarkBestPractices=Lisätietoja varten tutustu hyvien käytäntöjen suosituksiin dokumentaatiossamme. shareVault.remarkBestPractices=Lisätietoja varten tutustu hyvien käytäntöjen suosituksiin dokumentaatiossamme.
shareVault.docsTooltip=Avaa dokumentaatio lukeaksesi lisää holvein jakamisesta. 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.visitHub=Käy Cryptomator Hubissa
shareVault.hub.message=Kuinka jakaa Hub -holvi 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.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 shareVault.hub.openHub=Avaa Cryptomator Hub
# Decrypt File Names # 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 # Event View
eventView.title=Tapahtumat
eventView.filter.allVaults=Kaikki
eventView.clearListButton.tooltip=Tyhjennä luettelo
## event list entries ## 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
@@ -424,9 +424,6 @@ main.vaultDetail.stats=Vault 통계
main.vaultDetail.locateEncryptedFileBtn=암호화된 파일 위치 main.vaultDetail.locateEncryptedFileBtn=암호화된 파일 위치
main.vaultDetail.locateEncryptedFileBtn.tooltip=암호화된 파일을 보기 위해 Vault에서 파일을 선택하십시오. main.vaultDetail.locateEncryptedFileBtn.tooltip=암호화된 파일을 보기 위해 Vault에서 파일을 선택하십시오.
main.vaultDetail.encryptedPathsCopied=클립보드에 복사됨! main.vaultDetail.encryptedPathsCopied=클립보드에 복사됨!
main.vaultDetail.locateEncrypted.filePickerTitle=Vault 내부에서 파일 선택
main.vaultDetail.decryptName.buttonLabel=파일명 복호화
main.vaultDetail.decryptName.tooltip=암호화된 볼트 파일을 선택해 파일 이름을 복호화
### Missing ### Missing
main.vaultDetail.missing.info=Cryptomator가 이 경로에 있는 Vault를 찾지 못했습니다. main.vaultDetail.missing.info=Cryptomator가 이 경로에 있는 Vault를 찾지 못했습니다.
main.vaultDetail.missing.recheck=다시 시도 main.vaultDetail.missing.recheck=다시 시도
@@ -583,21 +580,11 @@ shareVault.hub.instruction.2=2. Cryptomator Hub에서 팀 구성원에 접근을
shareVault.hub.openHub=Cryptomator Hub 열기 shareVault.hub.openHub=Cryptomator Hub 열기
# Decrypt File Names # 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 # Event View
eventView.title=이벤트 eventView.title=이벤트
eventView.filter.allVaults=전체 eventView.filter.allVaults=전체
eventView.clearListButton.tooltip=목록 지우기
## event list entries ## event list entries
eventView.entry.vaultLocked.description="%s"를 잠금 해제하여 세부정보 보기 eventView.entry.vaultLocked.description="%s"를 잠금 해제하여 세부정보 보기
eventView.entry.conflictResolved.message=해결된 충돌 eventView.entry.conflictResolved.message=해결된 충돌
@@ -1,7 +1,6 @@
# Locale Specific CSS files such as CJK, RTL,... # Locale Specific CSS files such as CJK, RTL,...
# Generics # Generics
generic.action.dismiss=Откажи
## Button ## Button
generic.button.apply=Примени generic.button.apply=Примени
generic.button.back=Назад generic.button.back=Назад
@@ -14,7 +13,6 @@ generic.button.copied=Копирано!
generic.button.done=Прифати generic.button.done=Прифати
generic.button.next=Продолжи generic.button.next=Продолжи
generic.button.print=Печати generic.button.print=Печати
generic.button.remove=Отстрани
# Error # Error
error.message=Грешка error.message=Грешка
@@ -24,8 +22,6 @@ error.hyperlink.report=Пријави ја оваа грешка
error.technicalDetails=Детали: error.technicalDetails=Детали:
error.existingSolutionDescription=Не очекуваше да се случи ова. Но најдовме постоечко решение за оваа грешка. Ве молиме погледнете го следниот линк. error.existingSolutionDescription=Не очекуваше да се случи ова. Но најдовме постоечко решение за оваа грешка. Ве молиме погледнете го следниот линк.
error.hyperlink.solution=Пребарај решение error.hyperlink.solution=Пребарај решение
error.dismiss=Откажи
error.lookUpSolution=Пребарај решение
# Defaults # Defaults
defaults.vault.vaultName=Сеф defaults.vault.vaultName=Сеф
+24 -24
View File
@@ -424,9 +424,9 @@ main.vaultDetail.stats=Estatísticas do Cofre
main.vaultDetail.locateEncryptedFileBtn=Localizar Ficheiro Encriptado main.vaultDetail.locateEncryptedFileBtn=Localizar Ficheiro Encriptado
main.vaultDetail.locateEncryptedFileBtn.tooltip=Escolha um ficheiro do seu cofre para localizar a sua contraparte encriptada main.vaultDetail.locateEncryptedFileBtn.tooltip=Escolha um ficheiro do seu cofre para localizar a sua contraparte encriptada
main.vaultDetail.encryptedPathsCopied=Caminhos copiados para a área de transferência! main.vaultDetail.encryptedPathsCopied=Caminhos copiados para a área de transferência!
main.vaultDetail.locateEncrypted.filePickerTitle=Selecione o ficheiro no cofre main.vaultDetail.locateEncrypted.filePickerTitle=Selecionar ficheiro dentro do cofre
main.vaultDetail.decryptName.buttonLabel=Descriptografar o nome do ficheiro main.vaultDetail.decryptName.buttonLabel=Desencriptar nome do ficheiro
main.vaultDetail.decryptName.tooltip=Escolha um ficheiro encriptado do cofre para desencriptar o seu nome main.vaultDetail.decryptName.tooltip=Escolha um ficheiro de cofre encriptado para desencriptar o seu nome
### Missing ### Missing
main.vaultDetail.missing.info=O Cryptomator não conseguiu encontrar um cofre neste diretório. main.vaultDetail.missing.info=O Cryptomator não conseguiu encontrar um cofre neste diretório.
main.vaultDetail.missing.recheck=Verificar novamente main.vaultDetail.missing.recheck=Verificar novamente
@@ -583,17 +583,17 @@ shareVault.hub.instruction.2=2. Conceder acesso ao membro da equipe no Hub Crypt
shareVault.hub.openHub=Abrir Hub do Cryptomator shareVault.hub.openHub=Abrir Hub do Cryptomator
# Decrypt File Names # Decrypt File Names
decryptNames.title=Desencriptar os nomes dos ficheiros decryptNames.title=Desencriptar nomes de ficheiros
decryptNames.filePicker.title=Selecione o ficheiro encriptado decryptNames.filePicker.title=Selecione o ficheiro encriptado
decryptNames.filePicker.extensionDescription=Ficheiro encriptado pelo Criptomator decryptNames.filePicker.extensionDescription=Ficheiro encriptado do Cryptomator
decryptNames.copyTable.tooltip=Copiar a tabela decryptNames.copyTable.tooltip=Copiar tabela
decryptNames.clearTable.tooltip=Limpar a tabela decryptNames.clearTable.tooltip=Limpar tabela
decryptNames.copyHint=Copiar o conteúdo da célula com %s decryptNames.copyHint=Copiar conteúdo da célula com %s
decryptNames.dropZone.message=Largue os ficheiros ou clique para selecionar decryptNames.dropZone.message=Solte os ficheiros ou clique para selecionar
decryptNames.dropZone.error.vaultInternalFiles=Ficheiros internos do coftre sem nome desencriptável selecionado decryptNames.dropZone.error.vaultInternalFiles=Ficheiros internos do cofre sem nome decifrável selecionado
decryptNames.dropZone.error.foreignFiles=Os ficheiros não pertencem ao cofre "%s" decryptNames.dropZone.error.foreignFiles=Ficheiros não pertencem ao cofre "%s"
decryptNames.dropZone.error.noDirIdBackup=O diretório dos ficheiros selecionados não contém o ficheiro dirId.c9r decryptNames.dropZone.error.noDirIdBackup=O diretório dos ficheiros selecionados não contém o ficheiro dirId.c9r
decryptNames.dropZone.error.generic=Falha ao desencriptar os nomes dos ficheiros decryptNames.dropZone.error.generic=Falha ao desencriptar nomes de ficheiros
# Event View # Event View
@@ -603,20 +603,20 @@ eventView.clearListButton.tooltip=Limpar lista
## event list entries ## event list entries
eventView.entry.vaultLocked.description=Desbloquear "%s" para detalhes eventView.entry.vaultLocked.description=Desbloquear "%s" para detalhes
eventView.entry.conflictResolved.message=Conflito resolvido eventView.entry.conflictResolved.message=Conflito resolvido
eventView.entry.conflictResolved.showDecrypted=Mostrar o ficheiro desencriptado eventView.entry.conflictResolved.showDecrypted=Mostrar ficheiro desencriptado
eventView.entry.conflictResolved.copyDecrypted=Copiar o caminho desencriptado eventView.entry.conflictResolved.copyDecrypted=Copiar caminho desencriptado
eventView.entry.conflict.message=A resolução do conflito falhou eventView.entry.conflict.message=Resolução de conflito falhou
eventView.entry.conflict.showDecrypted=Mostrar o ficheiro original desencriptado eventView.entry.conflict.showDecrypted=Mostrar ficheiro original desencriptado
eventView.entry.conflict.copyDecrypted=Copie o caminho original desencriptado eventView.entry.conflict.copyDecrypted=Copie caminho original desencriptado
eventView.entry.conflict.showEncrypted=Mostrar o ficheiro encriptado em conflito eventView.entry.conflict.showEncrypted=Mostrar ficheiro encriptado conflitante
eventView.entry.conflict.copyEncrypted=Copiar o caminho encriptado em conflito eventView.entry.conflict.copyEncrypted=Copiar caminho encriptado conflituante
eventView.entry.decryptionFailed.message=A desencriptação falhou eventView.entry.decryptionFailed.message=Falha na desencriptação
eventView.entry.decryptionFailed.showEncrypted=Mostrar ficheiro encriptado eventView.entry.decryptionFailed.showEncrypted=Mostrar ficheiro encriptado
eventView.entry.decryptionFailed.copyEncrypted=Copiar o caminho encriptado eventView.entry.decryptionFailed.copyEncrypted=Copiar caminho de encriptação
eventView.entry.brokenDirFile.message=Link de diretório quebrado eventView.entry.brokenDirFile.message=Link de diretório quebrado
eventView.entry.brokenDirFile.showEncrypted=Mostrar o link quebrado e encriptado eventView.entry.brokenDirFile.showEncrypted=Mostrar link quebrado e encriptado
eventView.entry.brokenDirFile.copyEncrypted=Copiar caminho do link quebrado eventView.entry.brokenDirFile.copyEncrypted=Copiar caminho do link quebrado
eventView.entry.brokenFileNode.message=Nó do sistema de ficheiros avariado eventView.entry.brokenFileNode.message=Nó do sistema de ficheiros avariado
eventView.entry.brokenFileNode.showEncrypted=Mostrar nó encriptado e danificado eventView.entry.brokenFileNode.showEncrypted=Mostrar nó encriptado quebrado
eventView.entry.brokenFileNode.copyEncrypted=Copiar o caminho do nó encriptado e danificado eventView.entry.brokenFileNode.copyEncrypted=Copiar o caminho do nó encriptado e danificado
eventView.entry.brokenFileNode.copyDecrypted=Copiar o caminho desencriptado eventView.entry.brokenFileNode.copyDecrypted=Copiar caminho desencriptado
@@ -68,7 +68,6 @@ addvaultwizard.new.validCharacters.dashes=Dấu gạch ngang (%s) hoặc dấu g
### Expert Settings ### Expert Settings
addvaultwizard.new.expertSettings.enableExpertSettingsCheckbox="Bật các cài đặt chuyên gia" 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.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.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ệ" addvaultwizard.new.expertSettings.shorteningThreshold.valid="Hợp lệ"
### Password ### Password
@@ -139,12 +138,7 @@ 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.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.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.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.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 unlock.error.title=Mở khóa "%s" không thành công
## Hub ## Hub
hub.noKeychain.message=Không thể truy cập khoá thiết bị hub.noKeychain.message=Không thể truy cập khoá thiết bị
@@ -159,30 +153,18 @@ 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ờ. hub.receive.description=Cryptomator đang nhận và xử lý phản hồi từ Hub. Vui lòng chờ.
### Register Device ### Register Device
hub.register.message=Thiết bị mới 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.nameLabel=Tên thiết bị
hub.register.invalidAccountKeyLabel=Khóa Tài Khoản không đúng
hub.register.registerBtn=Đăng ký hub.register.registerBtn=Đăng ký
### Register Device Legacy ### Register Device Legacy
hub.register.legacy.occupiedMsg=Tên đã sử dụng 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 ### Registration Success
hub.registerSuccess.message=Đã đăng ký thiết bị 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.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 ### Registration Failed
hub.registerFailed.message=Đăng ký thiết bị thất bại 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 ### Unauthorized
hub.unauthorized.message=Truy cập bị từ chối 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 ### 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 ### License Exceeded
hub.invalidLicense.message=Giấy phép Hub không hợp lệ 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. 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.
@@ -283,12 +265,10 @@ preferences.title=Tùy chỉnh
## General ## General
preferences.general=Chung preferences.general=Chung
preferences.general.startHidden=Ẩn cửa sổ khi khởi động Cryptomator 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.debugLogging=Bật nhật kí gỡ lỗi
preferences.general.debugDirectory=Mở tệp nhật ký 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.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.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 ## Interface
preferences.interface=Giao diện preferences.interface=Giao diện
preferences.interface.theme=Cái nhìn và cảm nhận preferences.interface.theme=Cái nhìn và cảm nhận
@@ -302,10 +282,8 @@ preferences.interface.interfaceOrientation=Định hướng giao diện
preferences.interface.interfaceOrientation.ltr=Trái sang phải preferences.interface.interfaceOrientation.ltr=Trái sang phải
preferences.interface.interfaceOrientation.rtl=Phải sang trá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.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 ## Volume
preferences.volume=Ổ lưu trữ ảo preferences.volume=Ổ lưu trữ ảo
preferences.volume.type=Loại ổ đĩa mặc định
preferences.volume.type.automatic=Tự động 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.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. preferences.volume.fuseRestartRequired=Để áp dụng các thay đổi, Cryptomator cần được khởi động lại.
@@ -322,13 +300,10 @@ 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.autoUpdateCheck=Tự động kiểm tra phiên bản mới
preferences.updates.checkNowBtn=Kiểm tra ngay 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.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.never=không bao giờ
preferences.updates.lastUpdateCheck.recently=gần đây preferences.updates.lastUpdateCheck.recently=gần đây
preferences.updates.lastUpdateCheck.daysAgo=%s ngày trước preferences.updates.lastUpdateCheck.daysAgo=%s ngày trước
preferences.updates.lastUpdateCheck.hoursAgo=%s giờ 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 ## Contribution
preferences.contribute=Hỗ trợ chúng tôi preferences.contribute=Hỗ trợ chúng tôi
@@ -336,14 +311,8 @@ 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.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.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.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 ### 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 --> #<-- Add entries for donations and code/translation/documentation contribution -->
## About ## About
@@ -393,12 +362,7 @@ main.vaultlist.contextMenu.unlock=Mở khoá…
main.vaultlist.contextMenu.unlockNow=Mở khóa bây giờ main.vaultlist.contextMenu.unlockNow=Mở khóa bây giờ
main.vaultlist.contextMenu.vaultoptions=Hiện tùy chọn vault main.vaultlist.contextMenu.vaultoptions=Hiện tùy chọn vault
main.vaultlist.contextMenu.reveal=Hiển thị Ổ đĩa 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 ##Notificaition
main.notification.updateAvailable=Có bản cập nhật mới.
main.notification.support=Hỗ trợ Cryptomator.
## Vault Detail ## Vault Detail
### Welcome ### 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: 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:
@@ -424,9 +388,6 @@ main.vaultDetail.stats=Thống kê Vault
main.vaultDetail.locateEncryptedFileBtn=Định vị Tệp Đã mã hoá 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.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.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 ### Missing
main.vaultDetail.missing.info=Cryptomator không thể tìm thấy vault tại đường dẫn này. 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 main.vaultDetail.missing.recheck=Kiểm tra lại
@@ -465,7 +426,6 @@ vaultOptions.general.startHealthCheckBtn=Bắt đầu Kiểm tra sức khỏe
## Mount ## Mount
vaultOptions.mount=Gắn kết 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.readonly=Chỉ đọc
vaultOptions.mount.customMountFlags=Cờ gắn kết tuỳ chỉnh vaultOptions.mount.customMountFlags=Cờ gắn kết tuỳ chỉnh
vaultOptions.mount.winDriveLetterOccupied=đã bị chiếm vaultOptions.mount.winDriveLetterOccupied=đã bị chiếm
@@ -476,7 +436,6 @@ vaultOptions.mount.mountPoint.custom=Sử dụng thư mục đã chọn
vaultOptions.mount.mountPoint.directoryPickerButton=Chọn… vaultOptions.mount.mountPoint.directoryPickerButton=Chọn…
vaultOptions.mount.mountPoint.directoryPickerTitle=Chọn một thư mục vaultOptions.mount.mountPoint.directoryPickerTitle=Chọn một thư mục
vaultOptions.mount.volumeType.default=Mặc định (%s) 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.tcp.port=Cổng TCP
vaultOptions.mount.volume.type=Loại Ổ đĩa vaultOptions.mount.volume.type=Loại Ổ đĩa
## Master Key ## Master Key
@@ -545,78 +504,25 @@ quit.forced.forceAndQuitBtn=Bắt buộc và Thoát
# Update Reminder # Update Reminder
updateReminder.title=Kiểm tra cập nhật updateReminder.title=Kiểm tra cập nhật
updateReminder.message=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.notNow=Không phải bây giờ
updateReminder.yesOnce=Có, chỉ một lần
updateReminder.yesAutomatically=Có, tự động
#Dokany Support End #Dokany Support End
dokanySupportEnd.title=Thông báo ngừng phát triển dokanySupportEnd.title=Thông báo ngừng phát triển
dokanySupportEnd.message=Kết thúc hỗ trợ cho Dokany 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 dokanySupportEnd.preferencesBtn=Mở Tuỳ chọn
#Retry If Readonly #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 # Share Vault
shareVault.title=Chia sẻ 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.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.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.hubAd.encryption=• Mã hóa đầu cuối
shareVault.visitHub=Truy cập Cryptomator Hub 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 # 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 # Event View
eventView.title=Sự kiện
eventView.filter.allVaults=Tất cả
eventView.clearListButton.tooltip=Xóa danh sách
## event list entries ## 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ã
@@ -16,7 +16,7 @@ public class ReadMeGeneratorTest {
@CsvSource({ // @CsvSource({ //
"test,test", // "test,test", //
"t\u00E4st,t\\'E4st", // "t\u00E4st,t\\'E4st", //
"t\uD83D\uDE09st,t\\u55357\\u56841st", // "t\uD83D\uDE09st,t\\uc1\\u55357\\uc1\\u56841st", //
}) })
public void testEscapeNonAsciiChars(String input, String expectedResult) { public void testEscapeNonAsciiChars(String input, String expectedResult) {
ReadmeGenerator readmeGenerator = new ReadmeGenerator(null); 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.startsWith("{\\rtf1\\fbidis\\ansi\\uc0\\fs32"));
MatcherAssert.assertThat(result, CoreMatchers.containsString("{\\sa80 Dear User,}\\par")); 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 \\b please don't touch the \"d\" directory.}\\par "));
MatcherAssert.assertThat(result, CoreMatchers.containsString("{\\sa80 Thank you for your cooperation \\u55357\\u56841}\\par")); MatcherAssert.assertThat(result, CoreMatchers.containsString("{\\sa80 Thank you for your cooperation \\uc1\\u55357\\uc1\\u56841}\\par"));
MatcherAssert.assertThat(result, CoreMatchers.endsWith("}")); MatcherAssert.assertThat(result, CoreMatchers.endsWith("}"));
} }