mirror of
https://github.com/cryptomator/cryptomator.git
synced 2026-05-15 01:01:26 +00:00
Compare commits
35 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ac9fe28967 | ||
|
|
515755d84a | ||
|
|
fef19fe6b3 | ||
|
|
5f56dacc4e | ||
|
|
aa249dabb5 | ||
|
|
06a5bed6e3 | ||
|
|
02f1ffc6bf | ||
|
|
de9af9e303 | ||
|
|
e2bc71a0bc | ||
|
|
e528f6827c | ||
|
|
2882ae8ef8 | ||
|
|
e37f7cea1a | ||
|
|
9b4ee10155 | ||
|
|
c9d970955c | ||
|
|
9e0afd36c4 | ||
|
|
0e523599a3 | ||
|
|
1df6589dd7 | ||
|
|
fb60c97fd3 | ||
|
|
90cd149be8 | ||
|
|
89c04ad83b | ||
|
|
f2d383a211 | ||
|
|
73fde5d020 | ||
|
|
5c0857e98e | ||
|
|
3e87b9c0c6 | ||
|
|
a1d0b6b1d3 | ||
|
|
b0d4b2e403 | ||
|
|
6996d36ea2 | ||
|
|
f77ba908da | ||
|
|
9890789c51 | ||
|
|
a385f2eaef | ||
|
|
553cb5ee3d | ||
|
|
d0dc8819f4 | ||
|
|
221deeda25 | ||
|
|
86000ac454 | ||
|
|
d026afec35 |
12
.travis.yml
12
.travis.yml
@@ -1,3 +1,7 @@
|
||||
sudo: required
|
||||
|
||||
dist: trusty
|
||||
|
||||
language: java
|
||||
|
||||
jdk:
|
||||
@@ -8,7 +12,7 @@ env:
|
||||
- secure: "Lgj042RD0X3rB8VZVZLWP1GetLhjd3PqI5JbJMlzgHJpDI6RkFIBLN9SWAGmkLPCehIp2zA5tu9+UVy0NNMxm9xz6SyjMCaxS28/fnYEXaNmwwDSF6O6gLUbdxyzoYIFPYOPmFxpzhebqnNIsxaM29oZpgRgUGqosCczQxiB+Ng=" #coveralls
|
||||
- secure: "IfYURwZaDWuBDvyn47n0k1Zod/IQw1FF+CS5nnV08Q+NfC3vGGJMwV8m59XnbfwnWGxwvCaAbk4qP6s6+ijgZNKkvgfFMo3rfTok5zt43bIqgaFOANYV+OC/1c59gYD6ZUxhW5iNgMgU3qdsRtJuwSmfkVv/jKyLGfAbS4kN8BA=" #coverity
|
||||
|
||||
before_install: "curl -L --cookie 'oraclelicense=accept-securebackup-cookie;' http://download.oracle.com/otn-pub/java/jce/8/jce_policy-8.zip -o /tmp/policy.zip && sudo unzip -j -o /tmp/policy.zip *.jar -d `jdk_switcher home oraclejdk8`/jre/lib/security && rm /tmp/policy.zip"
|
||||
before_install: "curl -L --cookie 'oraclelicense=accept-securebackup-cookie;' http://download.oracle.com/otn-pub/java/jce/8/jce_policy-8.zip -o /tmp/policy.zip && sudo unzip -j -o /tmp/policy.zip *.jar -d `jdk_switcher home oraclejdk8`/jre/lib/security && rm /tmp/policy.zip"
|
||||
|
||||
script: mvn -fmain/pom.xml clean test
|
||||
|
||||
@@ -27,7 +31,7 @@ notifications:
|
||||
on_success: change
|
||||
on_failure: always
|
||||
|
||||
before_deploy: mvn -fmain/pom.xml -Puber-jar clean package -DskipTests
|
||||
before_deploy: mvn -fmain/pom.xml -Prelease clean package -DskipTests
|
||||
|
||||
addons:
|
||||
coverity_scan:
|
||||
@@ -42,7 +46,9 @@ deploy:
|
||||
prerelease: false
|
||||
api_key:
|
||||
secure: "ZjE1j93v3qbPIe2YbmhS319aCbMdLQw0HuymmluTurxXsZtn9D4t2+eTr99vBVxGRuB5lzzGezPR5zjk5W7iHF7xhwrawXrFzr2rPJWzWFt0aM+Ry2njU1ROTGGXGTbv4anWeBlgMxLEInTAy/9ytOGNJlec83yc0THpOY2wxnk="
|
||||
file: main/uber-jar/target/Cryptomator-$TRAVIS_TAG.jar
|
||||
file:
|
||||
- "main/uber-jar/target/Cryptomator-$TRAVIS_TAG.jar"
|
||||
- "main/ant-kit/target/antkit.tar.gz"
|
||||
skip_cleanup: true
|
||||
on:
|
||||
repo: cryptomator/cryptomator
|
||||
|
||||
74
CODE_OF_CONDUCT.md
Normal file
74
CODE_OF_CONDUCT.md
Normal file
@@ -0,0 +1,74 @@
|
||||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
In the interest of fostering an open and welcoming environment, we as
|
||||
contributors and maintainers pledge to making participation in our project and
|
||||
our community a harassment-free experience for everyone, regardless of age, body
|
||||
size, disability, ethnicity, gender identity and expression, level of experience,
|
||||
nationality, personal appearance, race, religion, or sexual identity and
|
||||
orientation.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to creating a positive environment
|
||||
include:
|
||||
|
||||
* Using welcoming and inclusive language
|
||||
* Being respectful of differing viewpoints and experiences
|
||||
* Gracefully accepting constructive criticism
|
||||
* Focusing on what is best for the community
|
||||
* Showing empathy towards other community members
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* The use of sexualized language or imagery and unwelcome sexual attention or
|
||||
advances
|
||||
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or electronic
|
||||
address, without explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
|
||||
## Our Responsibilities
|
||||
|
||||
Project maintainers are responsible for clarifying the standards of acceptable
|
||||
behavior and are expected to take appropriate and fair corrective action in
|
||||
response to any instances of unacceptable behavior.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or
|
||||
reject comments, commits, code, wiki edits, issues, and other contributions
|
||||
that are not aligned to this Code of Conduct, or to ban temporarily or
|
||||
permanently any contributor for other behaviors that they deem inappropriate,
|
||||
threatening, offensive, or harmful.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies both within project spaces and in public spaces
|
||||
when an individual is representing the project or its community. Examples of
|
||||
representing a project or community include using an official project e-mail
|
||||
address, posting via an official social media account, or acting as an appointed
|
||||
representative at an online or offline event. Representation of a project may be
|
||||
further defined and clarified by project maintainers.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported by contacting the project team at support@cryptomator.org. All
|
||||
complaints will be reviewed and investigated and will result in a response that
|
||||
is deemed necessary and appropriate to the circumstances. The project team is
|
||||
obligated to maintain confidentiality with regard to the reporter of an incident.
|
||||
Further details of specific enforcement policies may be posted separately.
|
||||
|
||||
Project maintainers who do not follow or enforce the Code of Conduct in good
|
||||
faith may face temporary or permanent repercussions as determined by other
|
||||
members of the project's leadership.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
|
||||
available at [http://contributor-covenant.org/version/1/4][version]
|
||||
|
||||
[homepage]: http://contributor-covenant.org
|
||||
[version]: http://contributor-covenant.org/version/1/4/
|
||||
33
CONTRIBUTING.md
Normal file
33
CONTRIBUTING.md
Normal file
@@ -0,0 +1,33 @@
|
||||
# Contributing to Cryptomator
|
||||
|
||||
## Did you find a bug?
|
||||
|
||||
- Ensure you're running the latest version of Cryptomator.
|
||||
- Ensure the bug is related to the desktop version of Cryptomator. Bugs concerning the Cryptomator iOS app can be reported on the [Cryptomator for iOS issues list](https://github.com/cryptomator/cryptomator-ios/issues).
|
||||
- Ensure the bug was not [already reported](https://github.com/cryptomator/cryptomator/issues). You can also check out our [FAQ](https://cryptomator.org/faq/) and our [Wiki](https://github.com/cryptomator/cryptomator/wiki).
|
||||
- If you're unable to find an open issue addressing the problem, [submit a new one](https://github.com/cryptomator/cryptomator/issues/new).
|
||||
|
||||
## Do you have questions?
|
||||
|
||||
- Ask questions by [submitting a new issue](https://github.com/cryptomator/cryptomator/issues/new).
|
||||
- [Contact us](https://cryptomator.org/contact/) directly by writing an email. Wir sprechen auch Deutsch!
|
||||
- Have a chat with us on [Gitter](https://gitter.im/cryptomator/cryptomator).
|
||||
|
||||
## Did you write a patch that fixes a bug?
|
||||
|
||||
- Open a new pull request with the patch.
|
||||
- Ensure the PR description clearly describes the problem and solution. Include the relevant issue number if applicable.
|
||||
|
||||
## Do you intend to add a new feature or change an existing one?
|
||||
|
||||
- Suggest your change by [submitting a new issue](https://github.com/cryptomator/cryptomator/issues/new) and start writing code.
|
||||
|
||||
## Code of Conduct
|
||||
|
||||
Help us keep Cryptomator open and inclusive. Please read and follow our [Code of Conduct](https://github.com/cryptomator/cryptomator/blob/master/CODE_OF_CONDUCT.md).
|
||||
|
||||
## Above all, thank you for your contributions
|
||||
|
||||
Thank you for taking the time to contribute to the project! :+1:
|
||||
|
||||
Cryptomator Team
|
||||
19
ISSUE_TEMPLATE.md
Normal file
19
ISSUE_TEMPLATE.md
Normal file
@@ -0,0 +1,19 @@
|
||||
### Basic Info
|
||||
|
||||
- I'm running Cryptomator on: [Windows, OS X, and/or Debian (or other Linux Distribution), don't forget the version]
|
||||
- I'm using Cryptomator in version: [you can check the version in the settings of Cryptomator]
|
||||
|
||||
### Description
|
||||
|
||||
[description of the bug, question or feature - what did you do? what problem occurred? etc.]
|
||||
|
||||
### Log File (optional)
|
||||
|
||||
```
|
||||
[insert relevant parts of the log file here if applicable,
|
||||
don't forget to redact sensitive information
|
||||
|
||||
on Windows: %appdata%/Cryptomator/cryptomator.log
|
||||
on OS X: ~/Library/Logs/Cryptomator/cryptomator.log
|
||||
on Debian: ~/.Cryptomator/cryptomator.log]
|
||||
```
|
||||
65
README.md
65
README.md
@@ -1,44 +1,67 @@
|
||||
Cryptomator
|
||||
====================
|
||||

|
||||
|
||||
[](https://travis-ci.org/cryptomator/cryptomator)
|
||||
[](https://scan.coverity.com/projects/cryptomator-cryptomator)
|
||||
[](https://coveralls.io/github/cryptomator/cryptomator?branch=master)
|
||||
[](https://gitter.im/cryptomator/cryptomator?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
[](http://twitter.com/Cryptomator)
|
||||
[](https://poeditor.com/join/project/bHwbvJmx0E)
|
||||
|
||||
Multiplatform transparent client-side encryption of your files in the cloud.
|
||||
Multi-platform transparent client-side encryption of your files in the cloud.
|
||||
|
||||
If you want to take a look at the current beta version, go ahead and get your copy of cryptomator on [Cryptomator.org](https://cryptomator.org) or clone and build Cryptomator using Maven (instructions below).
|
||||
Download native binaries of Cryptomator on [cryptomator.org](https://cryptomator.org/) or clone and build Cryptomator using Maven (instructions below).
|
||||
|
||||
## Features
|
||||
- Totally transparent: Just work on the encrypted volume, as if it was an USB flash drive
|
||||
- Works with Dropbox, OneDrive (Skydrive), Google Drive and any other cloud storage, that syncs with a local directory.
|
||||
- In fact it works with any directory. You can use it to encrypt as many folders as you like
|
||||
|
||||
- Works with Dropbox, Google Drive, OneDrive, and any other cloud storage service that synchronizes with a local directory
|
||||
- Open Source means: No backdoors, control is better than trust
|
||||
- Client-side: No accounts, no data shared with any online service
|
||||
- Totally transparent: Just work on the virtual drive as if it were a USB flash drive
|
||||
- AES encryption with 256-bit key length
|
||||
- Client-side. No accounts, no data shared with any online service
|
||||
- Filenames get encrypted too
|
||||
- No need to provide credentials for any 3rd party service
|
||||
- Open Source means: No backdoors. Control is better than trust
|
||||
- Use as many encrypted folders in your Dropbox as you want. Each having individual passwords
|
||||
- No commercial interest, no government agency, no wasted taxpayers' money ;-)
|
||||
- Filenames get encrypted, too
|
||||
- Use as many vaults in your Dropbox as you want, each having individual passwords
|
||||
|
||||
### Privacy
|
||||
- 256 bit keys (unlimited strength policy bundled with native binaries - 128-bit elsewhere)
|
||||
|
||||
- 256-bit keys (unlimited strength policy bundled with native binaries)
|
||||
- Scrypt key derivation
|
||||
- Cryptographically secure random numbers for salts, IVs and the master key of course
|
||||
- Sensitive data is swiped from the heap asap
|
||||
- Cryptographically secure random numbers for salts, IVs and the masterkey of course
|
||||
- Sensitive data is wiped from the heap asap
|
||||
- Lightweight: [Complexity kills security](https://www.schneier.com/essays/archives/1999/11/a_plea_for_simplicit.html)
|
||||
|
||||
### Consistency
|
||||
|
||||
- HMAC over file contents to recognize changed ciphertext before decryption
|
||||
- I/O operations are transactional and atomic, if the file systems support it
|
||||
- Each file contains all information needed for decryption (except for the key of course). No common metadata means no [SPOF](http://en.wikipedia.org/wiki/Single_point_of_failure)
|
||||
- I/O operations are transactional and atomic, if the filesystems support it
|
||||
- Each file contains all information needed for decryption (except for the key of course), no common metadata means no [SPOF](http://en.wikipedia.org/wiki/Single_point_of_failure)
|
||||
|
||||
### Security Architecture
|
||||
|
||||
For more information on the security details visit [cryptomator.org](https://cryptomator.org/architecture/).
|
||||
|
||||
## Building
|
||||
|
||||
#### Dependencies
|
||||
### Dependencies
|
||||
|
||||
* Java 8 + JCE unlimited strength policy files (needed for 256-bit keys)
|
||||
* Maven 3
|
||||
* Optional: OS-dependent build tools for native packaging (See [Windows](https://github.com/cryptomator/cryptomator-win), [OS X](https://github.com/cryptomator/cryptomator-osx), [Debian](https://github.com/cryptomator/cryptomator-deb))
|
||||
* Optional: OS-dependent build tools for native packaging (see [Windows](https://github.com/cryptomator/cryptomator-win), [OS X](https://github.com/cryptomator/cryptomator-osx), [Debian](https://github.com/cryptomator/cryptomator-deb))
|
||||
|
||||
### Run Maven
|
||||
|
||||
```
|
||||
cd main
|
||||
mvn clean install
|
||||
```
|
||||
|
||||
## Contributing to Cryptomator
|
||||
|
||||
Please read our [contribution guide](https://github.com/cryptomator/cryptomator/blob/master/CONTRIBUTING.md), if you would like to report a bug, ask a question or help us with coding.
|
||||
|
||||
## Code of Conduct
|
||||
|
||||
Help us keep Cryptomator open and inclusive. Please read and follow our [Code of Conduct](https://github.com/cryptomator/cryptomator/blob/master/CODE_OF_CONDUCT.md).
|
||||
|
||||
## License
|
||||
|
||||
Distributed under the MIT X Consortium license. See the LICENSE file for more info.
|
||||
Distributed under the MIT X Consortium license. See the `LICENSES/MIT-X-Consortium-License.txt` file for more info.
|
||||
|
||||
BIN
cryptomator.png
Normal file
BIN
cryptomator.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 26 KiB |
1
main/ant-kit/.gitignore
vendored
Normal file
1
main/ant-kit/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/target/
|
||||
31
main/ant-kit/assembly.xml
Normal file
31
main/ant-kit/assembly.xml
Normal file
@@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3 http://maven.apache.org/xsd/assembly-1.1.3.xsd">
|
||||
<id>tarball</id>
|
||||
<includeBaseDirectory>false</includeBaseDirectory>
|
||||
<formats>
|
||||
<format>tar.gz</format>
|
||||
</formats>
|
||||
<fileSets>
|
||||
<fileSet>
|
||||
<directory>target/libs</directory>
|
||||
<includes>
|
||||
<include>*.jar</include>
|
||||
</includes>
|
||||
<outputDirectory>libs</outputDirectory>
|
||||
</fileSet>
|
||||
<fileSet>
|
||||
<directory>target/package</directory>
|
||||
<filtered>false</filtered>
|
||||
<outputDirectory>package</outputDirectory>
|
||||
</fileSet>
|
||||
<fileSet>
|
||||
<directory>target</directory>
|
||||
<includes>
|
||||
<include>build.xml</include>
|
||||
</includes>
|
||||
<filtered>false</filtered>
|
||||
<outputDirectory>.</outputDirectory>
|
||||
</fileSet>
|
||||
</fileSets>
|
||||
</assembly>
|
||||
93
main/ant-kit/pom.xml
Normal file
93
main/ant-kit/pom.xml
Normal file
@@ -0,0 +1,93 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Copyright (c) 2016 Sebastian Stenzel
|
||||
This file is licensed under the terms of the MIT license.
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>main</artifactId>
|
||||
<version>1.0.3d</version>
|
||||
</parent>
|
||||
<artifactId>ant-kit</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
<name>Cryptomator Ant Build Kit</name>
|
||||
<description>Builds a package that can be built with Ant locally</description>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>ui</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<!-- copy libraries to target/libs/: -->
|
||||
<plugin>
|
||||
<artifactId>maven-dependency-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>copy-libs</id>
|
||||
<phase>prepare-package</phase>
|
||||
<goals>
|
||||
<goal>copy-dependencies</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<outputDirectory>${project.build.directory}/libs</outputDirectory>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<!-- copy resources to target/: -->
|
||||
<plugin>
|
||||
<artifactId>maven-resources-plugin</artifactId>
|
||||
<version>2.7</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>copy-resources</id>
|
||||
<phase>prepare-package</phase>
|
||||
<goals>
|
||||
<goal>copy-resources</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<outputDirectory>${project.build.directory}</outputDirectory>
|
||||
<escapeString>\</escapeString>
|
||||
<encoding>UTF-8</encoding>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<filtering>true</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<!-- create antkit.tar.gz: -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>make-assembly</id>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>single</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<descriptors>
|
||||
<descriptor>assembly.xml</descriptor>
|
||||
</descriptors>
|
||||
<appendAssemblyId>false</appendAssemblyId>
|
||||
<finalName>antkit</finalName>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
79
main/ant-kit/src/main/resources/build.xml
Normal file
79
main/ant-kit/src/main/resources/build.xml
Normal file
@@ -0,0 +1,79 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project name="Cryptomator" default="create-jar" basedir="." xmlns:fx="javafx:com.sun.javafx.tools.ant">
|
||||
<taskdef uri="javafx:com.sun.javafx.tools.ant" resource="com/sun/javafx/tools/ant/antlib.xml" classpath="\${java.class.path}:\${java.home}/../lib/ant-javafx.jar:." />
|
||||
|
||||
<!-- Define application to build -->
|
||||
<fx:application id="Cryptomator" name="Cryptomator" version="${project.version}" mainClass="org.cryptomator.ui.Cryptomator" />
|
||||
|
||||
<!-- Create main application jar -->
|
||||
<target name="create-jar">
|
||||
<fx:jar destfile="antbuild/Cryptomator-${project.version}.jar">
|
||||
<fx:application refid="Cryptomator" />
|
||||
<fx:fileset dir="libs" includes="ui-${project.version}.jar" />
|
||||
<fx:resources>
|
||||
<fx:fileset dir="libs" type="jar" includes="*.jar" excludes="ui-${project.version}.jar" />
|
||||
</fx:resources>
|
||||
<fx:manifest>
|
||||
<fx:attribute name="Implementation-Vendor" value="cryptomator.org" />
|
||||
<fx:attribute name="Implementation-Title" value="Cryptomator"/>
|
||||
<fx:attribute name="Implementation-Version" value="${project.version}" />
|
||||
</fx:manifest>
|
||||
</fx:jar>
|
||||
</target>
|
||||
|
||||
<!-- Create native image -->
|
||||
<target name="create-linux-image-with-jvm" depends="create-jar">
|
||||
<fx:deploy nativeBundles="image" outdir="antbuild" outfile="Cryptomator-${project.version}" verbose="true">
|
||||
<fx:application refid="Cryptomator" />
|
||||
<fx:platform j2se="8.0">
|
||||
<fx:property name="cryptomator.logPath" value="~/.Cryptomator/cryptomator.log" />
|
||||
<fx:jvmarg value="-Xmx512m"/>
|
||||
</fx:platform>
|
||||
<fx:resources>
|
||||
<fx:fileset dir="antbuild" type="jar" includes="Cryptomator-${project.version}.jar" />
|
||||
<fx:fileset dir="libs" type="jar" includes="*.jar" excludes="ui-${project.version}.jar"/>
|
||||
</fx:resources>
|
||||
</fx:deploy>
|
||||
</target>
|
||||
|
||||
<!-- Create Debian package -->
|
||||
<target name="deb" depends="create-jar">
|
||||
<fx:deploy nativeBundles="deb" outdir="antbuild" outfile="Cryptomator-${project.version}" verbose="true">
|
||||
<fx:application refid="Cryptomator" />
|
||||
<fx:info title="Cryptomator" vendor="cryptomator.org" copyright="cryptomator.org" license="MIT" category="Utility">
|
||||
<fx:association mimetype="application/x-vnd.cryptomator-vault-metadata" extension="cryptomator" description="Cryptomator Vault Metadata" />
|
||||
</fx:info>
|
||||
<fx:platform j2se="8.0">
|
||||
<fx:property name="cryptomator.logPath" value="~/.Cryptomator/cryptomator.log" />
|
||||
<fx:jvmarg value="-Xmx1048m"/>
|
||||
</fx:platform>
|
||||
<fx:resources>
|
||||
<fx:fileset dir="antbuild" type="jar" includes="Cryptomator-${project.version}.jar" />
|
||||
<fx:fileset dir="libs" type="jar" includes="*.jar" excludes="ui-${project.version}.jar"/>
|
||||
</fx:resources>
|
||||
<fx:permissions elevated="false" />
|
||||
<fx:preferences install="true" />
|
||||
</fx:deploy>
|
||||
</target>
|
||||
|
||||
<!-- Create Red Hat package -->
|
||||
<target name="rpm" depends="create-jar">
|
||||
<fx:deploy nativeBundles="rpm" outdir="antbuild" outfile="Cryptomator-${project.version}" verbose="true">
|
||||
<fx:application refid="Cryptomator" />
|
||||
<fx:info title="Cryptomator" vendor="cryptomator.org" copyright="cryptomator.org" license="MIT" category="Utility">
|
||||
<fx:association mimetype="application/x-vnd.cryptomator-vault-metadata" extension="cryptomator" description="Cryptomator Vault Metadata" />
|
||||
</fx:info>
|
||||
<fx:platform j2se="8.0">
|
||||
<fx:property name="cryptomator.logPath" value="~/.Cryptomator/cryptomator.log" />
|
||||
<fx:jvmarg value="-Xmx1048m"/>
|
||||
</fx:platform>
|
||||
<fx:resources>
|
||||
<fx:fileset dir="antbuild" type="jar" includes="Cryptomator-${project.version}.jar" />
|
||||
<fx:fileset dir="libs" type="jar" includes="*.jar" excludes="ui-${project.version}.jar"/>
|
||||
</fx:resources>
|
||||
<fx:permissions elevated="false" />
|
||||
<fx:preferences install="true" />
|
||||
</fx:deploy>
|
||||
</target>
|
||||
|
||||
</project>
|
||||
BIN
main/ant-kit/src/main/resources/package/linux/Cryptomator.png
Normal file
BIN
main/ant-kit/src/main/resources/package/linux/Cryptomator.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 46 KiB |
16
main/ant-kit/src/main/resources/package/linux/control
Normal file
16
main/ant-kit/src/main/resources/package/linux/control
Normal file
@@ -0,0 +1,16 @@
|
||||
Package: APPLICATION_PACKAGE
|
||||
Version: APPLICATION_VERSION
|
||||
Section: contrib/utils
|
||||
Maintainer: Sebastian Stenzel <sebastian.stenzel@gmail.com>
|
||||
Homepage: https://cryptomator.org
|
||||
Vcs-Git: https://github.com/totalvoidness/cryptomator.git
|
||||
Vcs-Browser: https://github.com/totalvoidness/cryptomator
|
||||
Priority: optional
|
||||
Architecture: APPLICATION_ARCH
|
||||
Provides: APPLICATION_PACKAGE
|
||||
Installed-Size: APPLICATION_INSTALLED_SIZE
|
||||
Depends: gvfs-bin, gvfs-backends, gvfs-fuse, xdg-utils
|
||||
Description: Multi-platform client-side encryption of your cloud files.
|
||||
Cryptomator provides free client-side AES encryption for your cloud files.
|
||||
Create encrypted vaults, which get mounted as virtual volumes. Whatever
|
||||
you save on one of these volumes will end up encrypted inside your vault.
|
||||
23
main/ant-kit/src/main/resources/package/linux/copyright
Normal file
23
main/ant-kit/src/main/resources/package/linux/copyright
Normal file
@@ -0,0 +1,23 @@
|
||||
Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
|
||||
Upstream-Name: cryptomator
|
||||
Source: <https://github.com/totalvoidness/cryptomator>
|
||||
|
||||
Copyright: 2015 Sebastian Stenzel <sebastian.stenzel@gmail.com> and contributors.
|
||||
License: MIT
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
.
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
@@ -10,7 +10,7 @@
|
||||
<parent>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>main</artifactId>
|
||||
<version>1.0.2</version>
|
||||
<version>1.0.3d</version>
|
||||
</parent>
|
||||
<artifactId>commons-test</artifactId>
|
||||
<name>Cryptomator common test dependencies</name>
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<parent>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>main</artifactId>
|
||||
<version>1.0.2</version>
|
||||
<version>1.0.3d</version>
|
||||
</parent>
|
||||
<artifactId>commons</artifactId>
|
||||
<name>Cryptomator common</name>
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<parent>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>main</artifactId>
|
||||
<version>1.0.2</version>
|
||||
<version>1.0.3d</version>
|
||||
</parent>
|
||||
<artifactId>filesystem-api</artifactId>
|
||||
<name>Cryptomator filesystem: API</name>
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
<parent>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>main</artifactId>
|
||||
<version>1.0.2</version>
|
||||
<version>1.0.3d</version>
|
||||
</parent>
|
||||
<artifactId>filesystem-crypto-integration-tests</artifactId>
|
||||
<name>Cryptomator filesystem: Encryption layer tests</name>
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
<parent>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>main</artifactId>
|
||||
<version>1.0.2</version>
|
||||
<version>1.0.3d</version>
|
||||
</parent>
|
||||
<artifactId>filesystem-crypto</artifactId>
|
||||
<name>Cryptomator filesystem: Encryption layer</name>
|
||||
|
||||
@@ -27,7 +27,12 @@ public class CryptoEngineModule {
|
||||
@Provides
|
||||
public SecureRandom provideSecureRandom() {
|
||||
try {
|
||||
return SecureRandom.getInstanceStrong();
|
||||
// https://tersesystems.com/2015/12/17/the-right-way-to-use-securerandom/
|
||||
final SecureRandom nativeRandom = SecureRandom.getInstanceStrong();
|
||||
byte[] seed = nativeRandom.generateSeed(55); // NIST SP800-90A suggests 440 bits for SHA1 seed
|
||||
SecureRandom sha1Random = SecureRandom.getInstance("SHA1PRNG");
|
||||
sha1Random.setSeed(seed);
|
||||
return sha1Random;
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new IllegalStateException("No strong PRNGs available.", e);
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
<parent>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>main</artifactId>
|
||||
<version>1.0.2</version>
|
||||
<version>1.0.3d</version>
|
||||
</parent>
|
||||
<artifactId>filesystem-inmemory</artifactId>
|
||||
<name>Cryptomator filesystem: In-memory mock</name>
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<parent>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>main</artifactId>
|
||||
<version>1.0.2</version>
|
||||
<version>1.0.3d</version>
|
||||
</parent>
|
||||
<artifactId>filesystem-invariants-tests</artifactId>
|
||||
<name>Cryptomator filesystem: Invariants tests</name>
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
<parent>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>main</artifactId>
|
||||
<version>1.0.2</version>
|
||||
<version>1.0.3d</version>
|
||||
</parent>
|
||||
<artifactId>filesystem-nameshortening</artifactId>
|
||||
<name>Cryptomator filesystem: Name shortening layer</name>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>main</artifactId>
|
||||
<version>1.0.2</version>
|
||||
<version>1.0.3d</version>
|
||||
</parent>
|
||||
<artifactId>filesystem-nio</artifactId>
|
||||
<name>Cryptomator filesystem: NIO-based physical layer</name>
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
<parent>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>main</artifactId>
|
||||
<version>1.0.2</version>
|
||||
<version>1.0.3d</version>
|
||||
</parent>
|
||||
<artifactId>filesystem-stats</artifactId>
|
||||
<name>Cryptomator filesystem: Throughput statistics</name>
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
<parent>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>main</artifactId>
|
||||
<version>1.0.2</version>
|
||||
<version>1.0.3d</version>
|
||||
</parent>
|
||||
<artifactId>frontend-api</artifactId>
|
||||
<name>Cryptomator frontend: API</name>
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
<parent>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>main</artifactId>
|
||||
<version>1.0.2</version>
|
||||
<version>1.0.3d</version>
|
||||
</parent>
|
||||
<artifactId>frontend-webdav</artifactId>
|
||||
<name>Cryptomator frontend: WebDAV frontend</name>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>main</artifactId>
|
||||
<version>1.0.2</version>
|
||||
<version>1.0.3d</version>
|
||||
<packaging>pom</packaging>
|
||||
<name>Cryptomator</name>
|
||||
|
||||
@@ -282,9 +282,10 @@
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>uber-jar</id>
|
||||
<id>release</id>
|
||||
<modules>
|
||||
<module>uber-jar</module>
|
||||
<module>ant-kit</module>
|
||||
</modules>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
<parent>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>main</artifactId>
|
||||
<version>1.0.2</version>
|
||||
<version>1.0.3d</version>
|
||||
</parent>
|
||||
<artifactId>uber-jar</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
<parent>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>main</artifactId>
|
||||
<version>1.0.2</version>
|
||||
<version>1.0.3d</version>
|
||||
</parent>
|
||||
<artifactId>ui</artifactId>
|
||||
<name>Cryptomator GUI</name>
|
||||
|
||||
@@ -29,5 +29,5 @@ interface CryptomatorComponent {
|
||||
|
||||
Localization localization();
|
||||
|
||||
TrayIconUtil trayIconUtil();
|
||||
ExitUtil exitUtil();
|
||||
}
|
||||
@@ -38,22 +38,41 @@ import javafx.application.Platform;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
@Singleton
|
||||
class TrayIconUtil {
|
||||
class ExitUtil {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(TrayIconUtil.class);
|
||||
private static final Logger LOG = LoggerFactory.getLogger(ExitUtil.class);
|
||||
|
||||
private final Stage mainWindow;
|
||||
private final Localization localization;
|
||||
private final Settings settings;
|
||||
|
||||
@Inject
|
||||
public TrayIconUtil(@Named("mainWindow") Stage mainWindow, Localization localization, Settings settings) {
|
||||
public ExitUtil(@Named("mainWindow") Stage mainWindow, Localization localization, Settings settings) {
|
||||
this.mainWindow = mainWindow;
|
||||
this.localization = localization;
|
||||
this.settings = settings;
|
||||
}
|
||||
|
||||
public void initTrayIcon(Runnable exitCommand) {
|
||||
public void initExitHandler(Runnable exitCommand) {
|
||||
if (SystemUtils.IS_OS_LINUX) {
|
||||
initMinimizeExitHandler(exitCommand);
|
||||
} else {
|
||||
initTrayIconExitHandler(exitCommand);
|
||||
}
|
||||
}
|
||||
|
||||
private void initMinimizeExitHandler(Runnable exitCommand) {
|
||||
mainWindow.setOnCloseRequest(e -> {
|
||||
if (Platform.isImplicitExit()) {
|
||||
exitCommand.run();
|
||||
} else {
|
||||
mainWindow.setIconified(true);
|
||||
e.consume();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void initTrayIconExitHandler(Runnable exitCommand) {
|
||||
final TrayIcon trayIcon = createTrayIcon(exitCommand);
|
||||
try {
|
||||
SystemTray.getSystemTray().add(trayIcon);
|
||||
@@ -67,7 +67,7 @@ public class MainApplication extends Application {
|
||||
// show window and start observing its focus:
|
||||
primaryStage.show();
|
||||
ActiveWindowStyleSupport.startObservingFocus(primaryStage);
|
||||
comp.trayIconUtil().initTrayIcon(this::quit);
|
||||
comp.exitUtil().initExitHandler(this::quit);
|
||||
|
||||
// open files, if requested during startup:
|
||||
for (String arg : getParameters().getUnnamed()) {
|
||||
|
||||
@@ -12,7 +12,6 @@ import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.net.URL;
|
||||
import java.util.Optional;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
@@ -37,19 +36,18 @@ import javafx.scene.control.Hyperlink;
|
||||
import javafx.scene.text.Text;
|
||||
|
||||
@Singleton
|
||||
public class ChangePasswordController extends AbstractFXMLViewController {
|
||||
public class ChangePasswordController extends LocalizedFXMLViewController {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(ChangePasswordController.class);
|
||||
|
||||
private final Application app;
|
||||
private final Localization localization;
|
||||
final ObjectProperty<Vault> vault = new SimpleObjectProperty<>();
|
||||
private Optional<ChangePasswordListener> listener = Optional.empty();
|
||||
|
||||
@Inject
|
||||
public ChangePasswordController(Application app, Localization localization) {
|
||||
super(localization);
|
||||
this.app = app;
|
||||
this.localization = localization;
|
||||
}
|
||||
|
||||
@FXML
|
||||
@@ -83,11 +81,6 @@ public class ChangePasswordController extends AbstractFXMLViewController {
|
||||
return getClass().getResource("/fxml/change_password.fxml");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ResourceBundle getFxmlResourceBundle() {
|
||||
return localization;
|
||||
}
|
||||
|
||||
// ****************************************
|
||||
// Downloads link
|
||||
// ****************************************
|
||||
@@ -143,13 +136,13 @@ public class ChangePasswordController extends AbstractFXMLViewController {
|
||||
|
||||
private void invokeListenerLater(ChangePasswordListener listener) {
|
||||
Platform.runLater(() -> {
|
||||
listener.didChangePassword(this);
|
||||
listener.didChangePassword();
|
||||
});
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
interface ChangePasswordListener {
|
||||
void didChangePassword(ChangePasswordController ctrl);
|
||||
void didChangePassword();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -13,7 +13,6 @@ import java.io.UncheckedIOException;
|
||||
import java.net.URL;
|
||||
import java.nio.file.FileAlreadyExistsException;
|
||||
import java.util.Optional;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
@@ -34,17 +33,16 @@ import javafx.scene.control.Button;
|
||||
import javafx.scene.control.Label;
|
||||
|
||||
@Singleton
|
||||
public class InitializeController extends AbstractFXMLViewController {
|
||||
public class InitializeController extends LocalizedFXMLViewController {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(InitializeController.class);
|
||||
|
||||
private final Localization localization;
|
||||
final ObjectProperty<Vault> vault = new SimpleObjectProperty<>();
|
||||
private Optional<InitializationListener> listener = Optional.empty();
|
||||
|
||||
@Inject
|
||||
public InitializeController(Localization localization) {
|
||||
this.localization = localization;
|
||||
super(localization);
|
||||
}
|
||||
|
||||
@FXML
|
||||
@@ -71,11 +69,6 @@ public class InitializeController extends AbstractFXMLViewController {
|
||||
return getClass().getResource("/fxml/initialize.fxml");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ResourceBundle getFxmlResourceBundle() {
|
||||
return localization;
|
||||
}
|
||||
|
||||
// ****************************************
|
||||
// OK button
|
||||
// ****************************************
|
||||
@@ -111,13 +104,13 @@ public class InitializeController extends AbstractFXMLViewController {
|
||||
|
||||
private void invokeListenerLater(InitializationListener listener) {
|
||||
Platform.runLater(() -> {
|
||||
listener.didInitialize(this);
|
||||
listener.didInitialize();
|
||||
});
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
interface InitializationListener {
|
||||
void didInitialize(InitializeController ctrl);
|
||||
void didInitialize();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
package org.cryptomator.ui.controllers;
|
||||
|
||||
import org.cryptomator.ui.settings.Localization;
|
||||
|
||||
abstract class LocalizedFXMLViewController extends AbstractFXMLViewController {
|
||||
|
||||
protected final Localization localization;
|
||||
|
||||
public LocalizedFXMLViewController(Localization localization) {
|
||||
this.localization = localization;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Localization getFxmlResourceBundle() {
|
||||
return localization;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -9,7 +9,6 @@
|
||||
package org.cryptomator.ui.controllers;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.inject.Inject;
|
||||
@@ -39,10 +38,9 @@ import javafx.scene.control.cell.CheckBoxListCell;
|
||||
import javafx.stage.Stage;
|
||||
import javafx.util.StringConverter;
|
||||
|
||||
public class MacWarningsController extends AbstractFXMLViewController {
|
||||
public class MacWarningsController extends LocalizedFXMLViewController {
|
||||
|
||||
private final Application application;
|
||||
private final Localization localization;
|
||||
private final ObservableList<Warning> warnings = FXCollections.observableArrayList();
|
||||
private final ListChangeListener<String> unauthenticatedResourcesChangeListener = this::unauthenticatedResourcesDidChange;
|
||||
private final ChangeListener<Boolean> stageVisibilityChangeListener = this::windowVisibilityDidChange;
|
||||
@@ -51,8 +49,8 @@ public class MacWarningsController extends AbstractFXMLViewController {
|
||||
|
||||
@Inject
|
||||
public MacWarningsController(Application application, Localization localization) {
|
||||
super(localization);
|
||||
this.application = application;
|
||||
this.localization = localization;
|
||||
}
|
||||
|
||||
@FXML
|
||||
@@ -85,11 +83,6 @@ public class MacWarningsController extends AbstractFXMLViewController {
|
||||
return getClass().getResource("/fxml/mac_warnings.fxml");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ResourceBundle getFxmlResourceBundle() {
|
||||
return localization;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initStage(Stage stage) {
|
||||
super.initStage(stage);
|
||||
@@ -130,7 +123,7 @@ public class MacWarningsController extends AbstractFXMLViewController {
|
||||
|
||||
private void windowVisibilityDidChange(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
|
||||
if (Boolean.TRUE.equals(newValue)) {
|
||||
stage.setTitle(String.format(localization.getString("macWarnings.windowTitle"), vault.get().getName()));
|
||||
stage.setTitle(String.format(localization.getString("macWarnings.windowTitle"), vault.get().name().getValue()));
|
||||
warnings.addAll(vault.get().getNamesOfResourcesWithInvalidMac().stream().map(Warning::new).collect(Collectors.toList()));
|
||||
vault.get().getNamesOfResourcesWithInvalidMac().addListener(this.unauthenticatedResourcesChangeListener);
|
||||
} else {
|
||||
|
||||
@@ -16,7 +16,6 @@ import java.nio.file.Path;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
@@ -57,15 +56,16 @@ import javafx.stage.FileChooser;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
@Singleton
|
||||
public class MainController extends AbstractFXMLViewController {
|
||||
public class MainController extends LocalizedFXMLViewController {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(MainController.class);
|
||||
|
||||
private final Stage mainWindow;
|
||||
private final Localization localization;
|
||||
private final VaultFactory vaultFactoy;
|
||||
private final Lazy<WelcomeController> welcomeController;
|
||||
private final Lazy<InitializeController> initializeController;
|
||||
private final Lazy<NotFoundController> notFoundController;
|
||||
private final Lazy<UpgradeController> upgradeController;
|
||||
private final Lazy<UnlockController> unlockController;
|
||||
private final Provider<UnlockedController> unlockedControllerProvider;
|
||||
private final Lazy<ChangePasswordController> changePasswordController;
|
||||
@@ -73,20 +73,22 @@ public class MainController extends AbstractFXMLViewController {
|
||||
private final ObjectProperty<AbstractFXMLViewController> activeController = new SimpleObjectProperty<>();
|
||||
private final ObservableList<Vault> vaults;
|
||||
private final ObjectProperty<Vault> selectedVault = new SimpleObjectProperty<>();
|
||||
private final MonadicBinding<Boolean> isSelectedVaultUnlocked = EasyBind.select(selectedVault).selectObject(Vault::unlockedProperty);
|
||||
private final MonadicBinding<Boolean> isSelectedVaultUnlocked = EasyBind.select(selectedVault).selectObject(Vault::unlockedProperty);;
|
||||
private final Binding<Boolean> canEditSelectedVault = EasyBind.combine(selectedVault.isNull(), isSelectedVaultUnlocked.orElse(false), Boolean::logicalOr);
|
||||
private final BooleanBinding isShowingSettings;
|
||||
private final Map<Vault, UnlockedController> unlockedVaults = new HashMap<>();
|
||||
|
||||
@Inject
|
||||
public MainController(@Named("mainWindow") Stage mainWindow, Localization localization, Settings settings, VaultFactory vaultFactoy, Lazy<WelcomeController> welcomeController,
|
||||
Lazy<InitializeController> initializeController, Lazy<UnlockController> unlockController, Provider<UnlockedController> unlockedControllerProvider, Lazy<ChangePasswordController> changePasswordController,
|
||||
Lazy<SettingsController> settingsController) {
|
||||
Lazy<InitializeController> initializeController, Lazy<NotFoundController> notFoundController, Lazy<UpgradeController> upgradeController, Lazy<UnlockController> unlockController,
|
||||
Provider<UnlockedController> unlockedControllerProvider, Lazy<ChangePasswordController> changePasswordController, Lazy<SettingsController> settingsController) {
|
||||
super(localization);
|
||||
this.mainWindow = mainWindow;
|
||||
this.localization = localization;
|
||||
this.vaultFactoy = vaultFactoy;
|
||||
this.welcomeController = welcomeController;
|
||||
this.initializeController = initializeController;
|
||||
this.notFoundController = notFoundController;
|
||||
this.upgradeController = upgradeController;
|
||||
this.unlockController = unlockController;
|
||||
this.unlockedControllerProvider = unlockedControllerProvider;
|
||||
this.changePasswordController = changePasswordController;
|
||||
@@ -133,9 +135,8 @@ public class MainController extends AbstractFXMLViewController {
|
||||
removeVaultButton.disableProperty().bind(canEditSelectedVault);
|
||||
emptyListInstructions.visibleProperty().bind(Bindings.isEmpty(vaults));
|
||||
|
||||
EasyBind.subscribe(activeController, this::activeControllerDidChange);
|
||||
EasyBind.subscribe(selectedVault, this::selectedVaultDidChange);
|
||||
EasyBind.subscribe(isSelectedVaultUnlocked, this::selectedVaultUnlockedDidChange);
|
||||
EasyBind.subscribe(activeController, this::activeControllerDidChange);
|
||||
EasyBind.subscribe(isShowingSettings, settingsButton::setSelected);
|
||||
EasyBind.subscribe(addVaultContextMenu.showingProperty(), addVaultButton::setSelected);
|
||||
}
|
||||
@@ -145,11 +146,6 @@ public class MainController extends AbstractFXMLViewController {
|
||||
return getClass().getResource("/fxml/main.fxml");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ResourceBundle getFxmlResourceBundle() {
|
||||
return localization;
|
||||
}
|
||||
|
||||
private ListCell<Vault> createDirecoryListCell(ListView<Vault> param) {
|
||||
final DirectoryListCell cell = new DirectoryListCell();
|
||||
cell.setVaultContextMenu(vaultListCellContextMenu);
|
||||
@@ -172,19 +168,12 @@ public class MainController extends AbstractFXMLViewController {
|
||||
@FXML
|
||||
private void didClickCreateNewVault(ActionEvent event) {
|
||||
final FileChooser fileChooser = new FileChooser();
|
||||
fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("Cryptomator vault", "*" + Vault.VAULT_FILE_EXTENSION));
|
||||
final File file = fileChooser.showSaveDialog(mainWindow);
|
||||
if (file == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
final Path vaultDir;
|
||||
// enforce .cryptomator file extension:
|
||||
if (!file.getName().endsWith(Vault.VAULT_FILE_EXTENSION)) {
|
||||
vaultDir = file.toPath().resolveSibling(file.getName() + Vault.VAULT_FILE_EXTENSION);
|
||||
} else {
|
||||
vaultDir = file.toPath();
|
||||
}
|
||||
final Path vaultDir = file.toPath();
|
||||
if (!Files.exists(vaultDir)) {
|
||||
Files.createDirectory(vaultDir);
|
||||
}
|
||||
@@ -272,6 +261,10 @@ public class MainController extends AbstractFXMLViewController {
|
||||
}
|
||||
if (newValue.isUnlocked()) {
|
||||
this.showUnlockedView(newValue);
|
||||
} else if (!newValue.doesVaultDirectoryExist()) {
|
||||
this.showNotFoundView();
|
||||
} else if (newValue.isValidVaultDirectory() && newValue.needsUpgrade()) {
|
||||
this.showUpgradeView();
|
||||
} else if (newValue.isValidVaultDirectory()) {
|
||||
this.showUnlockView();
|
||||
} else {
|
||||
@@ -279,29 +272,23 @@ public class MainController extends AbstractFXMLViewController {
|
||||
}
|
||||
}
|
||||
|
||||
private void selectedVaultUnlockedDidChange(Boolean unlocked) {
|
||||
if (unlocked == null) {
|
||||
// no vault selected -> no-op
|
||||
} else if (unlocked) {
|
||||
Platform.setImplicitExit(false);
|
||||
this.showUnlockedView(selectedVault.get());
|
||||
} else {
|
||||
this.showUnlockView();
|
||||
}
|
||||
}
|
||||
|
||||
// ****************************************
|
||||
// Public Bindings
|
||||
// ****************************************
|
||||
|
||||
public Binding<String> windowTitle() {
|
||||
return EasyBind.monadic(selectedVault).map(Vault::getName).orElse(localization.getString("app.name"));
|
||||
return EasyBind.monadic(selectedVault).flatMap(Vault::name).orElse(localization.getString("app.name"));
|
||||
}
|
||||
|
||||
// ****************************************
|
||||
// Subcontroller for right panel
|
||||
// ****************************************
|
||||
|
||||
private void showNotFoundView() {
|
||||
final NotFoundController ctrl = notFoundController.get();
|
||||
activeController.set(ctrl);
|
||||
}
|
||||
|
||||
private void showInitializeView() {
|
||||
final InitializeController ctrl = initializeController.get();
|
||||
ctrl.vault.bind(selectedVault);
|
||||
@@ -309,16 +296,35 @@ public class MainController extends AbstractFXMLViewController {
|
||||
activeController.set(ctrl);
|
||||
}
|
||||
|
||||
public void didInitialize(InitializeController ctrl) {
|
||||
public void didInitialize() {
|
||||
showUnlockView();
|
||||
}
|
||||
|
||||
private void showUpgradeView() {
|
||||
final UpgradeController ctrl = upgradeController.get();
|
||||
ctrl.vault.bind(selectedVault);
|
||||
ctrl.setListener(this::didUpgrade);
|
||||
activeController.set(ctrl);
|
||||
}
|
||||
|
||||
public void didUpgrade() {
|
||||
showUnlockView();
|
||||
}
|
||||
|
||||
private void showUnlockView() {
|
||||
final UnlockController ctrl = unlockController.get();
|
||||
ctrl.vault.bind(selectedVault);
|
||||
ctrl.setListener(this::didUnlock);
|
||||
activeController.set(ctrl);
|
||||
}
|
||||
|
||||
public void didUnlock(Vault vault) {
|
||||
Platform.setImplicitExit(false);
|
||||
if (vault.equals(selectedVault.getValue())) {
|
||||
this.showUnlockedView(vault);
|
||||
}
|
||||
}
|
||||
|
||||
private void showUnlockedView(Vault vault) {
|
||||
final UnlockedController ctrl = unlockedVaults.computeIfAbsent(vault, k -> {
|
||||
return unlockedControllerProvider.get();
|
||||
@@ -343,7 +349,7 @@ public class MainController extends AbstractFXMLViewController {
|
||||
activeController.set(ctrl);
|
||||
}
|
||||
|
||||
public void didChangePassword(ChangePasswordController ctrl) {
|
||||
public void didChangePassword() {
|
||||
showUnlockView();
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
package org.cryptomator.ui.controllers;
|
||||
|
||||
import java.net.URL;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.cryptomator.ui.settings.Localization;
|
||||
|
||||
@Singleton
|
||||
public class NotFoundController extends LocalizedFXMLViewController {
|
||||
|
||||
@Inject
|
||||
public NotFoundController(Localization localization) {
|
||||
super(localization);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected URL getFxmlResourceUrl() {
|
||||
return getClass().getResource("/fxml/notfound.fxml");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -10,7 +10,6 @@ package org.cryptomator.ui.controllers;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.Optional;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
@@ -28,14 +27,13 @@ import javafx.scene.control.TextField;
|
||||
import javafx.scene.input.KeyEvent;
|
||||
|
||||
@Singleton
|
||||
public class SettingsController extends AbstractFXMLViewController {
|
||||
public class SettingsController extends LocalizedFXMLViewController {
|
||||
|
||||
private final Localization localization;
|
||||
private final Settings settings;
|
||||
|
||||
@Inject
|
||||
public SettingsController(Localization localization, Settings settings) {
|
||||
this.localization = localization;
|
||||
super(localization);
|
||||
this.settings = settings;
|
||||
}
|
||||
|
||||
@@ -44,7 +42,7 @@ public class SettingsController extends AbstractFXMLViewController {
|
||||
|
||||
@FXML
|
||||
private TextField portField;
|
||||
|
||||
|
||||
@FXML
|
||||
private CheckBox useIpv6Checkbox;
|
||||
|
||||
@@ -71,11 +69,6 @@ public class SettingsController extends AbstractFXMLViewController {
|
||||
return getClass().getResource("/fxml/settings.fxml");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ResourceBundle getFxmlResourceBundle() {
|
||||
return localization;
|
||||
}
|
||||
|
||||
private Optional<String> applicationVersion() {
|
||||
return Optional.ofNullable(getClass().getPackage().getImplementationVersion());
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ package org.cryptomator.ui.controllers;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.Comparator;
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
||||
import javax.inject.Inject;
|
||||
@@ -51,23 +51,23 @@ import javafx.scene.layout.GridPane;
|
||||
import javafx.scene.text.Text;
|
||||
import javafx.util.StringConverter;
|
||||
|
||||
public class UnlockController extends AbstractFXMLViewController {
|
||||
public class UnlockController extends LocalizedFXMLViewController {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(UnlockController.class);
|
||||
|
||||
private final Application app;
|
||||
private final Localization localization;
|
||||
private final ExecutorService exec;
|
||||
private final Lazy<FrontendFactory> frontendFactory;
|
||||
private final Settings settings;
|
||||
private final WindowsDriveLetters driveLetters;
|
||||
private final ChangeListener<Character> driveLetterChangeListener = this::winDriveLetterDidChange;
|
||||
final ObjectProperty<Vault> vault = new SimpleObjectProperty<>();
|
||||
private Optional<UnlockListener> listener = Optional.empty();
|
||||
|
||||
@Inject
|
||||
public UnlockController(Application app, Localization localization, ExecutorService exec, Lazy<FrontendFactory> frontendFactory, Settings settings, WindowsDriveLetters driveLetters) {
|
||||
super(localization);
|
||||
this.app = app;
|
||||
this.localization = localization;
|
||||
this.exec = exec;
|
||||
this.frontendFactory = frontendFactory;
|
||||
this.settings = settings;
|
||||
@@ -127,11 +127,6 @@ public class UnlockController extends AbstractFXMLViewController {
|
||||
return getClass().getResource("/fxml/unlock.fxml");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ResourceBundle getFxmlResourceBundle() {
|
||||
return localization;
|
||||
}
|
||||
|
||||
private void vaultChanged(Vault newVault) {
|
||||
if (newVault == null) {
|
||||
return;
|
||||
@@ -276,21 +271,24 @@ public class UnlockController extends AbstractFXMLViewController {
|
||||
progressIndicator.setVisible(true);
|
||||
downloadsPageLink.setVisible(false);
|
||||
CharSequence password = passwordField.getCharacters();
|
||||
exec.submit(() -> this.unlock(password));
|
||||
exec.submit(() -> this.unlock(vault.get(), password));
|
||||
|
||||
}
|
||||
|
||||
private void unlock(CharSequence password) {
|
||||
private void unlock(Vault vault, CharSequence password) {
|
||||
try {
|
||||
vault.get().activateFrontend(frontendFactory.get(), settings, password);
|
||||
vault.get().reveal();
|
||||
vault.activateFrontend(frontendFactory.get(), settings, password);
|
||||
vault.reveal();
|
||||
Platform.runLater(() -> {
|
||||
messageText.setText(null);
|
||||
listener.ifPresent(lstnr -> lstnr.didUnlock(vault));
|
||||
});
|
||||
} catch (InvalidPassphraseException e) {
|
||||
Platform.runLater(() -> {
|
||||
messageText.setText(localization.getString("unlock.errorMessage.wrongPassword"));
|
||||
passwordField.requestFocus();
|
||||
});
|
||||
} catch (UnsupportedVaultFormatException e) {
|
||||
LOG.warn("Unable to unlock vault: " + e.getMessage());
|
||||
Platform.runLater(() -> {
|
||||
downloadsPageLink.setVisible(true);
|
||||
if (e.isVaultOlderThanSoftware()) {
|
||||
@@ -314,4 +312,15 @@ public class UnlockController extends AbstractFXMLViewController {
|
||||
}
|
||||
}
|
||||
|
||||
/* callback */
|
||||
|
||||
public void setListener(UnlockListener listener) {
|
||||
this.listener = Optional.ofNullable(listener);
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
interface UnlockListener {
|
||||
void didUnlock(Vault vault);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@ package org.cryptomator.ui.controllers;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.Optional;
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
||||
import javax.inject.Inject;
|
||||
@@ -46,12 +45,11 @@ import javafx.stage.PopupWindow.AnchorLocation;
|
||||
import javafx.stage.Stage;
|
||||
import javafx.util.Duration;
|
||||
|
||||
public class UnlockedController extends AbstractFXMLViewController {
|
||||
public class UnlockedController extends LocalizedFXMLViewController {
|
||||
|
||||
private static final int IO_SAMPLING_STEPS = 100;
|
||||
private static final double IO_SAMPLING_INTERVAL = 0.25;
|
||||
|
||||
private final Localization localization;
|
||||
private final Stage macWarningsWindow = new Stage();
|
||||
private final MacWarningsController macWarningsController;
|
||||
private final ExecutorService exec;
|
||||
@@ -61,7 +59,7 @@ public class UnlockedController extends AbstractFXMLViewController {
|
||||
|
||||
@Inject
|
||||
public UnlockedController(Localization localization, Provider<MacWarningsController> macWarningsControllerProvider, ExecutorService exec) {
|
||||
this.localization = localization;
|
||||
super(localization);
|
||||
this.macWarningsController = macWarningsControllerProvider.get();
|
||||
this.exec = exec;
|
||||
|
||||
@@ -97,11 +95,6 @@ public class UnlockedController extends AbstractFXMLViewController {
|
||||
return getClass().getResource("/fxml/unlocked.fxml");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ResourceBundle getFxmlResourceBundle() {
|
||||
return localization;
|
||||
}
|
||||
|
||||
private void vaultChanged(Vault newVault) {
|
||||
if (newVault == null) {
|
||||
return;
|
||||
@@ -261,10 +254,6 @@ public class UnlockedController extends AbstractFXMLViewController {
|
||||
|
||||
/* callback */
|
||||
|
||||
public LockListener getListener() {
|
||||
return listener.orElse(null);
|
||||
}
|
||||
|
||||
public void setListener(LockListener listener) {
|
||||
this.listener = Optional.ofNullable(listener);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
package org.cryptomator.ui.controllers;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.cryptomator.ui.model.UpgradeInstruction;
|
||||
import org.cryptomator.ui.model.UpgradeInstruction.UpgradeFailedException;
|
||||
import org.cryptomator.ui.model.Vault;
|
||||
import org.cryptomator.ui.settings.Localization;
|
||||
import org.fxmisc.easybind.EasyBind;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.binding.Binding;
|
||||
import javafx.beans.property.ObjectProperty;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.ProgressIndicator;
|
||||
|
||||
public class UpgradeController extends LocalizedFXMLViewController {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(UpgradeController.class);
|
||||
|
||||
final ObjectProperty<Vault> vault = new SimpleObjectProperty<>();
|
||||
private final ExecutorService exec;
|
||||
private final Binding<Optional<UpgradeInstruction>> upgradeInstruction = EasyBind.monadic(vault).map(Vault::availableUpgrade);
|
||||
private Optional<UpgradeListener> listener = Optional.empty();
|
||||
|
||||
@Inject
|
||||
public UpgradeController(Localization localization, ExecutorService exec) {
|
||||
super(localization);
|
||||
this.exec = exec;
|
||||
}
|
||||
|
||||
@FXML
|
||||
private Label upgradeLabel;
|
||||
|
||||
@FXML
|
||||
private Button upgradeButton;
|
||||
|
||||
@FXML
|
||||
private ProgressIndicator progressIndicator;
|
||||
|
||||
@FXML
|
||||
private Label errorLabel;
|
||||
|
||||
@Override
|
||||
protected void initialize() {
|
||||
upgradeLabel.textProperty().bind(EasyBind.monadic(upgradeInstruction).map(instruction -> {
|
||||
return instruction.map(this::upgradeNotification).orElse("");
|
||||
}).orElse(""));
|
||||
|
||||
EasyBind.subscribe(vault, this::vaultChanged);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected URL getFxmlResourceUrl() {
|
||||
return getClass().getResource("/fxml/upgrade.fxml");
|
||||
}
|
||||
|
||||
private void vaultChanged(Vault newVault) {
|
||||
errorLabel.setText(null);
|
||||
}
|
||||
|
||||
// ****************************************
|
||||
// Upgrade label
|
||||
// ****************************************
|
||||
|
||||
private String upgradeNotification(UpgradeInstruction instruction) {
|
||||
return instruction.getNotification(vault.get(), localization);
|
||||
}
|
||||
|
||||
// ****************************************
|
||||
// Upgrade button
|
||||
// ****************************************
|
||||
|
||||
@FXML
|
||||
private void didClickUpgradeButton(ActionEvent event) {
|
||||
upgradeInstruction.getValue().ifPresent(this::upgrade);
|
||||
}
|
||||
|
||||
private void upgrade(UpgradeInstruction instruction) {
|
||||
Vault v = vault.getValue();
|
||||
Objects.requireNonNull(v);
|
||||
progressIndicator.setVisible(true);
|
||||
upgradeButton.setDisable(true);
|
||||
exec.submit(() -> {
|
||||
if (!instruction.isApplicable(v)) {
|
||||
LOG.error("No upgrade needed for " + v.path().getValue());
|
||||
throw new IllegalStateException("No ugprade needed for " + v.path().getValue());
|
||||
}
|
||||
try {
|
||||
instruction.upgrade(v, localization);
|
||||
Platform.runLater(() -> {
|
||||
progressIndicator.setVisible(false);
|
||||
upgradeButton.setDisable(false);
|
||||
listener.ifPresent(UpgradeListener::didUpgrade);
|
||||
});
|
||||
} catch (UpgradeFailedException e) {
|
||||
Platform.runLater(() -> {
|
||||
errorLabel.setText(e.getLocalizedMessage());
|
||||
progressIndicator.setVisible(false);
|
||||
upgradeButton.setDisable(false);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/* callback */
|
||||
|
||||
public void setListener(UpgradeListener listener) {
|
||||
this.listener = Optional.ofNullable(listener);
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
interface UpgradeListener {
|
||||
void didUpgrade();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -15,7 +15,6 @@ import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
||||
import javax.inject.Inject;
|
||||
@@ -48,20 +47,19 @@ import javafx.scene.control.Label;
|
||||
import javafx.scene.control.ProgressIndicator;
|
||||
|
||||
@Singleton
|
||||
public class WelcomeController extends AbstractFXMLViewController {
|
||||
public class WelcomeController extends LocalizedFXMLViewController {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(WelcomeController.class);
|
||||
|
||||
private final Application app;
|
||||
private final Localization localization;
|
||||
private final Settings settings;
|
||||
private final Comparator<String> semVerComparator;
|
||||
private final ExecutorService executor;
|
||||
|
||||
@Inject
|
||||
public WelcomeController(Application app, Localization localization, Settings settings, @Named("SemVer") Comparator<String> semVerComparator, ExecutorService executor) {
|
||||
super(localization);
|
||||
this.app = app;
|
||||
this.localization = localization;
|
||||
this.settings = settings;
|
||||
this.semVerComparator = semVerComparator;
|
||||
this.executor = executor;
|
||||
@@ -93,11 +91,6 @@ public class WelcomeController extends AbstractFXMLViewController {
|
||||
return getClass().getResource("/fxml/welcome.fxml");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ResourceBundle getFxmlResourceBundle() {
|
||||
return localization;
|
||||
}
|
||||
|
||||
// ****************************************
|
||||
// Check for updates
|
||||
// ****************************************
|
||||
|
||||
@@ -9,9 +9,8 @@
|
||||
package org.cryptomator.ui.controls;
|
||||
|
||||
import org.cryptomator.ui.model.Vault;
|
||||
import org.fxmisc.easybind.EasyBind;
|
||||
|
||||
import javafx.beans.value.ChangeListener;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.control.ContentDisplay;
|
||||
import javafx.scene.control.ContextMenu;
|
||||
@@ -21,15 +20,18 @@ import javafx.scene.control.Tooltip;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.VBox;
|
||||
import javafx.scene.paint.Color;
|
||||
import javafx.scene.paint.Paint;
|
||||
import javafx.scene.shape.Circle;
|
||||
|
||||
public class DirectoryListCell extends DraggableListCell<Vault>implements ChangeListener<Boolean> {
|
||||
public class DirectoryListCell extends DraggableListCell<Vault> {
|
||||
|
||||
// fill: #FD4943, stroke: #E1443F
|
||||
private static final Color RED_FILL = Color.rgb(253, 73, 67);
|
||||
private static final Color RED_STROKE = Color.rgb(225, 68, 63);
|
||||
|
||||
// fill: #FFBF2F, stroke: #E4AC36
|
||||
// private static final Color YELLOW_FILL = Color.rgb(255, 191, 47);
|
||||
// private static final Color YELLOW_STROKE = Color.rgb(228, 172, 54);
|
||||
|
||||
// fill: #28CA40, stroke: #30B740
|
||||
private static final Color GREEN_FILL = Color.rgb(40, 202, 64);
|
||||
private static final Color GREEN_STROKE = Color.rgb(48, 183, 64);
|
||||
@@ -46,58 +48,33 @@ public class DirectoryListCell extends DraggableListCell<Vault>implements Change
|
||||
hbox.setPrefWidth(1);
|
||||
vbox.setFillWidth(true);
|
||||
|
||||
nameText.textProperty().bind(EasyBind.monadic(itemProperty()).flatMap(Vault::name));
|
||||
nameText.textFillProperty().bind(this.textFillProperty());
|
||||
nameText.fontProperty().bind(this.fontProperty());
|
||||
|
||||
pathText.textProperty().bind(EasyBind.monadic(itemProperty()).flatMap(Vault::displayablePath));
|
||||
pathText.setTextOverrun(OverrunStyle.ELLIPSIS);
|
||||
pathText.getStyleClass().add("detail-label");
|
||||
|
||||
statusIndicator.fillProperty().bind(EasyBind.monadic(itemProperty()).flatMap(Vault::unlockedProperty).filter(Boolean.TRUE::equals).map(unlocked -> GREEN_FILL).orElse(RED_FILL));
|
||||
statusIndicator.strokeProperty().bind(EasyBind.monadic(itemProperty()).flatMap(Vault::unlockedProperty).filter(Boolean.TRUE::equals).map(unlocked -> GREEN_STROKE).orElse(RED_STROKE));
|
||||
|
||||
tooltipProperty().bind(EasyBind.monadic(itemProperty()).flatMap(Vault::path).map(p -> new Tooltip(p.toString())));
|
||||
contextMenuProperty().bind(EasyBind.monadic(itemProperty()).flatMap(Vault::unlockedProperty).map(unlocked -> {
|
||||
return unlocked ? null : vaultContextMenu;
|
||||
}));
|
||||
|
||||
setGraphic(hbox);
|
||||
setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateItem(Vault item, boolean empty) {
|
||||
final Vault oldItem = super.getItem();
|
||||
if (oldItem != null) {
|
||||
oldItem.unlockedProperty().removeListener(this);
|
||||
}
|
||||
super.updateItem(item, empty);
|
||||
if (item == null) {
|
||||
nameText.setText(null);
|
||||
pathText.setText(null);
|
||||
setTooltip(null);
|
||||
setContextMenu(null);
|
||||
statusIndicator.setVisible(false);
|
||||
} else {
|
||||
nameText.setText(item.getName());
|
||||
pathText.setText(item.getDisplayablePath());
|
||||
setTooltip(new Tooltip(item.getPath().toString()));
|
||||
statusIndicator.setVisible(true);
|
||||
item.unlockedProperty().addListener(this);
|
||||
updateStatusIndicator();
|
||||
updateContextMenu();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
|
||||
updateStatusIndicator();
|
||||
updateContextMenu();
|
||||
}
|
||||
|
||||
private void updateStatusIndicator() {
|
||||
final Paint fillColor = getItem().isUnlocked() ? GREEN_FILL : RED_FILL;
|
||||
final Paint strokeColor = getItem().isUnlocked() ? GREEN_STROKE : RED_STROKE;
|
||||
statusIndicator.setFill(fillColor);
|
||||
statusIndicator.setStroke(strokeColor);
|
||||
}
|
||||
|
||||
private void updateContextMenu() {
|
||||
if (getItem().isUnlocked()) {
|
||||
this.setContextMenu(null);
|
||||
} else {
|
||||
this.setContextMenu(vaultContextMenu);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
package org.cryptomator.ui.model;
|
||||
|
||||
import org.cryptomator.ui.settings.Localization;
|
||||
|
||||
public interface UpgradeInstruction {
|
||||
|
||||
static UpgradeInstruction[] AVAILABLE_INSTRUCTIONS = {new UpgradeVersion3DropBundleExtension()};
|
||||
|
||||
/**
|
||||
* @return Localized string to display to the user when an upgrade is needed.
|
||||
*/
|
||||
String getNotification(Vault vault, Localization localization);
|
||||
|
||||
/**
|
||||
* Upgrades a vault. Might take a moment, should be run in a background thread.
|
||||
*/
|
||||
void upgrade(Vault vault, Localization localization) throws UpgradeFailedException;
|
||||
|
||||
/**
|
||||
* Determines in O(1), if an upgrade can be applied to a vault.
|
||||
*
|
||||
* @return <code>true</code> if and only if the vault can be migrated to a newer version without the risk of data losses.
|
||||
*/
|
||||
boolean isApplicable(Vault vault);
|
||||
|
||||
/**
|
||||
* Thrown when data migration failed.
|
||||
*/
|
||||
public class UpgradeFailedException extends Exception {
|
||||
|
||||
UpgradeFailedException() {
|
||||
}
|
||||
|
||||
UpgradeFailedException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package org.cryptomator.ui.model;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.cryptomator.ui.settings.Localization;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javafx.application.Platform;
|
||||
|
||||
class UpgradeVersion3DropBundleExtension implements UpgradeInstruction {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(UpgradeVersion3DropBundleExtension.class);
|
||||
|
||||
@Override
|
||||
public String getNotification(Vault vault, Localization localization) {
|
||||
String fmt = localization.getString("upgrade.version3dropBundleExtension.msg");
|
||||
Path path = vault.path().getValue();
|
||||
String oldVaultName = path.getFileName().toString();
|
||||
String newVaultName = StringUtils.removeEnd(oldVaultName, Vault.VAULT_FILE_EXTENSION);
|
||||
return String.format(fmt, oldVaultName, newVaultName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void upgrade(Vault vault, Localization localization) throws UpgradeFailedException {
|
||||
Path path = vault.path().getValue();
|
||||
String oldVaultName = path.getFileName().toString();
|
||||
String newVaultName = StringUtils.removeEnd(oldVaultName, Vault.VAULT_FILE_EXTENSION);
|
||||
Path newPath = path.resolveSibling(newVaultName);
|
||||
if (Files.exists(newPath)) {
|
||||
String fmt = localization.getString("upgrade.version3dropBundleExtension.err.alreadyExists");
|
||||
String msg = String.format(fmt, newPath);
|
||||
throw new UpgradeFailedException(msg);
|
||||
} else {
|
||||
try {
|
||||
Files.move(path, path.resolveSibling(newVaultName));
|
||||
Platform.runLater(() -> {
|
||||
vault.setPath(newPath);
|
||||
});
|
||||
} catch (IOException e) {
|
||||
LOG.error("Vault migration failed", e);
|
||||
throw new UpgradeFailedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isApplicable(Vault vault) {
|
||||
return vault.path().getValue().getFileName().toString().endsWith(Vault.VAULT_FILE_EXTENSION);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -11,10 +11,12 @@ package org.cryptomator.ui.model;
|
||||
import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.nio.file.FileAlreadyExistsException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.text.Normalizer;
|
||||
import java.text.Normalizer.Form;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
@@ -42,12 +44,17 @@ import org.cryptomator.ui.settings.Settings;
|
||||
import org.cryptomator.ui.util.DeferredClosable;
|
||||
import org.cryptomator.ui.util.DeferredCloser;
|
||||
import org.cryptomator.ui.util.FXThreads;
|
||||
import org.fxmisc.easybind.EasyBind;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.binding.Binding;
|
||||
import javafx.beans.property.BooleanProperty;
|
||||
import javafx.beans.property.ObjectProperty;
|
||||
import javafx.beans.property.ReadOnlyObjectProperty;
|
||||
import javafx.beans.property.SimpleBooleanProperty;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
|
||||
@@ -55,7 +62,7 @@ public class Vault implements CryptoFileSystemDelegate {
|
||||
|
||||
public static final String VAULT_FILE_EXTENSION = ".cryptomator";
|
||||
|
||||
private final Path path;
|
||||
private final ObjectProperty<Path> path;
|
||||
private final DeferredCloser closer;
|
||||
private final ShorteningFileSystemFactory shorteningFileSystemFactory;
|
||||
private final CryptoFileSystemFactory cryptoFileSystemFactory;
|
||||
@@ -73,20 +80,20 @@ public class Vault implements CryptoFileSystemDelegate {
|
||||
* Package private constructor, use {@link VaultFactory}.
|
||||
*/
|
||||
Vault(Path vaultDirectoryPath, ShorteningFileSystemFactory shorteningFileSystemFactory, CryptoFileSystemFactory cryptoFileSystemFactory, DeferredCloser closer) {
|
||||
this.path = vaultDirectoryPath;
|
||||
this.path = new SimpleObjectProperty<Path>(vaultDirectoryPath);
|
||||
this.closer = closer;
|
||||
this.shorteningFileSystemFactory = shorteningFileSystemFactory;
|
||||
this.cryptoFileSystemFactory = cryptoFileSystemFactory;
|
||||
|
||||
try {
|
||||
setMountName(getName());
|
||||
setMountName(name().getValue());
|
||||
} catch (IllegalArgumentException e) {
|
||||
// mount name needs to be set by the user explicitly later
|
||||
}
|
||||
}
|
||||
|
||||
private FileSystem getNioFileSystem() {
|
||||
return LazyInitializer.initializeLazily(nioFileSystem, () -> NioFileSystem.rootedAt(path));
|
||||
return LazyInitializer.initializeLazily(nioFileSystem, () -> NioFileSystem.rootedAt(path.getValue()));
|
||||
}
|
||||
|
||||
// ******************************************************************************
|
||||
@@ -158,6 +165,16 @@ public class Vault implements CryptoFileSystemDelegate {
|
||||
Optionals.ifPresent(filesystemFrontend.get(), Frontend::unmount);
|
||||
}
|
||||
|
||||
public boolean needsUpgrade() {
|
||||
return availableUpgrade().isPresent();
|
||||
}
|
||||
|
||||
public Optional<UpgradeInstruction> availableUpgrade() {
|
||||
return Arrays.stream(UpgradeInstruction.AVAILABLE_INSTRUCTIONS).filter(instruction -> {
|
||||
return instruction.isApplicable(this);
|
||||
}).findAny();
|
||||
}
|
||||
|
||||
// ******************************************************************************
|
||||
// Delegate methods
|
||||
// ********************************************************************************/
|
||||
@@ -180,31 +197,42 @@ public class Vault implements CryptoFileSystemDelegate {
|
||||
return filesystemFrontend.get().map(Frontend::getWebDavUrl).orElseThrow(IllegalStateException::new);
|
||||
}
|
||||
|
||||
public Path getPath() {
|
||||
void setPath(Path path) {
|
||||
this.path.set(path);
|
||||
this.nioFileSystem.set(null);
|
||||
}
|
||||
|
||||
public ReadOnlyObjectProperty<Path> path() {
|
||||
return path;
|
||||
}
|
||||
|
||||
public String getDisplayablePath() {
|
||||
public Binding<String> displayablePath() {
|
||||
Path homeDir = Paths.get(SystemUtils.USER_HOME);
|
||||
if (path.startsWith(homeDir)) {
|
||||
Path relativePath = homeDir.relativize(path);
|
||||
String homePrefix = SystemUtils.IS_OS_WINDOWS ? "~\\" : "~/";
|
||||
return homePrefix + relativePath.toString();
|
||||
} else {
|
||||
return path.toString();
|
||||
}
|
||||
return EasyBind.map(path, p -> {
|
||||
if (p.startsWith(homeDir)) {
|
||||
Path relativePath = homeDir.relativize(p);
|
||||
String homePrefix = SystemUtils.IS_OS_WINDOWS ? "~\\" : "~/";
|
||||
return homePrefix + relativePath.toString();
|
||||
} else {
|
||||
return path.getValue().toString();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Directory name without preceeding path components and file extension
|
||||
*/
|
||||
public String getName() {
|
||||
return StringUtils.removeEnd(path.getFileName().toString(), VAULT_FILE_EXTENSION);
|
||||
public Binding<String> name() {
|
||||
return EasyBind.map(path, p -> p.getFileName().toString());
|
||||
}
|
||||
|
||||
public boolean doesVaultDirectoryExist() {
|
||||
return Files.isDirectory(path.getValue());
|
||||
}
|
||||
|
||||
public boolean isValidVaultDirectory() {
|
||||
try {
|
||||
return cryptoFileSystemFactory.isValidVaultStructure(getNioFileSystem());
|
||||
return doesVaultDirectoryExist() && cryptoFileSystemFactory.isValidVaultStructure(getNioFileSystem());
|
||||
} catch (UncheckedIOException e) {
|
||||
return false;
|
||||
}
|
||||
@@ -292,17 +320,17 @@ public class Vault implements CryptoFileSystemDelegate {
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return path.hashCode();
|
||||
return path.getValue().hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof Vault) {
|
||||
final Vault other = (Vault) obj;
|
||||
return this.path.equals(other.path);
|
||||
return this.path.getValue().equals(other.path.getValue());
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -55,7 +55,7 @@ public class VaultObjectMapperProvider implements Provider<ObjectMapper> {
|
||||
@Override
|
||||
public void serialize(Vault value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {
|
||||
jgen.writeStartObject();
|
||||
jgen.writeStringField("path", value.getPath().toString());
|
||||
jgen.writeStringField("path", value.path().getValue().toString());
|
||||
jgen.writeStringField("mountName", value.getMountName());
|
||||
final Character winDriveLetter = value.getWinDriveLetter();
|
||||
if (winDriveLetter != null) {
|
||||
|
||||
@@ -77,7 +77,6 @@ public class SettingsProvider implements Provider<Settings> {
|
||||
final Path settingsPath = getSettingsPath();
|
||||
final InputStream in = Files.newInputStream(settingsPath, StandardOpenOption.READ);
|
||||
settings = objectMapper.readValue(in, Settings.class);
|
||||
settings.getDirectories().removeIf(v -> !v.isValidVaultDirectory());
|
||||
} catch (IOException e) {
|
||||
LOG.warn("Failed to load settings, creating new one.");
|
||||
settings = new Settings();
|
||||
|
||||
20
main/ui/src/main/resources/fxml/notfound.fxml
Normal file
20
main/ui/src/main/resources/fxml/notfound.fxml
Normal file
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Copyright (c) 2014 Sebastian Stenzel
|
||||
This file is licensed under the terms of the MIT license.
|
||||
See the LICENSE.txt file for more info.
|
||||
|
||||
Contributors:
|
||||
Sebastian Stenzel - initial API and implementation
|
||||
-->
|
||||
<?import java.lang.String?>
|
||||
<?import javafx.scene.control.Label?>
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
|
||||
<VBox prefWidth="400.0" prefHeight="400.0" spacing="24.0" alignment="CENTER" xmlns:fx="http://javafx.com/fxml" cacheShape="true" cache="true">
|
||||
|
||||
<Label text="%notfound.label" textAlignment="CENTER" wrapText="true" cacheShape="true" cache="true"/>
|
||||
|
||||
</VBox>
|
||||
|
||||
|
||||
27
main/ui/src/main/resources/fxml/upgrade.fxml
Normal file
27
main/ui/src/main/resources/fxml/upgrade.fxml
Normal file
@@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Copyright (c) 2014 Sebastian Stenzel
|
||||
This file is licensed under the terms of the MIT license.
|
||||
See the LICENSE.txt file for more info.
|
||||
|
||||
Contributors:
|
||||
Sebastian Stenzel - initial API and implementation
|
||||
-->
|
||||
<?import java.lang.String?>
|
||||
<?import javafx.scene.control.Label?>
|
||||
<?import javafx.scene.control.ProgressIndicator?>
|
||||
<?import javafx.scene.control.Button?>
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
|
||||
<VBox prefWidth="400.0" prefHeight="400.0" spacing="24.0" alignment="CENTER" xmlns:fx="http://javafx.com/fxml" cacheShape="true" cache="true">
|
||||
|
||||
<Label fx:id="upgradeLabel" textAlignment="CENTER" wrapText="true"/>
|
||||
|
||||
<Button fx:id="upgradeButton" text="%upgrade.button" prefWidth="150.0" onAction="#didClickUpgradeButton" cacheShape="true" cache="true" />
|
||||
|
||||
<ProgressIndicator progress="-1" fx:id="progressIndicator" visible="false" cacheShape="true" cache="true" cacheHint="SPEED" />
|
||||
|
||||
<Label fx:id="errorLabel" textAlignment="CENTER" wrapText="true"/>
|
||||
</VBox>
|
||||
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
#-------------------------------------------------------------------------------
|
||||
# Copyright (c) 2014 Sebastian Stenzel
|
||||
# Copyright (c) 2016 The Cryptomator Contributors
|
||||
# This file is licensed under the terms of the MIT license.
|
||||
# See the LICENSE.txt file for more info.
|
||||
#
|
||||
# Contributors:
|
||||
# Sebastian Stenzel - initial API and implementation
|
||||
#-------------------------------------------------------------------------------
|
||||
# Sebastian Stenzel - initial translation
|
||||
|
||||
app.name=Cryptomator
|
||||
|
||||
@@ -27,6 +25,15 @@ initialize.button.ok=Create vault
|
||||
initialize.messageLabel.alreadyInitialized=Vault already initialized
|
||||
initialize.messageLabel.initializationFailed=Could not initialize vault. See logfile for details.
|
||||
|
||||
# notfound.fxml
|
||||
notfound.label=Vault couldn't be found. Has it been moved?
|
||||
|
||||
# upgrade.fxml
|
||||
upgrade.button=Upgrade vault
|
||||
|
||||
upgrade.version3dropBundleExtension.msg=This vault needs to be migrated to a newer format.\n"%1$s" will be renamed to "%2$s".\nPlease make sure synchronization has finished before proceeding.
|
||||
upgrade.version3dropBundleExtension.err.alreadyExists=Automatic migration failed.\n"%s" already exists.
|
||||
|
||||
# unlock.fxml
|
||||
unlock.label.password=Password
|
||||
unlock.label.mountName=Drive name
|
||||
|
||||
@@ -1,89 +1,83 @@
|
||||
#-------------------------------------------------------------------------------
|
||||
# Copyright (c) 2016 Markus Kreusch
|
||||
# Copyright (c) 2016 The Cryptomator Contributors
|
||||
# This file is licensed under the terms of the MIT license.
|
||||
# See the LICENSE.txt file for more info.
|
||||
#
|
||||
# Contributors:
|
||||
# Markus Kreusch - initial API and implementation
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
app.name=Cryptomator
|
||||
|
||||
# Markus Kreusch - initial translation
|
||||
app.name = Cryptomator
|
||||
# main.fxml
|
||||
main.emptyListInstructions=Klicken Sie hier, um neue Tresore hinzuzufügen
|
||||
main.directoryList.contextMenu.remove=Aus Liste entfernen
|
||||
main.directoryList.contextMenu.changePassword=Passwort ändern
|
||||
main.addDirectory.contextMenu.new=Tresor erstellen
|
||||
main.addDirectory.contextMenu.open=Tresor öffnen
|
||||
|
||||
main.emptyListInstructions = Klicken Sie hier, um neue Tresore hinzuzufügen
|
||||
main.directoryList.contextMenu.remove = Aus Liste entfernen
|
||||
main.directoryList.contextMenu.changePassword = Passwort ändern
|
||||
main.addDirectory.contextMenu.new = Tresor erstellen
|
||||
main.addDirectory.contextMenu.open = Tresor öffnen
|
||||
# welcome.fxml
|
||||
welcome.checkForUpdates.label.currentlyChecking=Auf Updates prüfen...
|
||||
welcome.newVersionMessage=Version %s kann heruntergeladen werden. Aktuelle Version %s.
|
||||
|
||||
welcome.checkForUpdates.label.currentlyChecking = Auf Updates prüfen...
|
||||
welcome.newVersionMessage = Version %s kann heruntergeladen werden. Aktuelle Version %s.
|
||||
# initialize.fxml
|
||||
initialize.label.password=Passwort
|
||||
initialize.label.retypePassword=Passwort bestätigen
|
||||
initialize.button.ok=Tresor erstellen
|
||||
initialize.messageLabel.alreadyInitialized=Tresor bereits vorhanden
|
||||
initialize.messageLabel.initializationFailed=Fehler beim Initialisieren. Details in der Log-Datei.
|
||||
|
||||
initialize.label.password = Passwort
|
||||
initialize.label.retypePassword = Passwort bestätigen
|
||||
initialize.button.ok = Tresor erstellen
|
||||
initialize.messageLabel.alreadyInitialized = Tresor bereits vorhanden
|
||||
initialize.messageLabel.initializationFailed = Fehler beim Initialisieren. Details in der Log-Datei.
|
||||
# notfound.fxml
|
||||
notfound.label = Tresor konnte nicht gefunden werden.\nWurde er verschoben?
|
||||
# upgrade.fxml
|
||||
upgrade.button = Tresor aktualisieren
|
||||
upgrade.version3dropBundleExtension.msg = Dieser Tresor muss auf ein neueres Format aktualisiert werden.\n"%1$s" wird in "%2$s" umbenannt.\nStellen Sie bitte sicher, dass derzeit keine Synchronisation stattfindet.
|
||||
upgrade.version3dropBundleExtension.err.alreadyExists = Migration fehlgeschlagen.\n"%s" existiert bereits.
|
||||
# unlock.fxml
|
||||
unlock.label.password=Passwort
|
||||
unlock.label.mountName=Laufwerksname
|
||||
unlock.label.winDriveLetter=Laufwerksbuchstabe
|
||||
unlock.label.downloadsPageLink=Alle Cryptomator Versionen
|
||||
unlock.label.advancedHeading=Erweiterte Optionen
|
||||
unlock.button.unlock=Tresor entsperren
|
||||
unlock.button.advancedOptions.show=Weitere Optionen
|
||||
unlock.button.advancedOptions.hide=Weniger Optionen
|
||||
unlock.choicebox.winDriveLetter.auto=Automatisch ermitteln
|
||||
unlock.errorMessage.wrongPassword=Falsches Passwort
|
||||
unlock.errorMessage.mountingFailed=Verbindung fehlgeschlagen. Details in der Log-Datei.
|
||||
unlock.errorMessage.unsupportedKeyLengthInstallJCE=Entschlüsselung fehlgeschlagen. Bitte die Oracle JCE Unlimited Strength Policy installieren.
|
||||
unlock.errorMessage.unsupportedVersion.vaultOlderThanSoftware=Tresor nicht unterstützt. Der Tresor wurde mit einer älteren Version von Cryptomator erstellt.
|
||||
unlock.errorMessage.unsupportedVersion.softwareOlderThanVault=Tresor nicht unterstützt. Der Tresor wurde mit einer neueren Version von Cryptomator erstellt.
|
||||
unlock.messageLabel.startServerFailed=Starten des WebDAV-Servers fehlgeschlagen.
|
||||
|
||||
unlock.label.password = Passwort
|
||||
unlock.label.mountName = Laufwerksname
|
||||
unlock.label.winDriveLetter = Laufwerksbuchstabe
|
||||
unlock.label.downloadsPageLink = Alle Cryptomator Versionen
|
||||
unlock.label.advancedHeading = Erweiterte Optionen
|
||||
unlock.button.unlock = Tresor entsperren
|
||||
unlock.button.advancedOptions.show = Weitere Optionen
|
||||
unlock.button.advancedOptions.hide = Weniger Optionen
|
||||
unlock.choicebox.winDriveLetter.auto = Automatisch ermitteln
|
||||
unlock.errorMessage.wrongPassword = Falsches Passwort
|
||||
unlock.errorMessage.mountingFailed = Verbindung fehlgeschlagen. Details in der Log-Datei.
|
||||
unlock.errorMessage.unsupportedKeyLengthInstallJCE = Entschlüsselung fehlgeschlagen. Bitte die Oracle JCE Unlimited Strength Policy installieren.
|
||||
unlock.errorMessage.unsupportedVersion.vaultOlderThanSoftware = Tresor nicht unterstützt. Der Tresor wurde mit einer älteren Version von Cryptomator erstellt.
|
||||
unlock.errorMessage.unsupportedVersion.softwareOlderThanVault = Tresor nicht unterstützt. Der Tresor wurde mit einer neueren Version von Cryptomator erstellt.
|
||||
unlock.messageLabel.startServerFailed = Starten des WebDAV-Servers fehlgeschlagen.
|
||||
# change_password.fxml
|
||||
changePassword.label.oldPassword=Altes Passwort
|
||||
changePassword.label.newPassword=Neues Passwort
|
||||
changePassword.label.retypePassword=Passwort bestätigen
|
||||
changePassword.label.downloadsPageLink=Alle Cryptomator Versionen
|
||||
changePassword.button.change=Passwort ändern
|
||||
changePassword.errorMessage.wrongPassword=Falsches Passwort
|
||||
changePassword.errorMessage.decryptionFailed=Entschlüsselung fehlgeschlagen
|
||||
changePassword.errorMessage.unsupportedKeyLengthInstallJCE=Entschlüsselung fehlgeschlagen. Bitte die Oracle JCE Unlimited Strength Policy installieren.
|
||||
changePassword.errorMessage.unsupportedVersion.vaultOlderThanSoftware=Tresor nicht unterstützt. Der Tresor wurde mit einer älteren Version von Cryptomator erstellt.
|
||||
changePassword.errorMessage.unsupportedVersion.softwareOlderThanVault=Tresor nicht unterstützt. Der Tresor wurde mit einer neueren Version von Cryptomator erstellt.
|
||||
changePassword.infoMessage.success=Passwort geändert
|
||||
|
||||
changePassword.label.oldPassword = Altes Passwort
|
||||
changePassword.label.newPassword = Neues Passwort
|
||||
changePassword.label.retypePassword = Passwort bestätigen
|
||||
changePassword.label.downloadsPageLink = Alle Cryptomator Versionen
|
||||
changePassword.button.change = Passwort ändern
|
||||
changePassword.errorMessage.wrongPassword = Falsches Passwort
|
||||
changePassword.errorMessage.decryptionFailed = Entschlüsselung fehlgeschlagen
|
||||
changePassword.errorMessage.unsupportedKeyLengthInstallJCE = Entschlüsselung fehlgeschlagen. Bitte die Oracle JCE Unlimited Strength Policy installieren.
|
||||
changePassword.errorMessage.unsupportedVersion.vaultOlderThanSoftware = Tresor nicht unterstützt. Der Tresor wurde mit einer älteren Version von Cryptomator erstellt.
|
||||
changePassword.errorMessage.unsupportedVersion.softwareOlderThanVault = Tresor nicht unterstützt. Der Tresor wurde mit einer neueren Version von Cryptomator erstellt.
|
||||
changePassword.infoMessage.success = Passwort geändert
|
||||
# unlocked.fxml
|
||||
unlocked.button.lock=Tresor sperren
|
||||
unlocked.moreOptions.reveal=Laufwerk anzeigen
|
||||
unlocked.moreOptions.copyUrl=WebDAV-URL kopieren
|
||||
unlocked.label.revealFailed=Befehl fehlgeschlagen
|
||||
unlocked.label.unmountFailed=Trennen des Laufwerks fehlgeschlagen
|
||||
unlocked.label.statsEncrypted=verschlüsselt
|
||||
unlocked.label.statsDecrypted=entschlüsselt
|
||||
unlocked.ioGraph.yAxis.label=Durchsatz (MiB/s)
|
||||
|
||||
unlocked.button.lock = Tresor sperren
|
||||
unlocked.moreOptions.reveal = Laufwerk anzeigen
|
||||
unlocked.moreOptions.copyUrl = WebDAV-URL kopieren
|
||||
unlocked.label.revealFailed = Befehl fehlgeschlagen
|
||||
unlocked.label.unmountFailed = Trennen des Laufwerks fehlgeschlagen
|
||||
unlocked.label.statsEncrypted = verschlüsselt
|
||||
unlocked.label.statsDecrypted = entschlüsselt
|
||||
unlocked.ioGraph.yAxis.label = Durchsatz (MiB/s)
|
||||
# mac_warnings.fxml
|
||||
macWarnings.windowTitle=Achtung - Kompromittierte Datei in %s
|
||||
macWarnings.message=Cryptomator hat möglicherweise unerlaubte Veränderungen in den folgenden Dateien erkannt:
|
||||
macWarnings.moreInformationButton=Mehr erfahren
|
||||
macWarnings.whitelistButton=Trotzdem entschlüsseln
|
||||
|
||||
macWarnings.windowTitle = Achtung - Kompromittierte Datei in %s
|
||||
macWarnings.message = Cryptomator hat möglicherweise unerlaubte Veränderungen in den folgenden Dateien erkannt\:
|
||||
macWarnings.moreInformationButton = Mehr erfahren
|
||||
macWarnings.whitelistButton = Trotzdem entschlüsseln
|
||||
# settings.fxml
|
||||
settings.version.label=Version %s
|
||||
settings.checkForUpdates.label=Auf Updates prüfen
|
||||
settings.port.label=WebDAV Port *
|
||||
settings.port.prompt=0 = Automatisch wählen
|
||||
settings.useipv6.label=IPv6-Literal nutzen
|
||||
settings.requiresRestartLabel=* benötigt Neustart von Cryptomator
|
||||
|
||||
settings.version.label = Version %s
|
||||
settings.checkForUpdates.label = Auf Updates prüfen
|
||||
settings.port.label = WebDAV Port *
|
||||
settings.port.prompt = 0 \= Automatisch wählen
|
||||
settings.useipv6.label = IPv6-Literal nutzen
|
||||
settings.requiresRestartLabel = * benötigt Neustart von Cryptomator
|
||||
# tray icon
|
||||
tray.menu.open=Öffnen
|
||||
tray.menu.quit=Beenden
|
||||
tray.infoMsg.title=Cryptomator läuft noch
|
||||
tray.infoMsg.msg=Cryptomator läuft noch. Mit dem Tray-Icon beenden.
|
||||
tray.infoMsg.msg.osx=Cryptomator läuft noch. Über die Menüleiste beenden.
|
||||
tray.menu.open = Öffnen
|
||||
tray.menu.quit = Beenden
|
||||
tray.infoMsg.title = Cryptomator läuft noch
|
||||
tray.infoMsg.msg = Cryptomator läuft noch. Mit dem Tray-Icon beenden.
|
||||
tray.infoMsg.msg.osx = Cryptomator läuft noch. Über die Menüleiste beenden.
|
||||
5
main/ui/src/main/resources/localization_es.properties
Normal file
5
main/ui/src/main/resources/localization_es.properties
Normal file
@@ -0,0 +1,5 @@
|
||||
# Copyright (c) 2016 The Cryptomator Contributors
|
||||
# This file is licensed under the terms of the MIT license.
|
||||
# See the LICENSE.txt file for more info.
|
||||
|
||||
app.name=Cryptomator
|
||||
96
main/ui/src/main/resources/localization_fr.properties
Normal file
96
main/ui/src/main/resources/localization_fr.properties
Normal file
@@ -0,0 +1,96 @@
|
||||
# Copyright (c) 2016 The Cryptomator Contributors
|
||||
# This file is licensed under the terms of the MIT license.
|
||||
# See the LICENSE.txt file for more info.
|
||||
#
|
||||
# Contributors:
|
||||
# Jean-Noël Charon - initial translation
|
||||
|
||||
app.name=Cryptomator
|
||||
|
||||
# main.fxml
|
||||
main.emptyListInstructions=Cliquez ici pour ajouter un coffre
|
||||
main.directoryList.contextMenu.remove=Retirer de la liste
|
||||
main.directoryList.contextMenu.changePassword=Changer le mot de passe
|
||||
main.addDirectory.contextMenu.new=Créer un nouveau coffre
|
||||
main.addDirectory.contextMenu.open=Ouvrir un coffre existant
|
||||
|
||||
# welcome.fxml
|
||||
welcome.checkForUpdates.label.currentlyChecking=Recherche de mise à jour...
|
||||
welcome.newVersionMessage=La version %s peut-être téléchargée. Il s'agit de %s.
|
||||
|
||||
# initialize.fxml
|
||||
initialize.label.password=Mot de passe
|
||||
initialize.label.retypePassword=Confirmation
|
||||
initialize.button.ok=Créer le coffre
|
||||
initialize.messageLabel.alreadyInitialized=Coffre déjà initialisé
|
||||
initialize.messageLabel.initializationFailed=Impossible d'initialiser le coffre. Voir le fichier de log pour plus de détails.
|
||||
|
||||
# notfound.fxml
|
||||
notfound.label=Coffre introuvable. A t'il été déplacé?
|
||||
|
||||
# upgrade.fxml
|
||||
upgrade.button=Mettre à niveau
|
||||
|
||||
upgrade.version3dropBundleExtension.msg=This vault needs to be migrated to a newer format.\n"%1$s" will be renamed to "%2$s".\nPlease make sure synchronization has finished before proceeding.
|
||||
upgrade.version3dropBundleExtension.err.alreadyExists=Automatic migration failed.\n"%s" already exists.
|
||||
|
||||
# unlock.fxml
|
||||
unlock.label.password=Mot de passe
|
||||
unlock.label.mountName=Nom du lecteur
|
||||
unlock.label.winDriveLetter=Lettre du lecteur
|
||||
unlock.label.downloadsPageLink=Toutes les versions de Cryptomator
|
||||
unlock.label.advancedHeading=Options avancées
|
||||
unlock.button.unlock=Déverrouiller le coffre
|
||||
unlock.button.advancedOptions.show=Plus d'options
|
||||
unlock.button.advancedOptions.hide=Moins d'options
|
||||
unlock.choicebox.winDriveLetter.auto=Assigner automatiquement
|
||||
unlock.errorMessage.wrongPassword=Mot de passe incorrect
|
||||
unlock.errorMessage.mountingFailed=Echec du montage. Voir le fichier de log pour plus de détails.
|
||||
unlock.errorMessage.unsupportedKeyLengthInstallJCE=Echec du décryptage. Veuillez installer la Policy Oracle "JCE Unlimited Strength Policy".
|
||||
unlock.errorMessage.unsupportedVersion.vaultOlderThanSoftware=Coffre non supporté. Ce coffre a été créé avec une ancienne version de Cryptomator.
|
||||
unlock.errorMessage.unsupportedVersion.softwareOlderThanVault=Coffre non supporté. Ce coffre a été créé avec une version de Cryptomator plus récente.
|
||||
unlock.messageLabel.startServerFailed=Le serveur WebDAV n'a pas pu démarrer.
|
||||
|
||||
# change_password.fxml
|
||||
changePassword.label.oldPassword=Ancien mot de passe
|
||||
changePassword.label.newPassword=Nouveau mot de passe
|
||||
changePassword.label.retypePassword=Resaisissez votre mot de passe
|
||||
changePassword.label.downloadsPageLink=Toutes les versions de Cryptomator
|
||||
changePassword.button.change=Modification du mot de masse
|
||||
changePassword.errorMessage.wrongPassword=Mot de passe incorrect
|
||||
changePassword.errorMessage.decryptionFailed=Echec du décryptage
|
||||
changePassword.errorMessage.unsupportedKeyLengthInstallJCE=Echec du décryptage. Veuillez installer la Policy Oracle "JCE Unlimited Strength Policy".
|
||||
changePassword.errorMessage.unsupportedVersion.vaultOlderThanSoftware=Coffre non supporté. Ce coffre a été créé avec une ancienne version de Cryptomator.
|
||||
changePassword.errorMessage.unsupportedVersion.softwareOlderThanVault=Coffre non supporté. Ce coffre a été créé avec une version de Cryptomator plus récente.
|
||||
changePassword.infoMessage.success=Password changed
|
||||
|
||||
# unlocked.fxml
|
||||
unlocked.button.lock=Verrouiller le coffre
|
||||
unlocked.moreOptions.reveal=Voir le lecteur
|
||||
unlocked.moreOptions.copyUrl=Copier l'URL WebDAV
|
||||
unlocked.label.revealFailed=Echec de la commande
|
||||
unlocked.label.unmountFailed=Echec de l'éjection du lecteur
|
||||
unlocked.label.statsEncrypted=cryptage
|
||||
unlocked.label.statsDecrypted=décryptage
|
||||
unlocked.ioGraph.yAxis.label=Débit (MiB/s)
|
||||
|
||||
# mac_warnings.fxml
|
||||
macWarnings.windowTitle=Attention - Fichier corrompu dans %s
|
||||
macWarnings.message=Cryptomator a détecté des corruptions de données dans les fichiers suivants:
|
||||
macWarnings.moreInformationButton=En savoir plus
|
||||
macWarnings.whitelistButton=Décrypter tout de même
|
||||
|
||||
# settings.fxml
|
||||
settings.version.label=Version %s
|
||||
settings.checkForUpdates.label=Vérif. des mises à jour
|
||||
settings.port.label=Port WebDAV *
|
||||
settings.port.prompt=0 = Choix automatique
|
||||
settings.useipv6.label=Utiliser un litéral IPv6
|
||||
settings.requiresRestartLabel=* Redémarrage requis
|
||||
|
||||
# tray icon
|
||||
tray.menu.open=Ouvrir
|
||||
tray.menu.quit=Quitter
|
||||
tray.infoMsg.title=Toujours en fonctionnement
|
||||
tray.infoMsg.msg=Cryptomator est toujours en fonctionnement. Utiliser l'icône de la barre des tâches pour quitter.
|
||||
tray.infoMsg.msg.osx=Cryptomator est toujours en fonctionnement. Utilisez la barre de menu pour quitter.
|
||||
Reference in New Issue
Block a user