Compare commits

...

35 Commits

Author SHA1 Message Date
Sebastian Stenzel
ac9fe28967 Merge branch 'master' into patches-1.0.x
Release 1.0.3d
2016-04-22 10:55:03 +02:00
Sebastian Stenzel
515755d84a updated antkit to support deb and rpm packages [ci skip] 2016-04-22 10:53:51 +02:00
Sebastian Stenzel
fef19fe6b3 Merge branch 'master' into patches-1.0.x 2016-04-14 22:39:56 +02:00
Sebastian Stenzel
5f56dacc4e adjusted travis configuration [ci skip] 2016-04-14 22:39:19 +02:00
Sebastian Stenzel
aa249dabb5 technical release 1.0.3c 2016-04-14 22:28:12 +02:00
Sebastian Stenzel
06a5bed6e3 Merge branch 'master' into patches-1.0.x 2016-04-14 22:27:15 +02:00
Sebastian Stenzel
02f1ffc6bf updated antkit creation (tarball no longer contains a base directory) 2016-04-14 22:26:36 +02:00
Sebastian Stenzel
de9af9e303 fixed funny detail label in vault list, if vault is not located inside home directory 2016-04-13 15:26:27 +02:00
Sebastian Stenzel
e2bc71a0bc added spanish translation template [ci skip] 2016-04-11 14:17:33 +02:00
Sebastian Stenzel
e528f6827c Added translation button [ci skip] 2016-04-11 14:02:11 +02:00
Sebastian Stenzel
2882ae8ef8 Update localization_de.properties (POEditor.com) 2016-04-11 13:46:51 +02:00
Sebastian Stenzel
e37f7cea1a Merge pull request #227 from jncharon/master
French translation
2016-04-11 10:55:26 +02:00
jncharon
9b4ee10155 Adjustments to the french translation 2016-04-10 15:53:53 +02:00
jncharon
c9d970955c French translaction 2016-04-10 15:10:47 +02:00
Sebastian Stenzel
9e0afd36c4 Merge branch 'master' into patches-1.0.x [ci skip] 2016-04-10 02:42:25 +02:00
Sebastian Stenzel
0e523599a3 add execution phase 2016-04-10 02:41:51 +02:00
Sebastian Stenzel
1df6589dd7 make sure, .tar.gz is built on travis 2016-04-10 02:36:10 +02:00
Sebastian Stenzel
fb60c97fd3 Merge branch 'master' into patches-1.0.x 2016-04-10 02:19:52 +02:00
Sebastian Stenzel
90cd149be8 Update .travis.yml 2016-04-10 02:19:01 +02:00
Sebastian Stenzel
89c04ad83b test release 1.0.3b 2016-04-10 02:07:52 +02:00
Sebastian Stenzel
f2d383a211 Merge branch 'master' into patches-1.0.x 2016-04-10 01:56:13 +02:00
Sebastian Stenzel
73fde5d020 null-safe status indicators 2016-04-10 01:54:44 +02:00
Sebastian Stenzel
5c0857e98e build ant-kit on tag/release [ci skip] 2016-04-10 01:53:44 +02:00
Sebastian Stenzel
3e87b9c0c6 oracle jdk8 + jce on trusty 2016-04-10 00:28:11 +02:00
Sebastian Stenzel
a1d0b6b1d3 trying to build with openjdk8 on trusty 2016-04-10 00:22:56 +02:00
Tobias Hagemann
b0d4b2e403 fixed support mail link in code of conduct [ci skip] 2016-04-06 00:04:36 +02:00
Tobias Hagemann
6996d36ea2 added issue template, contribution guide, code of conduct [ci skip] 2016-04-05 12:28:36 +02:00
Sebastian Stenzel
f77ba908da Patch 1.0.3 2016-03-25 16:43:58 +01:00
Sebastian Stenzel
9890789c51 Merge branch 'master' into patches-1.0.x
# Conflicts:
#	main/commons-test/pom.xml
#	main/commons/pom.xml
#	main/filesystem-api/pom.xml
#	main/filesystem-crypto-integration-tests/pom.xml
#	main/filesystem-crypto/pom.xml
#	main/filesystem-inmemory/pom.xml
#	main/filesystem-invariants-tests/pom.xml
#	main/filesystem-nameshortening/pom.xml
#	main/filesystem-nio/pom.xml
#	main/filesystem-stats/pom.xml
#	main/frontend-api/pom.xml
#	main/frontend-webdav/pom.xml
#	main/pom.xml
#	main/uber-jar/pom.xml
#	main/ui/pom.xml
2016-03-25 16:42:44 +01:00
Sebastian Stenzel
a385f2eaef fixes #174 2016-03-25 16:41:30 +01:00
Sebastian Stenzel
553cb5ee3d Migration of vault bundles ending on ".cryptomator" to normal directories. 2016-03-24 22:51:40 +01:00
Markus Kreusch
d0dc8819f4 No longer using TrayIcon on linux systems
* Reason: TrayIcon not supported well on linux and caused problems
* Renamed TrayIconUtil to ExitUtil
* fixes #177
2016-03-24 14:20:10 +01:00
Sebastian Stenzel
221deeda25 removed .cryptomator directory extension when creating new vaults 2016-03-22 21:36:26 +01:00
Sebastian Stenzel
86000ac454 removed test dependencies from main project 2016-03-22 13:04:46 +01:00
Sebastian Stenzel
d026afec35 adjusted snapshot version [ci skip] 2016-03-21 16:49:58 +01:00
55 changed files with 1110 additions and 301 deletions

View File

@@ -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
View 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
View 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
View 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]
```

View File

@@ -1,44 +1,67 @@
Cryptomator
====================
![cryptomator](cryptomator.png)
[![Build Status](https://travis-ci.org/cryptomator/cryptomator.svg?branch=master)](https://travis-ci.org/cryptomator/cryptomator)
[![Coverity Scan Build Status](https://scan.coverity.com/projects/cryptomator-cryptomator/badge.svg?flat=1)](https://scan.coverity.com/projects/cryptomator-cryptomator)
[![Coverage Status](https://coveralls.io/repos/github/cryptomator/cryptomator/badge.svg?branch=master)](https://coveralls.io/github/cryptomator/cryptomator?branch=master)
[![Join the chat at https://gitter.im/cryptomator/cryptomator](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/cryptomator/cryptomator?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![Twitter](https://img.shields.io/badge/twitter-@Cryptomator-blue.svg?style=flat)](http://twitter.com/Cryptomator)
[![POEditor](https://img.shields.io/badge/POEditor-Help%20Translate-blue.svg?style=flat)](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

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

1
main/ant-kit/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/target/

31
main/ant-kit/assembly.xml Normal file
View 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
View 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>

View 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>

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

View 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.

View 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.

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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);
}

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -29,5 +29,5 @@ interface CryptomatorComponent {
Localization localization();
TrayIconUtil trayIconUtil();
ExitUtil exitUtil();
}

View File

@@ -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);

View File

@@ -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()) {

View File

@@ -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();
}
}

View File

@@ -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();
}
}

View File

@@ -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;
}
}

View File

@@ -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 {

View File

@@ -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();
}

View File

@@ -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");
}
}

View File

@@ -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());
}

View File

@@ -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);
}
}

View File

@@ -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);
}

View File

@@ -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();
}
}

View File

@@ -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
// ****************************************

View File

@@ -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);
}
}

View File

@@ -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);
}
}
}

View File

@@ -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);
}
}

View File

@@ -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;
}
}
}
}

View File

@@ -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) {

View File

@@ -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();

View 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>

View 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>

View File

@@ -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

View File

@@ -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.

View 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

View 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.