mirror of
https://github.com/cryptomator/cryptomator.git
synced 2026-09-22 16:04:28 +00:00
Compare commits
120
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d013497c48 | ||
|
|
8691eec42b | ||
|
|
0f9d572677 | ||
|
|
baee23b6d4 | ||
|
|
532ffb1202 | ||
|
|
2a704d5eb4 | ||
|
|
e8f8466d9a | ||
|
|
9297562c99 | ||
|
|
7d62fc78de | ||
|
|
8e7e7de358 | ||
|
|
10c60d7492 | ||
|
|
aa03bd119a | ||
|
|
325ffda9af | ||
|
|
d1270ceeb2 | ||
|
|
7bfd0ed341 | ||
|
|
901a290dd9 | ||
|
|
35b9dadfc2 | ||
|
|
5f57678edc | ||
|
|
30e1922bc9 | ||
|
|
2e0908ab15 | ||
|
|
689ce5b985 | ||
|
|
a71a23aa31 | ||
|
|
864454e6fc | ||
|
|
94c3381723 | ||
|
|
d9f945e70a | ||
|
|
dc9b39202f | ||
|
|
2a01aba3cf | ||
|
|
4305fd3285 | ||
|
|
a24cd1ba7f | ||
|
|
2ba0d963ec | ||
|
|
cd0c6fbd33 | ||
|
|
f4374a2606 | ||
|
|
a1d5b8a4e2 | ||
|
|
34e430aff6 | ||
|
|
c79766cdf6 | ||
|
|
bf76bad626 | ||
|
|
c3f654b454 | ||
|
|
d1d990d47c | ||
|
|
6052c0589e | ||
|
|
db2560fccf | ||
|
|
3a50c32e50 | ||
|
|
65eca31d26 | ||
|
|
3462e0b540 | ||
|
|
697529136e | ||
|
|
50d31bdc18 | ||
|
|
84caf96d3f | ||
|
|
a1a5fd3609 | ||
|
|
6c11cc8f1d | ||
|
|
2b391a6ee3 | ||
|
|
b7fc03213d | ||
|
|
dfe17569e1 | ||
|
|
827f9ad141 | ||
|
|
c8a6d0339e | ||
|
|
b5bbd21f25 | ||
|
|
771468c8c6 | ||
|
|
ea2a48771f | ||
|
|
0e10da25b3 | ||
|
|
943a3e9cfd | ||
|
|
c988fb50a7 | ||
|
|
219ee0da9a | ||
|
|
5665e92839 | ||
|
|
04ff188624 | ||
|
|
ec7d6eafec | ||
|
|
28bb2ff9b1 | ||
|
|
a92ebfdc7b | ||
|
|
f1e97fa64b | ||
|
|
b9d5cf04c2 | ||
|
|
75cd3e44d8 | ||
|
|
3cf1b829b8 | ||
|
|
6e4e9cd261 | ||
|
|
e15dd7565f | ||
|
|
77bc60fe5b | ||
|
|
9f633a1ecb | ||
|
|
fcf59d12a8 | ||
|
|
6721075831 | ||
|
|
4bb0026415 | ||
|
|
bebae14744 | ||
|
|
997315eaf5 | ||
|
|
16d677c40f | ||
|
|
42a1913c17 | ||
|
|
c3f6655e48 | ||
|
|
fa1b0f2de8 | ||
|
|
385574a618 | ||
|
|
a67477bf3b | ||
|
|
03a362e9b4 | ||
|
|
2223bc5e78 | ||
|
|
fdc0d2d6b5 | ||
|
|
58ed48b097 | ||
|
|
7a0d255bd3 | ||
|
|
228fa099cb | ||
|
|
a60ff20f15 | ||
|
|
2328a5e3a8 | ||
|
|
e7e181b1a5 | ||
|
|
f3e7c08b43 | ||
|
|
2a41afcfa9 | ||
|
|
5bf38a328c | ||
|
|
f983b29034 | ||
|
|
4bc217e489 | ||
|
|
b24f52a4ec | ||
|
|
91e7fa3de3 | ||
|
|
1365efab3f | ||
|
|
852963b785 | ||
|
|
c47d4eaf02 | ||
|
|
36da26c6b9 | ||
|
|
33e1cb3131 | ||
|
|
ed4b433df0 | ||
|
|
d2ece543c8 | ||
|
|
4bb2df7d8f | ||
|
|
4d5c6ca29a | ||
|
|
f0d597ba73 | ||
|
|
310329d0b5 | ||
|
|
30f86a7f2a | ||
|
|
5237dc8cae | ||
|
|
4fc07c27b3 | ||
|
|
ec1d25bf65 | ||
|
|
7aa554498b | ||
|
|
85ac3c244d | ||
|
|
5db5346c88 | ||
|
|
8f4bf144c3 | ||
|
|
268c66a108 |
@@ -38,7 +38,7 @@ body:
|
|||||||
attributes:
|
attributes:
|
||||||
label: Volume Type
|
label: Volume Type
|
||||||
description: What volume type is selected under Settings → Virtual Drive?
|
description: What volume type is selected under Settings → Virtual Drive?
|
||||||
value: |
|
options:
|
||||||
- WinFsp
|
- WinFsp
|
||||||
- WinFsp (Local Drive)
|
- WinFsp (Local Drive)
|
||||||
- FUSE-T
|
- FUSE-T
|
||||||
@@ -49,7 +49,7 @@ body:
|
|||||||
- WebDAV (HTTP Address)
|
- WebDAV (HTTP Address)
|
||||||
- Dokany (1.5)
|
- Dokany (1.5)
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: false
|
||||||
- type: textarea
|
- type: textarea
|
||||||
id: reproduction-steps
|
id: reproduction-steps
|
||||||
attributes:
|
attributes:
|
||||||
|
|||||||
@@ -1,13 +0,0 @@
|
|||||||
# Configuration for probot-no-response - https://github.com/probot/no-response
|
|
||||||
|
|
||||||
# Number of days of inactivity before an Issue is closed for lack of response
|
|
||||||
daysUntilClose: 14
|
|
||||||
# Label requiring a response
|
|
||||||
responseRequiredLabel: state:awaiting-response
|
|
||||||
# Comment to post when closing an Issue for lack of response. Set to `false` to disable
|
|
||||||
closeComment: >
|
|
||||||
This issue has been automatically closed because there has been no response
|
|
||||||
to our request for more information from the original author. With only the
|
|
||||||
information that is currently in the issue, we don't have enough information
|
|
||||||
to take action. Please reach out if you have or find the answers we need so
|
|
||||||
that we can investigate further.
|
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
# .github/release.yml
|
||||||
|
# see https://docs.github.com/en/repositories/releasing-projects-on-github/automatically-generated-release-notes#configuring-automatically-generated-release-notes
|
||||||
|
|
||||||
|
changelog:
|
||||||
|
exclude:
|
||||||
|
authors:
|
||||||
|
- cryptobot
|
||||||
|
- dependabot
|
||||||
|
- github-actions
|
||||||
|
categories:
|
||||||
|
- title: What's New 🎉
|
||||||
|
labels:
|
||||||
|
- type:feature-request
|
||||||
|
- type:enhancement
|
||||||
|
- title: Bugfixes 🐛
|
||||||
|
labels:
|
||||||
|
- type:security-issue
|
||||||
|
- type:bug
|
||||||
|
- type:minor-bug
|
||||||
|
- title: Other Changes 📎
|
||||||
|
labels:
|
||||||
|
- "*"
|
||||||
|
exclude:
|
||||||
|
labels:
|
||||||
|
- type:feature-request
|
||||||
|
- type:enhancement
|
||||||
|
- type:security-issue
|
||||||
|
- type:bug
|
||||||
|
- type:minor-bug
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
# Number of days of inactivity before an issue becomes stale
|
|
||||||
daysUntilStale: 365
|
|
||||||
# Number of days of inactivity before a stale issue is closed
|
|
||||||
daysUntilClose: 90
|
|
||||||
# Issues with these labels will never be considered stale
|
|
||||||
exemptLabels:
|
|
||||||
- type:security-issue # never close automatically
|
|
||||||
- type:feature-request # never close automatically
|
|
||||||
- type:enhancement # never close automatically
|
|
||||||
- type:upstream-bug # never close automatically
|
|
||||||
- state:awaiting-response # handled by different bot
|
|
||||||
- state:blocked
|
|
||||||
- state:confirmed
|
|
||||||
# Set to true to ignore issues in a milestone (defaults to false)
|
|
||||||
exemptMilestones: true
|
|
||||||
# Label to use when marking an issue as stale
|
|
||||||
staleLabel: state:stale
|
|
||||||
# Comment to post when marking an issue as stale. Set to `false` to disable
|
|
||||||
markComment: >
|
|
||||||
This issue has been automatically marked as stale because it has not had
|
|
||||||
recent activity. It will be closed if no further activity occurs. Thank you
|
|
||||||
for your contributions.
|
|
||||||
# Comment to post when closing a stale issue. Set to `false` to disable
|
|
||||||
closeComment: false
|
|
||||||
@@ -54,7 +54,7 @@ jobs:
|
|||||||
--verbose
|
--verbose
|
||||||
--output runtime
|
--output runtime
|
||||||
--module-path "${JAVA_HOME}/jmods"
|
--module-path "${JAVA_HOME}/jmods"
|
||||||
--add-modules java.base,java.desktop,java.instrument,java.logging,java.naming,java.net.http,java.scripting,java.sql,java.xml,javafx.base,javafx.graphics,javafx.controls,javafx.fxml,jdk.unsupported,jdk.crypto.ec,jdk.security.auth,jdk.accessibility,jdk.management.jfr
|
--add-modules java.base,java.desktop,java.instrument,java.logging,java.naming,java.net.http,java.scripting,java.sql,java.xml,javafx.base,javafx.graphics,javafx.controls,javafx.fxml,jdk.unsupported,jdk.crypto.ec,jdk.security.auth,jdk.accessibility,jdk.management.jfr,jdk.zipfs
|
||||||
--strip-native-commands
|
--strip-native-commands
|
||||||
--no-header-files
|
--no-header-files
|
||||||
--no-man-pages
|
--no-man-pages
|
||||||
|
|||||||
@@ -53,4 +53,8 @@ jobs:
|
|||||||
body: |-
|
body: |-
|
||||||
:construction: Work in Progress
|
:construction: Work in Progress
|
||||||
|
|
||||||
|
Please be patient, the builds are still running. We will publish new versions of Cryptomator here in a few moments.
|
||||||
|
|
||||||
|
As usual, the GPG signatures can be checked using [our public key `5811 7AFA 1F85 B3EE C154 677D 615D 449F E6E6 A235`](https://gist.github.com/cryptobot/211111cf092037490275f39d408f461a).
|
||||||
---
|
---
|
||||||
|
<!-- Don't forget to include the 💾 SHA-256 checksums of release artifacts: -->
|
||||||
@@ -20,8 +20,8 @@ on:
|
|||||||
|
|
||||||
env:
|
env:
|
||||||
JAVA_VERSION: 19
|
JAVA_VERSION: 19
|
||||||
OPENJFX_JMODS_AMD64: 'https://download2.gluonhq.com/openjfx/19/openjfx-19_linux-x64_bin-jmods.zip'
|
OPENJFX_JMODS_AMD64: 'https://download2.gluonhq.com/openjfx/19.0.2.1/openjfx-19.0.2.1_linux-x64_bin-jmods.zip'
|
||||||
OPENJFX_JMODS_AARCH64: 'https://download2.gluonhq.com/openjfx/19/openjfx-19_linux-aarch64_bin-jmods.zip'
|
OPENJFX_JMODS_AARCH64: 'https://download2.gluonhq.com/openjfx/19.0.2.1/openjfx-19.0.2.1_linux-aarch64_bin-jmods.zip'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ jobs:
|
|||||||
--verbose
|
--verbose
|
||||||
--output runtime
|
--output runtime
|
||||||
--module-path "${JAVA_HOME}/jmods"
|
--module-path "${JAVA_HOME}/jmods"
|
||||||
--add-modules java.base,java.desktop,java.instrument,java.logging,java.naming,java.net.http,java.scripting,java.sql,java.xml,javafx.base,javafx.graphics,javafx.controls,javafx.fxml,jdk.unsupported,jdk.crypto.ec,jdk.accessibility,jdk.management.jfr
|
--add-modules java.base,java.desktop,java.instrument,java.logging,java.naming,java.net.http,java.scripting,java.sql,java.xml,javafx.base,javafx.graphics,javafx.controls,javafx.fxml,jdk.unsupported,jdk.crypto.ec,jdk.accessibility,jdk.management.jfr,jdk.zipfs
|
||||||
--strip-native-commands
|
--strip-native-commands
|
||||||
--no-header-files
|
--no-header-files
|
||||||
--no-man-pages
|
--no-man-pages
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
# Configuration for close-stale-issues - https://github.com/marketplace/actions/close-stale-issues
|
||||||
|
|
||||||
|
name: 'Close awaiting response issues'
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
- cron: '00 09 * * *'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
no-response:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
issues: write
|
||||||
|
pull-requests: write
|
||||||
|
steps:
|
||||||
|
- uses: actions/stale@v8
|
||||||
|
with:
|
||||||
|
days-before-stale: 14
|
||||||
|
days-before-close: 0
|
||||||
|
days-before-pr-close: -1
|
||||||
|
stale-issue-label: 'state:stale'
|
||||||
|
close-issue-message: "This issue has been automatically closed because there has been no response to our request for more information from the original author. With only the information that is currently in the issue, we don't have enough information to take action. Please reach out if you have or find the answers we need so that we can investigate further."
|
||||||
|
only-labels: 'state:awaiting-response'
|
||||||
@@ -10,7 +10,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- name: Download source tarball
|
- name: Download source tarball
|
||||||
run: |
|
run: |
|
||||||
curl -L -H "Accept: application/vnd.github+json" ${{ github.event.release.tarball_url }} --output cryptomator-${{ github.event.release.tag_name }}.tar.gz
|
curl -L -H "Accept: application/vnd.github+json" https://github.com/cryptomator/cryptomator/archive/refs/tags/${{ github.event.release.tag_name }}.tar.gz --output cryptomator-${{ github.event.release.tag_name }}.tar.gz
|
||||||
- name: Sign source tarball with key 615D449FE6E6A235
|
- name: Sign source tarball with key 615D449FE6E6A235
|
||||||
run: |
|
run: |
|
||||||
echo "${GPG_PRIVATE_KEY}" | gpg --batch --quiet --import
|
echo "${GPG_PRIVATE_KEY}" | gpg --batch --quiet --import
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
# Configuration for close-stale-issues - https://github.com/marketplace/actions/close-stale-issues
|
||||||
|
|
||||||
|
name: 'Close stale issues'
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
- cron: '00 09 * * *'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
stale:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
issues: write
|
||||||
|
pull-requests: write
|
||||||
|
steps:
|
||||||
|
- uses: actions/stale@v8
|
||||||
|
with:
|
||||||
|
days-before-stale: 365
|
||||||
|
days-before-close: 90
|
||||||
|
exempt-issue-labels: 'type:security-issue,type:feature-request,type:enhancement,type:upstream-bug,state:awaiting-response,state:blocked,state:confirmed'
|
||||||
|
exempt-all-milestones: true
|
||||||
|
stale-issue-label: 'state:stale'
|
||||||
|
stale-pr-label: 'state:stale'
|
||||||
|
stale-issue-message: 'This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.'
|
||||||
|
stale-pr-message: 'This PR has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.'
|
||||||
@@ -8,11 +8,17 @@ on:
|
|||||||
version:
|
version:
|
||||||
description: 'Version'
|
description: 'Version'
|
||||||
required: false
|
required: false
|
||||||
|
isDebug:
|
||||||
|
description: 'Build debug version with console output'
|
||||||
|
type: boolean
|
||||||
|
|
||||||
|
|
||||||
env:
|
env:
|
||||||
JAVA_VERSION: 19
|
JAVA_VERSION: 19
|
||||||
JAVA_DIST: 'zulu'
|
JAVA_DIST: 'temurin'
|
||||||
JAVA_CACHE: 'maven'
|
JAVA_CACHE: 'maven'
|
||||||
|
JFX_JMODS_URL: 'https://download2.gluonhq.com/openjfx/19.0.2.1/openjfx-19.0.2.1_windows-x64_bin-jmods.zip'
|
||||||
|
JFX_JMODS_HASH: 'B7CF2CAD2468842B3B78D99F6C0555771499A36FA1F1EE3DD1B9A4597F1FAB86'
|
||||||
|
|
||||||
defaults:
|
defaults:
|
||||||
run:
|
run:
|
||||||
@@ -30,6 +36,7 @@ jobs:
|
|||||||
needs: [get-version]
|
needs: [get-version]
|
||||||
env:
|
env:
|
||||||
LOOPBACK_ALIAS: 'cryptomator-vault'
|
LOOPBACK_ALIAS: 'cryptomator-vault'
|
||||||
|
WIN_CONSOLE_FLAG: ''
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- name: Setup Java
|
- name: Setup Java
|
||||||
@@ -37,17 +44,31 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
distribution: ${{ env.JAVA_DIST }}
|
distribution: ${{ env.JAVA_DIST }}
|
||||||
java-version: ${{ env.JAVA_VERSION }}
|
java-version: ${{ env.JAVA_VERSION }}
|
||||||
java-package: 'jdk+fx'
|
java-package: 'jdk'
|
||||||
cache: ${{ env.JAVA_CACHE }}
|
cache: ${{ env.JAVA_CACHE }}
|
||||||
- name: Ensure major jfx version in pom equals in jdk
|
- name: Download and extract JavaFX jmods from Gluon
|
||||||
shell: pwsh
|
#In the last step we move all jmods files a dir level up because jmods are placed inside a directory in the zip
|
||||||
run: |
|
run: |
|
||||||
$jfxPomVersion = (&mvn help:evaluate "-Dexpression=javafx.version" -q -DforceStdout) -split "\."
|
curl --output jfxjmods.zip -L "${{ env.JFX_JMODS_URL }}"
|
||||||
$jfxJdkVersion = ((Get-Content -path "${env:JAVA_HOME}/lib/javafx.properties" | Where-Object {$_ -like 'javafx.version=*' }) -replace '.*=','') -split "\."
|
if(!(Get-FileHash -Path jfxjmods.zip -Algorithm SHA256).Hash.equals("${{ env.JFX_JMODS_HASH }}")) {
|
||||||
if ($jfxPomVersion[0] -ne $jfxJdkVersion[0]) {
|
exit 1;
|
||||||
Write-Error "Major part of JavaFX version in pom($($jfxPomVersion[0])) does not match the version in JDK($($jfxJdkVersion[0])) "
|
|
||||||
exit 1
|
|
||||||
}
|
}
|
||||||
|
Expand-Archive -Path jfxjmods.zip -DestinationPath jfxjmods
|
||||||
|
Get-ChildItem -Path jfxjmods -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
|
||||||
|
run: |
|
||||||
|
JMOD_VERSION_AMD64=$(jmod describe jfxjmods/javafx.base.jmod | head -1)
|
||||||
|
JMOD_VERSION_AMD64=${JMOD_VERSION_AMD64#*@}
|
||||||
|
JMOD_VERSION_AMD64=${JMOD_VERSION_AMD64%%.*}
|
||||||
|
POM_JFX_VERSION=$(mvn help:evaluate "-Dexpression=javafx.version" -q -DforceStdout)
|
||||||
|
POM_JFX_VERSION=${POM_JFX_VERSION#*@}
|
||||||
|
POM_JFX_VERSION=${POM_JFX_VERSION%%.*}
|
||||||
|
|
||||||
|
if [ $POM_JFX_VERSION -ne $JMOD_VERSION_AMD64 ]; then
|
||||||
|
>&2 echo "Major JavaFX version in pom.xml (${POM_JFX_VERSION}) != amd64 jmod version (${JMOD_VERSION_AMD64})"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
- name: Set version
|
- 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
|
- name: Run maven
|
||||||
@@ -61,13 +82,16 @@ jobs:
|
|||||||
${JAVA_HOME}/bin/jlink
|
${JAVA_HOME}/bin/jlink
|
||||||
--verbose
|
--verbose
|
||||||
--output runtime
|
--output runtime
|
||||||
--module-path "${JAVA_HOME}/jmods"
|
--module-path "jfxjmods;${JAVA_HOME}/jmods"
|
||||||
--add-modules java.base,java.desktop,java.instrument,java.logging,java.naming,java.net.http,java.scripting,java.sql,java.xml,javafx.base,javafx.graphics,javafx.controls,javafx.fxml,jdk.unsupported,jdk.crypto.ec,jdk.accessibility,jdk.management.jfr
|
--add-modules java.base,java.desktop,java.instrument,java.logging,java.naming,java.net.http,java.scripting,java.sql,java.xml,javafx.base,javafx.graphics,javafx.controls,javafx.fxml,jdk.unsupported,jdk.crypto.ec,jdk.accessibility,jdk.management.jfr,jdk.zipfs
|
||||||
--strip-native-commands
|
--strip-native-commands
|
||||||
--no-header-files
|
--no-header-files
|
||||||
--no-man-pages
|
--no-man-pages
|
||||||
--strip-debug
|
--strip-debug
|
||||||
--compress=1
|
--compress=1
|
||||||
|
- name: Change win-console flag if debug is active
|
||||||
|
if: ${{ inputs.isDebug }}
|
||||||
|
run: echo "WIN_CONSOLE_FLAG=--win-console" >> $GITHUB_ENV
|
||||||
- name: Run jpackage
|
- name: Run jpackage
|
||||||
run: >
|
run: >
|
||||||
${JAVA_HOME}/bin/jpackage
|
${JAVA_HOME}/bin/jpackage
|
||||||
@@ -99,8 +123,10 @@ jobs:
|
|||||||
--java-options "-Dcryptomator.buildNumber=\"msi-${{ needs.get-version.outputs.revNum }}\""
|
--java-options "-Dcryptomator.buildNumber=\"msi-${{ needs.get-version.outputs.revNum }}\""
|
||||||
--java-options "-Dcryptomator.integrationsWin.autoStartShellLinkName=\"Cryptomator\""
|
--java-options "-Dcryptomator.integrationsWin.autoStartShellLinkName=\"Cryptomator\""
|
||||||
--java-options "-Dcryptomator.integrationsWin.keychainPaths=\"~/AppData/Roaming/Cryptomator/keychain.json\""
|
--java-options "-Dcryptomator.integrationsWin.keychainPaths=\"~/AppData/Roaming/Cryptomator/keychain.json\""
|
||||||
|
--java-options "-Djavafx.verbose=${{ inputs.isDebug }}"
|
||||||
--resource-dir dist/win/resources
|
--resource-dir dist/win/resources
|
||||||
--icon dist/win/resources/Cryptomator.ico
|
--icon dist/win/resources/Cryptomator.ico
|
||||||
|
${WIN_CONSOLE_FLAG}
|
||||||
- name: Patch Application Directory
|
- name: Patch Application Directory
|
||||||
run: |
|
run: |
|
||||||
cp dist/win/contrib/* appdir/Cryptomator
|
cp dist/win/contrib/* appdir/Cryptomator
|
||||||
@@ -203,15 +229,6 @@ jobs:
|
|||||||
*.msi
|
*.msi
|
||||||
*.asc
|
*.asc
|
||||||
|
|
||||||
call-winget-flow:
|
|
||||||
needs: [get-version, build-msi]
|
|
||||||
if: github.event.action == 'published' && needs.get-version.outputs.versionType == 'stable'
|
|
||||||
uses: ./.github/workflows/winget.yml
|
|
||||||
with:
|
|
||||||
releaseTag: ${{ github.event.release.tag_name }}
|
|
||||||
secrets: inherit
|
|
||||||
|
|
||||||
|
|
||||||
build-exe:
|
build-exe:
|
||||||
name: Build .exe installer
|
name: Build .exe installer
|
||||||
runs-on: windows-latest
|
runs-on: windows-latest
|
||||||
|
|||||||
@@ -1,49 +0,0 @@
|
|||||||
name: Release to Winget
|
|
||||||
|
|
||||||
on:
|
|
||||||
workflow_call:
|
|
||||||
inputs:
|
|
||||||
releaseTag:
|
|
||||||
required: true
|
|
||||||
type: string
|
|
||||||
workflow_dispatch:
|
|
||||||
inputs:
|
|
||||||
releaseTag:
|
|
||||||
description: 'Release tag name'
|
|
||||||
required: true
|
|
||||||
type: string
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
publish-winget:
|
|
||||||
name: Publish on winget repo
|
|
||||||
runs-on: windows-latest
|
|
||||||
steps:
|
|
||||||
- name: Get download url for release assets
|
|
||||||
id: get-release-assets
|
|
||||||
uses: actions/github-script@v6
|
|
||||||
with:
|
|
||||||
script: |
|
|
||||||
const query =`query($tag:String!) {
|
|
||||||
repository(owner:"cryptomator", name:"cryptomator"){
|
|
||||||
release(tagName: $tag) {
|
|
||||||
releaseAssets(first:20) {
|
|
||||||
nodes {
|
|
||||||
name
|
|
||||||
downloadUrl
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}`;
|
|
||||||
const variables = {
|
|
||||||
tag: "${{ inputs.releaseTag }}"
|
|
||||||
}
|
|
||||||
return await github.graphql(query, variables)
|
|
||||||
- name: Submit package to Windows Package Manager Community Repository
|
|
||||||
id: submit-winget
|
|
||||||
run: |
|
|
||||||
iwr https://aka.ms/wingetcreate/latest -OutFile wingetcreate.exe
|
|
||||||
$releaseAssets = (ConvertFrom-Json '${{ steps.get-release-assets.outputs.result }}').repository.release.releaseAssets.nodes
|
|
||||||
$installerUrl = $releaseAssets | Where-Object -Property name -match '^Cryptomator-.*\.msi$' | Select -ExpandProperty downloadUrl -First 1
|
|
||||||
.\wingetcreate.exe update Cryptomator.Cryptomator -s -v "${{ inputs.releaseTag }}" -u "$installerUrl" -t ${{ secrets.CRYPTOBOT_WINGET_TOKEN }}
|
|
||||||
shell: pwsh
|
|
||||||
@@ -21,7 +21,6 @@ Cryptomator is provided free of charge as an open-source project despite the hig
|
|||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<td><a href="https://www.gee-whiz.de/"><img src="https://cryptomator.org/img/sponsors/geewhiz.svg" alt="gee-whiz" height="80"></a></td>
|
<td><a href="https://www.gee-whiz.de/"><img src="https://cryptomator.org/img/sponsors/geewhiz.svg" alt="gee-whiz" height="80"></a></td>
|
||||||
<td><a href="https://proxy-hub.com/"><img src="https://cryptomator.org/img/sponsors/proxyhub.svg" alt="Proxy-Hub" height="80"></a></td>
|
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|||||||
Vendored
+1
-1
@@ -24,7 +24,7 @@ ${JAVA_HOME}/bin/jlink \
|
|||||||
--verbose \
|
--verbose \
|
||||||
--output runtime \
|
--output runtime \
|
||||||
--module-path "${JAVA_HOME}/jmods" \
|
--module-path "${JAVA_HOME}/jmods" \
|
||||||
--add-modules java.base,java.desktop,java.instrument,java.logging,java.naming,java.net.http,java.scripting,java.sql,java.xml,javafx.base,javafx.graphics,javafx.controls,javafx.fxml,jdk.unsupported,jdk.crypto.ec,jdk.security.auth,jdk.accessibility,jdk.management.jfr \
|
--add-modules java.base,java.desktop,java.instrument,java.logging,java.naming,java.net.http,java.scripting,java.sql,java.xml,javafx.base,javafx.graphics,javafx.controls,javafx.fxml,jdk.unsupported,jdk.crypto.ec,jdk.security.auth,jdk.accessibility,jdk.management.jfr,jdk.zipfs \
|
||||||
--strip-native-commands \
|
--strip-native-commands \
|
||||||
--no-header-files \
|
--no-header-files \
|
||||||
--no-man-pages \
|
--no-man-pages \
|
||||||
|
|||||||
@@ -66,6 +66,12 @@
|
|||||||
</content_rating>
|
</content_rating>
|
||||||
|
|
||||||
<releases>
|
<releases>
|
||||||
|
<release date="2023-04-25" version="1.8.0"/>
|
||||||
|
<release date="2023-04-07" version="1.7.5"/>
|
||||||
|
<release date="2023-04-05" version="1.7.4"/>
|
||||||
|
<release date="2023-03-15" version="1.7.3"/>
|
||||||
|
<release date="2023-03-07" version="1.7.2"/>
|
||||||
|
<release date="2023-03-03" version="1.7.1"/>
|
||||||
<release date="2023-03-01" version="1.7.0"/>
|
<release date="2023-03-01" version="1.7.0"/>
|
||||||
<release date="2022-12-14" version="1.6.17"/>
|
<release date="2022-12-14" version="1.6.17"/>
|
||||||
<release date="2022-12-06" version="1.6.16"/>
|
<release date="2022-12-06" version="1.6.16"/>
|
||||||
|
|||||||
Vendored
+1
-1
@@ -12,7 +12,7 @@ Package: cryptomator
|
|||||||
Architecture: any
|
Architecture: any
|
||||||
Section: utils
|
Section: utils
|
||||||
Priority: optional
|
Priority: optional
|
||||||
Depends: ${shlibs:Depends}, ${misc:Depends}, libfuse3-3
|
Depends: ${shlibs:Depends}, ${misc:Depends}, fuse3
|
||||||
Recommends: gvfs-backends, gvfs-fuse, gnome-keyring
|
Recommends: gvfs-backends, gvfs-fuse, gnome-keyring
|
||||||
XB-AppName: Cryptomator
|
XB-AppName: Cryptomator
|
||||||
XB-Category: Utility;Security;FileTools;
|
XB-Category: Utility;Security;FileTools;
|
||||||
|
|||||||
Vendored
+1
-1
@@ -27,7 +27,7 @@ override_dh_auto_build:
|
|||||||
$(JAVA_HOME)/bin/jlink \
|
$(JAVA_HOME)/bin/jlink \
|
||||||
--output runtime \
|
--output runtime \
|
||||||
--module-path "${JMODS_PATH}" \
|
--module-path "${JMODS_PATH}" \
|
||||||
--add-modules java.base,java.desktop,java.instrument,java.logging,java.naming,java.net.http,java.scripting,java.sql,java.xml,javafx.base,javafx.graphics,javafx.controls,javafx.fxml,jdk.unsupported,jdk.crypto.ec,jdk.security.auth,jdk.accessibility,jdk.management.jfr \
|
--add-modules java.base,java.desktop,java.instrument,java.logging,java.naming,java.net.http,java.scripting,java.sql,java.xml,javafx.base,javafx.graphics,javafx.controls,javafx.fxml,jdk.unsupported,jdk.crypto.ec,jdk.security.auth,jdk.accessibility,jdk.management.jfr,jdk.zipfs \
|
||||||
--strip-native-commands \
|
--strip-native-commands \
|
||||||
--no-header-files \
|
--no-header-files \
|
||||||
--no-man-pages \
|
--no-man-pages \
|
||||||
|
|||||||
Vendored
+1
-1
@@ -46,7 +46,7 @@ cp ../../../target/${MAIN_JAR_GLOB} ../../../target/mods
|
|||||||
${JAVA_HOME}/bin/jlink \
|
${JAVA_HOME}/bin/jlink \
|
||||||
--output runtime \
|
--output runtime \
|
||||||
--module-path "${JAVA_HOME}/jmods" \
|
--module-path "${JAVA_HOME}/jmods" \
|
||||||
--add-modules java.base,java.desktop,java.instrument,java.logging,java.naming,java.net.http,java.scripting,java.sql,java.xml,jdk.unsupported,jdk.crypto.ec,jdk.accessibility,jdk.management.jfr \
|
--add-modules java.base,java.desktop,java.instrument,java.logging,java.naming,java.net.http,java.scripting,java.sql,java.xml,jdk.unsupported,jdk.crypto.ec,jdk.accessibility,jdk.management.jfr,jdk.zipfs \
|
||||||
--strip-native-commands \
|
--strip-native-commands \
|
||||||
--no-header-files \
|
--no-header-files \
|
||||||
--no-man-pages \
|
--no-man-pages \
|
||||||
|
|||||||
Vendored
+1
-1
@@ -51,7 +51,7 @@ if ($clean -and (Test-Path -Path $runtimeImagePath)) {
|
|||||||
--verbose `
|
--verbose `
|
||||||
--output runtime `
|
--output runtime `
|
||||||
--module-path "$Env:JAVA_HOME/jmods" `
|
--module-path "$Env:JAVA_HOME/jmods" `
|
||||||
--add-modules java.base,java.desktop,java.instrument,java.logging,java.naming,java.net.http,java.scripting,java.sql,java.xml,jdk.unsupported,jdk.crypto.ec,jdk.accessibility,jdk.management.jfr `
|
--add-modules java.base,java.desktop,java.instrument,java.logging,java.naming,java.net.http,java.scripting,java.sql,java.xml,jdk.unsupported,jdk.crypto.ec,jdk.accessibility,jdk.management.jfr,jdk.zipfs `
|
||||||
--strip-native-commands `
|
--strip-native-commands `
|
||||||
--no-header-files `
|
--no-header-files `
|
||||||
--no-man-pages `
|
--no-man-pages `
|
||||||
|
|||||||
+1
-1
@@ -2,6 +2,6 @@
|
|||||||
|
|
||||||
<Include xmlns="http://schemas.microsoft.com/wix/2006/wi">
|
<Include xmlns="http://schemas.microsoft.com/wix/2006/wi">
|
||||||
<!-- A version number MUST be prefixed with letter "v", otherwise it is considered a normal string -->
|
<!-- A version number MUST be prefixed with letter "v", otherwise it is considered a normal string -->
|
||||||
<?define BundledWinFspVersion="v1.12.22309" ?>
|
<?define BundledWinFspVersion="v1.12.22339" ?>
|
||||||
<?define BundledWinFspDownloadLink="https://github.com/winfsp/winfsp/releases/download/v1.12.22339/winfsp-1.12.22339.msi" ?> <!-- Only used by external build scripts -->
|
<?define BundledWinFspDownloadLink="https://github.com/winfsp/winfsp/releases/download/v1.12.22339/winfsp-1.12.22339.msi" ?> <!-- Only used by external build scripts -->
|
||||||
</Include>
|
</Include>
|
||||||
@@ -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.7.0</version>
|
<version>1.9.0-SNAPSHOT</version>
|
||||||
<name>Cryptomator Desktop App</name>
|
<name>Cryptomator Desktop App</name>
|
||||||
|
|
||||||
<organization>
|
<organization>
|
||||||
@@ -17,6 +17,11 @@
|
|||||||
<email>sebastian.stenzel@gmail.com</email>
|
<email>sebastian.stenzel@gmail.com</email>
|
||||||
<timezone>+1</timezone>
|
<timezone>+1</timezone>
|
||||||
</developer>
|
</developer>
|
||||||
|
<developer>
|
||||||
|
<name>Armin Schrenk</name>
|
||||||
|
<email>armin.schrenk+dev@mailbox.org</email>
|
||||||
|
<timezone>+1</timezone>
|
||||||
|
</developer>
|
||||||
</developers>
|
</developers>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
@@ -28,15 +33,14 @@
|
|||||||
<nonModularGroupIds>org.ow2.asm,org.apache.jackrabbit,org.apache.httpcomponents,de.swiesend,org.purejava,com.github.hypfvieh</nonModularGroupIds>
|
<nonModularGroupIds>org.ow2.asm,org.apache.jackrabbit,org.apache.httpcomponents,de.swiesend,org.purejava,com.github.hypfvieh</nonModularGroupIds>
|
||||||
|
|
||||||
<!-- cryptomator dependencies -->
|
<!-- cryptomator dependencies -->
|
||||||
<cryptomator.cryptolib.version>2.1.1</cryptomator.cryptolib.version>
|
<cryptomator.cryptofs.version>2.6.2</cryptomator.cryptofs.version>
|
||||||
<cryptomator.cryptofs.version>2.6.1</cryptomator.cryptofs.version>
|
|
||||||
<cryptomator.integrations.version>1.2.0</cryptomator.integrations.version>
|
<cryptomator.integrations.version>1.2.0</cryptomator.integrations.version>
|
||||||
<cryptomator.integrations.win.version>1.2.0</cryptomator.integrations.win.version>
|
<cryptomator.integrations.win.version>1.2.0</cryptomator.integrations.win.version>
|
||||||
<cryptomator.integrations.mac.version>1.2.0</cryptomator.integrations.mac.version>
|
<cryptomator.integrations.mac.version>1.2.0</cryptomator.integrations.mac.version>
|
||||||
<cryptomator.integrations.linux.version>1.2.0</cryptomator.integrations.linux.version>
|
<cryptomator.integrations.linux.version>1.2.0</cryptomator.integrations.linux.version>
|
||||||
<cryptomator.fuse.version>2.0.2</cryptomator.fuse.version>
|
<cryptomator.fuse.version>2.0.5</cryptomator.fuse.version>
|
||||||
<cryptomator.dokany.version>2.0.0</cryptomator.dokany.version>
|
<cryptomator.dokany.version>2.0.0</cryptomator.dokany.version>
|
||||||
<cryptomator.webdav.version>2.0.0</cryptomator.webdav.version>
|
<cryptomator.webdav.version>2.0.2</cryptomator.webdav.version>
|
||||||
|
|
||||||
<!-- 3rd party dependencies -->
|
<!-- 3rd party dependencies -->
|
||||||
<commons-lang3.version>3.12.0</commons-lang3.version>
|
<commons-lang3.version>3.12.0</commons-lang3.version>
|
||||||
@@ -65,12 +69,6 @@
|
|||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<!-- Cryptomator Libs -->
|
<!-- Cryptomator Libs -->
|
||||||
<dependency>
|
|
||||||
<!-- needed due to https://github.com/cryptomator/cryptolib/issues/34 -->
|
|
||||||
<groupId>org.cryptomator</groupId>
|
|
||||||
<artifactId>cryptolib</artifactId>
|
|
||||||
<version>${cryptomator.cryptolib.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.cryptomator</groupId>
|
<groupId>org.cryptomator</groupId>
|
||||||
<artifactId>cryptofs</artifactId>
|
<artifactId>cryptofs</artifactId>
|
||||||
@@ -319,41 +317,6 @@
|
|||||||
</compilerArgs>
|
</compilerArgs>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
|
||||||
<groupId>org.codehaus.mojo</groupId>
|
|
||||||
<artifactId>exec-maven-plugin</artifactId>
|
|
||||||
<version>3.1.0</version>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<id>compile-light-theme</id>
|
|
||||||
<phase>compile</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>java</goal>
|
|
||||||
</goals>
|
|
||||||
<configuration>
|
|
||||||
<mainClass>javafx.graphics/com.sun.javafx.css.parser.Css2Bin</mainClass>
|
|
||||||
<arguments>
|
|
||||||
<arg>${project.basedir}/src/main/resources/css/light_theme.css</arg>
|
|
||||||
<arg>${project.build.outputDirectory}/css/light_theme.bss</arg>
|
|
||||||
</arguments>
|
|
||||||
</configuration>
|
|
||||||
</execution>
|
|
||||||
<execution>
|
|
||||||
<id>compile-dark-theme</id>
|
|
||||||
<phase>compile</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>java</goal>
|
|
||||||
</goals>
|
|
||||||
<configuration>
|
|
||||||
<mainClass>javafx.graphics/com.sun.javafx.css.parser.Css2Bin</mainClass>
|
|
||||||
<arguments>
|
|
||||||
<arg>${project.basedir}/src/main/resources/css/dark_theme.css</arg>
|
|
||||||
<arg>${project.build.outputDirectory}/css/dark_theme.bss</arg>
|
|
||||||
</arguments>
|
|
||||||
</configuration>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-jar-plugin</artifactId>
|
<artifactId>maven-jar-plugin</artifactId>
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
package org.cryptomator.common;
|
package org.cryptomator.common;
|
||||||
|
|
||||||
|
import org.cryptomator.ui.keyloading.masterkeyfile.MasterkeyFileLoadingStrategy;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
|
||||||
public interface Constants {
|
public interface Constants {
|
||||||
|
|
||||||
String MASTERKEY_FILENAME = "masterkey.cryptomator";
|
String MASTERKEY_FILENAME = "masterkey.cryptomator";
|
||||||
@@ -7,6 +11,7 @@ public interface Constants {
|
|||||||
String VAULTCONFIG_FILENAME = "vault.cryptomator";
|
String VAULTCONFIG_FILENAME = "vault.cryptomator";
|
||||||
String CRYPTOMATOR_FILENAME_EXT = ".cryptomator";
|
String CRYPTOMATOR_FILENAME_EXT = ".cryptomator";
|
||||||
String CRYPTOMATOR_FILENAME_GLOB = "*.cryptomator";
|
String CRYPTOMATOR_FILENAME_GLOB = "*.cryptomator";
|
||||||
|
URI DEFAULT_KEY_ID = URI.create(MasterkeyFileLoadingStrategy.SCHEME + ":" + MASTERKEY_FILENAME);
|
||||||
byte[] PEPPER = new byte[0];
|
byte[] PEPPER = new byte[0];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,9 @@ package org.cryptomator.common;
|
|||||||
|
|
||||||
import javafx.beans.binding.Bindings;
|
import javafx.beans.binding.Bindings;
|
||||||
import javafx.beans.value.ObservableValue;
|
import javafx.beans.value.ObservableValue;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
public class ObservableUtil {
|
public class ObservableUtil {
|
||||||
|
|
||||||
@@ -15,4 +17,14 @@ public class ObservableUtil {
|
|||||||
}
|
}
|
||||||
}, observable);
|
}, observable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static <T, U> ObservableValue<U> mapWithDefault(ObservableValue<T> observable, Function<? super T, ? extends U> mapper, Supplier<U> defaultValue) {
|
||||||
|
return Bindings.createObjectBinding(() -> {
|
||||||
|
if (observable.getValue() == null) {
|
||||||
|
return defaultValue.get();
|
||||||
|
} else {
|
||||||
|
return mapper.apply(observable.getValue());
|
||||||
|
}
|
||||||
|
}, observable);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,50 +2,71 @@ package org.cryptomator.common.mount;
|
|||||||
|
|
||||||
import dagger.Module;
|
import dagger.Module;
|
||||||
import dagger.Provides;
|
import dagger.Provides;
|
||||||
|
import org.cryptomator.common.ObservableUtil;
|
||||||
import org.cryptomator.common.settings.Settings;
|
import org.cryptomator.common.settings.Settings;
|
||||||
|
import org.cryptomator.integrations.mount.Mount;
|
||||||
import org.cryptomator.integrations.mount.MountService;
|
import org.cryptomator.integrations.mount.MountService;
|
||||||
|
|
||||||
|
import javax.inject.Named;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
import javafx.beans.property.SimpleObjectProperty;
|
|
||||||
import javafx.beans.value.ObservableValue;
|
import javafx.beans.value.ObservableValue;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
||||||
@Module
|
@Module
|
||||||
public class MountModule {
|
public class MountModule {
|
||||||
|
|
||||||
|
private static final AtomicReference<MountService> formerSelectedMountService = new AtomicReference<>(null);
|
||||||
|
private static final List<String> problematicFuseMountServices = List.of("org.cryptomator.frontend.fuse.mount.MacFuseMountProvider", "org.cryptomator.frontend.fuse.mount.FuseTMountProvider");
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
static List<MountService> provideSupportedMountServices() {
|
static List<MountService> provideSupportedMountServices() {
|
||||||
return MountService.get().toList();
|
return MountService.get().toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
//currently not used, because macFUSE and FUSE-T cannot be used in the same JVM
|
|
||||||
/*
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
static ObservableValue<ActualMountService> provideMountService(Settings settings, List<MountService> serviceImpls) {
|
@Named("FUPFMS")
|
||||||
|
static AtomicReference<MountService> provideFirstUsedProblematicFuseMountService() {
|
||||||
|
return new AtomicReference<>(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
static ObservableValue<ActualMountService> provideMountService(Settings settings, List<MountService> serviceImpls, @Named("FUPFMS") AtomicReference<MountService> fupfms) {
|
||||||
var fallbackProvider = serviceImpls.stream().findFirst().orElse(null);
|
var fallbackProvider = serviceImpls.stream().findFirst().orElse(null);
|
||||||
return ObservableUtil.mapWithDefault(settings.mountService(), //
|
|
||||||
|
var observableMountService = ObservableUtil.mapWithDefault(settings.mountService(), //
|
||||||
desiredServiceImpl -> { //
|
desiredServiceImpl -> { //
|
||||||
var desiredService = serviceImpls.stream().filter(serviceImpl -> serviceImpl.getClass().getName().equals(desiredServiceImpl)).findAny(); //
|
var serviceFromSettings = serviceImpls.stream().filter(serviceImpl -> serviceImpl.getClass().getName().equals(desiredServiceImpl)).findAny(); //
|
||||||
return new ActualMountService(desiredService.orElse(fallbackProvider), desiredService.isPresent()); //
|
var targetedService = serviceFromSettings.orElse(fallbackProvider);
|
||||||
|
return applyWorkaroundForProblematicFuse(targetedService, serviceFromSettings.isPresent(), fupfms);
|
||||||
}, //
|
}, //
|
||||||
new ActualMountService(fallbackProvider, true));
|
() -> { //
|
||||||
}
|
return applyWorkaroundForProblematicFuse(fallbackProvider, true, fupfms);
|
||||||
*/
|
});
|
||||||
|
return observableMountService;
|
||||||
@Provides
|
|
||||||
@Singleton
|
|
||||||
static ActualMountService provideActualMountService(Settings settings, List<MountService> serviceImpls) {
|
|
||||||
var fallbackProvider = serviceImpls.stream().findFirst().orElse(null);
|
|
||||||
var desiredService = serviceImpls.stream().filter(serviceImpl -> serviceImpl.getClass().getName().equals(settings.mountService().getValue())).findFirst(); //
|
|
||||||
return new ActualMountService(desiredService.orElse(fallbackProvider), desiredService.isPresent()); //
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
//see https://github.com/cryptomator/cryptomator/issues/2786
|
||||||
@Singleton
|
private synchronized static ActualMountService applyWorkaroundForProblematicFuse(MountService targetedService, boolean isDesired, AtomicReference<MountService> firstUsedProblematicFuseMountService) {
|
||||||
static ObservableValue<ActualMountService> provideMountService(ActualMountService service) {
|
//set the first used problematic fuse service if applicable
|
||||||
return new SimpleObjectProperty<>(service);
|
var targetIsProblematicFuse = isProblematicFuseService(targetedService);
|
||||||
|
if (targetIsProblematicFuse && firstUsedProblematicFuseMountService.get() == null) {
|
||||||
|
firstUsedProblematicFuseMountService.set(targetedService);
|
||||||
|
}
|
||||||
|
|
||||||
|
//do not use the targeted mount service and fallback to former one, if the service is problematic _and_ not the first problematic one used.
|
||||||
|
if (targetIsProblematicFuse && !firstUsedProblematicFuseMountService.get().equals(targetedService)) {
|
||||||
|
return new ActualMountService(formerSelectedMountService.get(), false);
|
||||||
|
} else {
|
||||||
|
formerSelectedMountService.set(targetedService);
|
||||||
|
return new ActualMountService(targetedService, isDesired);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isProblematicFuseService(MountService service) {
|
||||||
|
return problematicFuseMountServices.contains(service.getClass().getName());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,10 @@ package org.cryptomator.common.mount;
|
|||||||
|
|
||||||
public class MountPointPreparationException extends RuntimeException {
|
public class MountPointPreparationException extends RuntimeException {
|
||||||
|
|
||||||
|
public MountPointPreparationException(String msg) {
|
||||||
|
super(msg);
|
||||||
|
}
|
||||||
|
|
||||||
public MountPointPreparationException(Throwable cause) {
|
public MountPointPreparationException(Throwable cause) {
|
||||||
super(cause);
|
super(cause);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,8 +51,19 @@ public final class MountWithinParentUtil {
|
|||||||
if (SystemUtils.IS_OS_WINDOWS) {
|
if (SystemUtils.IS_OS_WINDOWS) {
|
||||||
Files.setAttribute(hideaway, WIN_HIDDEN_ATTR, true, LinkOption.NOFOLLOW_LINKS);
|
Files.setAttribute(hideaway, WIN_HIDDEN_ATTR, true, LinkOption.NOFOLLOW_LINKS);
|
||||||
}
|
}
|
||||||
|
int attempts = 0;
|
||||||
|
while (!Files.notExists(mountPoint)) {
|
||||||
|
if (attempts >= 10) {
|
||||||
|
throw new MountPointPreparationException("Path " + mountPoint + " could not be cleared");
|
||||||
|
}
|
||||||
|
Thread.sleep(1000);
|
||||||
|
attempts++;
|
||||||
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new MountPointPreparationException(e);
|
throw new MountPointPreparationException(e);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
throw new MountPointPreparationException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import org.slf4j.LoggerFactory;
|
|||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
import javafx.application.Platform;
|
||||||
import javafx.collections.ObservableList;
|
import javafx.collections.ObservableList;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
@@ -40,6 +41,7 @@ public class AutoLocker {
|
|||||||
private void autolock(Vault vault) {
|
private void autolock(Vault vault) {
|
||||||
try {
|
try {
|
||||||
vault.lock(false);
|
vault.lock(false);
|
||||||
|
Platform.runLater(() -> vault.stateProperty().set(VaultState.Value.LOCKED));
|
||||||
LOG.info("Autolocked {} after idle timeout", vault.getDisplayName());
|
LOG.info("Autolocked {} after idle timeout", vault.getDisplayName());
|
||||||
} catch (UnmountFailedException | IOException e) {
|
} catch (UnmountFailedException | IOException e) {
|
||||||
LOG.error("Autolocking failed.", e);
|
LOG.error("Autolocking failed.", e);
|
||||||
|
|||||||
@@ -1,39 +1,95 @@
|
|||||||
package org.cryptomator.launcher;
|
package org.cryptomator.launcher;
|
||||||
|
|
||||||
import org.cryptomator.common.settings.Settings;
|
import org.cryptomator.common.settings.Settings;
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
import java.nio.file.FileSystems;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.text.Collator;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.StreamSupport;
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
public class SupportedLanguages {
|
public class SupportedLanguages {
|
||||||
|
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(SupportedLanguages.class);
|
private static final Logger LOG = LoggerFactory.getLogger(SupportedLanguages.class);
|
||||||
// these are BCP 47 language codes, not ISO. Note the "-" instead of the "_":
|
public static final String ENGLISH = "en";
|
||||||
public static final List<String> LANGUAGAE_TAGS = List.of("en", "ar", "be", "bn", "bs", "ca", "cs", "da", "de", "el", "es", "fil", "fa", "fr", "gl", "he", //
|
|
||||||
"hi", "hr", "hu", "id", "it", "ja", "ko", "lv", "mk", "nb", "nl", "nn", "no", "pa", "pl", "pt", "pt-BR", "ro", "ru", "si", "sk", "sr", "sr-Latn", "sv", "sw", //
|
|
||||||
"ta", "te", "th", "tr", "uk", "vi", "zh", "zh-HK", "zh-TW");
|
|
||||||
|
|
||||||
@Nullable
|
private final List<String> sortedLanguageTags;
|
||||||
private final String preferredLanguage;
|
private final Locale preferredLocale;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public SupportedLanguages(Settings settings) {
|
public SupportedLanguages(Settings settings) {
|
||||||
this.preferredLanguage = settings.languageProperty().get();
|
var preferredLanguage = settings.languageProperty().get();
|
||||||
|
preferredLocale = preferredLanguage == null ? Locale.getDefault() : Locale.forLanguageTag(preferredLanguage);
|
||||||
|
var collator = Collator.getInstance(preferredLocale);
|
||||||
|
collator.setStrength(Collator.PRIMARY);
|
||||||
|
List<String> sortedTags = new ArrayList<>();
|
||||||
|
sortedTags.add(0, Settings.DEFAULT_LANGUAGE);
|
||||||
|
sortedTags.add(1, ENGLISH);
|
||||||
|
getSupportedLanguageTags().stream() //
|
||||||
|
.sorted((a, b) -> collator.compare(Locale.forLanguageTag(a).getDisplayName(), Locale.forLanguageTag(b).getDisplayName())) //
|
||||||
|
.forEach(sortedTags::add);
|
||||||
|
sortedLanguageTags = Collections.unmodifiableList(sortedTags);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void applyPreferred() {
|
public void applyPreferred() {
|
||||||
if (preferredLanguage == null) {
|
LOG.debug("Using locale {}", preferredLocale);
|
||||||
LOG.debug("Using system locale");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var preferredLocale = Locale.forLanguageTag(preferredLanguage);
|
|
||||||
LOG.debug("Applying preferred locale {}", preferredLocale.getDisplayName(Locale.ENGLISH));
|
|
||||||
Locale.setDefault(preferredLocale);
|
Locale.setDefault(preferredLocale);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<String> getLanguageTags() {
|
||||||
|
return sortedLanguageTags;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Iterates over the /i18n directory and extracts from every localization file the BCP 47 code.
|
||||||
|
*
|
||||||
|
* @return list of supported BCP 47 language codes
|
||||||
|
*/
|
||||||
|
private static List<String> getSupportedLanguageTags() {
|
||||||
|
try {
|
||||||
|
var i18DirURI = SupportedLanguages.class.getResource("/i18n").toURI();
|
||||||
|
var uriScheme = i18DirURI.getScheme();
|
||||||
|
if (uriScheme.equals("jar")) {
|
||||||
|
final String[] array = i18DirURI.toString().split("!");
|
||||||
|
try (var jarFs = FileSystems.newFileSystem(URI.create(array[0]), Map.<String, String>of())) {
|
||||||
|
return streamDirectory(jarFs.getPath(array[1]));
|
||||||
|
}
|
||||||
|
} else if (uriScheme.equals("file")) {
|
||||||
|
return streamDirectory(Path.of(i18DirURI));
|
||||||
|
} else {
|
||||||
|
throw new IOException("Unsupported uri scheme: " + uriScheme);
|
||||||
|
}
|
||||||
|
} catch (URISyntaxException | IOException e) {
|
||||||
|
LOG.warn("Unable to determine additional supported languages.", e);
|
||||||
|
return List.of();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<String> streamDirectory(Path i18Dir) throws IOException {
|
||||||
|
try (var dirStream = Files.newDirectoryStream(i18Dir, "strings_*.properties")) {
|
||||||
|
return StreamSupport.stream(dirStream.spliterator(), false) //
|
||||||
|
.map(SupportedLanguages::getBCP47CodeFromFileName) //
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getBCP47CodeFromFileName(Path p) {
|
||||||
|
var fileName = p.getFileName().toString();
|
||||||
|
return fileName.substring("strings_".length(), fileName.indexOf(".properties")).replace('_', '-');
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,8 +11,8 @@ import org.cryptomator.ui.common.FxControllerKey;
|
|||||||
import org.cryptomator.ui.common.FxmlFile;
|
import org.cryptomator.ui.common.FxmlFile;
|
||||||
import org.cryptomator.ui.common.FxmlLoaderFactory;
|
import org.cryptomator.ui.common.FxmlLoaderFactory;
|
||||||
import org.cryptomator.ui.common.FxmlScene;
|
import org.cryptomator.ui.common.FxmlScene;
|
||||||
import org.cryptomator.ui.common.NewPasswordController;
|
import org.cryptomator.ui.changepassword.NewPasswordController;
|
||||||
import org.cryptomator.ui.common.PasswordStrengthUtil;
|
import org.cryptomator.ui.changepassword.PasswordStrengthUtil;
|
||||||
import org.cryptomator.ui.common.StageFactory;
|
import org.cryptomator.ui.common.StageFactory;
|
||||||
import org.cryptomator.ui.fxapp.PrimaryStage;
|
import org.cryptomator.ui.fxapp.PrimaryStage;
|
||||||
import org.cryptomator.ui.recoverykey.RecoveryKeyDisplayController;
|
import org.cryptomator.ui.recoverykey.RecoveryKeyDisplayController;
|
||||||
|
|||||||
+2
-2
@@ -13,7 +13,7 @@ import org.cryptomator.cryptolib.common.MasterkeyFileAccess;
|
|||||||
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;
|
||||||
import org.cryptomator.ui.common.NewPasswordController;
|
import org.cryptomator.ui.changepassword.NewPasswordController;
|
||||||
import org.cryptomator.ui.common.Tasks;
|
import org.cryptomator.ui.common.Tasks;
|
||||||
import org.cryptomator.ui.fxapp.FxApplicationWindows;
|
import org.cryptomator.ui.fxapp.FxApplicationWindows;
|
||||||
import org.cryptomator.ui.keyloading.masterkeyfile.MasterkeyFileLoadingStrategy;
|
import org.cryptomator.ui.keyloading.masterkeyfile.MasterkeyFileLoadingStrategy;
|
||||||
@@ -48,13 +48,13 @@ import java.util.ResourceBundle;
|
|||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
|
|
||||||
import static java.nio.charset.StandardCharsets.US_ASCII;
|
import static java.nio.charset.StandardCharsets.US_ASCII;
|
||||||
|
import static org.cryptomator.common.Constants.DEFAULT_KEY_ID;
|
||||||
import static org.cryptomator.common.Constants.MASTERKEY_FILENAME;
|
import static org.cryptomator.common.Constants.MASTERKEY_FILENAME;
|
||||||
|
|
||||||
@AddVaultWizardScoped
|
@AddVaultWizardScoped
|
||||||
public class CreateNewVaultPasswordController implements FxController {
|
public class CreateNewVaultPasswordController implements FxController {
|
||||||
|
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(CreateNewVaultPasswordController.class);
|
private static final Logger LOG = LoggerFactory.getLogger(CreateNewVaultPasswordController.class);
|
||||||
private static final URI DEFAULT_KEY_ID = URI.create(MasterkeyFileLoadingStrategy.SCHEME + ":" + MASTERKEY_FILENAME); // TODO better place?
|
|
||||||
|
|
||||||
private final Stage window;
|
private final Stage window;
|
||||||
private final Lazy<Scene> chooseLocationScene;
|
private final Lazy<Scene> chooseLocationScene;
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import org.cryptomator.cryptolib.common.MasterkeyFileAccess;
|
|||||||
import org.cryptomator.integrations.keychain.KeychainAccessException;
|
import org.cryptomator.integrations.keychain.KeychainAccessException;
|
||||||
import org.cryptomator.ui.common.Animations;
|
import org.cryptomator.ui.common.Animations;
|
||||||
import org.cryptomator.ui.common.FxController;
|
import org.cryptomator.ui.common.FxController;
|
||||||
import org.cryptomator.ui.common.NewPasswordController;
|
|
||||||
import org.cryptomator.ui.controls.NiceSecurePasswordField;
|
import org.cryptomator.ui.controls.NiceSecurePasswordField;
|
||||||
import org.cryptomator.ui.fxapp.FxApplicationWindows;
|
import org.cryptomator.ui.fxapp.FxApplicationWindows;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
|||||||
@@ -10,8 +10,6 @@ import org.cryptomator.ui.common.FxControllerKey;
|
|||||||
import org.cryptomator.ui.common.FxmlFile;
|
import org.cryptomator.ui.common.FxmlFile;
|
||||||
import org.cryptomator.ui.common.FxmlLoaderFactory;
|
import org.cryptomator.ui.common.FxmlLoaderFactory;
|
||||||
import org.cryptomator.ui.common.FxmlScene;
|
import org.cryptomator.ui.common.FxmlScene;
|
||||||
import org.cryptomator.ui.common.NewPasswordController;
|
|
||||||
import org.cryptomator.ui.common.PasswordStrengthUtil;
|
|
||||||
import org.cryptomator.ui.common.StageFactory;
|
import org.cryptomator.ui.common.StageFactory;
|
||||||
|
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
|
|||||||
+7
-1
@@ -1,5 +1,7 @@
|
|||||||
package org.cryptomator.ui.common;
|
package org.cryptomator.ui.changepassword;
|
||||||
|
|
||||||
|
import org.cryptomator.common.Passphrase;
|
||||||
|
import org.cryptomator.ui.common.FxController;
|
||||||
import org.cryptomator.ui.controls.FontAwesome5IconView;
|
import org.cryptomator.ui.controls.FontAwesome5IconView;
|
||||||
import org.cryptomator.ui.controls.NiceSecurePasswordField;
|
import org.cryptomator.ui.controls.NiceSecurePasswordField;
|
||||||
|
|
||||||
@@ -91,4 +93,8 @@ public class NewPasswordController implements FxController {
|
|||||||
return passwordStrength.get();
|
return passwordStrength.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Passphrase getNewPassword() {
|
||||||
|
return passwordField.getCharacters();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
+1
-1
@@ -6,7 +6,7 @@
|
|||||||
* Contributors:
|
* Contributors:
|
||||||
* Jean-Noël Charon - initial API and implementation
|
* Jean-Noël Charon - initial API and implementation
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.cryptomator.ui.common;
|
package org.cryptomator.ui.changepassword;
|
||||||
|
|
||||||
import com.nulabinc.zxcvbn.Zxcvbn;
|
import com.nulabinc.zxcvbn.Zxcvbn;
|
||||||
import org.cryptomator.common.Environment;
|
import org.cryptomator.common.Environment;
|
||||||
@@ -9,6 +9,9 @@ public enum FxmlFile {
|
|||||||
ADDVAULT_SUCCESS("/fxml/addvault_success.fxml"), //
|
ADDVAULT_SUCCESS("/fxml/addvault_success.fxml"), //
|
||||||
ADDVAULT_WELCOME("/fxml/addvault_welcome.fxml"), //
|
ADDVAULT_WELCOME("/fxml/addvault_welcome.fxml"), //
|
||||||
CHANGEPASSWORD("/fxml/changepassword.fxml"), //
|
CHANGEPASSWORD("/fxml/changepassword.fxml"), //
|
||||||
|
CONVERTVAULT_HUBTOPASSWORD_START("/fxml/convertvault_hubtopassword_start.fxml"), //
|
||||||
|
CONVERTVAULT_HUBTOPASSWORD_CONVERT("/fxml/convertvault_hubtopassword_convert.fxml"), //
|
||||||
|
CONVERTVAULT_HUBTOPASSWORD_SUCCESS("/fxml/convertvault_hubtopassword_success.fxml"), //
|
||||||
ERROR("/fxml/error.fxml"), //
|
ERROR("/fxml/error.fxml"), //
|
||||||
FORGET_PASSWORD("/fxml/forget_password.fxml"), //
|
FORGET_PASSWORD("/fxml/forget_password.fxml"), //
|
||||||
HEALTH_START("/fxml/health_start.fxml"), //
|
HEALTH_START("/fxml/health_start.fxml"), //
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ public enum FontAwesome5Icon {
|
|||||||
COPY("\uF0C5"), //
|
COPY("\uF0C5"), //
|
||||||
CROWN("\uF521"), //
|
CROWN("\uF521"), //
|
||||||
EDIT("\uF044"), //
|
EDIT("\uF044"), //
|
||||||
|
EXCHANGE_ALT("\uF362"), //
|
||||||
EXCLAMATION("\uF12A"), //
|
EXCLAMATION("\uF12A"), //
|
||||||
EXCLAMATION_CIRCLE("\uF06A"), //
|
EXCLAMATION_CIRCLE("\uF06A"), //
|
||||||
EXCLAMATION_TRIANGLE("\uF071"), //
|
EXCLAMATION_TRIANGLE("\uF071"), //
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ public class SecurePasswordField extends TextField {
|
|||||||
private static final char WIPE_CHAR = ' ';
|
private static final char WIPE_CHAR = ' ';
|
||||||
private static final int INITIAL_BUFFER_SIZE = 50;
|
private static final int INITIAL_BUFFER_SIZE = 50;
|
||||||
private static final int GROW_BUFFER_SIZE = 50;
|
private static final int GROW_BUFFER_SIZE = 50;
|
||||||
private static final String DEFAULT_PLACEHOLDER = "●";
|
private static final String DEFAULT_PLACEHOLDER = "•";
|
||||||
private static final String STYLE_CLASS = "secure-password-field";
|
private static final String STYLE_CLASS = "secure-password-field";
|
||||||
private static final KeyCodeCombination SHORTCUT_BACKSPACE = new KeyCodeCombination(KeyCode.BACK_SPACE, KeyCombination.SHORTCUT_DOWN);
|
private static final KeyCodeCombination SHORTCUT_BACKSPACE = new KeyCodeCombination(KeyCode.BACK_SPACE, KeyCombination.SHORTCUT_DOWN);
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,41 @@
|
|||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2017 Skymatic UG (haftungsbeschränkt).
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the accompanying LICENSE file.
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.cryptomator.ui.convertvault;
|
||||||
|
|
||||||
|
import dagger.BindsInstance;
|
||||||
|
import dagger.Lazy;
|
||||||
|
import dagger.Subcomponent;
|
||||||
|
import org.cryptomator.common.vaults.Vault;
|
||||||
|
import org.cryptomator.ui.common.FxmlFile;
|
||||||
|
import org.cryptomator.ui.common.FxmlScene;
|
||||||
|
|
||||||
|
import javax.inject.Named;
|
||||||
|
import javafx.scene.Scene;
|
||||||
|
import javafx.stage.Stage;
|
||||||
|
|
||||||
|
@ConvertVaultScoped
|
||||||
|
@Subcomponent(modules = {ConvertVaultModule.class})
|
||||||
|
public interface ConvertVaultComponent {
|
||||||
|
|
||||||
|
@ConvertVaultWindow
|
||||||
|
Stage window();
|
||||||
|
|
||||||
|
@FxmlScene(FxmlFile.CONVERTVAULT_HUBTOPASSWORD_START)
|
||||||
|
Lazy<Scene> hubToPasswordScene();
|
||||||
|
|
||||||
|
default void showHubToPasswordWindow() {
|
||||||
|
Stage stage = window();
|
||||||
|
stage.setScene(hubToPasswordScene().get());
|
||||||
|
stage.sizeToScene();
|
||||||
|
stage.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subcomponent.Factory
|
||||||
|
interface Factory {
|
||||||
|
|
||||||
|
ConvertVaultComponent create(@BindsInstance @ConvertVaultWindow Vault vault, @BindsInstance @Named("convertVaultOwner") Stage owner);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,126 @@
|
|||||||
|
package org.cryptomator.ui.convertvault;
|
||||||
|
|
||||||
|
import dagger.Binds;
|
||||||
|
import dagger.Module;
|
||||||
|
import dagger.Provides;
|
||||||
|
import dagger.multibindings.IntoMap;
|
||||||
|
import org.cryptomator.common.vaults.Vault;
|
||||||
|
import org.cryptomator.cryptofs.VaultConfig;
|
||||||
|
import org.cryptomator.ui.changepassword.NewPasswordController;
|
||||||
|
import org.cryptomator.ui.changepassword.PasswordStrengthUtil;
|
||||||
|
import org.cryptomator.ui.common.DefaultSceneFactory;
|
||||||
|
import org.cryptomator.ui.common.FxController;
|
||||||
|
import org.cryptomator.ui.common.FxControllerKey;
|
||||||
|
import org.cryptomator.ui.common.FxmlFile;
|
||||||
|
import org.cryptomator.ui.common.FxmlLoaderFactory;
|
||||||
|
import org.cryptomator.ui.common.FxmlScene;
|
||||||
|
import org.cryptomator.ui.common.StageFactory;
|
||||||
|
import org.cryptomator.ui.recoverykey.RecoveryKeyFactory;
|
||||||
|
import org.cryptomator.ui.recoverykey.RecoveryKeyValidateController;
|
||||||
|
|
||||||
|
import javax.inject.Named;
|
||||||
|
import javax.inject.Provider;
|
||||||
|
import javafx.beans.property.SimpleStringProperty;
|
||||||
|
import javafx.beans.property.StringProperty;
|
||||||
|
import javafx.scene.Scene;
|
||||||
|
import javafx.stage.Modality;
|
||||||
|
import javafx.stage.Stage;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.ResourceBundle;
|
||||||
|
|
||||||
|
@Module
|
||||||
|
abstract class ConvertVaultModule {
|
||||||
|
|
||||||
|
//TODO: if this fails, we cannot display an error
|
||||||
|
@Provides
|
||||||
|
@ConvertVaultWindow
|
||||||
|
@ConvertVaultScoped
|
||||||
|
static VaultConfig.UnverifiedVaultConfig vaultConfig(@ConvertVaultWindow Vault vault) {
|
||||||
|
try {
|
||||||
|
return vault.getVaultConfigCache().get();
|
||||||
|
} catch (IOException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@ConvertVaultWindow
|
||||||
|
@ConvertVaultScoped
|
||||||
|
static StringProperty provideRecoveryKeyProperty() {
|
||||||
|
return new SimpleStringProperty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@ConvertVaultWindow
|
||||||
|
@ConvertVaultScoped
|
||||||
|
static FxmlLoaderFactory provideFxmlLoaderFactory(Map<Class<? extends FxController>, Provider<FxController>> factories, DefaultSceneFactory sceneFactory, ResourceBundle resourceBundle) {
|
||||||
|
return new FxmlLoaderFactory(factories, sceneFactory, resourceBundle);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@ConvertVaultWindow
|
||||||
|
@ConvertVaultScoped
|
||||||
|
static Stage provideStage(StageFactory factory, @Named("convertVaultOwner") Stage owner, ResourceBundle resourceBundle) {
|
||||||
|
Stage stage = factory.create();
|
||||||
|
stage.setResizable(false);
|
||||||
|
stage.initModality(Modality.WINDOW_MODAL);
|
||||||
|
stage.initOwner(owner);
|
||||||
|
stage.setTitle(resourceBundle.getString("convertVault.title"));
|
||||||
|
return stage;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@FxmlScene(FxmlFile.CONVERTVAULT_HUBTOPASSWORD_START)
|
||||||
|
@ConvertVaultScoped
|
||||||
|
static Scene provideHubToPasswordStartScene(@ConvertVaultWindow FxmlLoaderFactory fxmlLoaders) {
|
||||||
|
return fxmlLoaders.createScene(FxmlFile.CONVERTVAULT_HUBTOPASSWORD_START);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@FxmlScene(FxmlFile.CONVERTVAULT_HUBTOPASSWORD_CONVERT)
|
||||||
|
@ConvertVaultScoped
|
||||||
|
static Scene provideHubToPasswordConvertScene(@ConvertVaultWindow FxmlLoaderFactory fxmlLoaders) {
|
||||||
|
return fxmlLoaders.createScene(FxmlFile.CONVERTVAULT_HUBTOPASSWORD_CONVERT);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@FxmlScene(FxmlFile.CONVERTVAULT_HUBTOPASSWORD_SUCCESS)
|
||||||
|
@ConvertVaultScoped
|
||||||
|
static Scene provideHubToPasswordSuccessScene(@ConvertVaultWindow FxmlLoaderFactory fxmlLoaders) {
|
||||||
|
return fxmlLoaders.createScene(FxmlFile.CONVERTVAULT_HUBTOPASSWORD_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
@IntoMap
|
||||||
|
@FxControllerKey(HubToPasswordStartController.class)
|
||||||
|
abstract FxController bindHubToPasswordStartController(HubToPasswordStartController controller);
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
@IntoMap
|
||||||
|
@FxControllerKey(HubToPasswordConvertController.class)
|
||||||
|
abstract FxController bindHubToPasswordConvertController(HubToPasswordConvertController controller);
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
@IntoMap
|
||||||
|
@FxControllerKey(HubToPasswordSuccessController.class)
|
||||||
|
abstract FxController bindHubToPasswordSuccessController(HubToPasswordSuccessController controller);
|
||||||
|
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@IntoMap
|
||||||
|
@FxControllerKey(NewPasswordController.class)
|
||||||
|
static FxController provideNewPasswordController(ResourceBundle resourceBundle, PasswordStrengthUtil strengthRater) {
|
||||||
|
return new NewPasswordController(resourceBundle, strengthRater);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@IntoMap
|
||||||
|
@FxControllerKey(RecoveryKeyValidateController.class)
|
||||||
|
static FxController bindRecoveryKeyValidateController(@ConvertVaultWindow Vault vault, @ConvertVaultWindow VaultConfig.UnverifiedVaultConfig vaultConfig, @ConvertVaultWindow StringProperty recoveryKey, RecoveryKeyFactory recoveryKeyFactory) {
|
||||||
|
return new RecoveryKeyValidateController(vault, vaultConfig, recoveryKey, recoveryKeyFactory);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package org.cryptomator.ui.convertvault;
|
||||||
|
|
||||||
|
import javax.inject.Scope;
|
||||||
|
import java.lang.annotation.Documented;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
|
||||||
|
@Scope
|
||||||
|
@Documented
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@interface ConvertVaultScoped {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package org.cryptomator.ui.convertvault;
|
||||||
|
|
||||||
|
import javax.inject.Qualifier;
|
||||||
|
import java.lang.annotation.Documented;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
|
||||||
|
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||||
|
|
||||||
|
@Qualifier
|
||||||
|
@Documented
|
||||||
|
@Retention(RUNTIME)
|
||||||
|
@interface ConvertVaultWindow {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,171 @@
|
|||||||
|
package org.cryptomator.ui.convertvault;
|
||||||
|
|
||||||
|
import com.google.common.base.Preconditions;
|
||||||
|
import dagger.Lazy;
|
||||||
|
import org.cryptomator.common.Constants;
|
||||||
|
import org.cryptomator.common.Passphrase;
|
||||||
|
import org.cryptomator.common.vaults.Vault;
|
||||||
|
import org.cryptomator.cryptofs.VaultConfig;
|
||||||
|
import org.cryptomator.cryptofs.VaultVersionMismatchException;
|
||||||
|
import org.cryptomator.cryptofs.common.BackupHelper;
|
||||||
|
import org.cryptomator.cryptolib.api.MasterkeyLoadingFailedException;
|
||||||
|
import org.cryptomator.cryptolib.common.MasterkeyFileAccess;
|
||||||
|
import org.cryptomator.ui.changepassword.NewPasswordController;
|
||||||
|
import org.cryptomator.ui.common.FxController;
|
||||||
|
import org.cryptomator.ui.common.FxmlFile;
|
||||||
|
import org.cryptomator.ui.common.FxmlScene;
|
||||||
|
import org.cryptomator.ui.fxapp.FxApplicationWindows;
|
||||||
|
import org.cryptomator.ui.recoverykey.RecoveryKeyFactory;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javafx.application.Platform;
|
||||||
|
import javafx.beans.binding.Bindings;
|
||||||
|
import javafx.beans.property.BooleanProperty;
|
||||||
|
import javafx.beans.property.SimpleBooleanProperty;
|
||||||
|
import javafx.beans.property.StringProperty;
|
||||||
|
import javafx.fxml.FXML;
|
||||||
|
import javafx.scene.Scene;
|
||||||
|
import javafx.scene.control.Button;
|
||||||
|
import javafx.scene.control.ContentDisplay;
|
||||||
|
import javafx.stage.Stage;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.StandardCopyOption;
|
||||||
|
import java.util.ResourceBundle;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.concurrent.CompletionException;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
|
||||||
|
import static java.nio.file.StandardOpenOption.CREATE_NEW;
|
||||||
|
import static java.nio.file.StandardOpenOption.WRITE;
|
||||||
|
import static org.cryptomator.common.Constants.MASTERKEY_BACKUP_SUFFIX;
|
||||||
|
import static org.cryptomator.common.Constants.MASTERKEY_FILENAME;
|
||||||
|
import static org.cryptomator.common.Constants.VAULTCONFIG_FILENAME;
|
||||||
|
|
||||||
|
public class HubToPasswordConvertController implements FxController {
|
||||||
|
|
||||||
|
private static final Logger LOG = LoggerFactory.getLogger(HubToPasswordConvertController.class);
|
||||||
|
|
||||||
|
private final Stage window;
|
||||||
|
private final Lazy<Scene> successScene;
|
||||||
|
private final FxApplicationWindows applicationWindows;
|
||||||
|
private final Vault vault;
|
||||||
|
private final StringProperty recoveryKey;
|
||||||
|
private final RecoveryKeyFactory recoveryKeyFactory;
|
||||||
|
private final MasterkeyFileAccess masterkeyFileAccess;
|
||||||
|
private final ExecutorService backgroundExecutorService;
|
||||||
|
private final ResourceBundle resourceBundle;
|
||||||
|
private final BooleanProperty conversionStarted;
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
NewPasswordController newPasswordController;
|
||||||
|
public Button convertBtn;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public HubToPasswordConvertController(@ConvertVaultWindow Stage window, @FxmlScene(FxmlFile.CONVERTVAULT_HUBTOPASSWORD_SUCCESS) Lazy<Scene> successScene, FxApplicationWindows applicationWindows, @ConvertVaultWindow Vault vault, @ConvertVaultWindow StringProperty recoveryKey, RecoveryKeyFactory recoveryKeyFactory, MasterkeyFileAccess masterkeyFileAccess, ExecutorService backgroundExecutorService, ResourceBundle resourceBundle) {
|
||||||
|
this.window = window;
|
||||||
|
this.successScene = successScene;
|
||||||
|
this.applicationWindows = applicationWindows;
|
||||||
|
this.vault = vault;
|
||||||
|
this.recoveryKey = recoveryKey;
|
||||||
|
this.recoveryKeyFactory = recoveryKeyFactory;
|
||||||
|
this.masterkeyFileAccess = masterkeyFileAccess;
|
||||||
|
this.backgroundExecutorService = backgroundExecutorService;
|
||||||
|
this.resourceBundle = resourceBundle;
|
||||||
|
this.conversionStarted = new SimpleBooleanProperty(false);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
public void initialize() {
|
||||||
|
convertBtn.disableProperty().bind(Bindings.createBooleanBinding( //
|
||||||
|
() -> !newPasswordController.isGoodPassword() || conversionStarted.get(), //
|
||||||
|
newPasswordController.goodPasswordProperty(), //
|
||||||
|
conversionStarted));
|
||||||
|
convertBtn.contentDisplayProperty().bind(Bindings.createObjectBinding( //
|
||||||
|
() -> conversionStarted.getValue() ? ContentDisplay.LEFT : ContentDisplay.TEXT_ONLY, //
|
||||||
|
conversionStarted));
|
||||||
|
convertBtn.textProperty().bind(Bindings.createStringBinding( //
|
||||||
|
() -> resourceBundle.getString("convertVault.convert.convertBtn." + (conversionStarted.get() ? "processing" : "before")), //
|
||||||
|
conversionStarted));
|
||||||
|
}
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
public void close() {
|
||||||
|
window.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
public void convert() {
|
||||||
|
Preconditions.checkState(newPasswordController.isGoodPassword());
|
||||||
|
LOG.info("Converting access method of vault {} from hub to password", vault.getPath());
|
||||||
|
CompletableFuture.runAsync(() -> conversionStarted.setValue(true), Platform::runLater) //
|
||||||
|
.thenRunAsync(this::convertInternal, backgroundExecutorService) //
|
||||||
|
.whenCompleteAsync((result, exception) -> {
|
||||||
|
if (exception == null) {
|
||||||
|
LOG.info("Conversion of vault {} succeeded.", vault.getPath());
|
||||||
|
window.setScene(successScene.get());
|
||||||
|
} else {
|
||||||
|
LOG.error("Conversion of vault {} failed.", vault.getPath(), exception);
|
||||||
|
applicationWindows.showErrorWindow(exception, window, null);
|
||||||
|
}
|
||||||
|
}, Platform::runLater); //
|
||||||
|
}
|
||||||
|
|
||||||
|
//visible for testing
|
||||||
|
void convertInternal() throws CompletionException, IllegalArgumentException {
|
||||||
|
var passphrase = newPasswordController.getNewPassword();
|
||||||
|
var vaultPath = vault.getPath();
|
||||||
|
try {
|
||||||
|
//create masterkey
|
||||||
|
recoveryKeyFactory.newMasterkeyFileWithPassphrase(vaultPath, recoveryKey.get(), passphrase);
|
||||||
|
LOG.debug("Successfully created masterkey file for vault {}", vaultPath);
|
||||||
|
//create password config
|
||||||
|
Path passwordConfigPath = vaultPath.resolve("passwordBased." + VAULTCONFIG_FILENAME + ".tmp");
|
||||||
|
passwordConfigPath = createPasswordConfig(passwordConfigPath, vaultPath.resolve(MASTERKEY_FILENAME), passphrase);
|
||||||
|
//backup hub config
|
||||||
|
var hubConfigPath = vaultPath.resolve(VAULTCONFIG_FILENAME);
|
||||||
|
backupHubConfig(hubConfigPath);
|
||||||
|
//replace hub by password
|
||||||
|
Files.move(passwordConfigPath, hubConfigPath, StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.ATOMIC_MOVE);
|
||||||
|
} catch (MasterkeyLoadingFailedException e) {
|
||||||
|
throw new CompletionException(new IOException("Vault conversion failed", e));
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new CompletionException("Vault conversion failed", e);
|
||||||
|
} finally {
|
||||||
|
passphrase.destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//visible for testing
|
||||||
|
void backupHubConfig(Path hubConfigPath) throws IOException {
|
||||||
|
byte[] hubConfigBytes = Files.readAllBytes(hubConfigPath);
|
||||||
|
Path backupPath = hubConfigPath.resolveSibling(VAULTCONFIG_FILENAME + BackupHelper.generateFileIdSuffix(hubConfigBytes) + MASTERKEY_BACKUP_SUFFIX);
|
||||||
|
Files.copy(hubConfigPath, backupPath, StandardCopyOption.REPLACE_EXISTING);
|
||||||
|
LOG.debug("Successfully created hub config backup {}", backupPath.getFileName());
|
||||||
|
}
|
||||||
|
|
||||||
|
//visible for testing
|
||||||
|
Path createPasswordConfig(Path passwordConfigPath, Path masterkeyFile, Passphrase passphrase) throws IOException, MasterkeyLoadingFailedException {
|
||||||
|
var unverifiedVaultConfig = vault.getVaultConfigCache().get();
|
||||||
|
try (var masterkey = masterkeyFileAccess.load(masterkeyFile, passphrase)) {
|
||||||
|
var hubConfig = unverifiedVaultConfig.verify(masterkey.getEncoded(), unverifiedVaultConfig.allegedVaultVersion());
|
||||||
|
var passwordConfig = VaultConfig.createNew() //
|
||||||
|
.cipherCombo(hubConfig.getCipherCombo()) //
|
||||||
|
.shorteningThreshold(hubConfig.getShorteningThreshold()) //
|
||||||
|
.build();
|
||||||
|
if (passwordConfig.getVaultVersion() != hubConfig.getVaultVersion()) {
|
||||||
|
throw new VaultVersionMismatchException("Only vaults of version " + passwordConfig.getVaultVersion() + " can be converted.");
|
||||||
|
}
|
||||||
|
var token = passwordConfig.toToken(Constants.DEFAULT_KEY_ID.toString(), masterkey.getEncoded());
|
||||||
|
Files.writeString(passwordConfigPath, token, StandardCharsets.US_ASCII, WRITE, CREATE_NEW);
|
||||||
|
LOG.debug("Successfully created password config {}", passwordConfigPath);
|
||||||
|
return passwordConfigPath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
package org.cryptomator.ui.convertvault;
|
||||||
|
|
||||||
|
import dagger.Lazy;
|
||||||
|
import org.cryptomator.ui.common.FxController;
|
||||||
|
import org.cryptomator.ui.common.FxmlFile;
|
||||||
|
import org.cryptomator.ui.common.FxmlScene;
|
||||||
|
import org.cryptomator.ui.recoverykey.RecoveryKeyValidateController;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javafx.fxml.FXML;
|
||||||
|
import javafx.scene.Scene;
|
||||||
|
import javafx.stage.Stage;
|
||||||
|
|
||||||
|
public class HubToPasswordStartController implements FxController {
|
||||||
|
|
||||||
|
private final Stage window;
|
||||||
|
private final Lazy<Scene> convertScene;
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
RecoveryKeyValidateController recoveryKeyValidateController;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public HubToPasswordStartController(@ConvertVaultWindow Stage window, @FxmlScene(FxmlFile.CONVERTVAULT_HUBTOPASSWORD_CONVERT) Lazy<Scene> convertScene) {
|
||||||
|
this.window = window;
|
||||||
|
this.convertScene = convertScene;
|
||||||
|
}
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
public void initialize() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
public void close() {
|
||||||
|
window.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
public void next() {
|
||||||
|
window.setScene(convertScene.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Getter/Setter */
|
||||||
|
|
||||||
|
public RecoveryKeyValidateController getValidateController() {
|
||||||
|
return recoveryKeyValidateController;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
package org.cryptomator.ui.convertvault;
|
||||||
|
|
||||||
|
import org.cryptomator.common.vaults.Vault;
|
||||||
|
import org.cryptomator.ui.common.FxController;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javafx.fxml.FXML;
|
||||||
|
import javafx.stage.Stage;
|
||||||
|
|
||||||
|
public class HubToPasswordSuccessController implements FxController {
|
||||||
|
|
||||||
|
private final Stage window;
|
||||||
|
private final Vault vault;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
HubToPasswordSuccessController(@ConvertVaultWindow Stage window, @ConvertVaultWindow Vault vault) {
|
||||||
|
this.window = window;
|
||||||
|
this.vault = vault;
|
||||||
|
}
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
public void close() {
|
||||||
|
window.close();
|
||||||
|
window.getOwner().hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Observables */
|
||||||
|
|
||||||
|
public Vault getVault() {
|
||||||
|
return vault;
|
||||||
|
}
|
||||||
|
}
|
||||||
+3
-1
@@ -1,8 +1,10 @@
|
|||||||
package org.cryptomator.ui.common;
|
package org.cryptomator.ui.error;
|
||||||
|
|
||||||
import dagger.BindsInstance;
|
import dagger.BindsInstance;
|
||||||
import dagger.Subcomponent;
|
import dagger.Subcomponent;
|
||||||
import org.cryptomator.common.Nullable;
|
import org.cryptomator.common.Nullable;
|
||||||
|
import org.cryptomator.ui.common.FxmlFile;
|
||||||
|
import org.cryptomator.ui.common.FxmlScene;
|
||||||
|
|
||||||
import javafx.scene.Scene;
|
import javafx.scene.Scene;
|
||||||
import javafx.stage.Stage;
|
import javafx.stage.Stage;
|
||||||
+2
-1
@@ -1,8 +1,9 @@
|
|||||||
package org.cryptomator.ui.common;
|
package org.cryptomator.ui.error;
|
||||||
|
|
||||||
import org.cryptomator.common.Environment;
|
import org.cryptomator.common.Environment;
|
||||||
import org.cryptomator.common.ErrorCode;
|
import org.cryptomator.common.ErrorCode;
|
||||||
import org.cryptomator.common.Nullable;
|
import org.cryptomator.common.Nullable;
|
||||||
|
import org.cryptomator.ui.common.FxController;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
+7
-1
@@ -1,10 +1,16 @@
|
|||||||
package org.cryptomator.ui.common;
|
package org.cryptomator.ui.error;
|
||||||
|
|
||||||
import dagger.Binds;
|
import dagger.Binds;
|
||||||
import dagger.Module;
|
import dagger.Module;
|
||||||
import dagger.Provides;
|
import dagger.Provides;
|
||||||
import dagger.multibindings.IntoMap;
|
import dagger.multibindings.IntoMap;
|
||||||
import org.cryptomator.common.ErrorCode;
|
import org.cryptomator.common.ErrorCode;
|
||||||
|
import org.cryptomator.ui.common.DefaultSceneFactory;
|
||||||
|
import org.cryptomator.ui.common.FxController;
|
||||||
|
import org.cryptomator.ui.common.FxControllerKey;
|
||||||
|
import org.cryptomator.ui.common.FxmlFile;
|
||||||
|
import org.cryptomator.ui.common.FxmlLoaderFactory;
|
||||||
|
import org.cryptomator.ui.common.FxmlScene;
|
||||||
|
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
import javax.inject.Provider;
|
import javax.inject.Provider;
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package org.cryptomator.ui.forgetPassword;
|
package org.cryptomator.ui.forgetpassword;
|
||||||
|
|
||||||
import dagger.BindsInstance;
|
import dagger.BindsInstance;
|
||||||
import dagger.Lazy;
|
import dagger.Lazy;
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package org.cryptomator.ui.forgetPassword;
|
package org.cryptomator.ui.forgetpassword;
|
||||||
|
|
||||||
import org.cryptomator.common.keychain.KeychainManager;
|
import org.cryptomator.common.keychain.KeychainManager;
|
||||||
import org.cryptomator.common.vaults.Vault;
|
import org.cryptomator.common.vaults.Vault;
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package org.cryptomator.ui.forgetPassword;
|
package org.cryptomator.ui.forgetpassword;
|
||||||
|
|
||||||
import dagger.Binds;
|
import dagger.Binds;
|
||||||
import dagger.Module;
|
import dagger.Module;
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package org.cryptomator.ui.forgetPassword;
|
package org.cryptomator.ui.forgetpassword;
|
||||||
|
|
||||||
import javax.inject.Scope;
|
import javax.inject.Scope;
|
||||||
import java.lang.annotation.Documented;
|
import java.lang.annotation.Documented;
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package org.cryptomator.ui.forgetPassword;
|
package org.cryptomator.ui.forgetpassword;
|
||||||
|
|
||||||
import javax.inject.Qualifier;
|
import javax.inject.Qualifier;
|
||||||
import java.lang.annotation.Documented;
|
import java.lang.annotation.Documented;
|
||||||
@@ -7,9 +7,7 @@ package org.cryptomator.ui.fxapp;
|
|||||||
|
|
||||||
import dagger.Module;
|
import dagger.Module;
|
||||||
import dagger.Provides;
|
import dagger.Provides;
|
||||||
import org.apache.commons.lang3.SystemUtils;
|
import org.cryptomator.ui.error.ErrorComponent;
|
||||||
import org.cryptomator.ui.common.ErrorComponent;
|
|
||||||
import org.cryptomator.ui.common.StageFactory;
|
|
||||||
import org.cryptomator.ui.lock.LockComponent;
|
import org.cryptomator.ui.lock.LockComponent;
|
||||||
import org.cryptomator.ui.mainwindow.MainWindowComponent;
|
import org.cryptomator.ui.mainwindow.MainWindowComponent;
|
||||||
import org.cryptomator.ui.preferences.PreferencesComponent;
|
import org.cryptomator.ui.preferences.PreferencesComponent;
|
||||||
@@ -18,13 +16,9 @@ import org.cryptomator.ui.quit.QuitComponent;
|
|||||||
import org.cryptomator.ui.traymenu.TrayMenuComponent;
|
import org.cryptomator.ui.traymenu.TrayMenuComponent;
|
||||||
import org.cryptomator.ui.unlock.UnlockComponent;
|
import org.cryptomator.ui.unlock.UnlockComponent;
|
||||||
|
|
||||||
import javax.inject.Named;
|
|
||||||
import javafx.scene.image.Image;
|
import javafx.scene.image.Image;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.UncheckedIOException;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@Module(includes = {UpdateCheckerModule.class}, subcomponents = {TrayMenuComponent.class, MainWindowComponent.class, PreferencesComponent.class, UnlockComponent.class, LockComponent.class, QuitComponent.class, ErrorComponent.class})
|
@Module(includes = {UpdateCheckerModule.class}, subcomponents = {TrayMenuComponent.class, MainWindowComponent.class, PreferencesComponent.class, UnlockComponent.class, LockComponent.class, QuitComponent.class, ErrorComponent.class})
|
||||||
abstract class FxApplicationModule {
|
abstract class FxApplicationModule {
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import dagger.Lazy;
|
|||||||
import org.cryptomator.common.vaults.Vault;
|
import org.cryptomator.common.vaults.Vault;
|
||||||
import org.cryptomator.common.vaults.VaultState;
|
import org.cryptomator.common.vaults.VaultState;
|
||||||
import org.cryptomator.integrations.tray.TrayIntegrationProvider;
|
import org.cryptomator.integrations.tray.TrayIntegrationProvider;
|
||||||
import org.cryptomator.ui.common.ErrorComponent;
|
import org.cryptomator.ui.error.ErrorComponent;
|
||||||
import org.cryptomator.ui.lock.LockComponent;
|
import org.cryptomator.ui.lock.LockComponent;
|
||||||
import org.cryptomator.ui.mainwindow.MainWindowComponent;
|
import org.cryptomator.ui.mainwindow.MainWindowComponent;
|
||||||
import org.cryptomator.ui.preferences.PreferencesComponent;
|
import org.cryptomator.ui.preferences.PreferencesComponent;
|
||||||
|
|||||||
@@ -15,8 +15,6 @@ import org.cryptomator.ui.common.FxControllerKey;
|
|||||||
import org.cryptomator.ui.common.FxmlFile;
|
import org.cryptomator.ui.common.FxmlFile;
|
||||||
import org.cryptomator.ui.common.FxmlLoaderFactory;
|
import org.cryptomator.ui.common.FxmlLoaderFactory;
|
||||||
import org.cryptomator.ui.common.FxmlScene;
|
import org.cryptomator.ui.common.FxmlScene;
|
||||||
import org.cryptomator.ui.common.NewPasswordController;
|
|
||||||
import org.cryptomator.ui.common.PasswordStrengthUtil;
|
|
||||||
import org.cryptomator.ui.keyloading.KeyLoading;
|
import org.cryptomator.ui.keyloading.KeyLoading;
|
||||||
import org.cryptomator.ui.keyloading.KeyLoadingScoped;
|
import org.cryptomator.ui.keyloading.KeyLoadingScoped;
|
||||||
import org.cryptomator.ui.keyloading.KeyLoadingStrategy;
|
import org.cryptomator.ui.keyloading.KeyLoadingStrategy;
|
||||||
@@ -153,13 +151,6 @@ public abstract class HubKeyLoadingModule {
|
|||||||
@FxControllerKey(AuthFlowController.class)
|
@FxControllerKey(AuthFlowController.class)
|
||||||
abstract FxController bindAuthFlowController(AuthFlowController controller);
|
abstract FxController bindAuthFlowController(AuthFlowController controller);
|
||||||
|
|
||||||
@Provides
|
|
||||||
@IntoMap
|
|
||||||
@FxControllerKey(NewPasswordController.class)
|
|
||||||
static FxController provideNewPasswordController(ResourceBundle resourceBundle, PasswordStrengthUtil strengthRater) {
|
|
||||||
return new NewPasswordController(resourceBundle, strengthRater);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Binds
|
@Binds
|
||||||
@IntoMap
|
@IntoMap
|
||||||
@FxControllerKey(InvalidLicenseController.class)
|
@FxControllerKey(InvalidLicenseController.class)
|
||||||
|
|||||||
@@ -29,8 +29,8 @@ import java.util.concurrent.ExecutionException;
|
|||||||
public class HubKeyLoadingStrategy implements KeyLoadingStrategy {
|
public class HubKeyLoadingStrategy implements KeyLoadingStrategy {
|
||||||
|
|
||||||
private static final String SCHEME_PREFIX = "hub+";
|
private static final String SCHEME_PREFIX = "hub+";
|
||||||
static final String SCHEME_HUB_HTTP = SCHEME_PREFIX + "http";
|
public static final String SCHEME_HUB_HTTP = SCHEME_PREFIX + "http";
|
||||||
static final String SCHEME_HUB_HTTPS = SCHEME_PREFIX + "https";
|
public static final String SCHEME_HUB_HTTPS = SCHEME_PREFIX + "https";
|
||||||
|
|
||||||
private final Stage window;
|
private final Stage window;
|
||||||
private final KeychainManager keychainManager;
|
private final KeychainManager keychainManager;
|
||||||
|
|||||||
+1
-1
@@ -8,7 +8,7 @@ import dagger.multibindings.StringKey;
|
|||||||
import org.cryptomator.common.keychain.KeychainManager;
|
import org.cryptomator.common.keychain.KeychainManager;
|
||||||
import org.cryptomator.common.vaults.Vault;
|
import org.cryptomator.common.vaults.Vault;
|
||||||
import org.cryptomator.integrations.keychain.KeychainAccessException;
|
import org.cryptomator.integrations.keychain.KeychainAccessException;
|
||||||
import org.cryptomator.ui.forgetPassword.ForgetPasswordComponent;
|
import org.cryptomator.ui.forgetpassword.ForgetPasswordComponent;
|
||||||
import org.cryptomator.ui.keyloading.KeyLoading;
|
import org.cryptomator.ui.keyloading.KeyLoading;
|
||||||
import org.cryptomator.ui.keyloading.KeyLoadingScoped;
|
import org.cryptomator.ui.keyloading.KeyLoadingScoped;
|
||||||
import org.cryptomator.ui.keyloading.KeyLoadingStrategy;
|
import org.cryptomator.ui.keyloading.KeyLoadingStrategy;
|
||||||
|
|||||||
+1
-1
@@ -7,7 +7,7 @@ import org.cryptomator.common.vaults.Vault;
|
|||||||
import org.cryptomator.ui.common.FxController;
|
import org.cryptomator.ui.common.FxController;
|
||||||
import org.cryptomator.ui.common.WeakBindings;
|
import org.cryptomator.ui.common.WeakBindings;
|
||||||
import org.cryptomator.ui.controls.NiceSecurePasswordField;
|
import org.cryptomator.ui.controls.NiceSecurePasswordField;
|
||||||
import org.cryptomator.ui.forgetPassword.ForgetPasswordComponent;
|
import org.cryptomator.ui.forgetpassword.ForgetPasswordComponent;
|
||||||
import org.cryptomator.ui.keyloading.KeyLoading;
|
import org.cryptomator.ui.keyloading.KeyLoading;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import dagger.Provides;
|
|||||||
import dagger.multibindings.IntoMap;
|
import dagger.multibindings.IntoMap;
|
||||||
import org.cryptomator.common.vaults.Vault;
|
import org.cryptomator.common.vaults.Vault;
|
||||||
import org.cryptomator.ui.addvaultwizard.AddVaultWizardComponent;
|
import org.cryptomator.ui.addvaultwizard.AddVaultWizardComponent;
|
||||||
import org.cryptomator.ui.common.ErrorComponent;
|
import org.cryptomator.ui.error.ErrorComponent;
|
||||||
import org.cryptomator.ui.common.FxController;
|
import org.cryptomator.ui.common.FxController;
|
||||||
import org.cryptomator.ui.common.FxControllerKey;
|
import org.cryptomator.ui.common.FxControllerKey;
|
||||||
import org.cryptomator.ui.common.FxmlFile;
|
import org.cryptomator.ui.common.FxmlFile;
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package org.cryptomator.ui.preferences;
|
package org.cryptomator.ui.preferences;
|
||||||
|
|
||||||
import com.google.common.base.Strings;
|
|
||||||
import org.cryptomator.common.LicenseHolder;
|
import org.cryptomator.common.LicenseHolder;
|
||||||
import org.cryptomator.common.settings.Settings;
|
import org.cryptomator.common.settings.Settings;
|
||||||
import org.cryptomator.common.settings.UiTheme;
|
import org.cryptomator.common.settings.UiTheme;
|
||||||
@@ -35,6 +34,7 @@ public class InterfacePreferencesController implements FxController {
|
|||||||
private final ObjectProperty<SelectedPreferencesTab> selectedTabProperty;
|
private final ObjectProperty<SelectedPreferencesTab> selectedTabProperty;
|
||||||
private final LicenseHolder licenseHolder;
|
private final LicenseHolder licenseHolder;
|
||||||
private final ResourceBundle resourceBundle;
|
private final ResourceBundle resourceBundle;
|
||||||
|
private final SupportedLanguages supportedLanguages;
|
||||||
public ChoiceBox<UiTheme> themeChoiceBox;
|
public ChoiceBox<UiTheme> themeChoiceBox;
|
||||||
public CheckBox showMinimizeButtonCheckbox;
|
public CheckBox showMinimizeButtonCheckbox;
|
||||||
public CheckBox showTrayIconCheckbox;
|
public CheckBox showTrayIconCheckbox;
|
||||||
@@ -44,13 +44,14 @@ public class InterfacePreferencesController implements FxController {
|
|||||||
public RadioButton nodeOrientationRtl;
|
public RadioButton nodeOrientationRtl;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
InterfacePreferencesController(Settings settings, TrayMenuComponent trayMenu, ObjectProperty<SelectedPreferencesTab> selectedTabProperty, LicenseHolder licenseHolder, ResourceBundle resourceBundle) {
|
InterfacePreferencesController(Settings settings, SupportedLanguages supportedLanguages, TrayMenuComponent trayMenu, ObjectProperty<SelectedPreferencesTab> selectedTabProperty, LicenseHolder licenseHolder, ResourceBundle resourceBundle) {
|
||||||
this.settings = settings;
|
this.settings = settings;
|
||||||
this.trayMenuInitialized = trayMenu.isInitialized();
|
this.trayMenuInitialized = trayMenu.isInitialized();
|
||||||
this.trayMenuSupported = trayMenu.isSupported();
|
this.trayMenuSupported = trayMenu.isSupported();
|
||||||
this.selectedTabProperty = selectedTabProperty;
|
this.selectedTabProperty = selectedTabProperty;
|
||||||
this.licenseHolder = licenseHolder;
|
this.licenseHolder = licenseHolder;
|
||||||
this.resourceBundle = resourceBundle;
|
this.resourceBundle = resourceBundle;
|
||||||
|
this.supportedLanguages = supportedLanguages;
|
||||||
}
|
}
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
@@ -66,8 +67,7 @@ public class InterfacePreferencesController implements FxController {
|
|||||||
|
|
||||||
showTrayIconCheckbox.selectedProperty().bindBidirectional(settings.showTrayIcon());
|
showTrayIconCheckbox.selectedProperty().bindBidirectional(settings.showTrayIcon());
|
||||||
|
|
||||||
preferredLanguageChoiceBox.getItems().add(null);
|
preferredLanguageChoiceBox.getItems().addAll(supportedLanguages.getLanguageTags());
|
||||||
preferredLanguageChoiceBox.getItems().addAll(SupportedLanguages.LANGUAGAE_TAGS);
|
|
||||||
preferredLanguageChoiceBox.valueProperty().bindBidirectional(settings.languageProperty());
|
preferredLanguageChoiceBox.valueProperty().bindBidirectional(settings.languageProperty());
|
||||||
preferredLanguageChoiceBox.setConverter(new LanguageTagConverter(resourceBundle));
|
preferredLanguageChoiceBox.setConverter(new LanguageTagConverter(resourceBundle));
|
||||||
|
|
||||||
@@ -141,9 +141,7 @@ public class InterfacePreferencesController implements FxController {
|
|||||||
return resourceBundle.getString("preferences.interface.language.auto");
|
return resourceBundle.getString("preferences.interface.language.auto");
|
||||||
} else {
|
} else {
|
||||||
var locale = Locale.forLanguageTag(tag);
|
var locale = Locale.forLanguageTag(tag);
|
||||||
var lang = locale.getDisplayLanguage(locale);
|
return locale.getDisplayName();
|
||||||
var region = locale.getDisplayCountry(locale);
|
|
||||||
return lang + (Strings.isNullOrEmpty(region) ? "" : " (" + region + ")");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,12 +2,14 @@ package org.cryptomator.ui.preferences;
|
|||||||
|
|
||||||
import dagger.Lazy;
|
import dagger.Lazy;
|
||||||
import org.cryptomator.common.ObservableUtil;
|
import org.cryptomator.common.ObservableUtil;
|
||||||
|
import org.cryptomator.common.mount.MountModule;
|
||||||
import org.cryptomator.common.settings.Settings;
|
import org.cryptomator.common.settings.Settings;
|
||||||
import org.cryptomator.integrations.mount.MountCapability;
|
import org.cryptomator.integrations.mount.MountCapability;
|
||||||
import org.cryptomator.integrations.mount.MountService;
|
import org.cryptomator.integrations.mount.MountService;
|
||||||
import org.cryptomator.ui.common.FxController;
|
import org.cryptomator.ui.common.FxController;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Named;
|
||||||
import javafx.application.Application;
|
import javafx.application.Application;
|
||||||
import javafx.beans.binding.Bindings;
|
import javafx.beans.binding.Bindings;
|
||||||
import javafx.beans.binding.BooleanExpression;
|
import javafx.beans.binding.BooleanExpression;
|
||||||
@@ -19,11 +21,12 @@ import javafx.util.StringConverter;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.ResourceBundle;
|
import java.util.ResourceBundle;
|
||||||
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
||||||
@PreferencesScoped
|
@PreferencesScoped
|
||||||
public class VolumePreferencesController implements FxController {
|
public class VolumePreferencesController implements FxController {
|
||||||
|
|
||||||
private static final String DOCS_MOUNTING_URL = "https://docs.cryptomator.org/en/1.7/desktop/vault-mounting/";
|
private static final String DOCS_MOUNTING_URL = "https://docs.cryptomator.org/en/1.7/desktop/volume-type/";
|
||||||
|
|
||||||
private final Settings settings;
|
private final Settings settings;
|
||||||
private final ObservableValue<MountService> selectedMountService;
|
private final ObservableValue<MountService> selectedMountService;
|
||||||
@@ -33,6 +36,7 @@ public class VolumePreferencesController implements FxController {
|
|||||||
private final ObservableValue<Boolean> mountToDriveLetterSupported;
|
private final ObservableValue<Boolean> mountToDriveLetterSupported;
|
||||||
private final ObservableValue<Boolean> mountFlagsSupported;
|
private final ObservableValue<Boolean> mountFlagsSupported;
|
||||||
private final ObservableValue<Boolean> readonlySupported;
|
private final ObservableValue<Boolean> readonlySupported;
|
||||||
|
private final ObservableValue<Boolean> fuseRestartRequired;
|
||||||
private final Lazy<Application> application;
|
private final Lazy<Application> application;
|
||||||
private final List<MountService> mountProviders;
|
private final List<MountService> mountProviders;
|
||||||
public ChoiceBox<MountService> volumeTypeChoiceBox;
|
public ChoiceBox<MountService> volumeTypeChoiceBox;
|
||||||
@@ -40,7 +44,7 @@ public class VolumePreferencesController implements FxController {
|
|||||||
public Button loopbackPortApplyButton;
|
public Button loopbackPortApplyButton;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
VolumePreferencesController(Settings settings, Lazy<Application> application, List<MountService> mountProviders, ResourceBundle resourceBundle) {
|
VolumePreferencesController(Settings settings, Lazy<Application> application, List<MountService> mountProviders, @Named("FUPFMS") AtomicReference<MountService> firstUsedProblematicFuseMountService, ResourceBundle resourceBundle) {
|
||||||
this.settings = settings;
|
this.settings = settings;
|
||||||
this.application = application;
|
this.application = application;
|
||||||
this.mountProviders = mountProviders;
|
this.mountProviders = mountProviders;
|
||||||
@@ -53,6 +57,12 @@ public class VolumePreferencesController implements FxController {
|
|||||||
this.mountToDriveLetterSupported = selectedMountService.map(s -> s.hasCapability(MountCapability.MOUNT_AS_DRIVE_LETTER));
|
this.mountToDriveLetterSupported = selectedMountService.map(s -> s.hasCapability(MountCapability.MOUNT_AS_DRIVE_LETTER));
|
||||||
this.mountFlagsSupported = selectedMountService.map(s -> s.hasCapability(MountCapability.MOUNT_FLAGS));
|
this.mountFlagsSupported = selectedMountService.map(s -> s.hasCapability(MountCapability.MOUNT_FLAGS));
|
||||||
this.readonlySupported = selectedMountService.map(s -> s.hasCapability(MountCapability.READ_ONLY));
|
this.readonlySupported = selectedMountService.map(s -> s.hasCapability(MountCapability.READ_ONLY));
|
||||||
|
this.fuseRestartRequired = selectedMountService.map(s -> {//
|
||||||
|
return firstUsedProblematicFuseMountService.get() != null //
|
||||||
|
&& MountModule.isProblematicFuseService(s) //
|
||||||
|
&& !firstUsedProblematicFuseMountService.get().equals(s);
|
||||||
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void initialize() {
|
public void initialize() {
|
||||||
@@ -129,6 +139,14 @@ public class VolumePreferencesController implements FxController {
|
|||||||
return mountFlagsSupported.getValue();
|
return mountFlagsSupported.getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ObservableValue<Boolean> fuseRestartRequiredProperty() {
|
||||||
|
return fuseRestartRequired;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean getFuseRestartRequired() {
|
||||||
|
return fuseRestartRequired.getValue();
|
||||||
|
}
|
||||||
|
|
||||||
/* Helpers */
|
/* Helpers */
|
||||||
|
|
||||||
private class MountServiceConverter extends StringConverter<MountService> {
|
private class MountServiceConverter extends StringConverter<MountService> {
|
||||||
|
|||||||
@@ -38,16 +38,11 @@ public interface RecoveryKeyComponent {
|
|||||||
stage.show();
|
stage.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subcomponent.Builder
|
|
||||||
interface Builder {
|
|
||||||
|
|
||||||
@BindsInstance
|
@Subcomponent.Factory
|
||||||
Builder vault(@RecoveryKeyWindow Vault vault);
|
interface Factory {
|
||||||
|
|
||||||
@BindsInstance
|
RecoveryKeyComponent create(@BindsInstance @RecoveryKeyWindow Vault vault, @BindsInstance @Named("keyRecoveryOwner") Stage owner);
|
||||||
Builder owner(@Named("keyRecoveryOwner") Stage owner);
|
|
||||||
|
|
||||||
RecoveryKeyComponent build();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ public class RecoveryKeyFactory {
|
|||||||
* @throws IllegalArgumentException If the recoveryKey is invalid
|
* @throws IllegalArgumentException If the recoveryKey is invalid
|
||||||
* @apiNote This is a long-running operation and should be invoked in a background thread
|
* @apiNote This is a long-running operation and should be invoked in a background thread
|
||||||
*/
|
*/
|
||||||
public void resetPasswordWithRecoveryKey(Path vaultPath, String recoveryKey, CharSequence newPassword) throws IOException, IllegalArgumentException {
|
public void newMasterkeyFileWithPassphrase(Path vaultPath, String recoveryKey, CharSequence newPassword) throws IOException, IllegalArgumentException {
|
||||||
final byte[] rawKey = decodeRecoveryKey(recoveryKey);
|
final byte[] rawKey = decodeRecoveryKey(recoveryKey);
|
||||||
try (var masterkey = new Masterkey(rawKey)) {
|
try (var masterkey = new Masterkey(rawKey)) {
|
||||||
Path masterkeyPath = vaultPath.resolve(MASTERKEY_FILENAME);
|
Path masterkeyPath = vaultPath.resolve(MASTERKEY_FILENAME);
|
||||||
|
|||||||
@@ -13,8 +13,8 @@ import org.cryptomator.ui.common.FxControllerKey;
|
|||||||
import org.cryptomator.ui.common.FxmlFile;
|
import org.cryptomator.ui.common.FxmlFile;
|
||||||
import org.cryptomator.ui.common.FxmlLoaderFactory;
|
import org.cryptomator.ui.common.FxmlLoaderFactory;
|
||||||
import org.cryptomator.ui.common.FxmlScene;
|
import org.cryptomator.ui.common.FxmlScene;
|
||||||
import org.cryptomator.ui.common.NewPasswordController;
|
import org.cryptomator.ui.changepassword.NewPasswordController;
|
||||||
import org.cryptomator.ui.common.PasswordStrengthUtil;
|
import org.cryptomator.ui.changepassword.PasswordStrengthUtil;
|
||||||
import org.cryptomator.ui.common.StageFactory;
|
import org.cryptomator.ui.common.StageFactory;
|
||||||
|
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
@@ -140,6 +140,13 @@ abstract class RecoveryKeyModule {
|
|||||||
@FxControllerKey(RecoveryKeyResetPasswordSuccessController.class)
|
@FxControllerKey(RecoveryKeyResetPasswordSuccessController.class)
|
||||||
abstract FxController bindRecoveryKeyResetPasswordSuccessController(RecoveryKeyResetPasswordSuccessController controller);
|
abstract FxController bindRecoveryKeyResetPasswordSuccessController(RecoveryKeyResetPasswordSuccessController controller);
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@IntoMap
|
||||||
|
@FxControllerKey(RecoveryKeyValidateController.class)
|
||||||
|
static FxController bindRecoveryKeyValidateController(@RecoveryKeyWindow Vault vault, @RecoveryKeyWindow @Nullable VaultConfig.UnverifiedVaultConfig vaultConfig, @RecoveryKeyWindow StringProperty recoveryKey, RecoveryKeyFactory recoveryKeyFactory) {
|
||||||
|
return new RecoveryKeyValidateController(vault, vaultConfig, recoveryKey, recoveryKeyFactory);
|
||||||
|
}
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@IntoMap
|
@IntoMap
|
||||||
@FxControllerKey(NewPasswordController.class)
|
@FxControllerKey(NewPasswordController.class)
|
||||||
|
|||||||
@@ -1,14 +1,9 @@
|
|||||||
package org.cryptomator.ui.recoverykey;
|
package org.cryptomator.ui.recoverykey;
|
||||||
|
|
||||||
import com.google.common.base.CharMatcher;
|
|
||||||
import com.google.common.base.Strings;
|
|
||||||
import dagger.Lazy;
|
import dagger.Lazy;
|
||||||
import org.cryptomator.common.Nullable;
|
import org.cryptomator.common.Nullable;
|
||||||
import org.cryptomator.common.ObservableUtil;
|
|
||||||
import org.cryptomator.common.vaults.Vault;
|
import org.cryptomator.common.vaults.Vault;
|
||||||
import org.cryptomator.cryptofs.VaultConfig;
|
import org.cryptomator.cryptofs.VaultConfig;
|
||||||
import org.cryptomator.cryptofs.VaultConfigLoadException;
|
|
||||||
import org.cryptomator.cryptofs.VaultKeyInvalidException;
|
|
||||||
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;
|
||||||
@@ -16,96 +11,34 @@ import org.slf4j.Logger;
|
|||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javafx.beans.property.ObjectProperty;
|
import javafx.beans.Observable;
|
||||||
import javafx.beans.property.SimpleObjectProperty;
|
|
||||||
import javafx.beans.property.StringProperty;
|
import javafx.beans.property.StringProperty;
|
||||||
import javafx.beans.value.ObservableValue;
|
import javafx.beans.value.ObservableValue;
|
||||||
import javafx.fxml.FXML;
|
import javafx.fxml.FXML;
|
||||||
import javafx.scene.Scene;
|
import javafx.scene.Scene;
|
||||||
import javafx.scene.control.TextArea;
|
|
||||||
import javafx.scene.control.TextFormatter;
|
|
||||||
import javafx.scene.input.KeyCode;
|
|
||||||
import javafx.scene.input.KeyEvent;
|
|
||||||
import javafx.stage.Stage;
|
import javafx.stage.Stage;
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.ResourceBundle;
|
import java.util.ResourceBundle;
|
||||||
|
|
||||||
@RecoveryKeyScoped
|
@RecoveryKeyScoped
|
||||||
public class RecoveryKeyRecoverController implements FxController {
|
public class RecoveryKeyRecoverController implements FxController {
|
||||||
|
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(RecoveryKeyCreationController.class);
|
private static final Logger LOG = LoggerFactory.getLogger(RecoveryKeyCreationController.class);
|
||||||
private static final CharMatcher ALLOWED_CHARS = CharMatcher.inRange('a', 'z').or(CharMatcher.is(' '));
|
|
||||||
|
|
||||||
private final Stage window;
|
private final Stage window;
|
||||||
private final Vault vault;
|
|
||||||
private final VaultConfig.UnverifiedVaultConfig unverifiedVaultConfig;
|
|
||||||
private final StringProperty recoveryKey;
|
|
||||||
private final ObservableValue<Boolean> recoveryKeyCorrect;
|
|
||||||
private final ObservableValue<Boolean> recoveryKeyWrong;
|
|
||||||
private final ObservableValue<Boolean> recoveryKeyInvalid;
|
|
||||||
private final RecoveryKeyFactory recoveryKeyFactory;
|
|
||||||
private final ObjectProperty<RecoveryKeyState> recoveryKeyState;
|
|
||||||
private final Lazy<Scene> resetPasswordScene;
|
private final Lazy<Scene> resetPasswordScene;
|
||||||
private final AutoCompleter autoCompleter;
|
|
||||||
|
|
||||||
private volatile boolean isWrongKey;
|
@FXML
|
||||||
|
RecoveryKeyValidateController recoveryKeyValidateController;
|
||||||
public TextArea textarea;
|
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public RecoveryKeyRecoverController(@RecoveryKeyWindow Stage window, @RecoveryKeyWindow Vault vault, @RecoveryKeyWindow @Nullable VaultConfig.UnverifiedVaultConfig unverifiedVaultConfig, @RecoveryKeyWindow StringProperty recoveryKey, RecoveryKeyFactory recoveryKeyFactory, @FxmlScene(FxmlFile.RECOVERYKEY_RESET_PASSWORD) Lazy<Scene> resetPasswordScene, ResourceBundle resourceBundle) {
|
public RecoveryKeyRecoverController(@RecoveryKeyWindow Stage window, @RecoveryKeyWindow Vault vault, @RecoveryKeyWindow StringProperty recoveryKey, @FxmlScene(FxmlFile.RECOVERYKEY_RESET_PASSWORD) Lazy<Scene> resetPasswordScene, ResourceBundle resourceBundle) {
|
||||||
this.window = window;
|
this.window = window;
|
||||||
window.setTitle(resourceBundle.getString("recoveryKey.recover.title"));
|
window.setTitle(resourceBundle.getString("recoveryKey.recover.title"));
|
||||||
this.vault = vault;
|
|
||||||
this.unverifiedVaultConfig = unverifiedVaultConfig;
|
|
||||||
this.recoveryKey = recoveryKey;
|
|
||||||
this.recoveryKeyFactory = recoveryKeyFactory;
|
|
||||||
this.resetPasswordScene = resetPasswordScene;
|
this.resetPasswordScene = resetPasswordScene;
|
||||||
this.autoCompleter = new AutoCompleter(recoveryKeyFactory.getDictionary());
|
|
||||||
this.recoveryKeyState = new SimpleObjectProperty<>();
|
|
||||||
this.recoveryKeyCorrect = ObservableUtil.mapWithDefault(recoveryKeyState, RecoveryKeyState.CORRECT::equals, false);
|
|
||||||
this.recoveryKeyWrong = ObservableUtil.mapWithDefault(recoveryKeyState, RecoveryKeyState.WRONG::equals, false);
|
|
||||||
this.recoveryKeyInvalid = ObservableUtil.mapWithDefault(recoveryKeyState, RecoveryKeyState.INVALID::equals, false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
public void initialize() {
|
public void initialize() {
|
||||||
recoveryKey.bind(textarea.textProperty());
|
|
||||||
textarea.textProperty().addListener(((observable, oldValue, newValue) -> validateRecoveryKey()));
|
|
||||||
}
|
|
||||||
|
|
||||||
private TextFormatter.Change filterTextChange(TextFormatter.Change change) {
|
|
||||||
if (Strings.isNullOrEmpty(change.getText())) {
|
|
||||||
// pass-through caret/selection changes that don't affect the text
|
|
||||||
return change;
|
|
||||||
}
|
|
||||||
if (!ALLOWED_CHARS.matchesAllOf(change.getText())) {
|
|
||||||
return null; // reject change
|
|
||||||
}
|
|
||||||
|
|
||||||
String text = change.getControlNewText();
|
|
||||||
int caretPos = change.getCaretPosition();
|
|
||||||
if (caretPos == text.length() || text.charAt(caretPos) == ' ') { // are we at the end of a word?
|
|
||||||
int beginOfWord = Math.max(text.substring(0, caretPos).lastIndexOf(' ') + 1, 0);
|
|
||||||
String currentWord = text.substring(beginOfWord, caretPos);
|
|
||||||
Optional<String> suggestion = autoCompleter.autocomplete(currentWord);
|
|
||||||
if (suggestion.isPresent()) {
|
|
||||||
String completion = suggestion.get().substring(currentWord.length());
|
|
||||||
change.setText(change.getText() + completion);
|
|
||||||
change.setAnchor(caretPos + completion.length());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return change;
|
|
||||||
}
|
|
||||||
|
|
||||||
@FXML
|
|
||||||
public void onKeyPressed(KeyEvent keyEvent) {
|
|
||||||
if (keyEvent.getCode() == KeyCode.TAB && textarea.getAnchor() > textarea.getCaretPosition()) {
|
|
||||||
// apply autocompletion:
|
|
||||||
int pos = textarea.getAnchor();
|
|
||||||
textarea.insertText(pos, " ");
|
|
||||||
textarea.positionCaret(pos + 1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
@@ -118,85 +51,10 @@ public class RecoveryKeyRecoverController implements FxController {
|
|||||||
window.setScene(resetPasswordScene.get());
|
window.setScene(resetPasswordScene.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks, if vault config is signed with the given key.
|
|
||||||
*
|
|
||||||
* @param key byte array of possible signing key
|
|
||||||
* @return true, if vault config is signed with this key
|
|
||||||
*/
|
|
||||||
private boolean checkKeyAgainstVaultConfig(byte[] key) {
|
|
||||||
try {
|
|
||||||
var config = unverifiedVaultConfig.verify(key, unverifiedVaultConfig.allegedVaultVersion());
|
|
||||||
LOG.info("Provided recovery key matches vault config signature for vault {}", config.getId());
|
|
||||||
return true;
|
|
||||||
} catch (VaultKeyInvalidException e) {
|
|
||||||
LOG.debug("Provided recovery key does not match vault config signature.");
|
|
||||||
isWrongKey = true;
|
|
||||||
return false;
|
|
||||||
} catch (VaultConfigLoadException e) {
|
|
||||||
LOG.error("Failed to parse vault config", e);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void validateRecoveryKey() {
|
|
||||||
isWrongKey = false;
|
|
||||||
var valid = recoveryKeyFactory.validateRecoveryKey(recoveryKey.get(), unverifiedVaultConfig != null ? this::checkKeyAgainstVaultConfig : null);
|
|
||||||
if (valid) {
|
|
||||||
recoveryKeyState.set(RecoveryKeyState.CORRECT);
|
|
||||||
} else if (isWrongKey) { //set via side effect in checkKeyAgainstVaultConfig()
|
|
||||||
recoveryKeyState.set(RecoveryKeyState.WRONG);
|
|
||||||
} else {
|
|
||||||
recoveryKeyState.set(RecoveryKeyState.INVALID);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Getter/Setter */
|
/* Getter/Setter */
|
||||||
|
|
||||||
public Vault getVault() {
|
public RecoveryKeyValidateController getValidateController() {
|
||||||
return vault;
|
return recoveryKeyValidateController;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TextFormatter getRecoveryKeyTextFormatter() {
|
|
||||||
return new TextFormatter<>(this::filterTextChange);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ObservableValue<Boolean> recoveryKeyInvalidProperty() {
|
|
||||||
return recoveryKeyInvalid;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isRecoveryKeyInvalid() {
|
|
||||||
return recoveryKeyInvalid.getValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
public ObservableValue<Boolean> recoveryKeyCorrectProperty() {
|
|
||||||
return recoveryKeyCorrect;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isRecoveryKeyCorrect() {
|
|
||||||
return recoveryKeyCorrect.getValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
public ObservableValue<Boolean> recoveryKeyWrongProperty() {
|
|
||||||
return recoveryKeyWrong;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isRecoveryKeyWrong() {
|
|
||||||
return recoveryKeyWrong.getValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
private enum RecoveryKeyState {
|
|
||||||
/**
|
|
||||||
* Recovery key is a valid key and belongs to this vault
|
|
||||||
*/
|
|
||||||
CORRECT,
|
|
||||||
/**
|
|
||||||
* Recovery key is a valid key, but does not belong to this vault
|
|
||||||
*/
|
|
||||||
WRONG,
|
|
||||||
/**
|
|
||||||
* Recovery key is not a valid key.
|
|
||||||
*/
|
|
||||||
INVALID;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -5,7 +5,7 @@ import org.cryptomator.common.vaults.Vault;
|
|||||||
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;
|
||||||
import org.cryptomator.ui.common.NewPasswordController;
|
import org.cryptomator.ui.changepassword.NewPasswordController;
|
||||||
import org.cryptomator.ui.fxapp.FxApplicationWindows;
|
import org.cryptomator.ui.fxapp.FxApplicationWindows;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@@ -76,7 +76,7 @@ public class RecoveryKeyResetPasswordController implements FxController {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Void call() throws IOException, IllegalArgumentException {
|
protected Void call() throws IOException, IllegalArgumentException {
|
||||||
recoveryKeyFactory.resetPasswordWithRecoveryKey(vault.getPath(), recoveryKey.get(), newPasswordController.passwordField.getCharacters());
|
recoveryKeyFactory.newMasterkeyFileWithPassphrase(vault.getPath(), recoveryKey.get(), newPasswordController.passwordField.getCharacters());
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,180 @@
|
|||||||
|
package org.cryptomator.ui.recoverykey;
|
||||||
|
|
||||||
|
|
||||||
|
import com.google.common.base.CharMatcher;
|
||||||
|
import com.google.common.base.Strings;
|
||||||
|
import org.cryptomator.common.Nullable;
|
||||||
|
import org.cryptomator.common.ObservableUtil;
|
||||||
|
import org.cryptomator.common.vaults.Vault;
|
||||||
|
import org.cryptomator.cryptofs.VaultConfig;
|
||||||
|
import org.cryptomator.cryptofs.VaultConfigLoadException;
|
||||||
|
import org.cryptomator.cryptofs.VaultKeyInvalidException;
|
||||||
|
import org.cryptomator.ui.common.FxController;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import javafx.beans.property.ObjectProperty;
|
||||||
|
import javafx.beans.property.SimpleObjectProperty;
|
||||||
|
import javafx.beans.property.StringProperty;
|
||||||
|
import javafx.beans.value.ObservableValue;
|
||||||
|
import javafx.fxml.FXML;
|
||||||
|
import javafx.scene.control.TextArea;
|
||||||
|
import javafx.scene.control.TextFormatter;
|
||||||
|
import javafx.scene.input.KeyCode;
|
||||||
|
import javafx.scene.input.KeyEvent;
|
||||||
|
|
||||||
|
public class RecoveryKeyValidateController implements FxController {
|
||||||
|
|
||||||
|
private static final Logger LOG = LoggerFactory.getLogger(RecoveryKeyCreationController.class);
|
||||||
|
private static final CharMatcher ALLOWED_CHARS = CharMatcher.inRange('a', 'z').or(CharMatcher.is(' '));
|
||||||
|
|
||||||
|
private final Vault vault;
|
||||||
|
private final VaultConfig.UnverifiedVaultConfig unverifiedVaultConfig;
|
||||||
|
private final StringProperty recoveryKey;
|
||||||
|
private final ObservableValue<Boolean> recoveryKeyCorrect;
|
||||||
|
private final ObservableValue<Boolean> recoveryKeyWrong;
|
||||||
|
private final ObservableValue<Boolean> recoveryKeyInvalid;
|
||||||
|
private final RecoveryKeyFactory recoveryKeyFactory;
|
||||||
|
private final ObjectProperty<RecoveryKeyState> recoveryKeyState;
|
||||||
|
private final AutoCompleter autoCompleter;
|
||||||
|
|
||||||
|
private volatile boolean isWrongKey;
|
||||||
|
|
||||||
|
public TextArea textarea;
|
||||||
|
|
||||||
|
public RecoveryKeyValidateController(Vault vault, @Nullable VaultConfig.UnverifiedVaultConfig vaultConfig, StringProperty recoveryKey, RecoveryKeyFactory recoveryKeyFactory) {
|
||||||
|
this.vault = vault;
|
||||||
|
this.unverifiedVaultConfig = vaultConfig;
|
||||||
|
this.recoveryKey = recoveryKey;
|
||||||
|
this.recoveryKeyFactory = recoveryKeyFactory;
|
||||||
|
this.autoCompleter = new AutoCompleter(recoveryKeyFactory.getDictionary());
|
||||||
|
this.recoveryKeyState = new SimpleObjectProperty<>();
|
||||||
|
this.recoveryKeyCorrect = ObservableUtil.mapWithDefault(recoveryKeyState, RecoveryKeyState.CORRECT::equals, false);
|
||||||
|
this.recoveryKeyWrong = ObservableUtil.mapWithDefault(recoveryKeyState, RecoveryKeyState.WRONG::equals, false);
|
||||||
|
this.recoveryKeyInvalid = ObservableUtil.mapWithDefault(recoveryKeyState, RecoveryKeyState.INVALID::equals, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
public void initialize() {
|
||||||
|
recoveryKey.bind(textarea.textProperty());
|
||||||
|
textarea.textProperty().addListener(((observable, oldValue, newValue) -> validateRecoveryKey()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private TextFormatter.Change filterTextChange(TextFormatter.Change change) {
|
||||||
|
if (Strings.isNullOrEmpty(change.getText())) {
|
||||||
|
// pass-through caret/selection changes that don't affect the text
|
||||||
|
return change;
|
||||||
|
}
|
||||||
|
if (!ALLOWED_CHARS.matchesAllOf(change.getText())) {
|
||||||
|
return null; // reject change
|
||||||
|
}
|
||||||
|
|
||||||
|
String text = change.getControlNewText();
|
||||||
|
int caretPos = change.getCaretPosition();
|
||||||
|
if (caretPos == text.length() || text.charAt(caretPos) == ' ') { // are we at the end of a word?
|
||||||
|
int beginOfWord = Math.max(text.substring(0, caretPos).lastIndexOf(' ') + 1, 0);
|
||||||
|
String currentWord = text.substring(beginOfWord, caretPos);
|
||||||
|
var suggestion = autoCompleter.autocomplete(currentWord);
|
||||||
|
if (suggestion.isPresent()) {
|
||||||
|
String completion = suggestion.get().substring(currentWord.length());
|
||||||
|
change.setText(change.getText() + completion);
|
||||||
|
change.setAnchor(caretPos + completion.length());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return change;
|
||||||
|
}
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
public void onKeyPressed(KeyEvent keyEvent) {
|
||||||
|
if (keyEvent.getCode() == KeyCode.TAB && textarea.getAnchor() > textarea.getCaretPosition()) {
|
||||||
|
// apply autocompletion:
|
||||||
|
int pos = textarea.getAnchor();
|
||||||
|
textarea.insertText(pos, " ");
|
||||||
|
textarea.positionCaret(pos + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks, if vault config is signed with the given key.
|
||||||
|
*
|
||||||
|
* @param key byte array of possible signing key
|
||||||
|
* @return true, if vault config is signed with this key
|
||||||
|
*/
|
||||||
|
private boolean checkKeyAgainstVaultConfig(byte[] key) {
|
||||||
|
assert unverifiedVaultConfig != null;
|
||||||
|
try {
|
||||||
|
var config = unverifiedVaultConfig.verify(key, unverifiedVaultConfig.allegedVaultVersion());
|
||||||
|
LOG.info("Provided recovery key matches vault config signature for vault {}", config.getId());
|
||||||
|
return true;
|
||||||
|
} catch (VaultKeyInvalidException e) {
|
||||||
|
LOG.debug("Provided recovery key does not match vault config signature.");
|
||||||
|
isWrongKey = true;
|
||||||
|
return false;
|
||||||
|
} catch (VaultConfigLoadException e) {
|
||||||
|
LOG.error("Failed to parse vault config", e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void validateRecoveryKey() {
|
||||||
|
isWrongKey = false;
|
||||||
|
var valid = recoveryKeyFactory.validateRecoveryKey(recoveryKey.get(), unverifiedVaultConfig != null ? this::checkKeyAgainstVaultConfig : null);
|
||||||
|
if (valid) {
|
||||||
|
recoveryKeyState.set(RecoveryKeyState.CORRECT);
|
||||||
|
} else if (isWrongKey) { //set via side effect in checkKeyAgainstVaultConfig()
|
||||||
|
recoveryKeyState.set(RecoveryKeyState.WRONG);
|
||||||
|
} else {
|
||||||
|
recoveryKeyState.set(RecoveryKeyState.INVALID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Getter/Setter */
|
||||||
|
|
||||||
|
public Vault getVault() {
|
||||||
|
return vault;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TextFormatter getRecoveryKeyTextFormatter() {
|
||||||
|
return new TextFormatter<>(this::filterTextChange);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ObservableValue<Boolean> recoveryKeyInvalidProperty() {
|
||||||
|
return recoveryKeyInvalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isRecoveryKeyInvalid() {
|
||||||
|
return recoveryKeyInvalid.getValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ObservableValue<Boolean> recoveryKeyCorrectProperty() {
|
||||||
|
return recoveryKeyCorrect;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isRecoveryKeyCorrect() {
|
||||||
|
return recoveryKeyCorrect.getValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ObservableValue<Boolean> recoveryKeyWrongProperty() {
|
||||||
|
return recoveryKeyWrong;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isRecoveryKeyWrong() {
|
||||||
|
return recoveryKeyWrong.getValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum RecoveryKeyState {
|
||||||
|
/**
|
||||||
|
* Recovery key is a valid key and belongs to this vault
|
||||||
|
*/
|
||||||
|
CORRECT,
|
||||||
|
/**
|
||||||
|
* Recovery key is a valid key, but does not belong to this vault
|
||||||
|
*/
|
||||||
|
WRONG,
|
||||||
|
/**
|
||||||
|
* Recovery key is not a valid key.
|
||||||
|
*/
|
||||||
|
INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
package org.cryptomator.ui.vaultoptions;
|
||||||
|
|
||||||
|
import org.cryptomator.common.vaults.Vault;
|
||||||
|
import org.cryptomator.ui.common.FxController;
|
||||||
|
import org.cryptomator.ui.convertvault.ConvertVaultComponent;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javafx.stage.Stage;
|
||||||
|
|
||||||
|
public class HubOptionsController implements FxController {
|
||||||
|
|
||||||
|
private final Vault vault;
|
||||||
|
private final Stage window;
|
||||||
|
private final ConvertVaultComponent.Factory convertVaultFactory;
|
||||||
|
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public HubOptionsController(@VaultOptionsWindow Vault vault, @VaultOptionsWindow Stage window, ConvertVaultComponent.Factory convertVaultFactory) {
|
||||||
|
this.vault = vault;
|
||||||
|
this.window = window;
|
||||||
|
this.convertVaultFactory = convertVaultFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void startConversion() {
|
||||||
|
convertVaultFactory.create(vault,window).showHubToPasswordWindow();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,7 +4,7 @@ import org.cryptomator.common.keychain.KeychainManager;
|
|||||||
import org.cryptomator.common.vaults.Vault;
|
import org.cryptomator.common.vaults.Vault;
|
||||||
import org.cryptomator.ui.changepassword.ChangePasswordComponent;
|
import org.cryptomator.ui.changepassword.ChangePasswordComponent;
|
||||||
import org.cryptomator.ui.common.FxController;
|
import org.cryptomator.ui.common.FxController;
|
||||||
import org.cryptomator.ui.forgetPassword.ForgetPasswordComponent;
|
import org.cryptomator.ui.forgetpassword.ForgetPasswordComponent;
|
||||||
import org.cryptomator.ui.recoverykey.RecoveryKeyComponent;
|
import org.cryptomator.ui.recoverykey.RecoveryKeyComponent;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@@ -23,14 +23,14 @@ public class MasterkeyOptionsController implements FxController {
|
|||||||
private final Vault vault;
|
private final Vault vault;
|
||||||
private final Stage window;
|
private final Stage window;
|
||||||
private final ChangePasswordComponent.Builder changePasswordWindow;
|
private final ChangePasswordComponent.Builder changePasswordWindow;
|
||||||
private final RecoveryKeyComponent.Builder recoveryKeyWindow;
|
private final RecoveryKeyComponent.Factory recoveryKeyWindow;
|
||||||
private final ForgetPasswordComponent.Builder forgetPasswordWindow;
|
private final ForgetPasswordComponent.Builder forgetPasswordWindow;
|
||||||
private final KeychainManager keychain;
|
private final KeychainManager keychain;
|
||||||
private final ObservableValue<Boolean> passwordSaved;
|
private final ObservableValue<Boolean> passwordSaved;
|
||||||
|
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
MasterkeyOptionsController(@VaultOptionsWindow Vault vault, @VaultOptionsWindow Stage window, ChangePasswordComponent.Builder changePasswordWindow, RecoveryKeyComponent.Builder recoveryKeyWindow, ForgetPasswordComponent.Builder forgetPasswordWindow, KeychainManager keychain) {
|
MasterkeyOptionsController(@VaultOptionsWindow Vault vault, @VaultOptionsWindow Stage window, ChangePasswordComponent.Builder changePasswordWindow, RecoveryKeyComponent.Factory recoveryKeyWindow, ForgetPasswordComponent.Builder forgetPasswordWindow, KeychainManager keychain) {
|
||||||
this.vault = vault;
|
this.vault = vault;
|
||||||
this.window = window;
|
this.window = window;
|
||||||
this.changePasswordWindow = changePasswordWindow;
|
this.changePasswordWindow = changePasswordWindow;
|
||||||
@@ -51,12 +51,12 @@ public class MasterkeyOptionsController implements FxController {
|
|||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
public void showRecoveryKey() {
|
public void showRecoveryKey() {
|
||||||
recoveryKeyWindow.vault(vault).owner(window).build().showRecoveryKeyCreationWindow();
|
recoveryKeyWindow.create(vault, window).showRecoveryKeyCreationWindow();
|
||||||
}
|
}
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
public void showRecoverVaultDialog() {
|
public void showRecoverVaultDialog() {
|
||||||
recoveryKeyWindow.vault(vault).owner(window).build().showRecoveryKeyRecoverWindow();
|
recoveryKeyWindow.create(vault, window).showRecoveryKeyRecoverWindow();
|
||||||
}
|
}
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
|
|||||||
@@ -21,4 +21,9 @@ public enum SelectedVaultOptionsTab {
|
|||||||
*/
|
*/
|
||||||
KEY,
|
KEY,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show hub tab
|
||||||
|
*/
|
||||||
|
HUB
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ package org.cryptomator.ui.vaultoptions;
|
|||||||
|
|
||||||
import org.cryptomator.common.vaults.Vault;
|
import org.cryptomator.common.vaults.Vault;
|
||||||
import org.cryptomator.ui.common.FxController;
|
import org.cryptomator.ui.common.FxController;
|
||||||
|
import org.cryptomator.ui.keyloading.hub.HubKeyLoadingStrategy;
|
||||||
|
import org.cryptomator.ui.keyloading.masterkeyfile.MasterkeyFileLoadingStrategy;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
@@ -25,6 +27,7 @@ public class VaultOptionsController implements FxController {
|
|||||||
public Tab generalTab;
|
public Tab generalTab;
|
||||||
public Tab mountTab;
|
public Tab mountTab;
|
||||||
public Tab keyTab;
|
public Tab keyTab;
|
||||||
|
public Tab hubTab;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
VaultOptionsController(@VaultOptionsWindow Stage window, @VaultOptionsWindow Vault vault, ObjectProperty<SelectedVaultOptionsTab> selectedTabProperty) {
|
VaultOptionsController(@VaultOptionsWindow Stage window, @VaultOptionsWindow Vault vault, ObjectProperty<SelectedVaultOptionsTab> selectedTabProperty) {
|
||||||
@@ -38,9 +41,13 @@ public class VaultOptionsController implements FxController {
|
|||||||
window.setOnShowing(this::windowWillAppear);
|
window.setOnShowing(this::windowWillAppear);
|
||||||
selectedTabProperty.addListener(observable -> this.selectChosenTab());
|
selectedTabProperty.addListener(observable -> this.selectChosenTab());
|
||||||
tabPane.getSelectionModel().selectedItemProperty().addListener(observable -> this.selectedTabChanged());
|
tabPane.getSelectionModel().selectedItemProperty().addListener(observable -> this.selectedTabChanged());
|
||||||
if(!vault.getVaultConfigCache().getUnchecked().getKeyId().getScheme().equals("masterkeyfile")){
|
var vaultScheme = vault.getVaultConfigCache().getUnchecked().getKeyId().getScheme();
|
||||||
|
if(!vaultScheme.equals(MasterkeyFileLoadingStrategy.SCHEME)){
|
||||||
tabPane.getTabs().remove(keyTab);
|
tabPane.getTabs().remove(keyTab);
|
||||||
}
|
}
|
||||||
|
if(!(vaultScheme.equals(HubKeyLoadingStrategy.SCHEME_HUB_HTTP) || vaultScheme.equals(HubKeyLoadingStrategy.SCHEME_HUB_HTTPS))){
|
||||||
|
tabPane.getTabs().remove(hubTab);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void selectChosenTab() {
|
private void selectChosenTab() {
|
||||||
@@ -53,6 +60,7 @@ public class VaultOptionsController implements FxController {
|
|||||||
case ANY, GENERAL -> generalTab;
|
case ANY, GENERAL -> generalTab;
|
||||||
case MOUNT -> mountTab;
|
case MOUNT -> mountTab;
|
||||||
case KEY -> keyTab;
|
case KEY -> keyTab;
|
||||||
|
case HUB -> hubTab;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,8 @@ import org.cryptomator.ui.common.FxmlFile;
|
|||||||
import org.cryptomator.ui.common.FxmlLoaderFactory;
|
import org.cryptomator.ui.common.FxmlLoaderFactory;
|
||||||
import org.cryptomator.ui.common.FxmlScene;
|
import org.cryptomator.ui.common.FxmlScene;
|
||||||
import org.cryptomator.ui.common.StageFactory;
|
import org.cryptomator.ui.common.StageFactory;
|
||||||
import org.cryptomator.ui.forgetPassword.ForgetPasswordComponent;
|
import org.cryptomator.ui.convertvault.ConvertVaultComponent;
|
||||||
|
import org.cryptomator.ui.forgetpassword.ForgetPasswordComponent;
|
||||||
import org.cryptomator.ui.fxapp.PrimaryStage;
|
import org.cryptomator.ui.fxapp.PrimaryStage;
|
||||||
import org.cryptomator.ui.recoverykey.RecoveryKeyComponent;
|
import org.cryptomator.ui.recoverykey.RecoveryKeyComponent;
|
||||||
|
|
||||||
@@ -26,7 +27,7 @@ import javafx.stage.Stage;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.ResourceBundle;
|
import java.util.ResourceBundle;
|
||||||
|
|
||||||
@Module(subcomponents = {ChangePasswordComponent.class, RecoveryKeyComponent.class, ForgetPasswordComponent.class})
|
@Module(subcomponents = {ChangePasswordComponent.class, RecoveryKeyComponent.class, ForgetPasswordComponent.class, ConvertVaultComponent.class})
|
||||||
abstract class VaultOptionsModule {
|
abstract class VaultOptionsModule {
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@@ -84,4 +85,9 @@ abstract class VaultOptionsModule {
|
|||||||
@IntoMap
|
@IntoMap
|
||||||
@FxControllerKey(MasterkeyOptionsController.class)
|
@FxControllerKey(MasterkeyOptionsController.class)
|
||||||
abstract FxController bindMasterkeyOptionsController(MasterkeyOptionsController controller);
|
abstract FxController bindMasterkeyOptionsController(MasterkeyOptionsController controller);
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
@IntoMap
|
||||||
|
@FxControllerKey(HubOptionsController.class)
|
||||||
|
abstract FxController bindHubOptionsController(HubOptionsController controller);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -116,6 +116,10 @@
|
|||||||
-fx-font-size: 0.64em;
|
-fx-font-size: 0.64em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.label-red {
|
||||||
|
-fx-text-fill: RED_5;
|
||||||
|
}
|
||||||
|
|
||||||
.text-flow > * {
|
.text-flow > * {
|
||||||
-fx-fill: TEXT_FILL;
|
-fx-fill: TEXT_FILL;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -116,6 +116,10 @@
|
|||||||
-fx-font-size: 0.64em;
|
-fx-font-size: 0.64em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.label-red {
|
||||||
|
-fx-text-fill: RED_5;
|
||||||
|
}
|
||||||
|
|
||||||
.text-flow > * {
|
.text-flow > * {
|
||||||
-fx-fill: TEXT_FILL;
|
-fx-fill: TEXT_FILL;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
|
<?import org.cryptomator.ui.controls.FontAwesome5Spinner?>
|
||||||
|
<?import javafx.geometry.Insets?>
|
||||||
|
<?import javafx.scene.control.Button?>
|
||||||
|
<?import javafx.scene.control.ButtonBar?>
|
||||||
|
<?import javafx.scene.layout.Region?>
|
||||||
|
<?import javafx.scene.layout.VBox?>
|
||||||
|
<VBox xmlns:fx="http://javafx.com/fxml"
|
||||||
|
xmlns="http://javafx.com/javafx"
|
||||||
|
fx:controller="org.cryptomator.ui.convertvault.HubToPasswordConvertController"
|
||||||
|
minWidth="400"
|
||||||
|
maxWidth="400"
|
||||||
|
minHeight="145"
|
||||||
|
spacing="12"
|
||||||
|
alignment="TOP_CENTER">
|
||||||
|
<padding>
|
||||||
|
<Insets topRightBottomLeft="12"/>
|
||||||
|
</padding>
|
||||||
|
<children>
|
||||||
|
<fx:include fx:id="newPassword" source="new_password.fxml"/>
|
||||||
|
|
||||||
|
<Region VBox.vgrow="ALWAYS"/>
|
||||||
|
|
||||||
|
<VBox alignment="BOTTOM_CENTER" VBox.vgrow="ALWAYS">
|
||||||
|
<ButtonBar buttonMinWidth="120" buttonOrder="+CI">
|
||||||
|
<buttons>
|
||||||
|
<Button text="%generic.button.cancel" ButtonBar.buttonData="CANCEL_CLOSE" cancelButton="true" onAction="#close"/>
|
||||||
|
<Button fx:id="convertBtn" ButtonBar.buttonData="FINISH" defaultButton="true" onAction="#convert"> <!-- for button logic, see controller -->
|
||||||
|
<graphic>
|
||||||
|
<FontAwesome5Spinner glyphSize="12"/>
|
||||||
|
</graphic>
|
||||||
|
</Button>
|
||||||
|
</buttons>
|
||||||
|
</ButtonBar>
|
||||||
|
</VBox>
|
||||||
|
</children>
|
||||||
|
</VBox>
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
|
<?import javafx.scene.layout.*?>
|
||||||
|
|
||||||
|
<?import javafx.geometry.Insets?>
|
||||||
|
<?import javafx.scene.control.ButtonBar?>
|
||||||
|
<?import javafx.scene.control.Button?>
|
||||||
|
<VBox xmlns:fx="http://javafx.com/fxml"
|
||||||
|
xmlns="http://javafx.com/javafx"
|
||||||
|
fx:controller="org.cryptomator.ui.convertvault.HubToPasswordStartController"
|
||||||
|
minWidth="400"
|
||||||
|
maxWidth="400"
|
||||||
|
minHeight="145"
|
||||||
|
spacing="12"
|
||||||
|
alignment="TOP_CENTER">
|
||||||
|
<padding>
|
||||||
|
<Insets topRightBottomLeft="12"/>
|
||||||
|
</padding>
|
||||||
|
<children>
|
||||||
|
<fx:include fx:id="recoveryKeyValidate" source="recoverykey_validate.fxml"/>
|
||||||
|
|
||||||
|
<Region VBox.vgrow="ALWAYS"/>
|
||||||
|
|
||||||
|
<VBox alignment="BOTTOM_CENTER" VBox.vgrow="ALWAYS">
|
||||||
|
<ButtonBar buttonMinWidth="120" buttonOrder="+CX">
|
||||||
|
<buttons>
|
||||||
|
<Button text="%generic.button.cancel" ButtonBar.buttonData="CANCEL_CLOSE" cancelButton="true" onAction="#close"/>
|
||||||
|
<Button text="%generic.button.next" ButtonBar.buttonData="NEXT_FORWARD" defaultButton="true" onAction="#next" disable="${!controller.validateController.recoveryKeyCorrect}"/>
|
||||||
|
</buttons>
|
||||||
|
</ButtonBar>
|
||||||
|
</VBox>
|
||||||
|
</children>
|
||||||
|
</VBox>
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
|
<?import org.cryptomator.ui.controls.FontAwesome5IconView?>
|
||||||
|
<?import org.cryptomator.ui.controls.FormattedLabel?>
|
||||||
|
<?import javafx.geometry.Insets?>
|
||||||
|
<?import javafx.scene.control.Button?>
|
||||||
|
<?import javafx.scene.control.ButtonBar?>
|
||||||
|
<?import javafx.scene.layout.HBox?>
|
||||||
|
<?import javafx.scene.layout.Region?>
|
||||||
|
<?import javafx.scene.layout.StackPane?>
|
||||||
|
<?import javafx.scene.layout.VBox?>
|
||||||
|
<?import javafx.scene.shape.Circle?>
|
||||||
|
<?import javafx.scene.control.Label?>
|
||||||
|
<?import javafx.scene.Group?>
|
||||||
|
<HBox xmlns:fx="http://javafx.com/fxml"
|
||||||
|
xmlns="http://javafx.com/javafx"
|
||||||
|
fx:controller="org.cryptomator.ui.convertvault.HubToPasswordSuccessController"
|
||||||
|
minWidth="400"
|
||||||
|
maxWidth="400"
|
||||||
|
minHeight="145"
|
||||||
|
spacing="12"
|
||||||
|
alignment="TOP_LEFT">
|
||||||
|
<padding>
|
||||||
|
<Insets topRightBottomLeft="12"/>
|
||||||
|
</padding>
|
||||||
|
<children>
|
||||||
|
<Group>
|
||||||
|
<StackPane>
|
||||||
|
<padding>
|
||||||
|
<Insets topRightBottomLeft="6"/>
|
||||||
|
</padding>
|
||||||
|
<Circle styleClass="glyph-icon-primary" radius="24"/>
|
||||||
|
<FontAwesome5IconView styleClass="glyph-icon-white" glyph="CHECK" glyphSize="24"/>
|
||||||
|
</StackPane>
|
||||||
|
</Group>
|
||||||
|
|
||||||
|
<VBox HBox.hgrow="ALWAYS">
|
||||||
|
<Label styleClass="label-large" text="%convertVault.success.message" wrapText="true" textAlignment="LEFT">
|
||||||
|
<padding>
|
||||||
|
<Insets bottom="6" top="6"/>
|
||||||
|
</padding>
|
||||||
|
</Label>
|
||||||
|
|
||||||
|
<Label text="%convertVault.hubToPassword.success.description" wrapText="true" textAlignment="LEFT"/>
|
||||||
|
|
||||||
|
<Region VBox.vgrow="ALWAYS" minHeight="18"/>
|
||||||
|
<ButtonBar buttonMinWidth="120" buttonOrder="+C">
|
||||||
|
<buttons>
|
||||||
|
<Button text="%generic.button.close" ButtonBar.buttonData="CANCEL_CLOSE" defaultButton="true" cancelButton="true" onAction="#close"/>
|
||||||
|
</buttons>
|
||||||
|
</ButtonBar>
|
||||||
|
</VBox>
|
||||||
|
|
||||||
|
</children>
|
||||||
|
</HBox>
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
<?import javafx.scene.shape.Circle?>
|
<?import javafx.scene.shape.Circle?>
|
||||||
<VBox xmlns:fx="http://javafx.com/fxml"
|
<VBox xmlns:fx="http://javafx.com/fxml"
|
||||||
xmlns="http://javafx.com/javafx"
|
xmlns="http://javafx.com/javafx"
|
||||||
fx:controller="org.cryptomator.ui.common.ErrorController"
|
fx:controller="org.cryptomator.ui.error.ErrorController"
|
||||||
prefWidth="450"
|
prefWidth="450"
|
||||||
prefHeight="450"
|
prefHeight="450"
|
||||||
spacing="18"
|
spacing="18"
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
<?import javafx.scene.layout.Region?>
|
<?import javafx.scene.layout.Region?>
|
||||||
<HBox xmlns:fx="http://javafx.com/fxml"
|
<HBox xmlns:fx="http://javafx.com/fxml"
|
||||||
xmlns="http://javafx.com/javafx"
|
xmlns="http://javafx.com/javafx"
|
||||||
fx:controller="org.cryptomator.ui.forgetPassword.ForgetPasswordController"
|
fx:controller="org.cryptomator.ui.forgetpassword.ForgetPasswordController"
|
||||||
minWidth="400"
|
minWidth="400"
|
||||||
maxWidth="400"
|
maxWidth="400"
|
||||||
minHeight="145"
|
minHeight="145"
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
<?import javafx.scene.layout.VBox?>
|
<?import javafx.scene.layout.VBox?>
|
||||||
<VBox xmlns:fx="http://javafx.com/fxml"
|
<VBox xmlns:fx="http://javafx.com/fxml"
|
||||||
xmlns="http://javafx.com/javafx"
|
xmlns="http://javafx.com/javafx"
|
||||||
fx:controller="org.cryptomator.ui.common.NewPasswordController"
|
fx:controller="org.cryptomator.ui.changepassword.NewPasswordController"
|
||||||
spacing="6"
|
spacing="6"
|
||||||
alignment="CENTER_LEFT">
|
alignment="CENTER_LEFT">
|
||||||
<fx:define>
|
<fx:define>
|
||||||
|
|||||||
@@ -8,9 +8,9 @@
|
|||||||
<?import javafx.scene.control.Hyperlink?>
|
<?import javafx.scene.control.Hyperlink?>
|
||||||
<?import javafx.scene.control.Label?>
|
<?import javafx.scene.control.Label?>
|
||||||
<?import javafx.scene.control.Separator?>
|
<?import javafx.scene.control.Separator?>
|
||||||
|
<?import javafx.scene.control.Tooltip?>
|
||||||
<?import javafx.scene.layout.HBox?>
|
<?import javafx.scene.layout.HBox?>
|
||||||
<?import javafx.scene.layout.VBox?>
|
<?import javafx.scene.layout.VBox?>
|
||||||
<?import javafx.scene.control.Tooltip?>
|
|
||||||
<VBox xmlns:fx="http://javafx.com/fxml"
|
<VBox xmlns:fx="http://javafx.com/fxml"
|
||||||
xmlns="http://javafx.com/javafx"
|
xmlns="http://javafx.com/javafx"
|
||||||
fx:controller="org.cryptomator.ui.preferences.VolumePreferencesController"
|
fx:controller="org.cryptomator.ui.preferences.VolumePreferencesController"
|
||||||
@@ -32,6 +32,8 @@
|
|||||||
</Hyperlink>
|
</Hyperlink>
|
||||||
</HBox>
|
</HBox>
|
||||||
|
|
||||||
|
<Label styleClass="label-red" text="%preferences.volume.fuseRestartRequired" visible="${controller.fuseRestartRequired}" managed="${controller.fuseRestartRequired}"/>
|
||||||
|
|
||||||
<HBox spacing="12" alignment="CENTER_LEFT" visible="${controller.loopbackPortSupported}" managed="${controller.loopbackPortSupported}">
|
<HBox spacing="12" alignment="CENTER_LEFT" visible="${controller.loopbackPortSupported}" managed="${controller.loopbackPortSupported}">
|
||||||
<Label text="%preferences.volume.tcp.port"/>
|
<Label text="%preferences.volume.tcp.port"/>
|
||||||
<NumericTextField fx:id="loopbackPortField"/>
|
<NumericTextField fx:id="loopbackPortField"/>
|
||||||
|
|||||||
@@ -1,16 +1,10 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
<?import org.cryptomator.ui.controls.FontAwesome5IconView?>
|
|
||||||
<?import org.cryptomator.ui.controls.FormattedLabel?>
|
|
||||||
<?import javafx.geometry.Insets?>
|
<?import javafx.geometry.Insets?>
|
||||||
<?import javafx.scene.control.Button?>
|
<?import javafx.scene.control.Button?>
|
||||||
<?import javafx.scene.control.ButtonBar?>
|
<?import javafx.scene.control.ButtonBar?>
|
||||||
<?import javafx.scene.control.Label?>
|
|
||||||
<?import javafx.scene.control.TextArea?>
|
|
||||||
<?import javafx.scene.layout.Region?>
|
<?import javafx.scene.layout.Region?>
|
||||||
<?import javafx.scene.layout.VBox?>
|
<?import javafx.scene.layout.VBox?>
|
||||||
<?import javafx.scene.layout.StackPane?>
|
|
||||||
<?import javafx.scene.Group?>
|
|
||||||
<VBox xmlns:fx="http://javafx.com/fxml"
|
<VBox xmlns:fx="http://javafx.com/fxml"
|
||||||
xmlns="http://javafx.com/javafx"
|
xmlns="http://javafx.com/javafx"
|
||||||
fx:controller="org.cryptomator.ui.recoverykey.RecoveryKeyRecoverController"
|
fx:controller="org.cryptomator.ui.recoverykey.RecoveryKeyRecoverController"
|
||||||
@@ -23,32 +17,8 @@
|
|||||||
<Insets topRightBottomLeft="12"/>
|
<Insets topRightBottomLeft="12"/>
|
||||||
</padding>
|
</padding>
|
||||||
<children>
|
<children>
|
||||||
<FormattedLabel format="%recoveryKey.recover.prompt" arg1="${controller.vault.displayName}" wrapText="true"/>
|
|
||||||
|
|
||||||
<TextArea wrapText="true" prefRowCount="4" fx:id="textarea" textFormatter="${controller.recoveryKeyTextFormatter}" onKeyPressed="#onKeyPressed"/>
|
<fx:include fx:id="recoveryKeyValidate" source="recoverykey_validate.fxml"/>
|
||||||
|
|
||||||
<StackPane>
|
|
||||||
<Label text="Just some Filler" visible="false" graphicTextGap="6">
|
|
||||||
<graphic>
|
|
||||||
<FontAwesome5IconView glyph="ANCHOR"/>
|
|
||||||
</graphic>
|
|
||||||
</Label>
|
|
||||||
<Label text="%recoveryKey.recover.correctKey" graphicTextGap="6" contentDisplay="LEFT" visible="${(!textarea.text.empty) && controller.recoveryKeyCorrect}">
|
|
||||||
<graphic>
|
|
||||||
<FontAwesome5IconView glyph="CHECK"/>
|
|
||||||
</graphic>
|
|
||||||
</Label>
|
|
||||||
<Label text="%recoveryKey.recover.wrongKey" graphicTextGap="6" contentDisplay="LEFT" visible="${(!textarea.text.empty) && controller.recoveryKeyWrong}">
|
|
||||||
<graphic>
|
|
||||||
<FontAwesome5IconView glyph="TIMES" styleClass="glyph-icon-red"/>
|
|
||||||
</graphic>
|
|
||||||
</Label>
|
|
||||||
<Label text="%recoveryKey.recover.invalidKey" graphicTextGap="6" contentDisplay="LEFT" visible="${(!textarea.text.empty) && controller.recoveryKeyInvalid}">
|
|
||||||
<graphic>
|
|
||||||
<FontAwesome5IconView glyph="TIMES" styleClass="glyph-icon-red"/>
|
|
||||||
</graphic>
|
|
||||||
</Label>
|
|
||||||
</StackPane>
|
|
||||||
|
|
||||||
<Region VBox.vgrow="ALWAYS"/>
|
<Region VBox.vgrow="ALWAYS"/>
|
||||||
|
|
||||||
@@ -56,7 +26,7 @@
|
|||||||
<ButtonBar buttonMinWidth="120" buttonOrder="+CX">
|
<ButtonBar buttonMinWidth="120" buttonOrder="+CX">
|
||||||
<buttons>
|
<buttons>
|
||||||
<Button text="%generic.button.cancel" ButtonBar.buttonData="CANCEL_CLOSE" cancelButton="true" onAction="#close"/>
|
<Button text="%generic.button.cancel" ButtonBar.buttonData="CANCEL_CLOSE" cancelButton="true" onAction="#close"/>
|
||||||
<Button text="%generic.button.next" ButtonBar.buttonData="NEXT_FORWARD" defaultButton="true" onAction="#recover" disable="${!controller.recoveryKeyCorrect}"/>
|
<Button text="%generic.button.next" ButtonBar.buttonData="NEXT_FORWARD" defaultButton="true" onAction="#recover" disable="${!controller.validateController.recoveryKeyCorrect}"/>
|
||||||
</buttons>
|
</buttons>
|
||||||
</ButtonBar>
|
</ButtonBar>
|
||||||
</VBox>
|
</VBox>
|
||||||
|
|||||||
@@ -0,0 +1,49 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
|
<?import org.cryptomator.ui.controls.FontAwesome5IconView?>
|
||||||
|
<?import org.cryptomator.ui.controls.FormattedLabel?>
|
||||||
|
<?import javafx.geometry.Insets?>
|
||||||
|
<?import javafx.scene.control.Label?>
|
||||||
|
<?import javafx.scene.control.TextArea?>
|
||||||
|
<?import javafx.scene.layout.StackPane?>
|
||||||
|
<?import javafx.scene.layout.VBox?>
|
||||||
|
<VBox xmlns:fx="http://javafx.com/fxml"
|
||||||
|
xmlns="http://javafx.com/javafx"
|
||||||
|
fx:controller="org.cryptomator.ui.recoverykey.RecoveryKeyValidateController"
|
||||||
|
minWidth="400"
|
||||||
|
maxWidth="400"
|
||||||
|
minHeight="145"
|
||||||
|
spacing="12"
|
||||||
|
alignment="TOP_CENTER">
|
||||||
|
<padding>
|
||||||
|
<Insets topRightBottomLeft="12"/>
|
||||||
|
</padding>
|
||||||
|
<children>
|
||||||
|
<FormattedLabel format="%recoveryKey.recover.prompt" arg1="${controller.vault.displayName}" wrapText="true"/>
|
||||||
|
|
||||||
|
<TextArea wrapText="true" prefRowCount="4" fx:id="textarea" textFormatter="${controller.recoveryKeyTextFormatter}" onKeyPressed="#onKeyPressed"/>
|
||||||
|
|
||||||
|
<StackPane>
|
||||||
|
<Label text="Just some Filler" visible="false" graphicTextGap="6">
|
||||||
|
<graphic>
|
||||||
|
<FontAwesome5IconView glyph="ANCHOR"/>
|
||||||
|
</graphic>
|
||||||
|
</Label>
|
||||||
|
<Label text="%recoveryKey.recover.correctKey" graphicTextGap="6" contentDisplay="LEFT" visible="${(!textarea.text.empty) && controller.recoveryKeyCorrect}">
|
||||||
|
<graphic>
|
||||||
|
<FontAwesome5IconView glyph="CHECK"/>
|
||||||
|
</graphic>
|
||||||
|
</Label>
|
||||||
|
<Label text="%recoveryKey.recover.wrongKey" graphicTextGap="6" contentDisplay="LEFT" visible="${(!textarea.text.empty) && controller.recoveryKeyWrong}">
|
||||||
|
<graphic>
|
||||||
|
<FontAwesome5IconView glyph="TIMES" styleClass="glyph-icon-red"/>
|
||||||
|
</graphic>
|
||||||
|
</Label>
|
||||||
|
<Label text="%recoveryKey.recover.invalidKey" graphicTextGap="6" contentDisplay="LEFT" visible="${(!textarea.text.empty) && controller.recoveryKeyInvalid}">
|
||||||
|
<graphic>
|
||||||
|
<FontAwesome5IconView glyph="TIMES" styleClass="glyph-icon-red"/>
|
||||||
|
</graphic>
|
||||||
|
</Label>
|
||||||
|
</StackPane>
|
||||||
|
</children>
|
||||||
|
</VBox>
|
||||||
@@ -36,5 +36,13 @@
|
|||||||
<fx:include source="vault_options_masterkey.fxml"/>
|
<fx:include source="vault_options_masterkey.fxml"/>
|
||||||
</content>
|
</content>
|
||||||
</Tab>
|
</Tab>
|
||||||
|
<Tab fx:id="hubTab" id="HUB" text="%vaultOptions.hub"> <!-- is removed in controller, when config.keyid.scheme is not cryptomator-hub -->
|
||||||
|
<graphic>
|
||||||
|
<FontAwesome5IconView glyph="KEY"/>
|
||||||
|
</graphic>
|
||||||
|
<content>
|
||||||
|
<fx:include source="vault_options_hub.fxml"/>
|
||||||
|
</content>
|
||||||
|
</Tab>
|
||||||
</tabs>
|
</tabs>
|
||||||
</TabPane>
|
</TabPane>
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
|
<?import org.cryptomator.ui.controls.FontAwesome5IconView?>
|
||||||
|
<?import javafx.geometry.Insets?>
|
||||||
|
<?import javafx.scene.control.Button?>
|
||||||
|
<?import javafx.scene.layout.VBox?>
|
||||||
|
<?import javafx.scene.control.Label?>
|
||||||
|
<VBox xmlns:fx="http://javafx.com/fxml"
|
||||||
|
xmlns="http://javafx.com/javafx"
|
||||||
|
fx:controller="org.cryptomator.ui.vaultoptions.HubOptionsController"
|
||||||
|
spacing="6"
|
||||||
|
alignment="TOP_CENTER">
|
||||||
|
<padding>
|
||||||
|
<Insets topRightBottomLeft="12"/>
|
||||||
|
</padding>
|
||||||
|
|
||||||
|
<Label maxWidth="-Infinity" text="%vaultOptions.hub.convertInfo" wrapText="true"/>
|
||||||
|
<VBox spacing="6" alignment="CENTER">
|
||||||
|
<Button fx:id="convertHubToPasswordButton" text="%vaultOptions.hub.convertBtn" onAction="#startConversion" maxWidth="Infinity">
|
||||||
|
<graphic>
|
||||||
|
<FontAwesome5IconView glyph="EXCHANGE_ALT"/>
|
||||||
|
</graphic>
|
||||||
|
</Button>
|
||||||
|
</VBox>
|
||||||
|
</VBox>
|
||||||
@@ -275,9 +275,10 @@ preferences.interface.showMinimizeButton=Show minimize button
|
|||||||
preferences.interface.showTrayIcon=Show tray icon (requires restart)
|
preferences.interface.showTrayIcon=Show tray icon (requires restart)
|
||||||
## Volume
|
## Volume
|
||||||
preferences.volume=Virtual Drive
|
preferences.volume=Virtual Drive
|
||||||
preferences.volume.type=Volume Type (requires restart)
|
preferences.volume.type=Volume Type
|
||||||
preferences.volume.type.automatic=Automatic
|
preferences.volume.type.automatic=Automatic
|
||||||
preferences.volume.docsTooltip=Open the documentation to learn more about the different volume types.
|
preferences.volume.docsTooltip=Open the documentation to learn more about the different volume types.
|
||||||
|
preferences.volume.fuseRestartRequired=To apply the changes, Cryptomator needs to be restarted.
|
||||||
preferences.volume.tcp.port=TCP Port
|
preferences.volume.tcp.port=TCP Port
|
||||||
preferences.volume.supportedFeatures=The chosen volume type supports the following features:
|
preferences.volume.supportedFeatures=The chosen volume type supports the following features:
|
||||||
preferences.volume.feature.mountAuto=Automatic mount point selection
|
preferences.volume.feature.mountAuto=Automatic mount point selection
|
||||||
@@ -307,27 +308,27 @@ stats.title=Statistics for %s
|
|||||||
stats.cacheHitRate=Cache Hit Rate
|
stats.cacheHitRate=Cache Hit Rate
|
||||||
## Read
|
## Read
|
||||||
stats.read.throughput.idle=Read: idle
|
stats.read.throughput.idle=Read: idle
|
||||||
stats.read.throughput.kibs=Read: %.2f kiB/s
|
stats.read.throughput.kibs=Read: %.2f KiB/s
|
||||||
stats.read.throughput.mibs=Read: %.2f MiB/s
|
stats.read.throughput.mibs=Read: %.2f MiB/s
|
||||||
stats.read.total.data.none=Data read: -
|
stats.read.total.data.none=Data read: -
|
||||||
stats.read.total.data.kib=Data read: %.1f kiB
|
stats.read.total.data.kib=Data read: %.1f KiB
|
||||||
stats.read.total.data.mib=Data read: %.1f MiB
|
stats.read.total.data.mib=Data read: %.1f MiB
|
||||||
stats.read.total.data.gib=Data read: %.1f GiB
|
stats.read.total.data.gib=Data read: %.1f GiB
|
||||||
stats.decr.total.data.none=Data decrypted: -
|
stats.decr.total.data.none=Data decrypted: -
|
||||||
stats.decr.total.data.kib=Data decrypted: %.1f kiB
|
stats.decr.total.data.kib=Data decrypted: %.1f KiB
|
||||||
stats.decr.total.data.mib=Data decrypted: %.1f MiB
|
stats.decr.total.data.mib=Data decrypted: %.1f MiB
|
||||||
stats.decr.total.data.gib=Data decrypted: %.1f GiB
|
stats.decr.total.data.gib=Data decrypted: %.1f GiB
|
||||||
stats.read.accessCount=Total reads: %d
|
stats.read.accessCount=Total reads: %d
|
||||||
## Write
|
## Write
|
||||||
stats.write.throughput.idle=Write: idle
|
stats.write.throughput.idle=Write: idle
|
||||||
stats.write.throughput.kibs=Write: %.2f kiB/s
|
stats.write.throughput.kibs=Write: %.2f KiB/s
|
||||||
stats.write.throughput.mibs=Write: %.2f MiB/s
|
stats.write.throughput.mibs=Write: %.2f MiB/s
|
||||||
stats.write.total.data.none=Data written: -
|
stats.write.total.data.none=Data written: -
|
||||||
stats.write.total.data.kib=Data written: %.1f kiB
|
stats.write.total.data.kib=Data written: %.1f KiB
|
||||||
stats.write.total.data.mib=Data written: %.1f MiB
|
stats.write.total.data.mib=Data written: %.1f MiB
|
||||||
stats.write.total.data.gib=Data written: %.1f GiB
|
stats.write.total.data.gib=Data written: %.1f GiB
|
||||||
stats.encr.total.data.none=Data encrypted: -
|
stats.encr.total.data.none=Data encrypted: -
|
||||||
stats.encr.total.data.kib=Data encrypted: %.1f kiB
|
stats.encr.total.data.kib=Data encrypted: %.1f KiB
|
||||||
stats.encr.total.data.mib=Data encrypted: %.1f MiB
|
stats.encr.total.data.mib=Data encrypted: %.1f MiB
|
||||||
stats.encr.total.data.gib=Data encrypted: %.1f GiB
|
stats.encr.total.data.gib=Data encrypted: %.1f GiB
|
||||||
stats.write.accessCount=Total writes: %d
|
stats.write.accessCount=Total writes: %d
|
||||||
@@ -370,7 +371,7 @@ main.vaultDetail.lockBtn=Lock
|
|||||||
main.vaultDetail.bytesPerSecondRead=Read:
|
main.vaultDetail.bytesPerSecondRead=Read:
|
||||||
main.vaultDetail.bytesPerSecondWritten=Write:
|
main.vaultDetail.bytesPerSecondWritten=Write:
|
||||||
main.vaultDetail.throughput.idle=idle
|
main.vaultDetail.throughput.idle=idle
|
||||||
main.vaultDetail.throughput.kbps=%.1f kiB/s
|
main.vaultDetail.throughput.kbps=%.1f KiB/s
|
||||||
main.vaultDetail.throughput.mbps=%.1f MiB/s
|
main.vaultDetail.throughput.mbps=%.1f MiB/s
|
||||||
main.vaultDetail.stats=Vault Statistics
|
main.vaultDetail.stats=Vault Statistics
|
||||||
main.vaultDetail.locateEncryptedFileBtn=Locate Encrypted File
|
main.vaultDetail.locateEncryptedFileBtn=Locate Encrypted File
|
||||||
@@ -433,7 +434,10 @@ vaultOptions.masterkey.forgetSavedPasswordBtn=Forget Saved Password
|
|||||||
vaultOptions.masterkey.recoveryKeyExplanation=A recovery key is your only means to restore access to a vault if you lose your password.
|
vaultOptions.masterkey.recoveryKeyExplanation=A recovery key is your only means to restore access to a vault if you lose your password.
|
||||||
vaultOptions.masterkey.showRecoveryKeyBtn=Display Recovery Key
|
vaultOptions.masterkey.showRecoveryKeyBtn=Display Recovery Key
|
||||||
vaultOptions.masterkey.recoverPasswordBtn=Reset Password
|
vaultOptions.masterkey.recoverPasswordBtn=Reset Password
|
||||||
|
## Hub
|
||||||
|
vaultOptions.hub=Recovery
|
||||||
|
vaultOptions.hub.convertInfo=You can use the recovery key to convert this Hub vault to a password-based vault in an emergency.
|
||||||
|
vaultOptions.hub.convertBtn=Convert to Password-Based Vault
|
||||||
|
|
||||||
# Recovery Key
|
# Recovery Key
|
||||||
## Display Recovery Key
|
## Display Recovery Key
|
||||||
@@ -445,7 +449,7 @@ recoveryKey.display.StorageHints=Keep it somewhere very secure, e.g.:\n • Stor
|
|||||||
## Reset Password
|
## Reset Password
|
||||||
### Enter Recovery Key
|
### Enter Recovery Key
|
||||||
recoveryKey.recover.title=Reset Password
|
recoveryKey.recover.title=Reset Password
|
||||||
recoveryKey.recover.prompt=Enter your recovery key for "%s":
|
recoveryKey.recover.prompt=Enter the recovery key for "%s":
|
||||||
recoveryKey.recover.correctKey=This recovery key is correct
|
recoveryKey.recover.correctKey=This recovery key is correct
|
||||||
recoveryKey.recover.wrongKey=This recovery key belongs to a different vault
|
recoveryKey.recover.wrongKey=This recovery key belongs to a different vault
|
||||||
recoveryKey.recover.invalidKey=This recovery key is not valid
|
recoveryKey.recover.invalidKey=This recovery key is not valid
|
||||||
@@ -456,6 +460,13 @@ recoveryKey.recover.resetBtn=Reset
|
|||||||
recoveryKey.recover.resetSuccess.message=Password reset successful
|
recoveryKey.recover.resetSuccess.message=Password reset successful
|
||||||
recoveryKey.recover.resetSuccess.description=You can unlock your vault with the new password.
|
recoveryKey.recover.resetSuccess.description=You can unlock your vault with the new password.
|
||||||
|
|
||||||
|
# Convert Vault
|
||||||
|
convertVault.title=Convert Vault
|
||||||
|
convertVault.convert.convertBtn.before=Convert
|
||||||
|
convertVault.convert.convertBtn.processing=Converting…
|
||||||
|
convertVault.success.message=Conversion successful
|
||||||
|
convertVault.hubToPassword.success.description=You can now unlock the vault with the chosen password without requiring Hub access.
|
||||||
|
|
||||||
# New Password
|
# New Password
|
||||||
newPassword.promptText=Enter a new password
|
newPassword.promptText=Enter a new password
|
||||||
newPassword.reenterPassword=Confirm the new password
|
newPassword.reenterPassword=Confirm the new password
|
||||||
|
|||||||
@@ -233,7 +233,6 @@ main.vaultDetail.lockBtn=قفل
|
|||||||
main.vaultDetail.bytesPerSecondRead=قراءة:
|
main.vaultDetail.bytesPerSecondRead=قراءة:
|
||||||
main.vaultDetail.bytesPerSecondWritten=كتابة:
|
main.vaultDetail.bytesPerSecondWritten=كتابة:
|
||||||
main.vaultDetail.throughput.idle=خمول
|
main.vaultDetail.throughput.idle=خمول
|
||||||
main.vaultDetail.throughput.kbps=%.1f كيلوبايت/ث
|
|
||||||
main.vaultDetail.throughput.mbps=%.1f ميجابايت/ث
|
main.vaultDetail.throughput.mbps=%.1f ميجابايت/ث
|
||||||
main.vaultDetail.stats=إحصائيات الخزنة
|
main.vaultDetail.stats=إحصائيات الخزنة
|
||||||
main.vaultDetail.locateEncryptedFileBtn=تحديد موقع الملف المشفر
|
main.vaultDetail.locateEncryptedFileBtn=تحديد موقع الملف المشفر
|
||||||
@@ -285,7 +284,7 @@ vaultOptions.masterkey.changePasswordBtn=تغيير كلمة المرور
|
|||||||
vaultOptions.masterkey.forgetSavedPasswordBtn=نسيان كلمة المرور المحفوظة
|
vaultOptions.masterkey.forgetSavedPasswordBtn=نسيان كلمة المرور المحفوظة
|
||||||
vaultOptions.masterkey.recoveryKeyExplanation=مفتاح الاسترداد هو وسيلتك الوحيدة لاستعادة الوصول إلى مخزنك إذا فقدت كلمة المرور.
|
vaultOptions.masterkey.recoveryKeyExplanation=مفتاح الاسترداد هو وسيلتك الوحيدة لاستعادة الوصول إلى مخزنك إذا فقدت كلمة المرور.
|
||||||
vaultOptions.masterkey.showRecoveryKeyBtn=عرض مفتاح الاسترداد
|
vaultOptions.masterkey.showRecoveryKeyBtn=عرض مفتاح الاسترداد
|
||||||
|
## Hub
|
||||||
|
|
||||||
# Recovery Key
|
# Recovery Key
|
||||||
## Display Recovery Key
|
## Display Recovery Key
|
||||||
@@ -294,12 +293,13 @@ recoveryKey.display.description=يمكن استخدام مفتاح الاستر
|
|||||||
recoveryKey.display.StorageHints=حافظ عليه في مكان ما آمن جداً، على سبيل المثال\n • تخزينه باستخدام مدير كلمات المرور\n • حفظه على محرك أقراص خارجي USB\n • كتابته أو طباعته على الورق
|
recoveryKey.display.StorageHints=حافظ عليه في مكان ما آمن جداً، على سبيل المثال\n • تخزينه باستخدام مدير كلمات المرور\n • حفظه على محرك أقراص خارجي USB\n • كتابته أو طباعته على الورق
|
||||||
## Reset Password
|
## Reset Password
|
||||||
### Enter Recovery Key
|
### Enter Recovery Key
|
||||||
recoveryKey.recover.prompt=أدخل مفتاح الاسترداد الخاص لـ "%s":
|
|
||||||
recoveryKey.recover.correctKey=هذا مفتاح استرداد صالح
|
recoveryKey.recover.correctKey=هذا مفتاح استرداد صالح
|
||||||
recoveryKey.printout.heading=مفتاح استرداد Cryptomator\n"%s"\n
|
recoveryKey.printout.heading=مفتاح استرداد Cryptomator\n"%s"\n
|
||||||
### Reset Password
|
### Reset Password
|
||||||
### Recovery Key Password Reset Success
|
### Recovery Key Password Reset Success
|
||||||
|
|
||||||
|
# Convert Vault
|
||||||
|
|
||||||
# New Password
|
# New Password
|
||||||
newPassword.promptText=أدخل كلمة مرور جديدة
|
newPassword.promptText=أدخل كلمة مرور جديدة
|
||||||
newPassword.reenterPassword=تأكيد كلمة المرور الجديدة
|
newPassword.reenterPassword=تأكيد كلمة المرور الجديدة
|
||||||
|
|||||||
@@ -123,7 +123,14 @@ unlock.success.description=Змест скарбніцы "%s" цяпер дас
|
|||||||
unlock.success.rememberChoice=Запомні мой выбар і больш не пытай
|
unlock.success.rememberChoice=Запомні мой выбар і больш не пытай
|
||||||
unlock.success.revealBtn=Паказаць дыск
|
unlock.success.revealBtn=Паказаць дыск
|
||||||
## Failure
|
## Failure
|
||||||
|
unlock.error.customPath.message=Не магчыма змантажаваць скарбніцу да карыстальніцкай сцежкі
|
||||||
|
unlock.error.customPath.description.notSupported=Калі ты надалей жадаеш карыстацца адмысловаю сцежкаю, калі ласка, пайдзі ў налады ды абары там тып тому, які падтрымлівае яе. У іншым выпадку пайдзі ў опцыі скарбніцы ды абяры там пункт мантажавання, які падтрымліваецца.
|
||||||
|
unlock.error.customPath.description.notExists=Адмысловая сцежка мантажавання не існуе. Ствары яе ў сваёй файлавай сістэме, альбо змяні яе ў опцыях скарбніцы.
|
||||||
|
unlock.error.customPath.description.generic=Ты абраў адмысловую сцежку мантажавання для гэтай скарбніцы, але скарыстацца ёю не ўдалося. Вось паведамленне пра памылку: %s
|
||||||
## Hub
|
## Hub
|
||||||
|
hub.noKeychain.message=Няма доступу да ключа прылады
|
||||||
|
hub.noKeychain.description=Каб разамкнуць скарбніцы Hub, патрэбны ключ прылады, які захаваны ў звязку ключоў. Каб працягнуць, уключы "%s" ды абяры звязак ключоў у наладах.
|
||||||
|
hub.noKeychain.openBtn=Адчыніць налады
|
||||||
### Waiting
|
### Waiting
|
||||||
hub.auth.message=Чаканне спраўджання…
|
hub.auth.message=Чаканне спраўджання…
|
||||||
hub.auth.description=Ты мусіш аўтаматычна перанакіравацца на старонку ўваходу.
|
hub.auth.description=Ты мусіш аўтаматычна перанакіравацца на старонку ўваходу.
|
||||||
@@ -147,6 +154,8 @@ hub.registerFailed.description=Падчас прысваення імя адбы
|
|||||||
hub.unauthorized.message=Адмова ў доступе
|
hub.unauthorized.message=Адмова ў доступе
|
||||||
hub.unauthorized.description=Тваёй прыладзе ў дадзены момант не дазволена мець доступ да гэтай скрабніцы. Запытайся ўладальніка скрабніцы за дазволам.
|
hub.unauthorized.description=Тваёй прыладзе ў дадзены момант не дазволена мець доступ да гэтай скрабніцы. Запытайся ўладальніка скрабніцы за дазволам.
|
||||||
### License Exceeded
|
### License Exceeded
|
||||||
|
hub.invalidLicense.message=Несапраўдная ліцэнзія Hub
|
||||||
|
hub.invalidLicense.description=Твая інстанцыя Cryptomator Hub мае некарэктную ліцэнзію. Калі ласка, паведамі адміністратару Hub пра гэта, каб абнавіць альбо аднавіць ліцэнзію.
|
||||||
|
|
||||||
# Lock
|
# Lock
|
||||||
## Force
|
## Force
|
||||||
@@ -162,6 +171,12 @@ lock.fail.description=Скарбніцу "%s" не мажліва замкнуц
|
|||||||
migration.title=Абнавіць скарбніцу
|
migration.title=Абнавіць скарбніцу
|
||||||
## Start
|
## Start
|
||||||
migration.start.header=Абнавіць скарбніцу
|
migration.start.header=Абнавіць скарбніцу
|
||||||
|
migration.start.text=Каб адчыніць тваю скарбніцу "%s" у гэтай новай вэрсіі Cryptomator, скарбніца мусіць быць абноўленая да навейшага фармату. Перад тым, як пачаць, трэба ведаць наступнае:
|
||||||
|
migration.start.remarkUndone=Не магчыма скасаваць гэта абнаўленне.
|
||||||
|
migration.start.remarkVersions=Старэйшыя вэрсіі Cryptomator ня змогуць адчыніць абноўленую скарбніцу.
|
||||||
|
migration.start.remarkCanRun=Ты мусіш упэўніцца, што на кожнай прыладзе, якая мае доступ да скарбніцы, працуе гэта вэрсія Cryptomator.
|
||||||
|
migration.start.remarkSynced=Ты мусіш упэўніцца, што твая скарбніца цалкам сынхранаваная на гэтай ды іншых прыладах, перад тым як пачаць абнаўленне.
|
||||||
|
migration.start.confirm=Я прачытала і зразумела інфармацыю зверху
|
||||||
## Run
|
## Run
|
||||||
migration.run.enterPassword=Увядзіце пароль да "%s"
|
migration.run.enterPassword=Увядзіце пароль да "%s"
|
||||||
migration.run.startMigrationBtn=Перамясціць скарбніцу
|
migration.run.startMigrationBtn=Перамясціць скарбніцу
|
||||||
@@ -183,17 +198,47 @@ migration.impossible.heading=Не мажліва перанесці скарбн
|
|||||||
## Start
|
## Start
|
||||||
health.title=Тэст на цэласнасць для "%s"
|
health.title=Тэст на цэласнасць для "%s"
|
||||||
health.intro.header=Тэст на цэласнасць
|
health.intro.header=Тэст на цэласнасць
|
||||||
|
health.intro.remarkFix=Ня ўсе хібы могуць быць выпраўленыя.
|
||||||
health.intro.remarkBackup=Калі даныя пашкоджаныя, дапаможа толькі рэзервовая копія.
|
health.intro.remarkBackup=Калі даныя пашкоджаныя, дапаможа толькі рэзервовая копія.
|
||||||
|
health.intro.affirmation=Я прачытала і зразумела інфармацыю зверху
|
||||||
## Start Failure
|
## Start Failure
|
||||||
|
health.fail.header=Падчас загрузкі налад скарбніцы адбылася памылка
|
||||||
|
health.fail.ioError=Здарылася памылка падчас спробы прачытаць канфіґурацыйны файл.
|
||||||
|
health.fail.parseError=Здарылася памылка падчас ператварэння канфіґурацыі скарбніцы.
|
||||||
health.fail.moreInfo=Падрабязней
|
health.fail.moreInfo=Падрабязней
|
||||||
## Check Selection
|
## Check Selection
|
||||||
|
health.checkList.description=Абяры тэсты ў левым спісе альбо скарыстайся кнопкамі ўнізе.
|
||||||
health.checkList.selectAllButton=Вылучыць усе элементы
|
health.checkList.selectAllButton=Вылучыць усе элементы
|
||||||
health.checkList.deselectAllButton=Адрабіць вылучэнне ўсіх элементаў
|
health.checkList.deselectAllButton=Адрабіць вылучэнне ўсіх элементаў
|
||||||
health.check.runBatchBtn=Выканаць вылучаныя элементы
|
health.check.runBatchBtn=Выканаць вылучаныя элементы
|
||||||
## Detail view
|
## Detail view
|
||||||
|
health.check.detail.noSelectedCheck=Каб праглядзець вынікі, абяры тэсты цэласнасці ў левым спісе.
|
||||||
|
health.check.detail.checkScheduled=Тэст пастаўлены ў чаргу.
|
||||||
|
health.check.detail.checkRunning=Тэст адбываецца ў гэты момант…
|
||||||
|
health.check.detail.checkSkipped=Тэст ня быў абраны для выканання.
|
||||||
|
health.check.detail.checkFinished=Тэст паспяхова скончыўся.
|
||||||
|
health.check.detail.checkFinishedAndFound=Тэст завершаны. Калі ласка, праглядзі вынікі.
|
||||||
|
health.check.detail.checkFailed=Тэст быў спынены з-за памылкі.
|
||||||
health.check.detail.checkCancelled=Праверка была скасавана.
|
health.check.detail.checkCancelled=Праверка была скасавана.
|
||||||
|
health.check.detail.listFilters.label=Фільтр
|
||||||
|
health.check.detail.fixAllSpecificBtn=Адрамантаваць усё гэтага тыпу
|
||||||
health.check.exportBtn=Экспартаваць справаздачу
|
health.check.exportBtn=Экспартаваць справаздачу
|
||||||
## Result view
|
## Result view
|
||||||
|
health.result.severityFilter.all=Стан – Усе
|
||||||
|
health.result.severityFilter.good=Добра
|
||||||
|
health.result.severityFilter.info=Інфармацыя
|
||||||
|
health.result.severityFilter.warn=Папярэджанне
|
||||||
|
health.result.severityFilter.crit=Крытычна
|
||||||
|
health.result.severityTip.good=Стан: Добры\nНармальная структура скарбніцы.
|
||||||
|
health.result.severityTip.info=Стан: Інфармацыя\nСтруктура скарбніцы непашкоджаная.
|
||||||
|
health.result.severityTip.warn=Стан: Папярэджанне\nСтруктура скарбніцы пашкоджаная, тэрмінова патрабуецца рамонт.
|
||||||
|
health.result.severityTip.crit=Стан: Крытычны\nСтруктура скарбніцы пашкоджаная, выяўлена страта даных.
|
||||||
|
health.result.fixStateFilter.all=Стан выпраўлення – Усе
|
||||||
|
health.result.fixStateFilter.fixable=Папраўны
|
||||||
|
health.result.fixStateFilter.notFixable=Непапраўны
|
||||||
|
health.result.fixStateFilter.fixing=Выпраўленне…
|
||||||
|
health.result.fixStateFilter.fixed=Выпраўлена
|
||||||
|
health.result.fixStateFilter.fixFailed=Няўдача выпраўлення
|
||||||
## Fix Application
|
## Fix Application
|
||||||
health.fix.fixBtn=Выправіць
|
health.fix.fixBtn=Выправіць
|
||||||
health.fix.successTip=Паспяхова выпраўлена
|
health.fix.successTip=Паспяхова выпраўлена
|
||||||
@@ -226,6 +271,14 @@ preferences.interface.showTrayIcon=Паказваць іконку на інфа
|
|||||||
## Volume
|
## Volume
|
||||||
preferences.volume=Віртуальны дыск
|
preferences.volume=Віртуальны дыск
|
||||||
preferences.volume.type.automatic=Аўтаматычна
|
preferences.volume.type.automatic=Аўтаматычна
|
||||||
|
preferences.volume.docsTooltip=Адчыні дакумэнтацыю, каб даведацца больш пра розныя тыпы тому.
|
||||||
|
preferences.volume.tcp.port=Порт TCP
|
||||||
|
preferences.volume.supportedFeatures=Абраны тып тому падтрымлівае наступныя функцыі:
|
||||||
|
preferences.volume.feature.mountAuto=Аўтаматычны выбар пункту мантажавання
|
||||||
|
preferences.volume.feature.mountToDir=Карыстальніцкая тэчка як пункт мантажавання
|
||||||
|
preferences.volume.feature.mountToDriveLetter=Літара тому як пункт мантажавання
|
||||||
|
preferences.volume.feature.mountFlags=Карыстальніцкія опцыі мантажавання
|
||||||
|
preferences.volume.feature.readOnly=Мантажаванне толькі для чытання
|
||||||
## Updates
|
## Updates
|
||||||
preferences.updates=Абнаўленні
|
preferences.updates=Абнаўленні
|
||||||
preferences.updates.currentVersion=Бягучая версія: %s
|
preferences.updates.currentVersion=Бягучая версія: %s
|
||||||
@@ -234,7 +287,10 @@ preferences.updates.checkNowBtn=Праверыць зараз
|
|||||||
preferences.updates.updateAvailable=Даступна абнаўленне да версіі %s
|
preferences.updates.updateAvailable=Даступна абнаўленне да версіі %s
|
||||||
## Contribution
|
## Contribution
|
||||||
preferences.contribute=Падтрымай нас
|
preferences.contribute=Падтрымай нас
|
||||||
|
preferences.contribute.registeredFor=Сэртыфікат ахвяравальніка зарэгістраваны на %s
|
||||||
|
preferences.contribute.noCertificate=Ахвяруй на Cryptomator ды атрымай сэртыфікат ахвяравальніка. Гэта штось падобнае на ліцэнзійны ключ, але для цудоўных людзей, якія карыстаюцца бясплатнай праграмай. ;-)
|
||||||
preferences.contribute.getCertificate=Яшчэ ня маеш такога? Даведайся, як атрымаць.
|
preferences.contribute.getCertificate=Яшчэ ня маеш такога? Даведайся, як атрымаць.
|
||||||
|
preferences.contribute.promptText=Устаў код сэртыфікату ахвяравальніка сюды
|
||||||
#<-- Add entries for donations and code/translation/documentation contribution -->
|
#<-- Add entries for donations and code/translation/documentation contribution -->
|
||||||
|
|
||||||
## About
|
## About
|
||||||
@@ -242,9 +298,10 @@ preferences.about=Пра нас
|
|||||||
|
|
||||||
# Vault Statistics
|
# Vault Statistics
|
||||||
stats.title=Статыстыкі для %s
|
stats.title=Статыстыкі для %s
|
||||||
|
stats.cacheHitRate=Трапнасць кэшу
|
||||||
## Read
|
## Read
|
||||||
stats.read.throughput.idle=Чытанне: -
|
stats.read.throughput.idle=Чытанне: нічога
|
||||||
stats.read.throughput.kibs=Чытанне: %.2f КіБ/с
|
stats.read.throughput.kibs=Чытанне: %.2f KiB/s
|
||||||
stats.read.throughput.mibs=Чытанне: %.2f МіБ/с
|
stats.read.throughput.mibs=Чытанне: %.2f МіБ/с
|
||||||
stats.read.total.data.none=Прачытана: -
|
stats.read.total.data.none=Прачытана: -
|
||||||
stats.read.total.data.kib=Прачытана: %.1f КіБ
|
stats.read.total.data.kib=Прачытана: %.1f КіБ
|
||||||
@@ -254,9 +311,9 @@ stats.decr.total.data.none=Расшыфравана: -
|
|||||||
stats.decr.total.data.kib=Расшыфравана: %.1f КіБ
|
stats.decr.total.data.kib=Расшыфравана: %.1f КіБ
|
||||||
stats.decr.total.data.mib=Расшыфравана: %.1f МіБ
|
stats.decr.total.data.mib=Расшыфравана: %.1f МіБ
|
||||||
stats.decr.total.data.gib=Расшыфравана: %.1f ҐіБ
|
stats.decr.total.data.gib=Расшыфравана: %.1f ҐіБ
|
||||||
stats.read.accessCount=Агульная колькасць чытанняў: %d
|
stats.read.accessCount=Прачытана агулам: %d
|
||||||
## Write
|
## Write
|
||||||
stats.write.throughput.idle=Чытанне: -
|
stats.write.throughput.idle=Пісанне: нічога
|
||||||
stats.write.throughput.kibs=Пісанне: %.2f КіБ/с
|
stats.write.throughput.kibs=Пісанне: %.2f КіБ/с
|
||||||
stats.write.throughput.mibs=Пісанне: %.2f МіБ/с
|
stats.write.throughput.mibs=Пісанне: %.2f МіБ/с
|
||||||
stats.write.total.data.none=Напісана: -
|
stats.write.total.data.none=Напісана: -
|
||||||
@@ -267,9 +324,11 @@ stats.encr.total.data.none=Зашыфравана: -
|
|||||||
stats.encr.total.data.kib=Зашыфравана: %.1f КіБ
|
stats.encr.total.data.kib=Зашыфравана: %.1f КіБ
|
||||||
stats.encr.total.data.mib=Зашыфравана: %.1f МіБ
|
stats.encr.total.data.mib=Зашыфравана: %.1f МіБ
|
||||||
stats.encr.total.data.gib=Зашыфравана: %.1f ҐіБ
|
stats.encr.total.data.gib=Зашыфравана: %.1f ҐіБ
|
||||||
stats.write.accessCount=Агульная колькасць запісаў: %d
|
stats.write.accessCount=Запісана агулам: %d
|
||||||
|
|
||||||
## Accesses
|
## Accesses
|
||||||
|
stats.access.current=Доступ: %d
|
||||||
|
stats.access.total=Доступы агулам: %d
|
||||||
|
|
||||||
|
|
||||||
# Main Window
|
# Main Window
|
||||||
@@ -299,6 +358,7 @@ main.vaultDetail.passwordSavedInKeychain=Пароль захаваны
|
|||||||
main.vaultDetail.unlockedStatus=РАЗАМКНЁНА
|
main.vaultDetail.unlockedStatus=РАЗАМКНЁНА
|
||||||
main.vaultDetail.accessLocation=Змест тваёй скарбніцы даступны тут:
|
main.vaultDetail.accessLocation=Змест тваёй скарбніцы даступны тут:
|
||||||
main.vaultDetail.revealBtn=Паказаць дыск
|
main.vaultDetail.revealBtn=Паказаць дыск
|
||||||
|
main.vaultDetail.copyUri=Скапіяваць URI
|
||||||
main.vaultDetail.lockBtn=Замкнуць
|
main.vaultDetail.lockBtn=Замкнуць
|
||||||
main.vaultDetail.bytesPerSecondRead=Чытанне:
|
main.vaultDetail.bytesPerSecondRead=Чытанне:
|
||||||
main.vaultDetail.bytesPerSecondWritten=Пісанне:
|
main.vaultDetail.bytesPerSecondWritten=Пісанне:
|
||||||
@@ -306,6 +366,10 @@ main.vaultDetail.throughput.idle=бяздзейны
|
|||||||
main.vaultDetail.throughput.kbps=%.1f КіБ/с
|
main.vaultDetail.throughput.kbps=%.1f КіБ/с
|
||||||
main.vaultDetail.throughput.mbps=%.1f МіБ/с
|
main.vaultDetail.throughput.mbps=%.1f МіБ/с
|
||||||
main.vaultDetail.stats=Статыстыка скарбніцы
|
main.vaultDetail.stats=Статыстыка скарбніцы
|
||||||
|
main.vaultDetail.locateEncryptedFileBtn=Знайсці зашыфраваны файл
|
||||||
|
main.vaultDetail.locateEncryptedFileBtn.tooltip=Абяры файл у тваёй скрабніцы, каб знайсці ягоны зашыфраваны адпаведнік
|
||||||
|
main.vaultDetail.encryptedPathsCopied=Шлях скапіяваны ў буфер абмену!
|
||||||
|
main.vaultDetail.filePickerTitle=Абраць файл унутры скарбніцы
|
||||||
### Missing
|
### Missing
|
||||||
main.vaultDetail.missing.info=Cryptomator ня змог знайсці скарбніцу па гэтай сцежцы.
|
main.vaultDetail.missing.info=Cryptomator ня змог знайсці скарбніцу па гэтай сцежцы.
|
||||||
main.vaultDetail.missing.recheck=Пераправерыць
|
main.vaultDetail.missing.recheck=Пераправерыць
|
||||||
@@ -339,23 +403,29 @@ vaultOptions.general.actionAfterUnlock=Пасля паспяховага раз
|
|||||||
vaultOptions.general.actionAfterUnlock.ignore=Нічога не рабі
|
vaultOptions.general.actionAfterUnlock.ignore=Нічога не рабі
|
||||||
vaultOptions.general.actionAfterUnlock.reveal=Паказаць дыск
|
vaultOptions.general.actionAfterUnlock.reveal=Паказаць дыск
|
||||||
vaultOptions.general.actionAfterUnlock.ask=Запытацца
|
vaultOptions.general.actionAfterUnlock.ask=Запытацца
|
||||||
|
vaultOptions.general.startHealthCheckBtn=Пачаць тэст на цэласнасць
|
||||||
|
|
||||||
## Mount
|
## Mount
|
||||||
vaultOptions.mount=Мантажаванне
|
vaultOptions.mount=Мантажаванне
|
||||||
|
vaultOptions.mount.info=Опцыі залежаць ад абранага тыпу тому.
|
||||||
|
vaultOptions.mount.linkToPreferences=Адчыніць налады віртуальнага дыску
|
||||||
vaultOptions.mount.readonly=Толькі для чытання
|
vaultOptions.mount.readonly=Толькі для чытання
|
||||||
vaultOptions.mount.customMountFlags=Карыстальніцкія опцыі мантажавання
|
vaultOptions.mount.customMountFlags=Карыстальніцкія опцыі мантажавання
|
||||||
vaultOptions.mount.winDriveLetterOccupied=занята
|
vaultOptions.mount.winDriveLetterOccupied=занята
|
||||||
vaultOptions.mount.mountPoint=Пункт мантажавання
|
vaultOptions.mount.mountPoint=Пункт мантажавання
|
||||||
vaultOptions.mount.mountPoint.auto=Аўтаматычны выбар пасуючага месцазнаходжання
|
vaultOptions.mount.mountPoint.auto=Аўтаматычны выбар пасуючага месцазнаходжання
|
||||||
vaultOptions.mount.mountPoint.driveLetter=Назначыць літару для дыску
|
vaultOptions.mount.mountPoint.driveLetter=Назначыць літару для дыску
|
||||||
|
vaultOptions.mount.mountPoint.custom=Выкарыстаць абраную тэчку
|
||||||
vaultOptions.mount.mountPoint.directoryPickerButton=Абраць…
|
vaultOptions.mount.mountPoint.directoryPickerButton=Абраць…
|
||||||
|
vaultOptions.mount.mountPoint.directoryPickerTitle=Абраць тэчку
|
||||||
## Master Key
|
## Master Key
|
||||||
vaultOptions.masterkey=Пароль
|
vaultOptions.masterkey=Пароль
|
||||||
vaultOptions.masterkey.changePasswordBtn=Змяніць пароль
|
vaultOptions.masterkey.changePasswordBtn=Змяніць пароль
|
||||||
vaultOptions.masterkey.forgetSavedPasswordBtn=Забыцца на захаваны пароль
|
vaultOptions.masterkey.forgetSavedPasswordBtn=Забыцца на захаваны пароль
|
||||||
|
vaultOptions.masterkey.recoveryKeyExplanation=Ключ аднаўлення – гэта адзіная мажлівасць аднавіць доступ да тваёй скарбніцы, калі ты згубіш пароль.
|
||||||
vaultOptions.masterkey.showRecoveryKeyBtn=Паказаць ключ аднаўлення
|
vaultOptions.masterkey.showRecoveryKeyBtn=Паказаць ключ аднаўлення
|
||||||
vaultOptions.masterkey.recoverPasswordBtn=Скінуць пароль
|
vaultOptions.masterkey.recoverPasswordBtn=Скінуць пароль
|
||||||
|
## Hub
|
||||||
|
|
||||||
# Recovery Key
|
# Recovery Key
|
||||||
## Display Recovery Key
|
## Display Recovery Key
|
||||||
@@ -367,8 +437,9 @@ recoveryKey.display.StorageHints=Захоўвай іх у бяспечным м
|
|||||||
## Reset Password
|
## Reset Password
|
||||||
### Enter Recovery Key
|
### Enter Recovery Key
|
||||||
recoveryKey.recover.title=Скінуць пароль
|
recoveryKey.recover.title=Скінуць пароль
|
||||||
recoveryKey.recover.prompt=Увядзі свой ключ аднаўлення для "%s":
|
|
||||||
recoveryKey.recover.correctKey=Гэта валідны ключ аднаўлення
|
recoveryKey.recover.correctKey=Гэта валідны ключ аднаўлення
|
||||||
|
recoveryKey.recover.wrongKey=Гэты ключ аднаўлення належыць іншай скарбніцы
|
||||||
|
recoveryKey.recover.invalidKey=Несапраўдны ключ аднаўлення
|
||||||
recoveryKey.printout.heading=Ключ аднаўлення Cryptomator\n"%s"\n
|
recoveryKey.printout.heading=Ключ аднаўлення Cryptomator\n"%s"\n
|
||||||
### Reset Password
|
### Reset Password
|
||||||
recoveryKey.recover.resetBtn=Скінуць
|
recoveryKey.recover.resetBtn=Скінуць
|
||||||
@@ -376,6 +447,8 @@ recoveryKey.recover.resetBtn=Скінуць
|
|||||||
recoveryKey.recover.resetSuccess.message=Пароль паспяхова скінуты
|
recoveryKey.recover.resetSuccess.message=Пароль паспяхова скінуты
|
||||||
recoveryKey.recover.resetSuccess.description=Ты можаш разамкнуць сваю скарбніцу з дапамогаю новага паролю.
|
recoveryKey.recover.resetSuccess.description=Ты можаш разамкнуць сваю скарбніцу з дапамогаю новага паролю.
|
||||||
|
|
||||||
|
# Convert Vault
|
||||||
|
|
||||||
# New Password
|
# New Password
|
||||||
newPassword.promptText=Увядзі новы пароль
|
newPassword.promptText=Увядзі новы пароль
|
||||||
newPassword.reenterPassword=Пацвердзі новы пароль
|
newPassword.reenterPassword=Пацвердзі новы пароль
|
||||||
@@ -396,4 +469,5 @@ quit.lockAndQuitBtn=Замкнуць ды вайсці
|
|||||||
|
|
||||||
# Forced Quit
|
# Forced Quit
|
||||||
quit.forced.message=Некаторыя скарбніцы не магчыма замкнуць
|
quit.forced.message=Некаторыя скарбніцы не магчыма замкнуць
|
||||||
|
quit.forced.description=Замыканне скарбніц было заблакавана праз дзеючыя аперацыі альбо праз адчыненыя файлы. Ты можаш прымусова замкнуць скарбніцы, але гэта можа прывесці да страты незахаваных даных.
|
||||||
quit.forced.forceAndQuitBtn=Прымусіць і выйсці
|
quit.forced.forceAndQuitBtn=Прымусіць і выйсці
|
||||||
@@ -157,7 +157,7 @@ vaultOptions.general.vaultName=ভোল্ট এর নাম
|
|||||||
## Mount
|
## Mount
|
||||||
vaultOptions.mount.mountPoint.directoryPickerButton=নির্বাচন করুন…
|
vaultOptions.mount.mountPoint.directoryPickerButton=নির্বাচন করুন…
|
||||||
## Master Key
|
## Master Key
|
||||||
|
## Hub
|
||||||
|
|
||||||
# Recovery Key
|
# Recovery Key
|
||||||
## Display Recovery Key
|
## Display Recovery Key
|
||||||
@@ -166,6 +166,8 @@ vaultOptions.mount.mountPoint.directoryPickerButton=নির্বাচন ক
|
|||||||
### Reset Password
|
### Reset Password
|
||||||
### Recovery Key Password Reset Success
|
### Recovery Key Password Reset Success
|
||||||
|
|
||||||
|
# Convert Vault
|
||||||
|
|
||||||
# New Password
|
# New Password
|
||||||
|
|
||||||
# Quit
|
# Quit
|
||||||
|
|||||||
@@ -182,27 +182,21 @@ stats.title=Statistika za %s
|
|||||||
stats.cacheHitRate=Brzina učitavanja u predmemoriju
|
stats.cacheHitRate=Brzina učitavanja u predmemoriju
|
||||||
## Read
|
## Read
|
||||||
stats.read.throughput.idle=Čitaj: U pripravnosti
|
stats.read.throughput.idle=Čitaj: U pripravnosti
|
||||||
stats.read.throughput.kibs=Čitanje: %.2f kiB/s
|
|
||||||
stats.read.throughput.mibs=Čitanje: %.2f MiB/s
|
stats.read.throughput.mibs=Čitanje: %.2f MiB/s
|
||||||
stats.read.total.data.none=Pročitano podataka: -
|
stats.read.total.data.none=Pročitano podataka: -
|
||||||
stats.read.total.data.kib=Pročitano podataka: %.1f kiB
|
|
||||||
stats.read.total.data.mib=Pročitano podataka: %.1f MiB
|
stats.read.total.data.mib=Pročitano podataka: %.1f MiB
|
||||||
stats.read.total.data.gib=Pročitano podataka: %.1f GiB
|
stats.read.total.data.gib=Pročitano podataka: %.1f GiB
|
||||||
stats.decr.total.data.none=Otključani podaci: -
|
stats.decr.total.data.none=Otključani podaci: -
|
||||||
stats.decr.total.data.kib=Otključano podataka: %.1f kiB
|
|
||||||
stats.decr.total.data.mib=Otključano podataka: %.1f MiB
|
stats.decr.total.data.mib=Otključano podataka: %.1f MiB
|
||||||
stats.decr.total.data.gib=Otključano podataka: %.1f GiB
|
stats.decr.total.data.gib=Otključano podataka: %.1f GiB
|
||||||
stats.read.accessCount=Ukupno pročitano: %d
|
stats.read.accessCount=Ukupno pročitano: %d
|
||||||
## Write
|
## Write
|
||||||
stats.write.throughput.idle=Pisanje: U pripravnosti
|
stats.write.throughput.idle=Pisanje: U pripravnosti
|
||||||
stats.write.throughput.kibs=Upisano: %.2f kiB/s
|
|
||||||
stats.write.throughput.mibs=Upisano: %.2f MiB/s
|
stats.write.throughput.mibs=Upisano: %.2f MiB/s
|
||||||
stats.write.total.data.none=Podaci su upisani:-
|
stats.write.total.data.none=Podaci su upisani:-
|
||||||
stats.write.total.data.kib=Upisano podataka: %.1f kiB
|
|
||||||
stats.write.total.data.mib=Upisano podataka: %.1f MiB
|
stats.write.total.data.mib=Upisano podataka: %.1f MiB
|
||||||
stats.write.total.data.gib=Upisano podataka: %.1f GiB
|
stats.write.total.data.gib=Upisano podataka: %.1f GiB
|
||||||
stats.encr.total.data.none=Otključano podataka: -
|
stats.encr.total.data.none=Otključano podataka: -
|
||||||
stats.encr.total.data.kib=Otključano podataka: %.1f kiB
|
|
||||||
stats.encr.total.data.mib=Otključano podataka: %.1f MiB
|
stats.encr.total.data.mib=Otključano podataka: %.1f MiB
|
||||||
stats.encr.total.data.gib=Otključano podataka: %.1f GiB
|
stats.encr.total.data.gib=Otključano podataka: %.1f GiB
|
||||||
stats.write.accessCount=Ukupno upisano: %d
|
stats.write.accessCount=Ukupno upisano: %d
|
||||||
@@ -242,7 +236,6 @@ main.vaultDetail.lockBtn=Zaključaj
|
|||||||
main.vaultDetail.bytesPerSecondRead=Čitaj:
|
main.vaultDetail.bytesPerSecondRead=Čitaj:
|
||||||
main.vaultDetail.bytesPerSecondWritten=Piši:
|
main.vaultDetail.bytesPerSecondWritten=Piši:
|
||||||
main.vaultDetail.throughput.idle=u stanju mirovanja
|
main.vaultDetail.throughput.idle=u stanju mirovanja
|
||||||
main.vaultDetail.throughput.kbps=%.1f kiB/s
|
|
||||||
main.vaultDetail.throughput.mbps=%.1f MiB/s
|
main.vaultDetail.throughput.mbps=%.1f MiB/s
|
||||||
main.vaultDetail.stats=Statistika sefa
|
main.vaultDetail.stats=Statistika sefa
|
||||||
### Missing
|
### Missing
|
||||||
@@ -290,7 +283,7 @@ vaultOptions.masterkey.changePasswordBtn=Promjeni lozinku
|
|||||||
vaultOptions.masterkey.forgetSavedPasswordBtn=Zaborav spremljenu šifru
|
vaultOptions.masterkey.forgetSavedPasswordBtn=Zaborav spremljenu šifru
|
||||||
vaultOptions.masterkey.recoveryKeyExplanation=Ključ za oporavak je vaše jedino sredstvo za vraćanje pristupa sefu ako izgubite lozinku.
|
vaultOptions.masterkey.recoveryKeyExplanation=Ključ za oporavak je vaše jedino sredstvo za vraćanje pristupa sefu ako izgubite lozinku.
|
||||||
vaultOptions.masterkey.showRecoveryKeyBtn=Pokaži ključ za oporavak
|
vaultOptions.masterkey.showRecoveryKeyBtn=Pokaži ključ za oporavak
|
||||||
|
## Hub
|
||||||
|
|
||||||
# Recovery Key
|
# Recovery Key
|
||||||
## Display Recovery Key
|
## Display Recovery Key
|
||||||
@@ -299,12 +292,13 @@ recoveryKey.display.description=Sljedeći ključ za oporavak može se koristiti
|
|||||||
recoveryKey.display.StorageHints=Pohranite ga negdje vrlo sigurno, npr.:\n • Spremite ga pomoću menadžera lozinki\n • Spremite ga na USB disk\n • Odštampajte ga na papiru
|
recoveryKey.display.StorageHints=Pohranite ga negdje vrlo sigurno, npr.:\n • Spremite ga pomoću menadžera lozinki\n • Spremite ga na USB disk\n • Odštampajte ga na papiru
|
||||||
## Reset Password
|
## Reset Password
|
||||||
### Enter Recovery Key
|
### Enter Recovery Key
|
||||||
recoveryKey.recover.prompt=Unesite ključ za oporavak za "%s":
|
|
||||||
recoveryKey.recover.correctKey=Ključ za oporavak je ispravan
|
recoveryKey.recover.correctKey=Ključ za oporavak je ispravan
|
||||||
recoveryKey.printout.heading=Cryptomator Ključ za oporavak za \n"%s"\n
|
recoveryKey.printout.heading=Cryptomator Ključ za oporavak za \n"%s"\n
|
||||||
### Reset Password
|
### Reset Password
|
||||||
### Recovery Key Password Reset Success
|
### Recovery Key Password Reset Success
|
||||||
|
|
||||||
|
# Convert Vault
|
||||||
|
|
||||||
# New Password
|
# New Password
|
||||||
newPassword.promptText=Unesi novu šifru
|
newPassword.promptText=Unesi novu šifru
|
||||||
newPassword.reenterPassword=Potvrdi novu šifru
|
newPassword.reenterPassword=Potvrdi novu šifru
|
||||||
|
|||||||
@@ -154,6 +154,8 @@ hub.registerFailed.description=S'ha produït un error en el procés de nomenamen
|
|||||||
hub.unauthorized.message=Accés denegat
|
hub.unauthorized.message=Accés denegat
|
||||||
hub.unauthorized.description=El vostre dispositiu no ha estat encara autoritzat a accedir a aquesta caixa forta. Demaneu autorització al propietari.
|
hub.unauthorized.description=El vostre dispositiu no ha estat encara autoritzat a accedir a aquesta caixa forta. Demaneu autorització al propietari.
|
||||||
### License Exceeded
|
### License Exceeded
|
||||||
|
hub.invalidLicense.message=La llicència del Hub no és vàlida
|
||||||
|
hub.invalidLicense.description=Aquest Cryptomator Hub no té una llicència vàlida. Informa si us plau a l'administrador perquè actualitzi o renovi la llicència.
|
||||||
|
|
||||||
# Lock
|
# Lock
|
||||||
## Force
|
## Force
|
||||||
@@ -272,8 +274,8 @@ preferences.interface.showMinimizeButton=Mostra el botó 'minimitzar'
|
|||||||
preferences.interface.showTrayIcon=Mostra la icona en la barra (cal reiniciar)
|
preferences.interface.showTrayIcon=Mostra la icona en la barra (cal reiniciar)
|
||||||
## Volume
|
## Volume
|
||||||
preferences.volume=Unitat virtual
|
preferences.volume=Unitat virtual
|
||||||
preferences.volume.type=Tipus de volum (requereix reiniciar)
|
|
||||||
preferences.volume.type.automatic=Automàtic
|
preferences.volume.type.automatic=Automàtic
|
||||||
|
preferences.volume.docsTooltip=Obre la documentació per aprendre més sobre els diferents tipus de volums.
|
||||||
preferences.volume.tcp.port=Port TCP
|
preferences.volume.tcp.port=Port TCP
|
||||||
preferences.volume.supportedFeatures=El tipus de volum escollit suporta les següents característiques:
|
preferences.volume.supportedFeatures=El tipus de volum escollit suporta les següents característiques:
|
||||||
preferences.volume.feature.mountAuto=Selecció automàtica del punt de muntatge
|
preferences.volume.feature.mountAuto=Selecció automàtica del punt de muntatge
|
||||||
@@ -303,27 +305,27 @@ stats.title=Estadístiques per a %s
|
|||||||
stats.cacheHitRate=Relació d'encerts de la memòria cau
|
stats.cacheHitRate=Relació d'encerts de la memòria cau
|
||||||
## Read
|
## Read
|
||||||
stats.read.throughput.idle=Llegit: inactiu
|
stats.read.throughput.idle=Llegit: inactiu
|
||||||
stats.read.throughput.kibs=Llegit: %.2f kiB/s
|
stats.read.throughput.kibs=Lectura: %.2f KiB/s
|
||||||
stats.read.throughput.mibs=Llegit: %.2f MiB/s
|
stats.read.throughput.mibs=Llegit: %.2f MiB/s
|
||||||
stats.read.total.data.none=Dades llegides: -
|
stats.read.total.data.none=Dades llegides: -
|
||||||
stats.read.total.data.kib=Dades llegides: %.1f kiB
|
stats.read.total.data.kib=Dades llegides: %.1f KiB
|
||||||
stats.read.total.data.mib=Dades llegides: %.1f MiB
|
stats.read.total.data.mib=Dades llegides: %.1f MiB
|
||||||
stats.read.total.data.gib=Dades llegides: %.1f GiB
|
stats.read.total.data.gib=Dades llegides: %.1f GiB
|
||||||
stats.decr.total.data.none=Dades desxifrades: -
|
stats.decr.total.data.none=Dades desxifrades: -
|
||||||
stats.decr.total.data.kib=Dades desxifrades: %.1f kiB
|
stats.decr.total.data.kib=Dades desxifrades: %.1f KiB
|
||||||
stats.decr.total.data.mib=Dades desxifrades: %.1f MiB
|
stats.decr.total.data.mib=Dades desxifrades: %.1f MiB
|
||||||
stats.decr.total.data.gib=Dades desxifrades: %.1f GiB
|
stats.decr.total.data.gib=Dades desxifrades: %.1f GiB
|
||||||
stats.read.accessCount=Lectures en total: %d
|
stats.read.accessCount=Lectures en total: %d
|
||||||
## Write
|
## Write
|
||||||
stats.write.throughput.idle=Escriu: inactiu
|
stats.write.throughput.idle=Escriu: inactiu
|
||||||
stats.write.throughput.kibs=Escriu: %.2f kiB/s
|
stats.write.throughput.kibs=Escriptura: %.2f KiB/s
|
||||||
stats.write.throughput.mibs=Escriu: %.2f MiB/s
|
stats.write.throughput.mibs=Escriu: %.2f MiB/s
|
||||||
stats.write.total.data.none=Dades escrites
|
stats.write.total.data.none=Dades escrites
|
||||||
stats.write.total.data.kib=Dades escrites: %.1f kiB
|
stats.write.total.data.kib=Dades escrites: %.1f KiB
|
||||||
stats.write.total.data.mib=Dades escrites: %.1f MiB
|
stats.write.total.data.mib=Dades escrites: %.1f MiB
|
||||||
stats.write.total.data.gib=Dades escrites: %.1f GiB
|
stats.write.total.data.gib=Dades escrites: %.1f GiB
|
||||||
stats.encr.total.data.none=Dades xifrades: -
|
stats.encr.total.data.none=Dades xifrades: -
|
||||||
stats.encr.total.data.kib=Dades xifrades: %.1f kiB
|
stats.encr.total.data.kib=Dades xifrades: %.1f KiB
|
||||||
stats.encr.total.data.mib=Dades xifrades: %.1f MiB
|
stats.encr.total.data.mib=Dades xifrades: %.1f MiB
|
||||||
stats.encr.total.data.gib=Dades xifrades: %.1f GiB
|
stats.encr.total.data.gib=Dades xifrades: %.1f GiB
|
||||||
stats.write.accessCount=Total escrits: %d
|
stats.write.accessCount=Total escrits: %d
|
||||||
@@ -366,7 +368,7 @@ main.vaultDetail.lockBtn=Bloqueja
|
|||||||
main.vaultDetail.bytesPerSecondRead=Lectura:
|
main.vaultDetail.bytesPerSecondRead=Lectura:
|
||||||
main.vaultDetail.bytesPerSecondWritten=Escriu:
|
main.vaultDetail.bytesPerSecondWritten=Escriu:
|
||||||
main.vaultDetail.throughput.idle=inactiu
|
main.vaultDetail.throughput.idle=inactiu
|
||||||
main.vaultDetail.throughput.kbps=%.1f kiB/s
|
main.vaultDetail.throughput.kbps=%.1f KiB/s
|
||||||
main.vaultDetail.throughput.mbps=%.1f MiB/s
|
main.vaultDetail.throughput.mbps=%.1f MiB/s
|
||||||
main.vaultDetail.stats=Estadístiques de la caixa forta
|
main.vaultDetail.stats=Estadístiques de la caixa forta
|
||||||
main.vaultDetail.locateEncryptedFileBtn=Trobar fitxer xifrat
|
main.vaultDetail.locateEncryptedFileBtn=Trobar fitxer xifrat
|
||||||
@@ -429,7 +431,7 @@ vaultOptions.masterkey.forgetSavedPasswordBtn=Oblida la contrasenya desada
|
|||||||
vaultOptions.masterkey.recoveryKeyExplanation=La clau de recuperació és l'unic mitjà de restaurar l'accès a la caixa forta en cas de perdre la contrasenya.
|
vaultOptions.masterkey.recoveryKeyExplanation=La clau de recuperació és l'unic mitjà de restaurar l'accès a la caixa forta en cas de perdre la contrasenya.
|
||||||
vaultOptions.masterkey.showRecoveryKeyBtn=Mostra la clau de recuperació
|
vaultOptions.masterkey.showRecoveryKeyBtn=Mostra la clau de recuperació
|
||||||
vaultOptions.masterkey.recoverPasswordBtn=Canviar contrasenya
|
vaultOptions.masterkey.recoverPasswordBtn=Canviar contrasenya
|
||||||
|
## Hub
|
||||||
|
|
||||||
# Recovery Key
|
# Recovery Key
|
||||||
## Display Recovery Key
|
## Display Recovery Key
|
||||||
@@ -441,8 +443,9 @@ recoveryKey.display.StorageHints=Conserveu-la en un lloc molt segur. P. ex.:\n
|
|||||||
## Reset Password
|
## Reset Password
|
||||||
### Enter Recovery Key
|
### Enter Recovery Key
|
||||||
recoveryKey.recover.title=Canviar contrasenya
|
recoveryKey.recover.title=Canviar contrasenya
|
||||||
recoveryKey.recover.prompt=Introduïu la vostra clau de recuperació de "%s":
|
|
||||||
recoveryKey.recover.correctKey=La clau de recuperació és vàlida
|
recoveryKey.recover.correctKey=La clau de recuperació és vàlida
|
||||||
|
recoveryKey.recover.wrongKey=Aquesta clau de recuperació pertany a una caixa forta diferent
|
||||||
|
recoveryKey.recover.invalidKey=Aquesta clau de recuperació no és vàlida
|
||||||
recoveryKey.printout.heading=Clau de recuperació de Cryptomator\n"%s"\n
|
recoveryKey.printout.heading=Clau de recuperació de Cryptomator\n"%s"\n
|
||||||
### Reset Password
|
### Reset Password
|
||||||
recoveryKey.recover.resetBtn=Reinicia
|
recoveryKey.recover.resetBtn=Reinicia
|
||||||
@@ -450,6 +453,8 @@ recoveryKey.recover.resetBtn=Reinicia
|
|||||||
recoveryKey.recover.resetSuccess.message=S'ha modificat la contrasenya correctament
|
recoveryKey.recover.resetSuccess.message=S'ha modificat la contrasenya correctament
|
||||||
recoveryKey.recover.resetSuccess.description=Pots desbloquejar la caixa forta amb la nova contrasenya.
|
recoveryKey.recover.resetSuccess.description=Pots desbloquejar la caixa forta amb la nova contrasenya.
|
||||||
|
|
||||||
|
# Convert Vault
|
||||||
|
|
||||||
# New Password
|
# New Password
|
||||||
newPassword.promptText=Introdueix una contrasenya nova
|
newPassword.promptText=Introdueix una contrasenya nova
|
||||||
newPassword.reenterPassword=Confirma la nova contrasenya
|
newPassword.reenterPassword=Confirma la nova contrasenya
|
||||||
|
|||||||
@@ -272,27 +272,21 @@ stats.title=Statistika pro %s
|
|||||||
stats.cacheHitRate=Rychlost dosažené mezipaměti
|
stats.cacheHitRate=Rychlost dosažené mezipaměti
|
||||||
## Read
|
## Read
|
||||||
stats.read.throughput.idle=Čtení: nečinné
|
stats.read.throughput.idle=Čtení: nečinné
|
||||||
stats.read.throughput.kibs=Čtení: %.2f kiB/s
|
|
||||||
stats.read.throughput.mibs=Čtení: %.2f MiB/s
|
stats.read.throughput.mibs=Čtení: %.2f MiB/s
|
||||||
stats.read.total.data.none=Přečteno: -
|
stats.read.total.data.none=Přečteno: -
|
||||||
stats.read.total.data.kib=Přečteno: %.1f kiB
|
|
||||||
stats.read.total.data.mib=Přečteno: %.1f MiB
|
stats.read.total.data.mib=Přečteno: %.1f MiB
|
||||||
stats.read.total.data.gib=Přečteno: %.1f GiB
|
stats.read.total.data.gib=Přečteno: %.1f GiB
|
||||||
stats.decr.total.data.none=Dešifrováno: -
|
stats.decr.total.data.none=Dešifrováno: -
|
||||||
stats.decr.total.data.kib=Dešifrováno: %.1f kiB
|
|
||||||
stats.decr.total.data.mib=Dešifrováno: %.1f MiB
|
stats.decr.total.data.mib=Dešifrováno: %.1f MiB
|
||||||
stats.decr.total.data.gib=Dešifrováno: %.1f GiB
|
stats.decr.total.data.gib=Dešifrováno: %.1f GiB
|
||||||
stats.read.accessCount=Celkem přečteno: %d
|
stats.read.accessCount=Celkem přečteno: %d
|
||||||
## Write
|
## Write
|
||||||
stats.write.throughput.idle=Zápis: nečinný
|
stats.write.throughput.idle=Zápis: nečinný
|
||||||
stats.write.throughput.kibs=Zápis: %.2f kiB/s
|
|
||||||
stats.write.throughput.mibs=Zápis: %.2f MiB/s
|
stats.write.throughput.mibs=Zápis: %.2f MiB/s
|
||||||
stats.write.total.data.none=Zapsaná data: -
|
stats.write.total.data.none=Zapsaná data: -
|
||||||
stats.write.total.data.kib=Zapsáno: %.1f kiB
|
|
||||||
stats.write.total.data.mib=Zapsáno: %.1f MiB
|
stats.write.total.data.mib=Zapsáno: %.1f MiB
|
||||||
stats.write.total.data.gib=Zapsáno: %.1f GiB
|
stats.write.total.data.gib=Zapsáno: %.1f GiB
|
||||||
stats.encr.total.data.none=Zašifrováno: -
|
stats.encr.total.data.none=Zašifrováno: -
|
||||||
stats.encr.total.data.kib=Zašifrováno: %.1f kiB
|
|
||||||
stats.encr.total.data.mib=Zašifrováno: %.1f MiB
|
stats.encr.total.data.mib=Zašifrováno: %.1f MiB
|
||||||
stats.encr.total.data.gib=Zašifrováno: %.1f GiB
|
stats.encr.total.data.gib=Zašifrováno: %.1f GiB
|
||||||
stats.write.accessCount=Celkem zapsáno: %d
|
stats.write.accessCount=Celkem zapsáno: %d
|
||||||
@@ -334,7 +328,6 @@ main.vaultDetail.lockBtn=Zamknout
|
|||||||
main.vaultDetail.bytesPerSecondRead=Přečteno:
|
main.vaultDetail.bytesPerSecondRead=Přečteno:
|
||||||
main.vaultDetail.bytesPerSecondWritten=Zapsáno:
|
main.vaultDetail.bytesPerSecondWritten=Zapsáno:
|
||||||
main.vaultDetail.throughput.idle=nečinný
|
main.vaultDetail.throughput.idle=nečinný
|
||||||
main.vaultDetail.throughput.kbps=%.1f kiB/s
|
|
||||||
main.vaultDetail.throughput.mbps=%.1f MiB/s
|
main.vaultDetail.throughput.mbps=%.1f MiB/s
|
||||||
main.vaultDetail.stats=Statistiky trezoru
|
main.vaultDetail.stats=Statistiky trezoru
|
||||||
### Missing
|
### Missing
|
||||||
@@ -389,7 +382,7 @@ vaultOptions.masterkey.forgetSavedPasswordBtn=Zapomenout uložené heslo
|
|||||||
vaultOptions.masterkey.recoveryKeyExplanation=Obnovovací klíč je váš jediný způsob, jak obnovit přístup k trezoru, pokud ztratíte své heslo.
|
vaultOptions.masterkey.recoveryKeyExplanation=Obnovovací klíč je váš jediný způsob, jak obnovit přístup k trezoru, pokud ztratíte své heslo.
|
||||||
vaultOptions.masterkey.showRecoveryKeyBtn=Zobrazit klíč k obnově
|
vaultOptions.masterkey.showRecoveryKeyBtn=Zobrazit klíč k obnově
|
||||||
vaultOptions.masterkey.recoverPasswordBtn=Resetovat heslo
|
vaultOptions.masterkey.recoverPasswordBtn=Resetovat heslo
|
||||||
|
## Hub
|
||||||
|
|
||||||
# Recovery Key
|
# Recovery Key
|
||||||
## Display Recovery Key
|
## Display Recovery Key
|
||||||
@@ -401,13 +394,14 @@ recoveryKey.display.StorageHints=Uchovejte ho někde velmi bezpečně, např.\n
|
|||||||
## Reset Password
|
## Reset Password
|
||||||
### Enter Recovery Key
|
### Enter Recovery Key
|
||||||
recoveryKey.recover.title=Resetovat heslo
|
recoveryKey.recover.title=Resetovat heslo
|
||||||
recoveryKey.recover.prompt=Zadejte váš obnovovací klíč pro "%s":
|
|
||||||
recoveryKey.recover.correctKey=Toto je platný obnovovací klíč
|
recoveryKey.recover.correctKey=Toto je platný obnovovací klíč
|
||||||
recoveryKey.printout.heading=Obnovovací klíč Cryptomator\n"%s"\n
|
recoveryKey.printout.heading=Obnovovací klíč Cryptomator\n"%s"\n
|
||||||
### Reset Password
|
### Reset Password
|
||||||
recoveryKey.recover.resetBtn=Resetovat
|
recoveryKey.recover.resetBtn=Resetovat
|
||||||
### Recovery Key Password Reset Success
|
### Recovery Key Password Reset Success
|
||||||
|
|
||||||
|
# Convert Vault
|
||||||
|
|
||||||
# New Password
|
# New Password
|
||||||
newPassword.promptText=Zadejte nové heslo
|
newPassword.promptText=Zadejte nové heslo
|
||||||
newPassword.reenterPassword=Potvrď nové heslo
|
newPassword.reenterPassword=Potvrď nové heslo
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ generic.button.choose=Vælg…
|
|||||||
generic.button.close=Luk
|
generic.button.close=Luk
|
||||||
generic.button.copy=Kopiér
|
generic.button.copy=Kopiér
|
||||||
generic.button.copied=Kopieret!
|
generic.button.copied=Kopieret!
|
||||||
generic.button.done=Ferdig
|
generic.button.done=Færdig
|
||||||
generic.button.next=Næste
|
generic.button.next=Næste
|
||||||
generic.button.print=Print
|
generic.button.print=Print
|
||||||
|
|
||||||
@@ -34,21 +34,21 @@ traymenu.vault.lock=Lås
|
|||||||
traymenu.vault.reveal=Vis
|
traymenu.vault.reveal=Vis
|
||||||
|
|
||||||
# Add Vault Wizard
|
# Add Vault Wizard
|
||||||
addvaultwizard.title=Legg til kvelv
|
addvaultwizard.title=Tilføj boks
|
||||||
## Welcome
|
## Welcome
|
||||||
addvaultwizard.welcome.newButton=Opprett ein ny kvelv
|
addvaultwizard.welcome.newButton=Opret ny boks
|
||||||
addvaultwizard.welcome.existingButton=Opn ein eksisterande kvelv
|
addvaultwizard.welcome.existingButton=Open eksisterende boks
|
||||||
## New
|
## New
|
||||||
### Name
|
### Name
|
||||||
addvaultwizard.new.nameInstruction=Vælg et navn til boksen
|
addvaultwizard.new.nameInstruction=Vælg et navn til boksen
|
||||||
addvaultwizard.new.namePrompt=Namn på kvelven
|
addvaultwizard.new.namePrompt=Boks-navn
|
||||||
### Location
|
### Location
|
||||||
addvaultwizard.new.locationInstruction=Kvar skal Cryptomator lagra dei krypterte filene i kvelven din?
|
addvaultwizard.new.locationInstruction=Hvor skal Cryptomator gemme de krypterede filer af din boks?
|
||||||
addvaultwizard.new.locationLabel=Dataplacering
|
addvaultwizard.new.locationLabel=Dataplacering
|
||||||
addvaultwizard.new.locationPrompt=…
|
addvaultwizard.new.locationPrompt=…
|
||||||
addvaultwizard.new.directoryPickerLabel=Vælg placering
|
addvaultwizard.new.directoryPickerLabel=Vælg placering
|
||||||
addvaultwizard.new.directoryPickerButton=Vælg…
|
addvaultwizard.new.directoryPickerButton=Vælg…
|
||||||
addvaultwizard.new.directoryPickerTitle=Vel mappe
|
addvaultwizard.new.directoryPickerTitle=Vælg mappe
|
||||||
addvaultwizard.new.fileAlreadyExists=En fil eller mappe med samme navn findes allerede
|
addvaultwizard.new.fileAlreadyExists=En fil eller mappe med samme navn findes allerede
|
||||||
addvaultwizard.new.locationDoesNotExist=En mappe i den valgte sti findes ikke, eller kan ikke tilgås
|
addvaultwizard.new.locationDoesNotExist=En mappe i den valgte sti findes ikke, eller kan ikke tilgås
|
||||||
addvaultwizard.new.locationIsNotWritable=Ingen redigeringsadgang til den valgte sti
|
addvaultwizard.new.locationIsNotWritable=Ingen redigeringsadgang til den valgte sti
|
||||||
@@ -61,61 +61,61 @@ addvaultwizard.new.validCharacters.numbers=Tal
|
|||||||
addvaultwizard.new.validCharacters.dashes=Bindestreg (%s) eller understregning (%s)
|
addvaultwizard.new.validCharacters.dashes=Bindestreg (%s) eller understregning (%s)
|
||||||
### Password
|
### Password
|
||||||
addvaultwizard.new.createVaultBtn=Opret boks
|
addvaultwizard.new.createVaultBtn=Opret boks
|
||||||
addvaultwizard.new.generateRecoveryKeyChoice=Du vil ikkje kunna få tilgang til dataa dine utan passordet. Vil du ha ein gjenopprettingsnøkkel i tilfelle du mistar passordet ditt?
|
addvaultwizard.new.generateRecoveryKeyChoice=Du kan ikke tilgå dine data uden din adgangskode. Vil du oprette en gendannelses-nøgle i tilfælde af, at du mister din adgangskode?
|
||||||
addvaultwizard.new.generateRecoveryKeyChoice.yes=Ja tak - for en sikkerheds skyld
|
addvaultwizard.new.generateRecoveryKeyChoice.yes=Ja tak - for en sikkerheds skyld
|
||||||
addvaultwizard.new.generateRecoveryKeyChoice.no=Nei takk, eg kjem ikkje til å mista passordet mitt
|
addvaultwizard.new.generateRecoveryKeyChoice.no=Nej tak. Jeg mister ikke min adgangskode
|
||||||
### Information
|
### Information
|
||||||
addvault.new.readme.storageLocation.fileName=VIGTIGT.rtf
|
addvault.new.readme.storageLocation.fileName=VIGTIGT.rtf
|
||||||
addvault.new.readme.storageLocation.1=⚠️ HVELVFILER ⚠️
|
addvault.new.readme.storageLocation.1=⚠️ BOKS-FILER ⚠️
|
||||||
addvault.new.readme.storageLocation.2=Dette er lagringsstaden til kvelven.
|
addvault.new.readme.storageLocation.2=Det er her er lokationen for din boks' data.
|
||||||
addvault.new.readme.storageLocation.3=SØRG FOR ALDRIG AT
|
addvault.new.readme.storageLocation.3=SØRG FOR ALDRIG AT
|
||||||
addvault.new.readme.storageLocation.4=• ændre filer i denne mappe eller
|
addvault.new.readme.storageLocation.4=• ændre filer i denne mappe eller
|
||||||
addvault.new.readme.storageLocation.5=• indsæt nogen filer som skal krypteres i denne mappe.
|
addvault.new.readme.storageLocation.5=• indsæt nogen filer som skal krypteres i denne mappe.
|
||||||
addvault.new.readme.storageLocation.6=Viss du vil kryptera filer og sjå innhaldet i kvelven, gjer du følgjande:
|
addvault.new.readme.storageLocation.6=Hvis du ønsker at kryptere filer eller se indholdet af boksen, skal du gøre følgende:
|
||||||
addvault.new.readme.storageLocation.7=1. Tilføj denne boks til Cryptomator.
|
addvault.new.readme.storageLocation.7=1. Tilføj denne boks til Cryptomator.
|
||||||
addvault.new.readme.storageLocation.8=2. Lås boksen op i Cryptomator.
|
addvault.new.readme.storageLocation.8=2. Lås boksen op i Cryptomator.
|
||||||
addvault.new.readme.storageLocation.9=3. Åbn placeringen ved at klikke på knappen "Vis boks".
|
addvault.new.readme.storageLocation.9=3. Åbn placeringen ved at klikke på knappen "Vis boks".
|
||||||
addvault.new.readme.storageLocation.10=Hvis du har brug for hjælp, så kig i dokumentationen: %s
|
addvault.new.readme.storageLocation.10=Hvis du har brug for hjælp, så kig i dokumentationen: %s
|
||||||
addvault.new.readme.accessLocation.fileName=VELKOMMEN.rtf
|
addvault.new.readme.accessLocation.fileName=VELKOMMEN.rtf
|
||||||
addvault.new.readme.accessLocation.1=🔐️ KRYPTERET DREV 🔐️
|
addvault.new.readme.accessLocation.1=🔐️ KRYPTERET DREV 🔐️
|
||||||
addvault.new.readme.accessLocation.2=Dette er lagringsstaden til kvelven.
|
addvault.new.readme.accessLocation.2=Det er her indholdet af din boks tilgås.
|
||||||
addvault.new.readme.accessLocation.3=Filer du tilføjer til dette drev vil blive krypteret af Cryptomator. Du har arbejde med filerne ligesom enhver anden fil/mappe. Dette er blot en dekrypteret visning af indholdet. Dine filer er stadig krypterede på din harddisk hele tiden.
|
addvault.new.readme.accessLocation.3=Filer du tilføjer til dette drev vil blive krypteret af Cryptomator. Du har arbejde med filerne ligesom enhver anden fil/mappe. Dette er blot en dekrypteret visning af indholdet. Dine filer er stadig krypterede på din harddisk hele tiden.
|
||||||
addvault.new.readme.accessLocation.4=Fjern denne fil hvis du har lyst.
|
addvault.new.readme.accessLocation.4=Fjern denne fil hvis du har lyst.
|
||||||
## Existing
|
## Existing
|
||||||
addvaultwizard.existing.instruction=Vælgt filen "vault.cryptomator" i mappen med dine boks-filer. Hvis der kun findes en fil med navnet "masterkey.cryptomator", skal du vælge den i stedet.
|
addvaultwizard.existing.instruction=Vælgt filen "vault.cryptomator" i mappen med dine boks-filer. Hvis der kun findes en fil med navnet "masterkey.cryptomator", skal du vælge den i stedet.
|
||||||
addvaultwizard.existing.chooseBtn=Vel…
|
addvaultwizard.existing.chooseBtn=Vælg…
|
||||||
addvaultwizard.existing.filePickerTitle=Vælg boks-fil
|
addvaultwizard.existing.filePickerTitle=Vælg boks-fil
|
||||||
addvaultwizard.existing.filePickerMimeDesc=Cryptomator boks
|
addvaultwizard.existing.filePickerMimeDesc=Cryptomator boks
|
||||||
## Success
|
## Success
|
||||||
addvaultwizard.success.nextStepsInstructions=Lagt til kvelven "%s".\nDu må låsa opp denne kvelven for å få tilgang til eller legga til innhald. Alternativt kan du låsa det opp på eit kva som helst seinare tidspunkt.
|
addvaultwizard.success.nextStepsInstructions=Tilføjede boks "%s".\nDu skal låse op for denne boks for at tilgå indholdet. Alternativt kan du låse den op på et senere tidspunkt.
|
||||||
addvaultwizard.success.unlockNow=Lås op nu
|
addvaultwizard.success.unlockNow=Lås op nu
|
||||||
|
|
||||||
# Remove Vault
|
# Remove Vault
|
||||||
removeVault.title=Fjern "%s"
|
removeVault.title=Fjern "%s"
|
||||||
removeVault.message=Fjern boks?
|
removeVault.message=Fjern boks?
|
||||||
removeVault.description=Dette får blot Cryptomator til at glemme boksen. Du kan tilføje den igen senere. Ingen krypterede filer bliver slettet fra harddisken.
|
removeVault.description=Dette får blot Cryptomator til at glemme boksen. Du kan tilføje den igen senere. Ingen krypterede filer bliver slettet fra harddisken.
|
||||||
removeVault.confirmBtn=Fjern kvelv
|
removeVault.confirmBtn=Fjern boks
|
||||||
|
|
||||||
# Change Password
|
# Change Password
|
||||||
changepassword.title=Byt passord
|
changepassword.title=Skift adgangskode
|
||||||
changepassword.enterOldPassword=Angiv den nuværende adgangskode for "%s"
|
changepassword.enterOldPassword=Angiv den nuværende adgangskode for "%s"
|
||||||
changepassword.finalConfirmation=Eg forstår at eg ikkje kan få tilgang til dataa mine viss eg gløymer passordet mitt
|
changepassword.finalConfirmation=Jeg er indforstået med at jeg ikke kan få adgang til mine data, hvis jeg glemmer min adgangskode
|
||||||
|
|
||||||
# Forget Password
|
# Forget Password
|
||||||
forgetPassword.title=Glemt adgangskode
|
forgetPassword.title=Glemt adgangskode
|
||||||
forgetPassword.message=Skal systemet holde op med at huske adgangskoden?
|
forgetPassword.message=Skal systemet holde op med at huske adgangskoden?
|
||||||
forgetPassword.description=Dette vil sletta det lagra passordet til denne kvelven frå systemnøkkelringen min.
|
forgetPassword.description=Dette vil slette den gemte adgangskode, til denne boks, fra dit system.
|
||||||
forgetPassword.confirmBtn=Gløym passord
|
forgetPassword.confirmBtn=Glem adgangskode
|
||||||
|
|
||||||
# Unlock
|
# Unlock
|
||||||
unlock.title=Lås op for "%s"
|
unlock.title=Lås op for "%s"
|
||||||
unlock.passwordPrompt=Indtast adgangskoden for "%s":
|
unlock.passwordPrompt=Indtast adgangskoden for "%s":
|
||||||
unlock.savePassword=Husk adgangskode
|
unlock.savePassword=Husk adgangskode
|
||||||
unlock.unlockBtn=Låse opp
|
unlock.unlockBtn=Lås op
|
||||||
## Select
|
## Select
|
||||||
unlock.chooseMasterkey.message=Hovednøgle-fil ikke fundet
|
unlock.chooseMasterkey.message=Hovednøgle-fil ikke fundet
|
||||||
unlock.chooseMasterkey.description=Cryptomator kunne ikke finde hovednøgle-filen for boksen "%s". Vælg venligst filen manuelt.
|
unlock.chooseMasterkey.description=Cryptomator kunne ikke finde hovednøgle-filen for boksen "%s". Vælg venligst filen manuelt.
|
||||||
unlock.chooseMasterkey.filePickerTitle=Vel hovudnøkkelfil
|
unlock.chooseMasterkey.filePickerTitle=Vælg hovednøgle-fil
|
||||||
unlock.chooseMasterkey.filePickerMimeDesc=Cryptomator hovednøgle
|
unlock.chooseMasterkey.filePickerMimeDesc=Cryptomator hovednøgle
|
||||||
## Success
|
## Success
|
||||||
unlock.success.message=Låst op
|
unlock.success.message=Låst op
|
||||||
@@ -154,6 +154,8 @@ hub.registerFailed.description=Der opstod en fejl i navngivnings-processen. Kig
|
|||||||
hub.unauthorized.message=Adgang nægtet
|
hub.unauthorized.message=Adgang nægtet
|
||||||
hub.unauthorized.description=Din enhed er endnu ikke blevet godkendt til at få adgang til denne boks. Spørg boks-ejeren om godkendelse.
|
hub.unauthorized.description=Din enhed er endnu ikke blevet godkendt til at få adgang til denne boks. Spørg boks-ejeren om godkendelse.
|
||||||
### License Exceeded
|
### License Exceeded
|
||||||
|
hub.invalidLicense.message=Ugyldig Hub licens
|
||||||
|
hub.invalidLicense.description=Din Cryptomator Hub har en ugyldig licens. Få venligst en Hub administrator til at opgradere eller forny licensen.
|
||||||
|
|
||||||
# Lock
|
# Lock
|
||||||
## Force
|
## Force
|
||||||
@@ -168,7 +170,7 @@ lock.fail.description=Boksen "%s" kunne ikke låses. Sørg for, at ikke-gemt arb
|
|||||||
# Migration
|
# Migration
|
||||||
migration.title=Opgradér boks
|
migration.title=Opgradér boks
|
||||||
## Start
|
## Start
|
||||||
migration.start.header=Oppgrader kvelv
|
migration.start.header=Opgradér boks
|
||||||
migration.start.text=For at åbne din boks "%s" i denne nye version af Cryptomator, skal boksen opgraderes til et nyere format. Før dette gøres, bør du vide følgende:
|
migration.start.text=For at åbne din boks "%s" i denne nye version af Cryptomator, skal boksen opgraderes til et nyere format. Før dette gøres, bør du vide følgende:
|
||||||
migration.start.remarkUndone=Denne opgradering kan ikke fortrydes.
|
migration.start.remarkUndone=Denne opgradering kan ikke fortrydes.
|
||||||
migration.start.remarkVersions=Ældre versioner af Cryptomator vil ikke være i stand til at åbne den opgraderede boks.
|
migration.start.remarkVersions=Ældre versioner af Cryptomator vil ikke være i stand til at åbne den opgraderede boks.
|
||||||
@@ -176,23 +178,23 @@ migration.start.remarkCanRun=Du skal være sikker på, at hver enhed, hvorfra du
|
|||||||
migration.start.remarkSynced=Du skal sikre at din boks er fuldt synkroniseret på denne enhed, og på dine andre enheder, før du opgraderer den.
|
migration.start.remarkSynced=Du skal sikre at din boks er fuldt synkroniseret på denne enhed, og på dine andre enheder, før du opgraderer den.
|
||||||
migration.start.confirm=Jeg har læst og forstået ovenstående oplysninger
|
migration.start.confirm=Jeg har læst og forstået ovenstående oplysninger
|
||||||
## Run
|
## Run
|
||||||
migration.run.enterPassword=Skriv inn passordet for "%s"
|
migration.run.enterPassword=Indtast adgangskoden for "%s"
|
||||||
migration.run.startMigrationBtn=Migrer kvelv
|
migration.run.startMigrationBtn=Migrér boks
|
||||||
migration.run.progressHint=Dette kan ta litt tid…
|
migration.run.progressHint=Dette kan tage noget tid…
|
||||||
## Success
|
## Success
|
||||||
migration.success.nextStepsInstructions=Vellykka migrering av "%s". Du kan no låsa opp kvelven din.
|
migration.success.nextStepsInstructions=Migrerede "%s" uden fejl.\nDu kan nu låse din boks op.
|
||||||
migration.success.unlockNow=Lås opp no
|
migration.success.unlockNow=Lås op nu
|
||||||
## Missing file system capabilities
|
## Missing file system capabilities
|
||||||
migration.error.missingFileSystemCapabilities.title=Filsystemet er ikkje støtta
|
migration.error.missingFileSystemCapabilities.title=Filsystem ikke understøttet
|
||||||
migration.error.missingFileSystemCapabilities.description=Migreringen vart ikkje starta fordi kvelven din ligg i eit mangelfullt filsystem.
|
migration.error.missingFileSystemCapabilities.description=Migreringen er ikke gået i gang, fordi din boks er placeret på et utilstrækkeligt filsystem.
|
||||||
migration.error.missingFileSystemCapabilities.reason.LONG_FILENAMES=Filsystemet støttar ikkje lange filnamn.
|
migration.error.missingFileSystemCapabilities.reason.LONG_FILENAMES=Filsystemet understøtter ikke lange filnavne.
|
||||||
migration.error.missingFileSystemCapabilities.reason.LONG_PATHS=Filsystemet støttar ikkje lange søkastiar.
|
migration.error.missingFileSystemCapabilities.reason.LONG_PATHS=Filsystemet understøtter ikke lange stier.
|
||||||
migration.error.missingFileSystemCapabilities.reason.READ_ACCESS=Filsystemet tillèt ikkje å bli lese.
|
migration.error.missingFileSystemCapabilities.reason.READ_ACCESS=Filsystemet tillader ikke læsning.
|
||||||
migration.error.missingFileSystemCapabilities.reason.WRITE_ACCESS=Filsystemet tillèt ikkje å bli skrive på.
|
migration.error.missingFileSystemCapabilities.reason.WRITE_ACCESS=Filsystemet tillader ikke at blive skrevet til.
|
||||||
## Impossible
|
## Impossible
|
||||||
migration.impossible.heading=Kunne ikkje overføra kvelven
|
migration.impossible.heading=Kan ikke migrere boks
|
||||||
migration.impossible.reason=Kvelven kan ikkje overførast automatisk fordi lagringsstaden eller tilgangspunkt ikkje er kompatibelt.
|
migration.impossible.reason=Boksen kan ikke automatisk migreres, fordi dens lagerplacering eller adgangspunkt ikke er kompatibel.
|
||||||
migration.impossible.moreInfo=Kvelven kan framleis opnast viss du bruker ein eldre versjon. For instruksjonar om korleis ein overfører ein kvelv, besøk
|
migration.impossible.moreInfo=Boksen kan stadig åbnes med en ældre version. For instruktioner om hvordan du manuelt migrerer en boks, besøg
|
||||||
|
|
||||||
# Health Check
|
# Health Check
|
||||||
## Start
|
## Start
|
||||||
@@ -247,14 +249,14 @@ health.fix.successTip=Repareret
|
|||||||
health.fix.failTip=Reparation fejlet. Se loggen for detaljer
|
health.fix.failTip=Reparation fejlet. Se loggen for detaljer
|
||||||
|
|
||||||
# Preferences
|
# Preferences
|
||||||
preferences.title=Innstillingar
|
preferences.title=Præferencer
|
||||||
## General
|
## General
|
||||||
preferences.general=Generelt
|
preferences.general=Generelt
|
||||||
preferences.general.startHidden=Skjul vindauget når du startar Cryptomator
|
preferences.general.startHidden=Skjul vinduet når Cryptomator starter
|
||||||
preferences.general.autoCloseVaults=Lås åbne bokse automatisk, når programmet afsluttes
|
preferences.general.autoCloseVaults=Lås åbne bokse automatisk, når programmet afsluttes
|
||||||
preferences.general.debugLogging=Aktivar protokollføring av feilsøk
|
preferences.general.debugLogging=Aktivér fejllogning
|
||||||
preferences.general.debugDirectory=Vis loggfiler
|
preferences.general.debugDirectory=Vis logfiler
|
||||||
preferences.general.autoStart=Start Cryptomator ved systemstart
|
preferences.general.autoStart=Start Cryptomator automatisk ved opstart
|
||||||
preferences.general.keychainBackend=Gem adgangskoder med
|
preferences.general.keychainBackend=Gem adgangskoder med
|
||||||
## Interface
|
## Interface
|
||||||
preferences.interface=Brugerflade
|
preferences.interface=Brugerflade
|
||||||
@@ -271,9 +273,11 @@ preferences.interface.interfaceOrientation.rtl=Højre til venstre
|
|||||||
preferences.interface.showMinimizeButton=Vis knap til minimering
|
preferences.interface.showMinimizeButton=Vis knap til minimering
|
||||||
preferences.interface.showTrayIcon=Vis ikon i system-bakken (kræver genstart)
|
preferences.interface.showTrayIcon=Vis ikon i system-bakken (kræver genstart)
|
||||||
## Volume
|
## Volume
|
||||||
preferences.volume=Virtuell eining
|
preferences.volume=Virtuelt drev
|
||||||
preferences.volume.type=Drev type (kræver genstart)
|
preferences.volume.type=Drev Type
|
||||||
preferences.volume.type.automatic=Automatisk
|
preferences.volume.type.automatic=Automatisk
|
||||||
|
preferences.volume.docsTooltip=Åbn dokumentationen for at lære mere om de forskellige typer drev.
|
||||||
|
preferences.volume.fuseRestartRequired=For at anvende ændringerne skal Cryptomator genstartes.
|
||||||
preferences.volume.tcp.port=TCP port
|
preferences.volume.tcp.port=TCP port
|
||||||
preferences.volume.supportedFeatures=Den valgte type drev understøtter følgende funktioner:
|
preferences.volume.supportedFeatures=Den valgte type drev understøtter følgende funktioner:
|
||||||
preferences.volume.feature.mountAuto=Automatisk valg af monteringspunkt
|
preferences.volume.feature.mountAuto=Automatisk valg af monteringspunkt
|
||||||
@@ -282,11 +286,11 @@ preferences.volume.feature.mountToDriveLetter=Enhedsbogstav som monteringspunkt
|
|||||||
preferences.volume.feature.mountFlags=Brugerdefinerede monteringsindstillinger
|
preferences.volume.feature.mountFlags=Brugerdefinerede monteringsindstillinger
|
||||||
preferences.volume.feature.readOnly=Skrivebeskyttet montering
|
preferences.volume.feature.readOnly=Skrivebeskyttet montering
|
||||||
## Updates
|
## Updates
|
||||||
preferences.updates=Oppdateringar
|
preferences.updates=Opdateringer
|
||||||
preferences.updates.currentVersion=Gjeldande versjon: %s
|
preferences.updates.currentVersion=Nuværende version: %s
|
||||||
preferences.updates.autoUpdateCheck=Sjå etter oppdateringar automatisk
|
preferences.updates.autoUpdateCheck=Søg automatisk efter opdateringer
|
||||||
preferences.updates.checkNowBtn=Sjekk no
|
preferences.updates.checkNowBtn=Kontrollér nu
|
||||||
preferences.updates.updateAvailable=Oppdatering til versjon %s er tilgjengeleg.
|
preferences.updates.updateAvailable=Opdatering til version %s er tilgængelig.
|
||||||
## Contribution
|
## Contribution
|
||||||
preferences.contribute=Støt os
|
preferences.contribute=Støt os
|
||||||
preferences.contribute.registeredFor=Registreret supporter-certifikat for %s
|
preferences.contribute.registeredFor=Registreret supporter-certifikat for %s
|
||||||
@@ -303,27 +307,27 @@ stats.title=Statistik for %s
|
|||||||
stats.cacheHitRate=Cache effektivitet
|
stats.cacheHitRate=Cache effektivitet
|
||||||
## Read
|
## Read
|
||||||
stats.read.throughput.idle=Læser: afventer
|
stats.read.throughput.idle=Læser: afventer
|
||||||
stats.read.throughput.kibs=Læser: %.2f kiB/s
|
stats.read.throughput.kibs=Læser: %.2f KiB/s
|
||||||
stats.read.throughput.mibs=Læser: %.2f MiB/s
|
stats.read.throughput.mibs=Læser: %.2f MiB/s
|
||||||
stats.read.total.data.none=Data læst: -
|
stats.read.total.data.none=Data læst: -
|
||||||
stats.read.total.data.kib=Data læst: %.1f kiB
|
stats.read.total.data.kib=Data læst: %.1f KiB
|
||||||
stats.read.total.data.mib=Data læst: %.1f MiB
|
stats.read.total.data.mib=Data læst: %.1f MiB
|
||||||
stats.read.total.data.gib=Data læst: %.1f GiB
|
stats.read.total.data.gib=Data læst: %.1f GiB
|
||||||
stats.decr.total.data.none=Data dekrypteret: -
|
stats.decr.total.data.none=Data dekrypteret: -
|
||||||
stats.decr.total.data.kib=Data dekrypteret: %.1f kiB
|
stats.decr.total.data.kib=Data dekrypteret: %.1f KiB
|
||||||
stats.decr.total.data.mib=Data dekrypteret: %.1f MiB
|
stats.decr.total.data.mib=Data dekrypteret: %.1f MiB
|
||||||
stats.decr.total.data.gib=Data dekrypteret: %.1f GiB
|
stats.decr.total.data.gib=Data dekrypteret: %.1f GiB
|
||||||
stats.read.accessCount=Totalt antal læsninger: %d
|
stats.read.accessCount=Totalt antal læsninger: %d
|
||||||
## Write
|
## Write
|
||||||
stats.write.throughput.idle=Skriver: afventer
|
stats.write.throughput.idle=Skriver: afventer
|
||||||
stats.write.throughput.kibs=Skriver: %.2f kiB/s
|
stats.write.throughput.kibs=Skriver: %.2f KiB/s
|
||||||
stats.write.throughput.mibs=Skriver: %.2f MiB/s
|
stats.write.throughput.mibs=Skriver: %.2f MiB/s
|
||||||
stats.write.total.data.none=Data skrevet: -
|
stats.write.total.data.none=Data skrevet: -
|
||||||
stats.write.total.data.kib=Data skrevet: %.1f kiB
|
stats.write.total.data.kib=Data skrevet: %.1f KiB
|
||||||
stats.write.total.data.mib=Data skrevet: %.1f MiB
|
stats.write.total.data.mib=Data skrevet: %.1f MiB
|
||||||
stats.write.total.data.gib=Data skrevet: %.1f GiB
|
stats.write.total.data.gib=Data skrevet: %.1f GiB
|
||||||
stats.encr.total.data.none=Data krypteret: -
|
stats.encr.total.data.none=Data krypteret: -
|
||||||
stats.encr.total.data.kib=Data krypteret: %.1f kiB
|
stats.encr.total.data.kib=Data krypteret: %.1f KiB
|
||||||
stats.encr.total.data.mib=Data krypteret: %.1f MiB
|
stats.encr.total.data.mib=Data krypteret: %.1f MiB
|
||||||
stats.encr.total.data.gib=Data krypteret: %.1f GiB
|
stats.encr.total.data.gib=Data krypteret: %.1f GiB
|
||||||
stats.write.accessCount=Totalt antal skrivninger: %d
|
stats.write.accessCount=Totalt antal skrivninger: %d
|
||||||
@@ -334,39 +338,39 @@ stats.access.total=Samlede adgang: %d
|
|||||||
|
|
||||||
|
|
||||||
# Main Window
|
# Main Window
|
||||||
main.closeBtn.tooltip=Lukk
|
main.closeBtn.tooltip=Luk
|
||||||
main.minimizeBtn.tooltip=Minimer
|
main.minimizeBtn.tooltip=Minimér
|
||||||
main.preferencesBtn.tooltip=Innstillingar
|
main.preferencesBtn.tooltip=Præferencer
|
||||||
main.debugModeEnabled.tooltip=Fejlfindingstilstand er aktiveret
|
main.debugModeEnabled.tooltip=Fejlfindingstilstand er aktiveret
|
||||||
main.supporterCertificateMissing.tooltip=Ver vennleg og vurder å donera
|
main.supporterCertificateMissing.tooltip=Overvej venligst at donere
|
||||||
## Vault List
|
## Vault List
|
||||||
main.vaultlist.emptyList.onboardingInstruction=Klikk her for å legga til ein kvelv
|
main.vaultlist.emptyList.onboardingInstruction=Klik her for at tilføje en boks
|
||||||
main.vaultlist.contextMenu.remove=Fjern…
|
main.vaultlist.contextMenu.remove=Fjern…
|
||||||
main.vaultlist.contextMenu.lock=Lås
|
main.vaultlist.contextMenu.lock=Lås
|
||||||
main.vaultlist.contextMenu.unlock=Lås opp…
|
main.vaultlist.contextMenu.unlock=Lås op…
|
||||||
main.vaultlist.contextMenu.unlockNow=Lås opp no
|
main.vaultlist.contextMenu.unlockNow=Lås op nu
|
||||||
main.vaultlist.contextMenu.vaultoptions=Vis boksindstillinger
|
main.vaultlist.contextMenu.vaultoptions=Vis boksindstillinger
|
||||||
main.vaultlist.contextMenu.reveal=Gjer eininga synleg
|
main.vaultlist.contextMenu.reveal=Vis drev
|
||||||
main.vaultlist.addVaultBtn=Legg til kvelv
|
main.vaultlist.addVaultBtn=Tilføj boks
|
||||||
## Vault Detail
|
## Vault Detail
|
||||||
### Welcome
|
### Welcome
|
||||||
main.vaultDetail.welcomeOnboarding=Takk for at du valde Cryptomator for å verna filene dine. Viss du treng hjelp, sjekk ut guidane våre for å komma i gang:
|
main.vaultDetail.welcomeOnboarding=Tak fordi du valgte Cryptomator til at beskytte dine filer. Hvis du har brug for hjælp, så tjek vores guider for at komme i gang:
|
||||||
### Locked
|
### Locked
|
||||||
main.vaultDetail.lockedStatus=LÅST
|
main.vaultDetail.lockedStatus=LÅST
|
||||||
main.vaultDetail.unlockBtn=Lås opp…
|
main.vaultDetail.unlockBtn=Lås op…
|
||||||
main.vaultDetail.unlockNowBtn=Lås opp no
|
main.vaultDetail.unlockNowBtn=Lås op nu
|
||||||
main.vaultDetail.optionsBtn=Alternativ for kvelven
|
main.vaultDetail.optionsBtn=Boksindstillinger
|
||||||
main.vaultDetail.passwordSavedInKeychain=Passordet er lagra
|
main.vaultDetail.passwordSavedInKeychain=Adgangskode gemt
|
||||||
### Unlocked
|
### Unlocked
|
||||||
main.vaultDetail.unlockedStatus=ULÅST
|
main.vaultDetail.unlockedStatus=LÅST OP
|
||||||
main.vaultDetail.accessLocation=Innhaldet i kvelven din er tilgjengeleg her:
|
main.vaultDetail.accessLocation=Boksens indhold er tilgængeligt her:
|
||||||
main.vaultDetail.revealBtn=Gjer eininga synleg
|
main.vaultDetail.revealBtn=Vis drev
|
||||||
main.vaultDetail.copyUri=Kopiér URI
|
main.vaultDetail.copyUri=Kopiér URI
|
||||||
main.vaultDetail.lockBtn=Lås
|
main.vaultDetail.lockBtn=Lås
|
||||||
main.vaultDetail.bytesPerSecondRead=Lesafart:
|
main.vaultDetail.bytesPerSecondRead=Læser:
|
||||||
main.vaultDetail.bytesPerSecondWritten=Skriver:
|
main.vaultDetail.bytesPerSecondWritten=Skriver:
|
||||||
main.vaultDetail.throughput.idle=inaktiv
|
main.vaultDetail.throughput.idle=afventer
|
||||||
main.vaultDetail.throughput.kbps=%.1f kiB/s
|
main.vaultDetail.throughput.kbps=%.1f KiB/s
|
||||||
main.vaultDetail.throughput.mbps=%.1f MiB/s
|
main.vaultDetail.throughput.mbps=%.1f MiB/s
|
||||||
main.vaultDetail.stats=Boks statistik
|
main.vaultDetail.stats=Boks statistik
|
||||||
main.vaultDetail.locateEncryptedFileBtn=Find Krypteret Fil
|
main.vaultDetail.locateEncryptedFileBtn=Find Krypteret Fil
|
||||||
@@ -374,99 +378,102 @@ main.vaultDetail.locateEncryptedFileBtn.tooltip=Vælg en fil fra din boks for at
|
|||||||
main.vaultDetail.encryptedPathsCopied=Stier kopieret!
|
main.vaultDetail.encryptedPathsCopied=Stier kopieret!
|
||||||
main.vaultDetail.filePickerTitle=Vælg fil inde i boks
|
main.vaultDetail.filePickerTitle=Vælg fil inde i boks
|
||||||
### Missing
|
### Missing
|
||||||
main.vaultDetail.missing.info=Cryptomator kunne ikkje finna ein kvelv på denne søkastien.
|
main.vaultDetail.missing.info=Cryptomator kunne ikke finde en boks på denne sti.
|
||||||
main.vaultDetail.missing.recheck=Kontroller igjen
|
main.vaultDetail.missing.recheck=Kontrollér igen
|
||||||
main.vaultDetail.missing.remove=Fjern fra listen over bokse…
|
main.vaultDetail.missing.remove=Fjern fra listen over bokse…
|
||||||
main.vaultDetail.missing.changeLocation=Skift placering for boks…
|
main.vaultDetail.missing.changeLocation=Skift placering for boks…
|
||||||
### Needs Migration
|
### Needs Migration
|
||||||
main.vaultDetail.migrateButton=Oppgrader kvelv
|
main.vaultDetail.migrateButton=Opgradér boks
|
||||||
main.vaultDetail.migratePrompt=Kvelven din må oppgraderast til eit nytt format før du kan få tilgang til det
|
main.vaultDetail.migratePrompt=Din boks skal opgraderes til et nyt format, før du kan tilgå den
|
||||||
### Error
|
### Error
|
||||||
main.vaultDetail.error.info=Der opstod en fejl under læsning af din boks.
|
main.vaultDetail.error.info=Der opstod en fejl under læsning af din boks.
|
||||||
main.vaultDetail.error.reload=Genindlæs
|
main.vaultDetail.error.reload=Genindlæs
|
||||||
main.vaultDetail.error.windowTitle=Fejl ved indlæsning af boks
|
main.vaultDetail.error.windowTitle=Fejl ved indlæsning af boks
|
||||||
|
|
||||||
# Wrong File Alert
|
# Wrong File Alert
|
||||||
wrongFileAlert.title=Slik krypterer du filer
|
wrongFileAlert.title=Sådan krypterer du filer
|
||||||
wrongFileAlert.message=Prøvde du å kryptera desse filene?
|
wrongFileAlert.message=Forsøgte du at kryptere disse filer?
|
||||||
wrongFileAlert.description=For dette formålet gir Cryptomator eit volum i systemfilbehandlaren.
|
wrongFileAlert.description=Til dette formål opretter Cryptomator et drev i din filhåndtering.
|
||||||
wrongFileAlert.instruction.0=Følg desse trinna for å kryptera filer:
|
wrongFileAlert.instruction.0=Følg disse trin for at kryptere filer:
|
||||||
wrongFileAlert.instruction.1=1. Lås opp kvelven din.
|
wrongFileAlert.instruction.1=1. Lås din boks op.
|
||||||
wrongFileAlert.instruction.2=2. Klikk på "Gjør synleg" for å opna volumet i filbehandlaren din.
|
wrongFileAlert.instruction.2=2. Klik på "Vis drev" for at åbne drevet i din stifinder.
|
||||||
wrongFileAlert.instruction.3=3. Legg filene dine til dette volumet.
|
wrongFileAlert.instruction.3=3. Tilføj filer til drevet.
|
||||||
wrongFileAlert.link=For ytterlegare hjelp, besøk
|
wrongFileAlert.link=For yderligere assistance, besøg
|
||||||
|
|
||||||
# Vault Options
|
# Vault Options
|
||||||
## General
|
## General
|
||||||
vaultOptions.general=Generelt
|
vaultOptions.general=Generelt
|
||||||
vaultOptions.general.vaultName=Namn på kvelven
|
vaultOptions.general.vaultName=Boks-navn
|
||||||
vaultOptions.general.autoLock.lockAfterTimePart1=Lås efter inaktivitet i
|
vaultOptions.general.autoLock.lockAfterTimePart1=Lås efter inaktivitet i
|
||||||
vaultOptions.general.autoLock.lockAfterTimePart2=minutter
|
vaultOptions.general.autoLock.lockAfterTimePart2=minutter
|
||||||
vaultOptions.general.unlockAfterStartup=Lås opp kvelven når du startar Cryptomator
|
vaultOptions.general.unlockAfterStartup=Lås boksen op når Cryptomator starter
|
||||||
vaultOptions.general.actionAfterUnlock=Etter vellykka opplåsing
|
vaultOptions.general.actionAfterUnlock=Efter oplåsning af boks
|
||||||
vaultOptions.general.actionAfterUnlock.ignore=Ikkje gjer noko
|
vaultOptions.general.actionAfterUnlock.ignore=Gør intet
|
||||||
vaultOptions.general.actionAfterUnlock.reveal=Gjer eininga synleg
|
vaultOptions.general.actionAfterUnlock.reveal=Vis drev
|
||||||
vaultOptions.general.actionAfterUnlock.ask=Spør
|
vaultOptions.general.actionAfterUnlock.ask=Spørg
|
||||||
vaultOptions.general.startHealthCheckBtn=Start sunhedstjek
|
vaultOptions.general.startHealthCheckBtn=Start sunhedstjek
|
||||||
|
|
||||||
## Mount
|
## Mount
|
||||||
vaultOptions.mount=Montering
|
vaultOptions.mount=Montering
|
||||||
vaultOptions.mount.info=Valgmulighederne afhænger af den valgte type drev.
|
vaultOptions.mount.info=Valgmulighederne afhænger af den valgte type drev.
|
||||||
vaultOptions.mount.linkToPreferences=Åbn virtuelle drev præferencer
|
vaultOptions.mount.linkToPreferences=Åbn virtuelle drev præferencer
|
||||||
vaultOptions.mount.readonly=Skriveverna
|
vaultOptions.mount.readonly=Skrivebeskyttet
|
||||||
vaultOptions.mount.customMountFlags=Tilpassa moteringparametrar
|
vaultOptions.mount.customMountFlags=Brugerdefinerede monterings-flag
|
||||||
vaultOptions.mount.winDriveLetterOccupied=opptatt
|
vaultOptions.mount.winDriveLetterOccupied=optaget
|
||||||
vaultOptions.mount.mountPoint=Monteringspunkt
|
vaultOptions.mount.mountPoint=Monterings-sted
|
||||||
vaultOptions.mount.mountPoint.auto=Vel ein passande stad automatisk
|
vaultOptions.mount.mountPoint.auto=Vælg automatisk en passende placering
|
||||||
vaultOptions.mount.mountPoint.driveLetter=Bruk tildelt einingsbokstav
|
vaultOptions.mount.mountPoint.driveLetter=Brug et ledigt drevbogstav
|
||||||
vaultOptions.mount.mountPoint.custom=Brug en valgt mappe
|
vaultOptions.mount.mountPoint.custom=Brug en valgt mappe
|
||||||
vaultOptions.mount.mountPoint.directoryPickerButton=Vel…
|
vaultOptions.mount.mountPoint.directoryPickerButton=Vælg…
|
||||||
vaultOptions.mount.mountPoint.directoryPickerTitle=Vælg en mappe
|
vaultOptions.mount.mountPoint.directoryPickerTitle=Vælg en mappe
|
||||||
## Master Key
|
## Master Key
|
||||||
vaultOptions.masterkey=Passord
|
vaultOptions.masterkey=Adgangskode
|
||||||
vaultOptions.masterkey.changePasswordBtn=Byt passord
|
vaultOptions.masterkey.changePasswordBtn=Skift adgangskode
|
||||||
vaultOptions.masterkey.forgetSavedPasswordBtn=Gløym passord
|
vaultOptions.masterkey.forgetSavedPasswordBtn=Glem gemt adgangskode
|
||||||
vaultOptions.masterkey.recoveryKeyExplanation=Ein "retta opp igjen"-nøkkel er den einaste måten å retta opp igjen tilgangen til ein kvelv på viss du mistar passordet.
|
vaultOptions.masterkey.recoveryKeyExplanation=En gendannelsesnøgle er den eneste måde du kan få adgang til din boks på, hvis du har glemt dit password.
|
||||||
vaultOptions.masterkey.showRecoveryKeyBtn=Vis 'Retta opp igjen'-nøkkelen
|
vaultOptions.masterkey.showRecoveryKeyBtn=Vis gendannelsesnøgle
|
||||||
vaultOptions.masterkey.recoverPasswordBtn=Nulstil adgangskode
|
vaultOptions.masterkey.recoverPasswordBtn=Nulstil adgangskode
|
||||||
|
## Hub
|
||||||
|
|
||||||
# Recovery Key
|
# Recovery Key
|
||||||
## Display Recovery Key
|
## Display Recovery Key
|
||||||
recoveryKey.display.title=Vis gendannelsesnøgle
|
recoveryKey.display.title=Vis gendannelsesnøgle
|
||||||
recoveryKey.create.message=Adgangskode krævet
|
recoveryKey.create.message=Adgangskode krævet
|
||||||
recoveryKey.create.description=Skriv inn passordet ditt for å visa 'Retta opp igjen'-nøkkelen for "%s":
|
recoveryKey.create.description=Indtast adgangskoden for "%s", for at vise gendannelsesnøglen.
|
||||||
recoveryKey.display.description=Følgjande gjenopprettingsnøkkel kan brukast til å retta opp igjen tilgang til "%s":
|
recoveryKey.display.description=Den følgende gendannelsesnøgle kan bruges til at genskabe adgang til "%s":
|
||||||
recoveryKey.display.StorageHints=Ta vare på han ein veldig sikker stad, t.d. ved å:\n • Lagre han ved hjelp av ein passordkvelv\n • Lagre han på ein USB-minnepenn\n • Skrive han ut på papir
|
recoveryKey.display.StorageHints=Opbevar den et meget sikkert sted, som fx:\n • Gem den i din adgangskode-manager\n • Gem den på et USB-drev\n • Print den ud på papir
|
||||||
## Reset Password
|
## Reset Password
|
||||||
### Enter Recovery Key
|
### Enter Recovery Key
|
||||||
recoveryKey.recover.title=Nulstil adgangskode
|
recoveryKey.recover.title=Nulstil adgangskode
|
||||||
recoveryKey.recover.prompt=Skriv inn gjenopprettingsnøkkelen for "%s":
|
recoveryKey.recover.correctKey=Dette er en gyldig gendannelsesnøgle
|
||||||
recoveryKey.recover.correctKey=Dette er ein gyldig gjenopprettingsnøkkel
|
recoveryKey.recover.wrongKey=Denne gendannelsesnøgle tilhører en anden boks
|
||||||
recoveryKey.printout.heading=Cryptomator-gjenopprettingsnøkkel\n"%s"\n
|
recoveryKey.recover.invalidKey=Denne gendannelsesnøgle er ikke gyldig
|
||||||
|
recoveryKey.printout.heading=Cryptomator gendannelsesnøgle\n"%s"\n
|
||||||
### Reset Password
|
### Reset Password
|
||||||
recoveryKey.recover.resetBtn=Nulstil
|
recoveryKey.recover.resetBtn=Nulstil
|
||||||
### Recovery Key Password Reset Success
|
### Recovery Key Password Reset Success
|
||||||
recoveryKey.recover.resetSuccess.message=Adgangskod nulstillet
|
recoveryKey.recover.resetSuccess.message=Adgangskod nulstillet
|
||||||
recoveryKey.recover.resetSuccess.description=Du kan nu låse din boks op med den nye adgangskode.
|
recoveryKey.recover.resetSuccess.description=Du kan nu låse din boks op med den nye adgangskode.
|
||||||
|
|
||||||
|
# Convert Vault
|
||||||
|
|
||||||
# New Password
|
# New Password
|
||||||
newPassword.promptText=Skriv inn eit nytt passord
|
newPassword.promptText=Skriv en ny adgangskode
|
||||||
newPassword.reenterPassword=Stadfest det nye passordet
|
newPassword.reenterPassword=Bekræft ny adgangskode
|
||||||
newPassword.passwordsMatch=Passorda samsvarer!
|
newPassword.passwordsMatch=Adgangskoderne er ens!
|
||||||
newPassword.passwordsDoNotMatch=Passorda samsvarer ikkje
|
newPassword.passwordsDoNotMatch=Adgangskoder stemmer ikke overens
|
||||||
passwordStrength.messageLabel.tooShort=Bruk minst %d teikn
|
passwordStrength.messageLabel.tooShort=Brug mindst %d tegn
|
||||||
passwordStrength.messageLabel.0=Veldig svakt
|
passwordStrength.messageLabel.0=Meget svag
|
||||||
passwordStrength.messageLabel.1=Svakt
|
passwordStrength.messageLabel.1=Svag
|
||||||
passwordStrength.messageLabel.2=Ok
|
passwordStrength.messageLabel.2=Rimelig
|
||||||
passwordStrength.messageLabel.3=Sterkt
|
passwordStrength.messageLabel.3=Stærk
|
||||||
passwordStrength.messageLabel.4=Veldig sterkt
|
passwordStrength.messageLabel.4=Meget god
|
||||||
|
|
||||||
# Quit
|
# Quit
|
||||||
quit.title=Afslut program
|
quit.title=Afslut program
|
||||||
quit.message=Der er ulåste bokse
|
quit.message=Der er ulåste bokse
|
||||||
quit.description=Bekræft venligst, at du vil afslutte. Cryptomator låser alle ulåste bokse for at forhindre tab af data.
|
quit.description=Bekræft venligst, at du vil afslutte. Cryptomator låser alle ulåste bokse for at forhindre tab af data.
|
||||||
quit.lockAndQuitBtn=Lås og avslutt
|
quit.lockAndQuitBtn=Lås og afslut
|
||||||
|
|
||||||
# Forced Quit
|
# Forced Quit
|
||||||
quit.forced.message=Nogle bokse kunne ikke låses
|
quit.forced.message=Nogle bokse kunne ikke låses
|
||||||
|
|||||||
@@ -124,12 +124,12 @@ unlock.success.rememberChoice=Auswahl merken und nicht mehr fragen
|
|||||||
unlock.success.revealBtn=Laufwerk anzeigen
|
unlock.success.revealBtn=Laufwerk anzeigen
|
||||||
## Failure
|
## Failure
|
||||||
unlock.error.customPath.message=Tresor kann nicht an benutzerdefinierten Pfad eingehängt werden
|
unlock.error.customPath.message=Tresor kann nicht an benutzerdefinierten Pfad eingehängt werden
|
||||||
unlock.error.customPath.description.notSupported=Wenn du den benutzerdefinierten Pfad weiter verwenden möchtest, gehe bitte in die Einstellungen und wähle einen Laufwerkstyp, der ihn unterstützt. Andernfalls gehe zu den Tresoroptionen und wähle einen unterstützten Einhängepunkt.
|
unlock.error.customPath.description.notSupported=Wenn du weiterhin den benutzerdefinierten Pfad verwenden möchtest, öffne die allgemeinen Einstellungen und wähle einen unterstützten Laufwerkstyp. Andernfalls gehe zu den Tresor-Optionen und wähle einen unterstützten Einhängepunkt.
|
||||||
unlock.error.customPath.description.notExists=Der benutzerdefinierte Einhängepfad existiert nicht. Erstelle ihn entweder in deinem lokalen Dateisystem oder ändere ihn in den Tresoreinstellungen.
|
unlock.error.customPath.description.notExists=Der benutzerdefinierte Einhängepunkt existiert nicht. Entweder erstelle ihn in deinem lokalen Dateisystem oder ändere ihn in den Tresor-Optionen.
|
||||||
unlock.error.customPath.description.generic=Du hast einen benutzerdefinierten Einhängepfad für diesen Tresor ausgewählt, aber die Verwendung ist fehlgeschlagen. Fehlermeldung: %s
|
unlock.error.customPath.description.generic=Du hast für diesen Tresor einen benutzerdefinierten Einhängepunkt ausgewählt, aber die Verwendung ist fehlgeschlagen mit der Meldung: %s
|
||||||
## Hub
|
## Hub
|
||||||
hub.noKeychain.message=Zugriff auf Geräteschlüssel nicht möglich
|
hub.noKeychain.message=Zugriff auf Geräteschlüssel nicht möglich
|
||||||
hub.noKeychain.description=Um Hub Tresore zu entsperren, wird ein Geräteschlüssel benötigt, der mit einem Schlüsselbund gesichert ist. Um fortzufahren, aktiviere “%s” und wähle einen Schlüsselbund in den Einstellungen.
|
hub.noKeychain.description=Zum Entsperren von Hub-Tresoren wird ein Geräteschlüssel benötigt, der in einem Schlüsselbund gesichert ist. Um fortzufahren, aktiviere „%s“ und wähle in den Einstellungen einen Schlüsselbund.
|
||||||
hub.noKeychain.openBtn=Einstellungen öffnen
|
hub.noKeychain.openBtn=Einstellungen öffnen
|
||||||
### Waiting
|
### Waiting
|
||||||
hub.auth.message=Warten auf Authentifizierung …
|
hub.auth.message=Warten auf Authentifizierung …
|
||||||
@@ -154,6 +154,8 @@ hub.registerFailed.description=Während der Namensvergabe wurde ein Fehler ausge
|
|||||||
hub.unauthorized.message=Zugriff verweigert
|
hub.unauthorized.message=Zugriff verweigert
|
||||||
hub.unauthorized.description=Dein Gerät wurde noch nicht für den Zugriff auf diesen Tresor autorisiert. Bitte den Tresorbesitzer, dein Gerät zu autorisieren.
|
hub.unauthorized.description=Dein Gerät wurde noch nicht für den Zugriff auf diesen Tresor autorisiert. Bitte den Tresorbesitzer, dein Gerät zu autorisieren.
|
||||||
### License Exceeded
|
### License Exceeded
|
||||||
|
hub.invalidLicense.message=Hub-Lizenz ungültig
|
||||||
|
hub.invalidLicense.description=Die Lizenz für deine Cryptomator Hub-Instanz ist ungültig. Bitte informiere einen Hub-Administrator, um die Lizenz zu aktualisieren oder zu erneuern.
|
||||||
|
|
||||||
# Lock
|
# Lock
|
||||||
## Force
|
## Force
|
||||||
@@ -242,8 +244,8 @@ health.result.fixStateFilter.fixing=Wird repariert …
|
|||||||
health.result.fixStateFilter.fixed=Repariert
|
health.result.fixStateFilter.fixed=Repariert
|
||||||
health.result.fixStateFilter.fixFailed=Reparatur gescheitert
|
health.result.fixStateFilter.fixFailed=Reparatur gescheitert
|
||||||
## Fix Application
|
## Fix Application
|
||||||
health.fix.fixBtn=Beheben
|
health.fix.fixBtn=Reparieren
|
||||||
health.fix.successTip=Fehlerbehebung erfolgreich
|
health.fix.successTip=Reparatur erfolgreich
|
||||||
health.fix.failTip=Reparatur fehlgeschlagen, siehe Protokoll für Details
|
health.fix.failTip=Reparatur fehlgeschlagen, siehe Protokoll für Details
|
||||||
|
|
||||||
# Preferences
|
# Preferences
|
||||||
@@ -271,10 +273,11 @@ preferences.interface.interfaceOrientation.rtl=Von rechts nach links
|
|||||||
preferences.interface.showMinimizeButton=Schaltfläche zum Minimieren anzeigen
|
preferences.interface.showMinimizeButton=Schaltfläche zum Minimieren anzeigen
|
||||||
preferences.interface.showTrayIcon=Symbol im Infobereich anzeigen (Neustart erforderlich)
|
preferences.interface.showTrayIcon=Symbol im Infobereich anzeigen (Neustart erforderlich)
|
||||||
## Volume
|
## Volume
|
||||||
preferences.volume=Tresorlaufwerk
|
preferences.volume=Virtuelles Laufwerk
|
||||||
preferences.volume.type=Laufwerkstyp (Neustart erforderlich)
|
preferences.volume.type=Laufwerkstyp
|
||||||
preferences.volume.type.automatic=Automatisch
|
preferences.volume.type.automatic=Automatisch
|
||||||
preferences.volume.docsTooltip=Öffne die Dokumentation, um mehr über die verschiedenen Laufwerkstypen zu erfahren.
|
preferences.volume.docsTooltip=Öffne die Dokumentation, um mehr über die verschiedenen Laufwerkstypen zu erfahren.
|
||||||
|
preferences.volume.fuseRestartRequired=Um die Änderungen anzuwenden, muss Cryptomator neu gestartet werden.
|
||||||
preferences.volume.tcp.port=TCP-Port
|
preferences.volume.tcp.port=TCP-Port
|
||||||
preferences.volume.supportedFeatures=Der gewählte Laufwerkstyp unterstützt folgende Funktionen:
|
preferences.volume.supportedFeatures=Der gewählte Laufwerkstyp unterstützt folgende Funktionen:
|
||||||
preferences.volume.feature.mountAuto=Automatische Einhängepunkt Auswahl
|
preferences.volume.feature.mountAuto=Automatische Einhängepunkt Auswahl
|
||||||
@@ -304,27 +307,27 @@ stats.title=Statistiken für %s
|
|||||||
stats.cacheHitRate=Cache-Trefferrate
|
stats.cacheHitRate=Cache-Trefferrate
|
||||||
## Read
|
## Read
|
||||||
stats.read.throughput.idle=Leserate: inaktiv
|
stats.read.throughput.idle=Leserate: inaktiv
|
||||||
stats.read.throughput.kibs=Leserate: %.2f kiB/s
|
stats.read.throughput.kibs=Leserate: %.2f KiB/s
|
||||||
stats.read.throughput.mibs=Leserate: %.2f MiB/s
|
stats.read.throughput.mibs=Leserate: %.2f MiB/s
|
||||||
stats.read.total.data.none=Gelesen: -
|
stats.read.total.data.none=Gelesen: -
|
||||||
stats.read.total.data.kib=Gelesen: %.1f kiB
|
stats.read.total.data.kib=Gelesen: %.1f KiB
|
||||||
stats.read.total.data.mib=Gelesen: %.1f MiB
|
stats.read.total.data.mib=Gelesen: %.1f MiB
|
||||||
stats.read.total.data.gib=Gelesen: %.1f GiB
|
stats.read.total.data.gib=Gelesen: %.1f GiB
|
||||||
stats.decr.total.data.none=Entschlüsselt: -
|
stats.decr.total.data.none=Entschlüsselt: -
|
||||||
stats.decr.total.data.kib=Entschlüsselt: %.1f kiB
|
stats.decr.total.data.kib=Entschlüsselt: %.1f KiB
|
||||||
stats.decr.total.data.mib=Entschlüsselt: %.1f MiB
|
stats.decr.total.data.mib=Entschlüsselt: %.1f MiB
|
||||||
stats.decr.total.data.gib=Entschlüsselt: %.1f GiB
|
stats.decr.total.data.gib=Entschlüsselt: %.1f GiB
|
||||||
stats.read.accessCount=Lesezugriffe: %d
|
stats.read.accessCount=Lesezugriffe: %d
|
||||||
## Write
|
## Write
|
||||||
stats.write.throughput.idle=Schreibrate: inaktiv
|
stats.write.throughput.idle=Schreibrate: inaktiv
|
||||||
stats.write.throughput.kibs=Schreibrate: %.2f kiB/s
|
stats.write.throughput.kibs=Schreibrate: %.2f KiB/s
|
||||||
stats.write.throughput.mibs=Schreibrate: %.2f MiB/s
|
stats.write.throughput.mibs=Schreibrate: %.2f MiB/s
|
||||||
stats.write.total.data.none=Geschrieben: -
|
stats.write.total.data.none=Geschrieben: -
|
||||||
stats.write.total.data.kib=Geschrieben: %.1f kiB
|
stats.write.total.data.kib=Geschrieben: %.1f KiB
|
||||||
stats.write.total.data.mib=Geschrieben: %.1f MiB
|
stats.write.total.data.mib=Geschrieben: %.1f MiB
|
||||||
stats.write.total.data.gib=Geschrieben: %.1f GiB
|
stats.write.total.data.gib=Geschrieben: %.1f GiB
|
||||||
stats.encr.total.data.none=Verschlüsselt: -
|
stats.encr.total.data.none=Verschlüsselt: -
|
||||||
stats.encr.total.data.kib=Verschlüsselt: %.1f kiB
|
stats.encr.total.data.kib=Verschlüsselt: %.1f KiB
|
||||||
stats.encr.total.data.mib=Verschlüsselt: %.1f MiB
|
stats.encr.total.data.mib=Verschlüsselt: %.1f MiB
|
||||||
stats.encr.total.data.gib=Verschlüsselt: %.1f GiB
|
stats.encr.total.data.gib=Verschlüsselt: %.1f GiB
|
||||||
stats.write.accessCount=Schreibzugriffe: %d
|
stats.write.accessCount=Schreibzugriffe: %d
|
||||||
@@ -367,12 +370,12 @@ main.vaultDetail.lockBtn=Sperren
|
|||||||
main.vaultDetail.bytesPerSecondRead=Leserate:
|
main.vaultDetail.bytesPerSecondRead=Leserate:
|
||||||
main.vaultDetail.bytesPerSecondWritten=Schreibrate:
|
main.vaultDetail.bytesPerSecondWritten=Schreibrate:
|
||||||
main.vaultDetail.throughput.idle=inaktiv
|
main.vaultDetail.throughput.idle=inaktiv
|
||||||
main.vaultDetail.throughput.kbps=%.1f kiB/s
|
main.vaultDetail.throughput.kbps=%.1f KiB/s
|
||||||
main.vaultDetail.throughput.mbps=%.1f MiB/s
|
main.vaultDetail.throughput.mbps=%.1f MiB/s
|
||||||
main.vaultDetail.stats=Tresorstatistik
|
main.vaultDetail.stats=Tresorstatistik
|
||||||
main.vaultDetail.locateEncryptedFileBtn=Verschlüsselte Datei finden
|
main.vaultDetail.locateEncryptedFileBtn=Verschlüsselte Datei finden
|
||||||
main.vaultDetail.locateEncryptedFileBtn.tooltip=Wähle eine Datei aus deinem Tresor aus, um das verschlüsselte Gegenstück zu finden
|
main.vaultDetail.locateEncryptedFileBtn.tooltip=Wähle eine Datei aus deinem Tresor aus, um das verschlüsselte Gegenstück zu finden
|
||||||
main.vaultDetail.encryptedPathsCopied=Pfade in die Zwischenablage kopiert!
|
main.vaultDetail.encryptedPathsCopied=Pfade in Zwischenablage kopiert!
|
||||||
main.vaultDetail.filePickerTitle=Datei im Tresor auswählen
|
main.vaultDetail.filePickerTitle=Datei im Tresor auswählen
|
||||||
### Missing
|
### Missing
|
||||||
main.vaultDetail.missing.info=Cryptomator konnte keinen Tresor mit diesem Pfad finden.
|
main.vaultDetail.missing.info=Cryptomator konnte keinen Tresor mit diesem Pfad finden.
|
||||||
@@ -413,6 +416,7 @@ vaultOptions.general.startHealthCheckBtn=Integritätsprüfung starten
|
|||||||
## Mount
|
## Mount
|
||||||
vaultOptions.mount=Laufwerk
|
vaultOptions.mount=Laufwerk
|
||||||
vaultOptions.mount.info=Die Optionen hängen vom gewählten Laufwerkstyp ab.
|
vaultOptions.mount.info=Die Optionen hängen vom gewählten Laufwerkstyp ab.
|
||||||
|
vaultOptions.mount.linkToPreferences=Einstellungen für virtuelles Laufwerk öffnen
|
||||||
vaultOptions.mount.readonly=Schreibgeschützt
|
vaultOptions.mount.readonly=Schreibgeschützt
|
||||||
vaultOptions.mount.customMountFlags=Benutzerdefinierte Einhänge-Optionen
|
vaultOptions.mount.customMountFlags=Benutzerdefinierte Einhänge-Optionen
|
||||||
vaultOptions.mount.winDriveLetterOccupied=belegt
|
vaultOptions.mount.winDriveLetterOccupied=belegt
|
||||||
@@ -429,7 +433,10 @@ vaultOptions.masterkey.forgetSavedPasswordBtn=Gespeichertes Passwort vergessen
|
|||||||
vaultOptions.masterkey.recoveryKeyExplanation=Ein Wiederherstellungsschlüssel ist bei Passwortverlust deine einzige Möglichkeit, den Zugriff auf einen Tresor wiederherzustellen.
|
vaultOptions.masterkey.recoveryKeyExplanation=Ein Wiederherstellungsschlüssel ist bei Passwortverlust deine einzige Möglichkeit, den Zugriff auf einen Tresor wiederherzustellen.
|
||||||
vaultOptions.masterkey.showRecoveryKeyBtn=Wiederherstellungsschlüssel anzeigen
|
vaultOptions.masterkey.showRecoveryKeyBtn=Wiederherstellungsschlüssel anzeigen
|
||||||
vaultOptions.masterkey.recoverPasswordBtn=Passwort zurücksetzen
|
vaultOptions.masterkey.recoverPasswordBtn=Passwort zurücksetzen
|
||||||
|
## Hub
|
||||||
|
vaultOptions.hub=Wiederherstellung
|
||||||
|
vaultOptions.hub.convertInfo=Im Notfall kannst du den Wiederherstellungsschlüssel verwenden, um diesen Hub-Tresor in einen passwortgeschützten Tresor umzuwandeln.
|
||||||
|
vaultOptions.hub.convertBtn=In einen passwortgeschützten Tresor umwandeln
|
||||||
|
|
||||||
# Recovery Key
|
# Recovery Key
|
||||||
## Display Recovery Key
|
## Display Recovery Key
|
||||||
@@ -441,8 +448,8 @@ recoveryKey.display.StorageHints=Bewahre ihn möglichst sicher auf, z. B.\n •
|
|||||||
## Reset Password
|
## Reset Password
|
||||||
### Enter Recovery Key
|
### Enter Recovery Key
|
||||||
recoveryKey.recover.title=Passwort zurücksetzen
|
recoveryKey.recover.title=Passwort zurücksetzen
|
||||||
recoveryKey.recover.prompt=Gib deinen Wiederherstellungsschlüssel für „%s“ ein:
|
recoveryKey.recover.prompt=Gib den Wiederherstellungsschlüssel für "%s" ein:
|
||||||
recoveryKey.recover.correctKey=Dies ist ein gültiger Wiederherstellungsschlüssel
|
recoveryKey.recover.correctKey=Dieser Wiederherstellungsschlüssel ist gültig
|
||||||
recoveryKey.recover.wrongKey=Dieser Wiederherstellungsschlüssel gehört zu einem anderen Tresor
|
recoveryKey.recover.wrongKey=Dieser Wiederherstellungsschlüssel gehört zu einem anderen Tresor
|
||||||
recoveryKey.recover.invalidKey=Dieser Wiederherstellungsschlüssel ist ungültig
|
recoveryKey.recover.invalidKey=Dieser Wiederherstellungsschlüssel ist ungültig
|
||||||
recoveryKey.printout.heading=Cryptomator-Wiederherstellungsschlüssel\n„%s“\n
|
recoveryKey.printout.heading=Cryptomator-Wiederherstellungsschlüssel\n„%s“\n
|
||||||
@@ -452,6 +459,13 @@ recoveryKey.recover.resetBtn=Zurücksetzen
|
|||||||
recoveryKey.recover.resetSuccess.message=Passwort erfolgreich zurückgesetzt
|
recoveryKey.recover.resetSuccess.message=Passwort erfolgreich zurückgesetzt
|
||||||
recoveryKey.recover.resetSuccess.description=Du kannst deinen Tresor mit dem neuen Passwort entsperren.
|
recoveryKey.recover.resetSuccess.description=Du kannst deinen Tresor mit dem neuen Passwort entsperren.
|
||||||
|
|
||||||
|
# Convert Vault
|
||||||
|
convertVault.title=Tresor konvertieren
|
||||||
|
convertVault.convert.convertBtn.before=Konvertieren
|
||||||
|
convertVault.convert.convertBtn.processing=Konvertierung läuft…
|
||||||
|
convertVault.success.message=Konvertierung erfolgreich
|
||||||
|
convertVault.hubToPassword.success.description=Du kannst nun den Tresor mit dem gewählten Passwort entsperren, ohne auf den Hub zuzugreifen.
|
||||||
|
|
||||||
# New Password
|
# New Password
|
||||||
newPassword.promptText=Gib ein neues Passwort ein
|
newPassword.promptText=Gib ein neues Passwort ein
|
||||||
newPassword.reenterPassword=Bestätige das neue Passwort
|
newPassword.reenterPassword=Bestätige das neue Passwort
|
||||||
|
|||||||
@@ -274,9 +274,10 @@ preferences.interface.showMinimizeButton=Εμφάνιση κουμπιού ελ
|
|||||||
preferences.interface.showTrayIcon=Εμφάνιση εικονιδίου tray (απαιτεί επανεκκίνηση)
|
preferences.interface.showTrayIcon=Εμφάνιση εικονιδίου tray (απαιτεί επανεκκίνηση)
|
||||||
## Volume
|
## Volume
|
||||||
preferences.volume=Εικονικός δίσκος
|
preferences.volume=Εικονικός δίσκος
|
||||||
preferences.volume.type=Τύπος Τόμου (απαιτείται επανεκκίνηση)
|
preferences.volume.type=Τύπος Τόμου
|
||||||
preferences.volume.type.automatic=Αυτόματα
|
preferences.volume.type.automatic=Αυτόματα
|
||||||
preferences.volume.docsTooltip=Ανοίξτε τις οδηγίες για να μάθετε περισσότερα σχετικά με τους διαφορετικούς τύπους τόμων.
|
preferences.volume.docsTooltip=Ανοίξτε τις οδηγίες για να μάθετε περισσότερα σχετικά με τους διαφορετικούς τύπους τόμων.
|
||||||
|
preferences.volume.fuseRestartRequired=Για να εφαρμοστούν οι αλλαγές, πρέπει να γίνει επανεκκίνηση του Cryptomator.
|
||||||
preferences.volume.tcp.port=Θύρα TCP
|
preferences.volume.tcp.port=Θύρα TCP
|
||||||
preferences.volume.supportedFeatures=Ο επιλεγμένος τύπος τόμου υποστηρίζει τις ακόλουθες δυνατότητες:
|
preferences.volume.supportedFeatures=Ο επιλεγμένος τύπος τόμου υποστηρίζει τις ακόλουθες δυνατότητες:
|
||||||
preferences.volume.feature.mountAuto=Αυτόματη επιλογή σημείου προσάρτησης
|
preferences.volume.feature.mountAuto=Αυτόματη επιλογή σημείου προσάρτησης
|
||||||
@@ -306,27 +307,27 @@ stats.title=Στατιστικά για %s
|
|||||||
stats.cacheHitRate=Ποσοστό χρήσης cache
|
stats.cacheHitRate=Ποσοστό χρήσης cache
|
||||||
## Read
|
## Read
|
||||||
stats.read.throughput.idle=Ανάγνωση: ηρεμία
|
stats.read.throughput.idle=Ανάγνωση: ηρεμία
|
||||||
stats.read.throughput.kibs=Ανάγνωση: %.2f kiB/s
|
stats.read.throughput.kibs=Ανάγνωση: %.2f KiB/s
|
||||||
stats.read.throughput.mibs=Ανάγνωση: %.2f MiB/s
|
stats.read.throughput.mibs=Ανάγνωση: %.2f MiB/s
|
||||||
stats.read.total.data.none=Ανάγνωση δεδομένων: -
|
stats.read.total.data.none=Ανάγνωση δεδομένων: -
|
||||||
stats.read.total.data.kib=Ανάγνωση δεδομένων: %.1f kiB
|
stats.read.total.data.kib=Ανάγνωση δεδομένων: %.1f KiB
|
||||||
stats.read.total.data.mib=Ανάγνωση δεδομένων: %.1f MiB
|
stats.read.total.data.mib=Ανάγνωση δεδομένων: %.1f MiB
|
||||||
stats.read.total.data.gib=Ανάγνωση δεδομένων: %.1f GiB
|
stats.read.total.data.gib=Ανάγνωση δεδομένων: %.1f GiB
|
||||||
stats.decr.total.data.none=Δεδομένα που αποκρυπτογραφήθηκαν: -
|
stats.decr.total.data.none=Δεδομένα που αποκρυπτογραφήθηκαν: -
|
||||||
stats.decr.total.data.kib=Δεδομένα που αποκρυπτογραφήθηκαν: %.1f kiB
|
stats.decr.total.data.kib=Δεδομένα που αποκρυπτογραφήθηκαν: %.1f KiB
|
||||||
stats.decr.total.data.mib=Δεδομένα που αποκρυπτογραφήθηκαν: %.1f MiB
|
stats.decr.total.data.mib=Δεδομένα που αποκρυπτογραφήθηκαν: %.1f MiB
|
||||||
stats.decr.total.data.gib=Δεδομένα που αποκρυπτογραφήθηκαν: %.1f GiB
|
stats.decr.total.data.gib=Δεδομένα που αποκρυπτογραφήθηκαν: %.1f GiB
|
||||||
stats.read.accessCount=Συνολικές αναγνώσεις: %d
|
stats.read.accessCount=Συνολικές αναγνώσεις: %d
|
||||||
## Write
|
## Write
|
||||||
stats.write.throughput.idle=Εγγραφή: ηρεμία
|
stats.write.throughput.idle=Εγγραφή: ηρεμία
|
||||||
stats.write.throughput.kibs=Εγγραφή: %.2f kiB/s
|
stats.write.throughput.kibs=Εγγραφή: %.2f KiB/s
|
||||||
stats.write.throughput.mibs=Εγγραφή: %.2f MiB/s
|
stats.write.throughput.mibs=Εγγραφή: %.2f MiB/s
|
||||||
stats.write.total.data.none=Δεδομένα που γράφηκαν: -
|
stats.write.total.data.none=Δεδομένα που γράφηκαν: -
|
||||||
stats.write.total.data.kib=Δεδομένα που γράφτηκαν: %.1f kiB
|
stats.write.total.data.kib=Δεδομένα που γράφτηκαν: %.1f KiB
|
||||||
stats.write.total.data.mib=Δεδομένα που γράφτηκαν: %.1f MiB
|
stats.write.total.data.mib=Δεδομένα που γράφτηκαν: %.1f MiB
|
||||||
stats.write.total.data.gib=Δεδομένα που γράφτηκαν: %.1f GiB
|
stats.write.total.data.gib=Δεδομένα που γράφτηκαν: %.1f GiB
|
||||||
stats.encr.total.data.none=Δεδομένα που κρυπτογραφήθηκαν: -
|
stats.encr.total.data.none=Δεδομένα που κρυπτογραφήθηκαν: -
|
||||||
stats.encr.total.data.kib=Δεδομένα που κρυπτογραφήθηκαν: %.1f kiB
|
stats.encr.total.data.kib=Δεδομένα που κρυπτογραφήθηκαν: %.1f KiB
|
||||||
stats.encr.total.data.mib=Δεδομένα που κρυπτογραφήθηκαν: %.1f MiB
|
stats.encr.total.data.mib=Δεδομένα που κρυπτογραφήθηκαν: %.1f MiB
|
||||||
stats.encr.total.data.gib=Δεδομένα που κρυπτογραφήθηκαν: %.1f GiB
|
stats.encr.total.data.gib=Δεδομένα που κρυπτογραφήθηκαν: %.1f GiB
|
||||||
stats.write.accessCount=Συνολικές εγγραφές: %d
|
stats.write.accessCount=Συνολικές εγγραφές: %d
|
||||||
@@ -369,7 +370,7 @@ main.vaultDetail.lockBtn=Κλείδωμα
|
|||||||
main.vaultDetail.bytesPerSecondRead=Ανάγνωση:
|
main.vaultDetail.bytesPerSecondRead=Ανάγνωση:
|
||||||
main.vaultDetail.bytesPerSecondWritten=Εγγραφή:
|
main.vaultDetail.bytesPerSecondWritten=Εγγραφή:
|
||||||
main.vaultDetail.throughput.idle=σε αδράνεια
|
main.vaultDetail.throughput.idle=σε αδράνεια
|
||||||
main.vaultDetail.throughput.kbps=%.1f kiB/s
|
main.vaultDetail.throughput.kbps=%.1f KiB/s
|
||||||
main.vaultDetail.throughput.mbps=%.1f MiB/s
|
main.vaultDetail.throughput.mbps=%.1f MiB/s
|
||||||
main.vaultDetail.stats=Στατιστικά Vault
|
main.vaultDetail.stats=Στατιστικά Vault
|
||||||
main.vaultDetail.locateEncryptedFileBtn=Εντοπισμός Κρυπτογραφημένου Αρχείου
|
main.vaultDetail.locateEncryptedFileBtn=Εντοπισμός Κρυπτογραφημένου Αρχείου
|
||||||
@@ -432,7 +433,10 @@ vaultOptions.masterkey.forgetSavedPasswordBtn=Διαγραφή αποθηκευ
|
|||||||
vaultOptions.masterkey.recoveryKeyExplanation=Το κλειδί ασφαλείας είναι ο μόνος τρόπος ανάκτησης πρόσβασης σε ένα vault αν χάσετε τον κωδικό σας.
|
vaultOptions.masterkey.recoveryKeyExplanation=Το κλειδί ασφαλείας είναι ο μόνος τρόπος ανάκτησης πρόσβασης σε ένα vault αν χάσετε τον κωδικό σας.
|
||||||
vaultOptions.masterkey.showRecoveryKeyBtn=Προβολή κλειδιού ανάκτησης
|
vaultOptions.masterkey.showRecoveryKeyBtn=Προβολή κλειδιού ανάκτησης
|
||||||
vaultOptions.masterkey.recoverPasswordBtn=Επαναφορά Κωδικού Πρόσβασης
|
vaultOptions.masterkey.recoverPasswordBtn=Επαναφορά Κωδικού Πρόσβασης
|
||||||
|
## Hub
|
||||||
|
vaultOptions.hub=Ανάκτηση
|
||||||
|
vaultOptions.hub.convertInfo=Μπορείτε να χρησιμοποιήσετε το κλειδί ανάκτησης για να μετατρέψετε αυτό το θησαυ/κιο Hub σε ένα θησαυ/κιο βασισμένο σε κωδικό πρόσβασης σε περίπτωση έκτακτης ανάγκης.
|
||||||
|
vaultOptions.hub.convertBtn=Μετατροπή σε Κρύπτη Βάσει Κωδικού πρόσβασης
|
||||||
|
|
||||||
# Recovery Key
|
# Recovery Key
|
||||||
## Display Recovery Key
|
## Display Recovery Key
|
||||||
@@ -455,6 +459,13 @@ recoveryKey.recover.resetBtn=Επαναφορά
|
|||||||
recoveryKey.recover.resetSuccess.message=Επιτυχής επαναφορά κωδικού πρόσβασης
|
recoveryKey.recover.resetSuccess.message=Επιτυχής επαναφορά κωδικού πρόσβασης
|
||||||
recoveryKey.recover.resetSuccess.description=Μπορείτε να ξεκλειδώσετε την κρύπτη σας με το νέο κωδικό πρόσβασης.
|
recoveryKey.recover.resetSuccess.description=Μπορείτε να ξεκλειδώσετε την κρύπτη σας με το νέο κωδικό πρόσβασης.
|
||||||
|
|
||||||
|
# Convert Vault
|
||||||
|
convertVault.title=Μετατροπή Θησαυ/κιου
|
||||||
|
convertVault.convert.convertBtn.before=Μετατροπή
|
||||||
|
convertVault.convert.convertBtn.processing=Μετατροπή…
|
||||||
|
convertVault.success.message=Η Μετατροπή ήταν επιτυχής
|
||||||
|
convertVault.hubToPassword.success.description=Τώρα μπορείτε να ξεκλειδώσετε το θησαυ/κιο με τον επιλεγμένο κωδικό πρόσβασης χωρίς να απαιτείται πρόσβαση στο Hub.
|
||||||
|
|
||||||
# New Password
|
# New Password
|
||||||
newPassword.promptText=Εισάγετε ένα νέο κωδικό
|
newPassword.promptText=Εισάγετε ένα νέο κωδικό
|
||||||
newPassword.reenterPassword=Επιβεβαιώστε το νέο κωδικό
|
newPassword.reenterPassword=Επιβεβαιώστε το νέο κωδικό
|
||||||
|
|||||||
@@ -11,12 +11,12 @@ generic.button.close=Cerrar
|
|||||||
generic.button.copy=Copiar
|
generic.button.copy=Copiar
|
||||||
generic.button.copied=¡Copiado!
|
generic.button.copied=¡Copiado!
|
||||||
generic.button.done=Hecho
|
generic.button.done=Hecho
|
||||||
generic.button.next=Continuar
|
generic.button.next=Siguiente
|
||||||
generic.button.print=Imprimir
|
generic.button.print=Imprimir
|
||||||
|
|
||||||
# Error
|
# Error
|
||||||
error.message=Error %s
|
error.message=Ocurrió un error
|
||||||
error.description=¡Ups! Cryptomator no esperaba que esto sucediera. Puede buscar soluciones existentes para este error. O si aún no se ha notiicado, siéntase libre de hacerlo.
|
error.description=Cryptomator no esperaba que esto sucediera. Puede buscar soluciones existentes para este error. O si aún no se ha notificado, siéntase libre de hacerlo.
|
||||||
error.hyperlink.lookup=Buscar este error
|
error.hyperlink.lookup=Buscar este error
|
||||||
error.hyperlink.report=Notificar este error
|
error.hyperlink.report=Notificar este error
|
||||||
error.technicalDetails=Detalles:
|
error.technicalDetails=Detalles:
|
||||||
@@ -56,9 +56,9 @@ addvaultwizard.new.locationIsOk=Ubicación adecuada para la bóveda
|
|||||||
addvaultwizard.new.invalidName=Nombre de bóveda no válido
|
addvaultwizard.new.invalidName=Nombre de bóveda no válido
|
||||||
addvaultwizard.new.validName=Nombre de bóveda válido
|
addvaultwizard.new.validName=Nombre de bóveda válido
|
||||||
addvaultwizard.new.validCharacters.message=El nombre de la bóveda puede contener los siguientes caracteres:
|
addvaultwizard.new.validCharacters.message=El nombre de la bóveda puede contener los siguientes caracteres:
|
||||||
addvaultwizard.new.validCharacters.chars=Caracteres de la palabra (por ejemplo, a, o o)
|
addvaultwizard.new.validCharacters.chars=Caracteres de la palabra (por ejemplo, a, ж o 수)
|
||||||
addvaultwizard.new.validCharacters.numbers=Números
|
addvaultwizard.new.validCharacters.numbers=Números
|
||||||
addvaultwizard.new.validCharacters.dashes=Separación (%s) o subrayado (%s)
|
addvaultwizard.new.validCharacters.dashes=Guion (%s) o subrayado (%s)
|
||||||
### Password
|
### Password
|
||||||
addvaultwizard.new.createVaultBtn=Crear bóveda
|
addvaultwizard.new.createVaultBtn=Crear bóveda
|
||||||
addvaultwizard.new.generateRecoveryKeyChoice=No podrá acceder a sus datos sin su contraseña. ¿Desea una clave de recuperación en caso de que pierda su contraseña?
|
addvaultwizard.new.generateRecoveryKeyChoice=No podrá acceder a sus datos sin su contraseña. ¿Desea una clave de recuperación en caso de que pierda su contraseña?
|
||||||
@@ -91,7 +91,7 @@ addvaultwizard.success.nextStepsInstructions=Bóveda "%s" añadida.\nSe necesita
|
|||||||
addvaultwizard.success.unlockNow=Desbloquear ahora
|
addvaultwizard.success.unlockNow=Desbloquear ahora
|
||||||
|
|
||||||
# Remove Vault
|
# Remove Vault
|
||||||
removeVault.title=Eliminar bóveda
|
removeVault.title=Eliminar "%s"
|
||||||
removeVault.message=¿Eliminar bóveda?
|
removeVault.message=¿Eliminar bóveda?
|
||||||
removeVault.description=Esto sólo hará que Cryptomator olvide la bóveda. Se la puede añadir de nuevo más tarde. Los archivos cifrados no se eliminarán del disco duro.
|
removeVault.description=Esto sólo hará que Cryptomator olvide la bóveda. Se la puede añadir de nuevo más tarde. Los archivos cifrados no se eliminarán del disco duro.
|
||||||
removeVault.confirmBtn=Eliminar bóveda
|
removeVault.confirmBtn=Eliminar bóveda
|
||||||
@@ -113,13 +113,13 @@ unlock.passwordPrompt=Ingresar contraseña para "%s":
|
|||||||
unlock.savePassword=Recordar contraseña
|
unlock.savePassword=Recordar contraseña
|
||||||
unlock.unlockBtn=Desbloquear
|
unlock.unlockBtn=Desbloquear
|
||||||
## Select
|
## Select
|
||||||
unlock.chooseMasterkey.message=Archivo masterkey no encontrado
|
unlock.chooseMasterkey.message=Archivo de la clave maestra no encontrado
|
||||||
unlock.chooseMasterkey.description=No se pudo encontrar el archivo de la clave maestra de esta bóveda en la ubicación esperada. Por favor, elija manualmente el archivo de la clave.
|
unlock.chooseMasterkey.description=No se pudo encontrar el archivo de la clave maestra para la bóveda "%s". Por favor, elija manualmente el archivo de la clave.
|
||||||
unlock.chooseMasterkey.filePickerTitle=Seleccione el archivo de la clave maestra
|
unlock.chooseMasterkey.filePickerTitle=Seleccione el archivo de la clave maestra
|
||||||
unlock.chooseMasterkey.filePickerMimeDesc=Clave maestra de Cryptomator
|
unlock.chooseMasterkey.filePickerMimeDesc=Clave maestra de Cryptomator
|
||||||
## Success
|
## Success
|
||||||
unlock.success.message=Desbloqueo exitoso
|
unlock.success.message=Desbloqueo exitoso
|
||||||
unlock.success.description=¡Desbloqueo de "%s" exitoso! Su bóveda ahora es accesible a través de su unidad virtual.
|
unlock.success.description=El contenido de la bóveda "%s" ahora es accesible a través de su punto de montaje.
|
||||||
unlock.success.rememberChoice=Recordar opción y no mostrar de nuevo
|
unlock.success.rememberChoice=Recordar opción y no mostrar de nuevo
|
||||||
unlock.success.revealBtn=Revelar unidad
|
unlock.success.revealBtn=Revelar unidad
|
||||||
## Failure
|
## Failure
|
||||||
@@ -133,11 +133,11 @@ hub.noKeychain.description=Para desbloquear las bóvedas de Hub, se requiere una
|
|||||||
hub.noKeychain.openBtn=Abrir preferencias
|
hub.noKeychain.openBtn=Abrir preferencias
|
||||||
### Waiting
|
### Waiting
|
||||||
hub.auth.message=Esperando la autenticación…
|
hub.auth.message=Esperando la autenticación…
|
||||||
hub.auth.description=Debe ser redirigido automáticamente a la página de inicio de sesión.
|
hub.auth.description=Debería ser redirigido automáticamente a la página de inicio de sesión.
|
||||||
hub.auth.loginLink=¿No se ha redireccionado? Haga clic aquí para abrirla.
|
hub.auth.loginLink=¿No se ha redireccionado? Haga clic aquí para abrirla.
|
||||||
### Receive Key
|
### Receive Key
|
||||||
hub.receive.message=Procesando la respuesta…
|
hub.receive.message=Procesando la respuesta…
|
||||||
hub.receive.description=Cryptomator está recibiendo y procesando la respuesta del Hub, espere.
|
hub.receive.description=Cryptomator está recibiendo y procesando la respuesta del Hub. Por favor espere.
|
||||||
### Register Device
|
### Register Device
|
||||||
hub.register.message=Nombre del dispositivo requerido
|
hub.register.message=Nombre del dispositivo requerido
|
||||||
hub.register.description=Este parece ser el primer acceso al Hub desde este dispositivo. Para identificarlo y autorizar el acceso, necesita nombrar este dispositivo.
|
hub.register.description=Este parece ser el primer acceso al Hub desde este dispositivo. Para identificarlo y autorizar el acceso, necesita nombrar este dispositivo.
|
||||||
@@ -274,9 +274,10 @@ preferences.interface.showMinimizeButton=Mostrar botón minimizar
|
|||||||
preferences.interface.showTrayIcon=Mostrar ícono de bandeja (requiere reiniciar)
|
preferences.interface.showTrayIcon=Mostrar ícono de bandeja (requiere reiniciar)
|
||||||
## Volume
|
## Volume
|
||||||
preferences.volume=Unidad virtual
|
preferences.volume=Unidad virtual
|
||||||
preferences.volume.type=Tipo de volumen (requiere reiniciar)
|
preferences.volume.type=Tipo de volumen
|
||||||
preferences.volume.type.automatic=Automático
|
preferences.volume.type.automatic=Automático
|
||||||
preferences.volume.docsTooltip=Abra la documentación para saber más sobre los diferentes tipos de volumen.
|
preferences.volume.docsTooltip=Abra la documentación para saber más sobre los diferentes tipos de volumen.
|
||||||
|
preferences.volume.fuseRestartRequired=Para aplicar los cambios, Cryptomator necesita ser reiniciado.
|
||||||
preferences.volume.tcp.port=Puerto TCP
|
preferences.volume.tcp.port=Puerto TCP
|
||||||
preferences.volume.supportedFeatures=El tipo de volumen elegido admite las siguientes funciones:
|
preferences.volume.supportedFeatures=El tipo de volumen elegido admite las siguientes funciones:
|
||||||
preferences.volume.feature.mountAuto=Selección automática del punto de montaje
|
preferences.volume.feature.mountAuto=Selección automática del punto de montaje
|
||||||
@@ -306,27 +307,27 @@ stats.title=Estadísticas para %s
|
|||||||
stats.cacheHitRate=La caché alcanzó la tasa
|
stats.cacheHitRate=La caché alcanzó la tasa
|
||||||
## Read
|
## Read
|
||||||
stats.read.throughput.idle=Lectura: inactivo
|
stats.read.throughput.idle=Lectura: inactivo
|
||||||
stats.read.throughput.kibs=Lectura: %.2f kiB/s
|
stats.read.throughput.kibs=Lectura: %.2f KiB/s
|
||||||
stats.read.throughput.mibs=Lectura: %.2f MiB/s
|
stats.read.throughput.mibs=Lectura: %.2f MiB/s
|
||||||
stats.read.total.data.none=Datos leídos: -
|
stats.read.total.data.none=Datos leídos: -
|
||||||
stats.read.total.data.kib=Datos leídos: %.1f kiB
|
stats.read.total.data.kib=Datos leídos: %.1f KiB
|
||||||
stats.read.total.data.mib=Datos leídos: %.1f MiB
|
stats.read.total.data.mib=Datos leídos: %.1f MiB
|
||||||
stats.read.total.data.gib=Datos leídos: %.1f GiB
|
stats.read.total.data.gib=Datos leídos: %.1f GiB
|
||||||
stats.decr.total.data.none=Datos descifrados: -
|
stats.decr.total.data.none=Datos descifrados: -
|
||||||
stats.decr.total.data.kib=Datos descifrados: %.1f kiB
|
stats.decr.total.data.kib=Datos descifrados: %.1f KiB
|
||||||
stats.decr.total.data.mib=Datos descifrados: %.1f MiB
|
stats.decr.total.data.mib=Datos descifrados: %.1f MiB
|
||||||
stats.decr.total.data.gib=Datos descifrados: %.1f GiB
|
stats.decr.total.data.gib=Datos descifrados: %.1f GiB
|
||||||
stats.read.accessCount=Total leídos: %d
|
stats.read.accessCount=Total leídos: %d
|
||||||
## Write
|
## Write
|
||||||
stats.write.throughput.idle=Escritura: inactivo
|
stats.write.throughput.idle=Escritura: inactivo
|
||||||
stats.write.throughput.kibs=Escritura: %.2f kiB/s
|
stats.write.throughput.kibs=Escritura: %.2f KiB/s
|
||||||
stats.write.throughput.mibs=Escritura: %.2f MiB/s
|
stats.write.throughput.mibs=Escritura: %.2f MiB/s
|
||||||
stats.write.total.data.none=Datos escritos: -
|
stats.write.total.data.none=Datos escritos: -
|
||||||
stats.write.total.data.kib=Datos escritos: %.1f kiB
|
stats.write.total.data.kib=Datos escritos: %.1f KiB
|
||||||
stats.write.total.data.mib=Datos escritos: %.1f MiB
|
stats.write.total.data.mib=Datos escritos: %.1f MiB
|
||||||
stats.write.total.data.gib=Datos escritos: %.1f GiB
|
stats.write.total.data.gib=Datos escritos: %.1f GiB
|
||||||
stats.encr.total.data.none=Datos cifrados: -
|
stats.encr.total.data.none=Datos cifrados: -
|
||||||
stats.encr.total.data.kib=Datos cifrados: %.1f kiB
|
stats.encr.total.data.kib=Datos cifrados: %.1f KiB
|
||||||
stats.encr.total.data.mib=Datos cifrados: %.1f MiB
|
stats.encr.total.data.mib=Datos cifrados: %.1f MiB
|
||||||
stats.encr.total.data.gib=Datos cifrados: %.1f GiB
|
stats.encr.total.data.gib=Datos cifrados: %.1f GiB
|
||||||
stats.write.accessCount=Total de escrituras: %d
|
stats.write.accessCount=Total de escrituras: %d
|
||||||
@@ -369,7 +370,7 @@ main.vaultDetail.lockBtn=Bloquear
|
|||||||
main.vaultDetail.bytesPerSecondRead=Lectura:
|
main.vaultDetail.bytesPerSecondRead=Lectura:
|
||||||
main.vaultDetail.bytesPerSecondWritten=Escritura:
|
main.vaultDetail.bytesPerSecondWritten=Escritura:
|
||||||
main.vaultDetail.throughput.idle=inactivo
|
main.vaultDetail.throughput.idle=inactivo
|
||||||
main.vaultDetail.throughput.kbps=%.1f kiB/s
|
main.vaultDetail.throughput.kbps=%.1f KiB/s
|
||||||
main.vaultDetail.throughput.mbps=%.1f MiB/s
|
main.vaultDetail.throughput.mbps=%.1f MiB/s
|
||||||
main.vaultDetail.stats=Estadísticas de la bóveda
|
main.vaultDetail.stats=Estadísticas de la bóveda
|
||||||
main.vaultDetail.locateEncryptedFileBtn=Ubicar archivo cifrado
|
main.vaultDetail.locateEncryptedFileBtn=Ubicar archivo cifrado
|
||||||
@@ -432,7 +433,10 @@ vaultOptions.masterkey.forgetSavedPasswordBtn=Olvidar contraseña guardada
|
|||||||
vaultOptions.masterkey.recoveryKeyExplanation=Una clave de recuperación es el único medio para restaurar el acceso a una bóveda si pierde su contraseña.
|
vaultOptions.masterkey.recoveryKeyExplanation=Una clave de recuperación es el único medio para restaurar el acceso a una bóveda si pierde su contraseña.
|
||||||
vaultOptions.masterkey.showRecoveryKeyBtn=Mostrar clave de recuperación
|
vaultOptions.masterkey.showRecoveryKeyBtn=Mostrar clave de recuperación
|
||||||
vaultOptions.masterkey.recoverPasswordBtn=Restablecer contraseña
|
vaultOptions.masterkey.recoverPasswordBtn=Restablecer contraseña
|
||||||
|
## Hub
|
||||||
|
vaultOptions.hub=Recuperación
|
||||||
|
vaultOptions.hub.convertInfo=Puede utilizar la clave de recuperación para convertir esta bóveda de Hub en una bóveda con contraseña en una emergencia.
|
||||||
|
vaultOptions.hub.convertBtn=Convertir a Bóveda con Contraseña
|
||||||
|
|
||||||
# Recovery Key
|
# Recovery Key
|
||||||
## Display Recovery Key
|
## Display Recovery Key
|
||||||
@@ -444,7 +448,7 @@ recoveryKey.display.StorageHints=Manténgala en algún lugar seguro, p.ej.:\n
|
|||||||
## Reset Password
|
## Reset Password
|
||||||
### Enter Recovery Key
|
### Enter Recovery Key
|
||||||
recoveryKey.recover.title=Restablecer contraseña
|
recoveryKey.recover.title=Restablecer contraseña
|
||||||
recoveryKey.recover.prompt=Ingresar la clave de recuperación para "%s":
|
recoveryKey.recover.prompt=Ingrese la clave de recuperación para "%s":
|
||||||
recoveryKey.recover.correctKey=Esta es una clave de recuperación válida
|
recoveryKey.recover.correctKey=Esta es una clave de recuperación válida
|
||||||
recoveryKey.recover.wrongKey=Esta clave de recuperación pertenece a una bóveda diferente
|
recoveryKey.recover.wrongKey=Esta clave de recuperación pertenece a una bóveda diferente
|
||||||
recoveryKey.recover.invalidKey=Esta clave de recuperación no es válida
|
recoveryKey.recover.invalidKey=Esta clave de recuperación no es válida
|
||||||
@@ -455,6 +459,13 @@ recoveryKey.recover.resetBtn=## Reiniciar contraseña\nrecoveryKey.recover.reset
|
|||||||
recoveryKey.recover.resetSuccess.message=Contraseña restablecida con éxito
|
recoveryKey.recover.resetSuccess.message=Contraseña restablecida con éxito
|
||||||
recoveryKey.recover.resetSuccess.description=Puede desbloquear su bóveda con la contraseña nueva.
|
recoveryKey.recover.resetSuccess.description=Puede desbloquear su bóveda con la contraseña nueva.
|
||||||
|
|
||||||
|
# Convert Vault
|
||||||
|
convertVault.title=Convertir bóveda
|
||||||
|
convertVault.convert.convertBtn.before=Convertir
|
||||||
|
convertVault.convert.convertBtn.processing=Convirtiendo…
|
||||||
|
convertVault.success.message=Conversión exitosa
|
||||||
|
convertVault.hubToPassword.success.description=Ahora puede desbloquear la bóveda con la contraseña elegida sin necesidad de acceso al Hub.
|
||||||
|
|
||||||
# New Password
|
# New Password
|
||||||
newPassword.promptText=Ingrese una contraseña nueva
|
newPassword.promptText=Ingrese una contraseña nueva
|
||||||
newPassword.reenterPassword=Confirme la contraseña nueva
|
newPassword.reenterPassword=Confirme la contraseña nueva
|
||||||
|
|||||||
@@ -130,7 +130,7 @@ vaultOptions.general.vaultName=نام گاوصندوق
|
|||||||
## Mount
|
## Mount
|
||||||
vaultOptions.mount.mountPoint.directoryPickerButton=انتخاب کنید…
|
vaultOptions.mount.mountPoint.directoryPickerButton=انتخاب کنید…
|
||||||
## Master Key
|
## Master Key
|
||||||
|
## Hub
|
||||||
|
|
||||||
# Recovery Key
|
# Recovery Key
|
||||||
## Display Recovery Key
|
## Display Recovery Key
|
||||||
@@ -139,6 +139,8 @@ vaultOptions.mount.mountPoint.directoryPickerButton=انتخاب کنید…
|
|||||||
### Reset Password
|
### Reset Password
|
||||||
### Recovery Key Password Reset Success
|
### Recovery Key Password Reset Success
|
||||||
|
|
||||||
|
# Convert Vault
|
||||||
|
|
||||||
# New Password
|
# New Password
|
||||||
|
|
||||||
# Quit
|
# Quit
|
||||||
|
|||||||
@@ -139,7 +139,7 @@ vaultOptions.general.vaultName=Pangalan ng Vault
|
|||||||
## Mount
|
## Mount
|
||||||
vaultOptions.mount.mountPoint.directoryPickerButton=Mamili…
|
vaultOptions.mount.mountPoint.directoryPickerButton=Mamili…
|
||||||
## Master Key
|
## Master Key
|
||||||
|
## Hub
|
||||||
|
|
||||||
# Recovery Key
|
# Recovery Key
|
||||||
## Display Recovery Key
|
## Display Recovery Key
|
||||||
@@ -148,6 +148,8 @@ vaultOptions.mount.mountPoint.directoryPickerButton=Mamili…
|
|||||||
### Reset Password
|
### Reset Password
|
||||||
### Recovery Key Password Reset Success
|
### Recovery Key Password Reset Success
|
||||||
|
|
||||||
|
# Convert Vault
|
||||||
|
|
||||||
# New Password
|
# New Password
|
||||||
|
|
||||||
# Quit
|
# Quit
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ addvaultwizard.new.generateRecoveryKeyChoice.no=Non merci, je n'oublierai pas mo
|
|||||||
### Information
|
### Information
|
||||||
addvault.new.readme.storageLocation.fileName=IMPORTANT.rtf
|
addvault.new.readme.storageLocation.fileName=IMPORTANT.rtf
|
||||||
addvault.new.readme.storageLocation.1=Fichiers de coffre-fort
|
addvault.new.readme.storageLocation.1=Fichiers de coffre-fort
|
||||||
addvault.new.readme.storageLocation.2=Ceci est le chemin de votre coffre-fort.
|
addvault.new.readme.storageLocation.2=Ceci est l'emplacement de stockage de votre coffre.
|
||||||
addvault.new.readme.storageLocation.3=NE PAS
|
addvault.new.readme.storageLocation.3=NE PAS
|
||||||
addvault.new.readme.storageLocation.4=• modifier les fichiers dans ce répertoire ni
|
addvault.new.readme.storageLocation.4=• modifier les fichiers dans ce répertoire ni
|
||||||
addvault.new.readme.storageLocation.5=• coller de fichier à chiffrer dans ce répertoire.
|
addvault.new.readme.storageLocation.5=• coller de fichier à chiffrer dans ce répertoire.
|
||||||
@@ -274,9 +274,10 @@ preferences.interface.showMinimizeButton=Afficher le bouton Réduire
|
|||||||
preferences.interface.showTrayIcon=Montrer l'icône de service (redémarrage nécessaire)
|
preferences.interface.showTrayIcon=Montrer l'icône de service (redémarrage nécessaire)
|
||||||
## Volume
|
## Volume
|
||||||
preferences.volume=Disque virtuel
|
preferences.volume=Disque virtuel
|
||||||
preferences.volume.type=Type de volume (redémarrage requis)
|
preferences.volume.type=Type de volume
|
||||||
preferences.volume.type.automatic=Automatique
|
preferences.volume.type.automatic=Automatique
|
||||||
preferences.volume.docsTooltip=Consultez la documentation pour en savoir plus sur les différents types de volumes.
|
preferences.volume.docsTooltip=Consultez la documentation pour en savoir plus sur les différents types de volumes.
|
||||||
|
preferences.volume.fuseRestartRequired=Pour appliquer les modifications, Cryptomator doit être redémarré.
|
||||||
preferences.volume.tcp.port=Port TCP
|
preferences.volume.tcp.port=Port TCP
|
||||||
preferences.volume.supportedFeatures=Le type de volume choisi prend en charge les fonctionnalités suivantes :
|
preferences.volume.supportedFeatures=Le type de volume choisi prend en charge les fonctionnalités suivantes :
|
||||||
preferences.volume.feature.mountAuto=Sélection automatique du point de montage
|
preferences.volume.feature.mountAuto=Sélection automatique du point de montage
|
||||||
@@ -306,27 +307,27 @@ stats.title=Statistiques sur %s
|
|||||||
stats.cacheHitRate=Taux de réussite du cache
|
stats.cacheHitRate=Taux de réussite du cache
|
||||||
## Read
|
## Read
|
||||||
stats.read.throughput.idle=Lecture : inactif
|
stats.read.throughput.idle=Lecture : inactif
|
||||||
stats.read.throughput.kibs=Lecture : %.2f kiB/s
|
stats.read.throughput.kibs=Lecture : %.2f Mio/s
|
||||||
stats.read.throughput.mibs=Lecture : %.2f Mo/s
|
stats.read.throughput.mibs=Lecture : %.2f Mo/s
|
||||||
stats.read.total.data.none=Lecture des données : -
|
stats.read.total.data.none=Lecture des données : -
|
||||||
stats.read.total.data.kib=Lecture des données : %.1f kiO
|
stats.read.total.data.kib=Lecture des données : %.1f kio
|
||||||
stats.read.total.data.mib=Lecture des données : %.1f MiO
|
stats.read.total.data.mib=Lecture des données : %.1f MiO
|
||||||
stats.read.total.data.gib=Lecture des données : %.1f GiO
|
stats.read.total.data.gib=Lecture des données : %.1f GiO
|
||||||
stats.decr.total.data.none=Données déchiffrées: -
|
stats.decr.total.data.none=Données déchiffrées: -
|
||||||
stats.decr.total.data.kib=Données déchiffrées: %.1f kiO
|
stats.decr.total.data.kib=Données déchiffrées: %.1f kio
|
||||||
stats.decr.total.data.mib=Données déchiffrées: %.1f MiO
|
stats.decr.total.data.mib=Données déchiffrées: %.1f MiO
|
||||||
stats.decr.total.data.gib=Données déchiffrées: %.1f GiO
|
stats.decr.total.data.gib=Données déchiffrées: %.1f GiO
|
||||||
stats.read.accessCount=Total des lectures: %d
|
stats.read.accessCount=Total des lectures: %d
|
||||||
## Write
|
## Write
|
||||||
stats.write.throughput.idle=Écriture : inactif
|
stats.write.throughput.idle=Écriture : inactif
|
||||||
stats.write.throughput.kibs=Écriture : %.2f kiO/s
|
stats.write.throughput.kibs=Écriture : %.2f kio/s
|
||||||
stats.write.throughput.mibs=Écriture : %.2f Mo/s
|
stats.write.throughput.mibs=Écriture : %.2f Mo/s
|
||||||
stats.write.total.data.none=Données écrites : -
|
stats.write.total.data.none=Données écrites : -
|
||||||
stats.write.total.data.kib=Données écrites : %.1f kiO
|
stats.write.total.data.kib=Données écrites : %.1f kio
|
||||||
stats.write.total.data.mib=Données écrites : %.1f MiO
|
stats.write.total.data.mib=Données écrites : %.1f MiO
|
||||||
stats.write.total.data.gib=Données écrites : %.1f GiO
|
stats.write.total.data.gib=Données écrites : %.1f GiO
|
||||||
stats.encr.total.data.none=Données chiffrées : -
|
stats.encr.total.data.none=Données chiffrées : -
|
||||||
stats.encr.total.data.kib=Données chiffrées: %.1f kiO
|
stats.encr.total.data.kib=Données chiffrées: %.1f kio
|
||||||
stats.encr.total.data.mib=Données chiffrées: %.1f MiO
|
stats.encr.total.data.mib=Données chiffrées: %.1f MiO
|
||||||
stats.encr.total.data.gib=Données chiffrées: %.1f GiO
|
stats.encr.total.data.gib=Données chiffrées: %.1f GiO
|
||||||
stats.write.accessCount=Total des écritures: %d
|
stats.write.accessCount=Total des écritures: %d
|
||||||
@@ -369,7 +370,7 @@ main.vaultDetail.lockBtn=Verrouiller
|
|||||||
main.vaultDetail.bytesPerSecondRead=Lecture :
|
main.vaultDetail.bytesPerSecondRead=Lecture :
|
||||||
main.vaultDetail.bytesPerSecondWritten=Écriture:
|
main.vaultDetail.bytesPerSecondWritten=Écriture:
|
||||||
main.vaultDetail.throughput.idle=inactif
|
main.vaultDetail.throughput.idle=inactif
|
||||||
main.vaultDetail.throughput.kbps=%.1f Ko/s
|
main.vaultDetail.throughput.kbps=%.1f kio/s
|
||||||
main.vaultDetail.throughput.mbps=%.1f Mo/s
|
main.vaultDetail.throughput.mbps=%.1f Mo/s
|
||||||
main.vaultDetail.stats=Statistiques du volume chiffré
|
main.vaultDetail.stats=Statistiques du volume chiffré
|
||||||
main.vaultDetail.locateEncryptedFileBtn=Localiser le fichier chiffré
|
main.vaultDetail.locateEncryptedFileBtn=Localiser le fichier chiffré
|
||||||
@@ -432,7 +433,10 @@ vaultOptions.masterkey.forgetSavedPasswordBtn=Oublier le mot de passe enregistr
|
|||||||
vaultOptions.masterkey.recoveryKeyExplanation=Une clé de récupération est le seul moyen de rétablir l'accès à un volume chiffré si vous en perdez le mot de passe.
|
vaultOptions.masterkey.recoveryKeyExplanation=Une clé de récupération est le seul moyen de rétablir l'accès à un volume chiffré si vous en perdez le mot de passe.
|
||||||
vaultOptions.masterkey.showRecoveryKeyBtn=Afficher la clé de récupération
|
vaultOptions.masterkey.showRecoveryKeyBtn=Afficher la clé de récupération
|
||||||
vaultOptions.masterkey.recoverPasswordBtn=Réinitialiser le mot de passe
|
vaultOptions.masterkey.recoverPasswordBtn=Réinitialiser le mot de passe
|
||||||
|
## Hub
|
||||||
|
vaultOptions.hub=Récupération
|
||||||
|
vaultOptions.hub.convertInfo=Vous pouvez utiliser la clé de récupération pour convertir ce coffre Hub en coffre basé sur un mot de passe en cas d'urgence.
|
||||||
|
vaultOptions.hub.convertBtn=Convertir en coffre-fort basé sur mot de passe
|
||||||
|
|
||||||
# Recovery Key
|
# Recovery Key
|
||||||
## Display Recovery Key
|
## Display Recovery Key
|
||||||
@@ -444,7 +448,7 @@ recoveryKey.display.StorageHints=Gardez-la dans un endroit sûr, par ex. :\n •
|
|||||||
## Reset Password
|
## Reset Password
|
||||||
### Enter Recovery Key
|
### Enter Recovery Key
|
||||||
recoveryKey.recover.title=Réinitialiser le mot de passe
|
recoveryKey.recover.title=Réinitialiser le mot de passe
|
||||||
recoveryKey.recover.prompt=Entrez votre clé de récupération pour "%s":
|
recoveryKey.recover.prompt=Entrez la clé de récupération pour "%s " :
|
||||||
recoveryKey.recover.correctKey=Cette clé de récupération est correcte
|
recoveryKey.recover.correctKey=Cette clé de récupération est correcte
|
||||||
recoveryKey.recover.wrongKey=Cette clé de récupération appartient à un autre coffre
|
recoveryKey.recover.wrongKey=Cette clé de récupération appartient à un autre coffre
|
||||||
recoveryKey.recover.invalidKey=Cette clé de récupération n'est pas valide
|
recoveryKey.recover.invalidKey=Cette clé de récupération n'est pas valide
|
||||||
@@ -455,6 +459,13 @@ recoveryKey.recover.resetBtn=Réinitialiser
|
|||||||
recoveryKey.recover.resetSuccess.message=Réinitialisation du mot de passe réussie
|
recoveryKey.recover.resetSuccess.message=Réinitialisation du mot de passe réussie
|
||||||
recoveryKey.recover.resetSuccess.description=Vous pouvez déverrouiller votre coffre avec le nouveau mot de passe.
|
recoveryKey.recover.resetSuccess.description=Vous pouvez déverrouiller votre coffre avec le nouveau mot de passe.
|
||||||
|
|
||||||
|
# Convert Vault
|
||||||
|
convertVault.title=Convertir le coffre
|
||||||
|
convertVault.convert.convertBtn.before=Convertir
|
||||||
|
convertVault.convert.convertBtn.processing=Conversion en cours…
|
||||||
|
convertVault.success.message=Conversion réussie
|
||||||
|
convertVault.hubToPassword.success.description=Vous pouvez maintenant déverrouiller le coffre avec le mot de passe choisi sans avoir besoin d'un accès Hub.
|
||||||
|
|
||||||
# New Password
|
# New Password
|
||||||
newPassword.promptText=Entrez un nouveau mot de passe
|
newPassword.promptText=Entrez un nouveau mot de passe
|
||||||
newPassword.reenterPassword=Confirmez le nouveau mot de passe
|
newPassword.reenterPassword=Confirmez le nouveau mot de passe
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user