Compare commits

...
Author SHA1 Message Date
Armin Schrenk 58eb6a6dee change status view from Label to Stackpane & adjust spinner size computation 2021-06-30 20:22:22 +02:00
Armin Schrenk b256670bcc replace static icon in vault detail screen by statusView 2021-06-30 13:50:06 +02:00
Armin Schrenk 91162d3d8f use RotateTranslation isntead of custom Animation 2021-06-30 13:20:34 +02:00
Armin Schrenk 683f17ef24 sum status indication with icon up in single class and apply proper css 2021-06-30 11:04:41 +02:00
Armin Schrenk e626104c06 Add progress indicator skin to light theme & correct attribution of origin 2021-06-29 17:59:15 +02:00
Armin Schrenk f73bcc0a9e clean up 2021-06-29 17:19:13 +02:00
Armin Schrenk 4167fdc850 create custom spinner 2021-06-29 16:30:52 +02:00
Armin Schrenk f544f72327 test impl 2021-06-29 15:59:45 +02:00
Armin SchrenkGitHubSnyk botTobias HagemannSebastian Stenzel <sebastian.stenzel@skymatic.de >
a96115ecd6 Feature: revamp health workflow init (#1695)
* Add health tab to vault options:
* health tool is started from there
* health tool closes old Window and creates new one
* added info and remarks about health tool
* adds confirmation checkbox before starting health tool
* close vault options window when starting health workflow
* Remove AutoLock tab, move options to general tab

Co-authored-by: Snyk bot <snyk-bot@snyk.io>
Co-authored-by: Tobias Hagemann <tobias.hagemann@skymatic.de>
Co-authored-by: Sebastian Stenzel <sebastian.stenzel@skymatic.de >
2021-06-29 09:57:45 +02:00
Sebastian Stenzel c6aceb3e59 don't setPassphraseStored to true after changing pw, when it isn't actually stored 2021-06-28 18:52:34 +02:00
Sebastian Stenzel cadd071ebd update cryptofs 2021-06-28 18:42:10 +02:00
Sebastian Stenzel b64264ef8b updated 3rd party licenses
[ci skip]
2021-06-26 17:49:18 +02:00
Sebastian Stenzel 46691f057e dependency update 2021-06-26 17:42:40 +02:00
Sebastian Stenzel f1b40e32a7 dependency update 2021-06-26 17:25:00 +02:00
b4a97803ff [Snyk] Security upgrade org.cryptomator:webdav-nio-adapter from 1.2.2 to 1.2.3 (#1698)
* fix: pom.xml to reduce vulnerabilities

The following vulnerabilities are fixed with an upgrade:
- https://snyk.io/vuln/SNYK-JAVA-ORGECLIPSEJETTY-1313686

* adjusted suppression config

* bump webdav version

Co-authored-by: Sebastian Stenzel <sebastian.stenzel@gmail.com>
2021-06-24 09:58:47 +02:00
JaniruTECandGitHub 8ac253504f Merge pull request #1697 from cryptomator/refactoring/spellchecking
Enabled spellchecking, added dictionaries, fixed spelling mistakes
2021-06-23 22:49:57 +02:00
JaniruTEC 135b61070d Fixed misspelled key 2021-06-23 22:48:18 +02:00
Armin Schrenk 903f55a24f improve health check gui:
* convert milliseconds to hours, minutes and seconds
* spelling
* adjust to dark theme
2021-06-22 17:17:28 +02:00
Julian Raufelder f2fadafa66 Fix snyk.io badge in README due to switch to single maven module 2021-06-16 16:11:31 +02:00
Julian RaufelderandGitHub 0676732796 Merge pull request #1693 from cryptomator/feature/sign-src-tarball
Sign tarball in release using GPG
2021-06-16 12:54:37 +00:00
Julian Raufelder 08cbfd47ea Prefix signature of tarball in release with cryptomator
To apply convention of the other release assets
2021-06-16 14:20:52 +02:00
b15cda260e Apply suggestions from code review
Co-authored-by: Sebastian Stenzel <overheadhunter@users.noreply.github.com>
2021-06-16 12:13:49 +00:00
Julian Raufelder 74355b128a Sign tarball in release using GPG 2021-06-16 13:49:26 +02:00
JaniruTEC 000f27e166 Fixed spelling mistakes that required API breaking changes 2021-06-12 01:56:15 +02:00
JaniruTEC e1d83c996e Fixed independent spelling mistakes
Added @SuppressWarnings("SpellCheckingInspection") to binary data (e.g. keys) or deliberately misspelled strings
2021-06-12 01:45:31 +02:00
JaniruTEC 0dc401883f Enabled proofreading
Removed dict_* files from .gitignore
Added dict_de.xml
Added dict_project.xml
2021-06-12 01:35:36 +02:00
JaniruTEC 364d59fdf7 Added ".idea/**/shelf" to .gitignore
See: https://github.com/github/gitignore/blob/991e760c1c6d50fdda246e0178b9c58b06770b90/Global/JetBrains.gitignore#L9
2021-06-11 18:28:25 +02:00
Sebastian Stenzel 210050d9d5 update cryptofs 2021-06-09 18:15:39 +02:00
Sebastian Stenzel f10d2b713b made tests public to avoid reflection and "open modules"
see also https://issues.apache.org/jira/browse/SUREFIRE-1909
2021-06-09 10:14:08 +02:00
JaniruTEC f9545b5532 Refactored MPC priority 2021-06-09 01:16:51 +02:00
Sebastian StenzelandGitHub 58376bddef Merge pull request #1685 from cryptomator/feature/provider-agnostic-keychains
Remove all references to specific keychain access providers
2021-06-08 14:42:56 +02:00
Sebastian Stenzel 72e2f64a68 show provided display name 2021-06-07 16:24:42 +02:00
Sebastian Stenzel 48ad74715e * store class name of selected keychain in settings.json
* prepared GeneralPreferencesController to use a provider-supplied display name
2021-06-07 15:17:58 +02:00
Ralph PlawetzkiandGitHub 2e1f33ca82 Fix instructions for building (#1682) 2021-06-06 21:56:28 +02:00
2d3f4d1c03 New Crowdin updates (#1678)
[ci skip]

Co-authored-by: Sebastian Stenzel <overheadhunter@users.noreply.github.com>
2021-06-05 09:11:48 +02:00
04c13ba242 New Crowdin updates (#1677)
[ci skip]

Co-authored-by: Cryptobot <cryptobot@users.noreply.github.com>
2021-06-04 21:00:56 +02:00
Cryptobot b70033e777 Update Crowdin configuration file 2021-06-04 20:48:48 +02:00
Sebastian Stenzel fafb7b229f update i18n config
[ci skip]
2021-06-04 20:29:15 +02:00
Sebastian StenzelandGitHub 7fac6da448 Single maven module (#1676)
combined all sources into single maven module
2021-06-04 20:09:10 +02:00
Sebastian StenzelandGitHub 72bd9c1fdf New Crowdin updates (#1643)
[ci skip]
2021-06-04 15:44:48 +02:00
Sebastian StenzelandGitHub 39b8e25f4f Merge pull request #1596 from eas5/test_improvement
Improved grouped assertions
2021-06-04 15:42:16 +02:00
Sebastian Stenzel c8fa7f1edd fix NPE in autolocker, when reading "lastActivity" before any activity happened 2021-06-04 09:40:23 +02:00
Sebastian StenzelandGitHub 95b98b8a36 Merge pull request #1603 from cryptomator/feature/autoLock
fixes #274
2021-06-02 16:24:26 +02:00
Sebastian Stenzel 005d2a82fe use stopwatch item for autolock tab 2021-06-02 16:22:19 +02:00
Sebastian Stenzel 820f7989d0 remove debug log statement
[ci skip]
2021-06-02 16:10:42 +02:00
Sebastian Stenzel 751a6079c3 use explicit imports
[ci skip]
2021-06-02 16:09:23 +02:00
Sebastian Stenzel 9be95efd10 store autolock time in seconds instead of minutes 2021-06-02 16:08:46 +02:00
Sebastian Stenzel 8f8fa0248c converted lock after "time" to "idle time" 2021-06-02 15:53:57 +02:00
Sebastian Stenzel cd7acea54e Use of NumericTextField 2021-06-02 14:52:27 +02:00
Sebastian StenzelandGitHub 18152e4f3d Merge branch 'develop' into feature/autoLock 2021-06-02 14:31:28 +02:00
7b689c6b78 Keychain is locked (#1550)
Fixes #1526

Co-authored-by: Sebastian Stenzel <overheadhunter@users.noreply.github.com>
Co-authored-by: Sebastian Stenzel <sebastian.stenzel@gmail.com>
2021-06-02 14:24:51 +02:00
Armin SchrenkandGitHub 1159681824 Merge pull request #1615 from cryptomator/feature/sanitizer
Add Vault Health Check

Fixes #312 and fixes #1224.
2021-06-01 18:09:22 +02:00
Armin Schrenk c868ac32cc Change localized text and tweak ui 2021-06-01 18:01:54 +02:00
Sebastian Stenzel f85f953668 Bind countOfWarnSeverity and countOfCritSeverity to list 2021-06-01 15:01:23 +02:00
Armin Schrenk 5185df631d rather add functionality to formattedLabel class than to extend it 2021-06-01 13:22:56 +02:00
Armin Schrenk 617feec111 deactivate fix button 2021-06-01 13:14:31 +02:00
Armin Schrenk eb196165c5 move healthcheck button to vault options 2021-06-01 11:53:33 +02:00
Armin Schrenk 8c37ab3675 Closes #961 2021-06-01 10:45:48 +02:00
Armin Schrenk 7eaade1555 Depeding on state of selected task, show appropiate status text in check detail view 2021-06-01 10:29:41 +02:00
Armin Schrenk 186c129a30 Replace stub check detail description with info about check duration and count of warnings and critical errors 2021-05-31 15:28:30 +02:00
Armin Schrenk f74b9d3347 Remove Scope 2021-05-26 15:50:50 +02:00
Armin Schrenk 6038559172 Localization and small ui fixes 2021-05-26 15:50:03 +02:00
Armin Schrenk 98a899c7e2 scope checklist cell and properly update graphic property 2021-05-25 13:21:13 +02:00
Armin Schrenk 783c8718c1 add localization for health check names 2021-05-25 13:20:18 +02:00
Armin Schrenk b47382811f apply ugly workaround for new vault config loading 2021-05-25 12:37:29 +02:00
Armin Schrenk 62f279b9f7 Merge branch 'develop' into feature/sanitizer 2021-05-25 11:16:27 +02:00
Armin Schrenk ab961f1a8b update thrid party licences 2021-05-25 11:16:17 +02:00
Armin Schrenk 9562db7e13 Closes 1659 2021-05-25 11:10:03 +02:00
Armin SchrenkandGitHub 1ca2e029dc method loadVaultConfig() throws exception instead of returning optional (#1661) 2021-05-21 18:51:49 +02:00
Sebastian Stenzel 944e3e6c50 placeholder: use identifier to look up human-readable names from ResourceBundle instead of if/elsing on classes
(e.g. `resourceBundle.getString(identifier() + ".name")`)

TODO @infeo
2021-05-21 17:55:39 +02:00
Sebastian Stenzel e134d2f422 keep more ui code in fxml 2021-05-21 17:48:20 +02:00
Sebastian Stenzel 04e5170403 * Made DiagnosticResultAction a "pseudo-singleton" that consumes diagnostic results
* renamed FxmlFile.HEALTH_CHECK to match fxml file name
* added missing DI scopes
* simplified cell layout
2021-05-21 17:47:42 +02:00
Armin Schrenk ea008df9f7 Add error screen to vault check start screen 2021-05-21 16:25:37 +02:00
Armin Schrenk e25dfaad35 clean up 2021-05-21 15:59:43 +02:00
Armin Schrenk e98f92c63f Only use CheckTask title in UI instead of HealthCheck::identifier 2021-05-21 15:56:32 +02:00
Armin Schrenk 85b761a9d7 show error screen when unable to write report 2021-05-21 15:29:14 +02:00
Armin Schrenk be8dcd4dc4 remove obsolete TODOs 2021-05-21 13:41:19 +02:00
Armin Schrenk c01c405f20 add select all checkbox 2021-05-21 13:16:14 +02:00
Armin Schrenk b4f268f551 more ui & clean up 2021-05-21 13:15:51 +02:00
Armin Schrenk 21f9e72cc5 preselect correct check in check screen 2021-05-21 12:48:58 +02:00
Armin Schrenk 4845984a35 ui sugar
* show correct name for health check tasks
* some padding
* resize window when run button is hit
2021-05-21 12:45:00 +02:00
Armin Schrenk b6f5ddaf30 Only show button when severity is WARN 2021-05-21 12:40:44 +02:00
Armin Schrenk 1abf0e1bfa Replace result table by result list 2021-05-21 12:00:46 +02:00
Armin Schrenk a8364a8c1a show directory containing exported health report 2021-05-20 16:52:28 +02:00
Armin Schrenk 13c95868fa fix report writer. Ignore not run tests 2021-05-20 16:46:34 +02:00
Armin Schrenk 85ff7542f1 rework gui to be more wizard like:
* show first only checkbox list of checks and single run button
* then show list of check run status with results
2021-05-20 16:35:37 +02:00
Armin Schrenk 432be6dd80 more ui alignments 2021-05-19 13:18:54 +02:00
Armin Schrenk ca0402aaf0 clear styleclass of icon view when content of ResultSeverityCell changes. 2021-05-19 12:38:04 +02:00
Armin Schrenk c7ef0056f9 let UI take space if window size is increased 2021-05-19 09:47:38 +02:00
Armin Schrenk cf13311665 add style class to used icon in result view 2021-05-19 09:32:55 +02:00
Armin Schrenk a7133dbebe Add icon to severity column 2021-05-18 17:12:37 +02:00
Armin Schrenk 168f9b9fb9 fix report writer 2021-05-18 16:57:25 +02:00
Armin Schrenk 2b332c3831 Add column with action button 2021-05-18 16:53:48 +02:00
Armin Schrenk 66e3625a0b Wrap diagnostic result in object to prepare it for possible fix action 2021-05-18 16:49:39 +02:00
Armin Schrenk 20f88e203a simplification and cleanup 2021-05-18 13:40:56 +02:00
Armin Schrenk 66a8dc9811 Revert d2680b9857 2021-05-18 13:36:00 +02:00
Armin Schrenk 9d89efc98c Unify interface:
* move all buttons to one button bar
* switch between runAll and runSelected, depending on list selection
* add a little localization
2021-05-18 09:09:53 +02:00
Armin Schrenk dfbe017316 Partially revert 8e1be4c 2021-05-18 08:47:40 +02:00
Armin Schrenk d2680b9857 Rename controller and fxml file which represents the whole health check screen 2021-05-17 13:06:28 +02:00
Armin Schrenk 8e1be4c67b remove redundant property, fix logic error 2021-05-17 12:49:08 +02:00
Armin Schrenk 749e0ac02d disable export-button as long as no batch run is finished 2021-05-17 12:40:29 +02:00
Armin SchrenkandGitHub a2ad7d69ab Simplify password creation (#1646)
* Remove the password properties and directly access password fields from included fxml files
* wipe the password fields when closing a window
2021-05-17 10:18:10 +02:00
Sebastian Stenzel a47c05c87d hide/disable elements if not relevant in current state 2021-05-10 15:56:46 +02:00
Sebastian Stenzel 6b871e56c8 hide results until task is started 2021-05-10 15:38:52 +02:00
Sebastian Stenzel 40dbc0ba48 cleanup 2021-05-10 15:38:37 +02:00
Sebastian Stenzel 2e52afed51 write report synchronously, reducing complexity 2021-05-10 13:39:46 +02:00
Sebastian Stenzel 64d54133f8 split up check view:
- checkListController is responsible for selecting and (batch)running checks
- checkDetailController is responsible for displaying results
2021-05-07 15:51:47 +02:00
Sebastian Stenzel ac289cc3f7 Merge branch 'develop' into feature/sanitizer
# Conflicts:
#	main/pom.xml
2021-05-07 09:20:54 +02:00
Armin Schrenk 189699d359 sh*te happens
check value instead reference for null
2021-05-06 15:44:27 +02:00
Sebastian StenzelandGitHub 0ce41e7ac3 New Crowdin updates (#1628)
New translations strings.properties

Japanese; Polish; Spanish; Dutch; Czech; Norwegian Bokmal; Korean; Greek; Catalan; Slovak; Russian; Punjabi; Italian; Arabic; Bosnian; Hungarian; German; Cyrillic); Latin); Romanian; French; Chinese Simplified; Croatian; Chinese Traditional; Portuguese; Latvian; Hindi; Indonesian; Turkish; Portuguese, Brazilian; Swedish; Norwegian Nynorsk; 

[ci skip]
2021-05-06 14:25:59 +02:00
Armin SchrenkandGitHub c1a249fd7f Merge pull request #1454 from cryptomator/feature/vault-format-8
Vault Format 8
2021-05-06 14:05:26 +02:00
Armin Schrenk c266c7583b bump dependencies (same as in cryptofs) 2021-05-06 13:59:37 +02:00
Armin Schrenk 00331d4857 check for vaultpath existence instead of catching (undocumented) exception 2021-05-06 13:51:30 +02:00
Armin Schrenk 8fd484e2bb Revert "Move window placements of "popup dialogs" to their corresponding controller"
This reverts commit bc83e23a34.
2021-05-06 13:44:05 +02:00
Armin Schrenk 165d740acd if vault directory is not present, declare it as missing 2021-05-06 12:51:39 +02:00
Armin Schrenk fd4010c6c9 cleanup 2021-05-06 12:43:15 +02:00
Armin Schrenk aa2900fa9e ensure to use cryptolib rc 2021-05-06 12:27:07 +02:00
Sebastian Stenzel 76d1875e01 adjusted to new CryptoFileSystemProvider.checkDirStructureForVault API 2021-05-06 09:56:50 +02:00
Armin Schrenk bc83e23a34 Move window placements of "popup dialogs" to their corresponding controller 2021-05-05 15:03:09 +02:00
Armin Schrenk 6a326bcbce remove password of migration window, when window is closed 2021-05-04 10:51:12 +02:00
Armin Schrenk 573ad03d68 bug fixin' 2021-05-03 17:33:28 +02:00
Sebastian Stenzel 07efb3e94d Merge branch 'feature/vault-format-8' into feature/sanitizer
# Conflicts:
#	main/pom.xml
2021-05-03 12:34:28 +02:00
Armin Schrenk 89e680fb45 reveal report storage location when task is finished. 2021-04-30 11:42:31 +02:00
Armin Schrenk 54128a0016 Refined exportet health report 2021-04-30 11:32:56 +02:00
Armin Schrenk e2565097cd add function to export a report of health checks 2021-04-29 16:31:39 +02:00
Armin Schrenk f827b1fc89 Refactor HealthCheckTask execution:
* new class HealthCheckSupervisor which encapsulates execution of all selected health checks
* checkControllor only users supervisor
2021-04-29 16:31:05 +02:00
Armin Schrenk c0baab2329 change comments 2021-04-28 09:58:14 +02:00
Armin Schrenk 70baa4d09f Rework sanitizer workflow:
* select set of performed HealthChecks prior to loading masterkey
* two predefined healthcheck sets and custom one
* start sequential execution of checks after successful masterkey loading
* removed vault config info
* destroy masterkey on window close, on cancellation, on check finish
2021-04-27 17:41:28 +02:00
Armin Schrenk d710d406d0 Merge branch 'master' into develop 2021-04-23 10:30:12 +02:00
Armin Schrenk 554f245f5d Merge branch 'hotfix/1.5.16' 2021-04-23 10:27:48 +02:00
Sebastian Stenzel 34995088ba addressed some issues identified during code review 2021-04-23 10:24:31 +02:00
Sebastian Stenzel 69c63702f2 pass a single keyloader to cryptofs 2021-04-23 09:55:08 +02:00
Armin Schrenk db7e731554 bumping dokany-nio-adapter 2021-04-23 09:48:56 +02:00
Armin Schrenk e08b43bf17 preparing hotfix 1.5.16 2021-04-23 09:48:40 +02:00
Sebastian Stenzel 58b45bacd1 Merge branch 'develop' into feature/vault-format-8
[ci skip]
2021-04-21 13:27:54 +02:00
Sebastian Stenzel 4f942bc23f reset version
[ci skip]
2021-04-21 13:27:25 +02:00
Armin Schrenk 09a8618fa0 Merge tag '1.5.15' into develop
1.5.15
2021-04-21 12:26:46 +02:00
Armin Schrenk 52af530d1b Merge branch 'release/1.5.15' 2021-04-21 12:26:45 +02:00
Armin Schrenk 86a42234c6 preparing 1.5.15 2021-04-21 12:21:50 +02:00
Armin Schrenk 37c4e78b1d update third party licenses
[ci skip]
2021-04-21 12:05:37 +02:00
Sebastian StenzelandGitHub 9c2c234bee New Crowdin updates (#1604)
New translations strings.properties

Slovak; Czech; Italian; French; Catalan; Romanian; Polish; Chinese Simplified; Dutch; Chinese Traditional;
Norwegian Nynorsk; Croatian; Turkish; German; Spanish; Russian; Hungarian; Punjabi; Portuguese;
Norwegian Bokmal; Indonesian; Hindi; Bosnian; Cyrillic); Swedish; Greek; Korean; Portuguese, Brazilian; Latin); Arabic; Latvian; Japanese; 

[ci skip]
2021-04-21 12:01:09 +02:00
Sebastian Stenzel 59f91267ae fix save password 2021-04-21 11:20:44 +02:00
Sebastian Stenzel b3ff9423b4 Merge branch 'develop' into feature/vault-format-8
# Conflicts:
#	main/commons/src/main/java/org/cryptomator/common/vaults/Vault.java
#	main/commons/src/main/java/org/cryptomator/common/vaults/VaultListManager.java
#	main/ui/src/main/java/org/cryptomator/ui/unlock/UnlockWorkflow.java
2021-04-21 11:20:31 +02:00
Armin Schrenk e3f3090341 bump javafx to version 16 2021-04-21 11:08:42 +02:00
Armin Schrenk 83be6c0864 enhanced release template for ci 2021-04-21 10:41:58 +02:00
Sebastian Stenzel c654951dc1 removed ambiguous filenameLengthLimit from settings, added maxCleartextFilenameLength, shortening is now a 100% independent setting stored in the vault rather than the device settings 2021-04-20 18:15:25 +02:00
Armin Schrenk 4e177c9ea7 Correcting misleading log message 2021-04-20 16:53:59 +02:00
Armin Schrenk dc3a951a1b add hotkeys to remove a vault 2021-04-20 15:07:14 +02:00
Armin Schrenk defa9c75eb add hotkeys for vault selection 2021-04-20 12:18:15 +02:00
Nour AghaandGitHub c1f498a114 Add MEGA & pCloud providers to vault location presets (#1622)
Fixes #1621
2021-04-20 08:09:17 +02:00
Armin Schrenk 8457c50ebc add muted style class to status text of newVaultLocationScreen 2021-04-19 16:11:28 +02:00
Armin SchrenkandGitHub 0144cbb99f Merge pull request #1618 from cryptomator/feature/#1508-observable-mounts
Closes #1508
2021-04-16 16:27:40 +02:00
Armin SchrenkandGitHub d6e4c7d177 Rework choose-location-screen in add vault wizard: (#1620)
* more checks for the chosen vault path
* every check has own error message
* perform checks when vault path changes
* if any radio button selected, enable vault path field (no-edit)
2021-04-16 16:18:01 +02:00
3376b16b7b Rename Donation Key to Supporter Certificate (#1613)
Renamed all occurences of donation key to supporter certificate and adjust ui.

Co-authored-by: Tobias Hagemann <tobias.hagemann@skymatic.de>
Co-authored-by: Sebastian Stenzel <overheadhunter@users.noreply.github.com>
2021-04-16 12:18:03 +02:00
Sebastian Stenzel 673fdcd095 stupid. 2021-04-15 13:45:20 +02:00
Armin Schrenk 0d00520ac1 Throw specifc exception on not completed lock of a vault 2021-04-15 12:54:19 +02:00
Armin Schrenk 22a0d3a9a5 bump fuse/dokany-nio versions 2021-04-15 11:11:05 +02:00
Sebastian Stenzel 24baa44e70 stronger encapsulation of vault state await/signal mechanism 2021-04-15 10:30:29 +02:00
Armin Schrenk 03886f88e8 Fix lock workflow for webdav:
* internally, wait for condition that onExit-Method is exceuted (with timeout)
* store and execute onExitAction also for webdav
2021-04-15 10:14:28 +02:00
Armin Schrenk 642816b631 rebuild tray menu when vaultname changes 2021-04-14 17:26:04 +02:00
Sebastian Stenzel f3a03c71ec implemented cancellable health checks 2021-04-14 10:20:34 +02:00
Sebastian Stenzel 1fab246fcd ugly PoC for new UI 2021-04-13 15:43:59 +02:00
Armin Schrenk cd5c55aad7 Refactor lock/unlock workflows:
* don't set vault state on successful lock workflow
* improved error handling
2021-04-13 11:22:42 +02:00
Armin Schrenk b066b4b045 opening a vault in read-only always assumes a filename length limit of 220
references #1605
2021-04-12 18:06:09 +02:00
JaniruTEC 41d2a2c77e Added .idea/uiDesigner.xml to .gitignore 2021-04-10 23:16:00 +02:00
Sebastian Stenzel 69186b916c adjusted to new async health check api 2021-04-09 16:04:52 +02:00
Armin Schrenk 0840695e0a Refactor lock/unlock convinience methods in FxApplication:
* execute vault state transition here
* on failed transition show error window
* only start worfklow on successful transition
2021-04-08 17:28:49 +02:00
Armin Schrenk 8447f105b0 rename instance variables 2021-04-08 13:08:05 +02:00
Sebastian Stenzel c306d8df04 alternative thread-safe vault state without requiring explicit synchronization 2021-04-08 11:23:57 +02:00
Armin Schrenk beba6490c3 Add locking mechanism to change the vault state t 2021-04-06 13:26:58 +02:00
Armin Schrenk fb1078b35b bump to SNAPSHOT nio-adapter and refactor Volume.mount() method:
* returns void
* add onExitAction parameter
* adjust classes
2021-04-06 10:05:32 +02:00
Armin Schrenk be0912e6ca Merge branch 'develop' into feature/#1508-observable-mounts 2021-04-06 09:00:05 +02:00
Sebastian Stenzel 13db1aa9b9 Actually run tests from within Sanitizer UI 2021-04-01 17:40:53 +02:00
Sebastian Stenzel d2cd2c923d unlock for health check 2021-04-01 13:26:33 +02:00
Martin Beyer 92de05b3db Changed textfield to only accept Integers, Using scheduled Executor as Timer 2021-04-01 11:42:41 +02:00
Sebastian Stenzel c1000d9958 Merge branch 'feature/vault-format-8' into feature/sanitizer 2021-04-01 09:26:21 +02:00
Sebastian Stenzel 2810c044ea reduced visibility 2021-03-31 16:23:54 +02:00
Sebastian Stenzel e09bd160b7 Made masterkey loading strategies reusable 2021-03-31 16:12:31 +02:00
Sebastian Stenzel e6d1e4697c Merge develop into feature/vault-format-8 2021-03-31 11:39:16 +02:00
Sebastian Stenzel 497e5ce73f Add health check window 2021-03-31 11:37:55 +02:00
Armin Schrenk cf7cbae567 Set dev branch back to SNAPSHOT version
[ci skip]
2021-03-31 11:32:06 +02:00
Armin Schrenk 803f517c62 Merge tag '1.5.14' into develop
1.5.14
2021-03-31 11:11:34 +02:00
Armin Schrenk 0afa7b8e37 Merge branch 'release/1.5.14' 2021-03-31 11:11:27 +02:00
Armin Schrenk 1a0f70f8e8 updating third-party-licenses 2021-03-31 10:59:21 +02:00
Armin Schrenk 8737eb83f0 Bumping webdav-nio-adapter dependency 2021-03-31 10:58:23 +02:00
Armin Schrenk a96239a19f closes #1245 2021-03-31 10:52:30 +02:00
Armin Schrenk 2b7cfcd1dc preparing 1.5.14 2021-03-31 09:52:24 +02:00
Sebastian StenzelandGitHub ebccb61750 New Crowdin updates (#1560) 2021-03-31 09:46:45 +02:00
Armin Schrenk 285f2aec23 unify wording
[ci skip]
2021-03-30 16:10:24 +02:00
Armin SchrenkandGitHub 217e31fbd7 Merge pull request #1595 from cryptomator/feature/MCGA
Feature: Make Context menu Great Again
* adding additional entries
* fixes #1478
* only appears on a selected vault
2021-03-30 16:03:41 +02:00
Sebastian Stenzel f0ebf7a638 EasyBind rulez 2021-03-30 14:20:05 +02:00
Armin Schrenk c05c5e3f90 closes #961 2021-03-30 13:57:21 +02:00
Sebastian Stenzel 30f0c5e697 split VaultList and ContextMenu into two separate controllers 2021-03-30 13:43:37 +02:00
Armin Schrenk f989b8627c Update java-jwt 2021-03-30 13:10:54 +02:00
Armin Schrenk ff84230566 structure constructor 2021-03-30 11:53:30 +02:00
Armin Schrenk 3b4f6276b5 Improve selection model of list view:
* Clear selection if an empty space is clicked
* only open context menu if an item is selected
2021-03-30 11:25:22 +02:00
Armin Schrenk 2be7a050a4 refine wording
[ci skip]
2021-03-30 09:47:11 +02:00
Martin Beyer 1c01228778 Removing LockOnSleep UI elements (not implemented yet) 2021-03-29 19:29:17 +02:00
Martin Beyer 1c35780d9e Cleaned up integrations implementation and added Regex for input 2021-03-29 19:10:05 +02:00
Armin Schrenk 96a612127c add reveal entry to context menu. 2021-03-29 16:23:24 +02:00
Armin Schrenk 0bdfb7c9f9 Distinct between "unlock" and "unlock now" in context menu:
* inject keychainManager
* bind/unbind passphraseStored property to selected vault
* rename bindings to show possible action
* removed unused binding
* initialize properties properly
2021-03-29 12:59:48 +02:00
Armin Schrenk f556301249 fix suggestion 2021-03-29 12:47:46 +02:00
f77b237e59 simplify private function
Co-authored-by: Sebastian Stenzel <overheadhunter@users.noreply.github.com>
2021-03-29 12:44:57 +02:00
Armin Schrenk 61b7a39aad change level of a log message from warn to debug
[ci skip]
2021-03-29 10:53:48 +02:00
Martin Beyer 2cee6e45f1 Merge remote-tracking branch 'upstream/develop' into feature/autoLock 2021-03-29 10:45:32 +02:00
Martin Beyer 1292548042 Implementing new settings and locking after a certain amount of minutes 2021-03-29 10:44:39 +02:00
Tobias HagemannandGitHub 16bd84ee62 Update README.md
[ci skip]
2021-03-26 10:46:49 +01:00
Tobias HagemannandGitHub 3d0a97fcdf Update README.md
[ci skip]
2021-03-25 17:06:15 +01:00
Elvys Soares 5ae2419e6d Improved grouped assertions
Signed-off-by: Elvys Soares <eas5@cin.ufpe.br>
2021-03-23 21:46:32 -03:00
Armin Schrenk 786d156b9f change wording in context menu entries 2021-03-23 15:08:23 +01:00
Armin Schrenk 629b6fb97d execute Service tasks on application thread 2021-03-23 12:53:17 +01:00
Armin Schrenk 17dc32bb79 lock vault on external unmount 2021-03-23 12:52:38 +01:00
Armin Schrenk c05e00d32a Change volume interface to observe mounts 2021-03-23 12:37:36 +01:00
Armin Schrenk 9dc8b2cb47 Use Bindings instead of properties 2021-03-23 10:50:04 +01:00
Armin Schrenk 0e32e96c7d made context menu great again:
* added entry to unlock / lock a vault
* added entry to show vault options
2021-03-22 17:10:45 +01:00
Armin Schrenk 97afadd7b9 fixes #1478 2021-03-22 12:58:45 +01:00
Armin Schrenk b199b65e38 closes #176 2021-03-22 12:51:07 +01:00
Tobias HagemannandGitHub 999abf3c13 Update README.md
[ci skip]
2021-03-22 12:24:54 +01:00
Sebastian Stenzel 2cdde54db6 updated mockito due to build errors caused by bytebuddy 2021-03-17 13:14:55 +01:00
Sebastian Stenzel 6941603cdd update to latest cryptolib/cryptofs beta 2021-03-17 13:03:55 +01:00
Sebastian Stenzel cdca4e047d Merge branch 'develop' into feature/vault-format-8 2021-03-17 12:55:47 +01:00
Sebastian StenzelandGitHub 31e938de6a Merge pull request #1587 from cryptomator/feature/jdk-16
Update to JDK 16
2021-03-17 12:29:29 +01:00
Sebastian Stenzel 4c10ab764a updated README 2021-03-17 09:33:43 +01:00
Sebastian Stenzel 4e075ab0ca using pattern-matching instanceof where applicable 2021-03-17 09:22:16 +01:00
Sebastian Stenzel f73ae9759f use new Stream.toList() where applicable 2021-03-17 09:16:44 +01:00
Sebastian Stenzel f6283b2f7e using text blocks where applicable 2021-03-17 09:12:54 +01:00
Sebastian Stenzel b23d2e4def allow use of reflection in codacy coverage reporter 2021-03-17 08:19:58 +01:00
Sebastian Stenzel 91a2943599 update to JDK 16 2021-03-17 08:16:26 +01:00
Sebastian Stenzel e32ce22d24 Merge branch 'develop' into feature/vault-format-8 2021-03-10 12:48:58 +01:00
Armin Schrenk e75c415b46 Load vault config on demand and don't cache it
* fixes issue with unlock after vault migration
2021-03-10 12:03:46 +01:00
Martin Beyer 8592e3667b Applying a SystemListener when the notify gets called with SLEEP 2021-03-09 18:55:35 +01:00
Martin Beyer 5a11d02fa8 Splitting the "Lock after X minutes" Checkbox in to two string resources. 2021-03-09 18:52:53 +01:00
Sebastian Stenzel 0ab28602d1 bumped cryptofs version 2021-03-05 17:33:58 +01:00
Sebastian Stenzel 62c8edff04 Choose key loading workflow depending on vaultconfig's key ID and allow KeyLoadingComponent to decide itself, what exceptions it can handle 2021-03-03 17:41:17 +01:00
Sebastian Stenzel d01c6268f8 remove unused field
[ci skip]
2021-03-02 16:16:24 +01:00
Sebastian Stenzel e083fd0bcc skip certain steps on forks 2021-03-02 11:55:20 +01:00
ff687f1bae fix: main/pom.xml to reduce vulnerabilities (#1569)
The following vulnerabilities are fixed with an upgrade:
- https://snyk.io/vuln/SNYK-JAVA-ORGECLIPSEJETTY-1080611

Co-authored-by: snyk-bot <snyk-bot@snyk.io>
2021-03-02 08:43:10 +01:00
Sebastian Stenzel 557aaa2480 Removed unused imports
[ci skip]
2021-03-01 15:59:13 +01:00
Sebastian Stenzel 78e43d401d split package org.cryptoamtor.ui.unlock to allow for different kinds of unlock workflows 2021-03-01 15:58:00 +01:00
Sebastian Stenzel 7b08c5d287 Merge branch 'develop' into feature/vault-format-8
# Conflicts:
#	main/pom.xml
#	main/ui/src/main/resources/license/THIRD-PARTY.txt
[ci skip]
2021-02-26 10:10:50 +01:00
Sebastian Stenzel 84d2644f19 fix wrong versions that have been merged from main branch 2021-02-26 10:05:26 +01:00
Martin Beyer d13dfe3526 First take at UI implementation of a Auto-Lock Tab 2021-02-24 16:23:49 +01:00
Armin Schrenk f9a9d7b870 Merge tag '1.5.13' into develop
1.5.13
2021-02-24 16:21:07 +01:00
Armin Schrenk d75a8c4bba Merge branch 'release/1.5.13' 2021-02-24 16:21:06 +01:00
Martin Beyer 8fccb1b8f0 Added some Settings 2021-02-24 16:20:34 +01:00
Armin Schrenk d326c7c990 preparing 1.5.13 2021-02-24 16:17:35 +01:00
Armin SchrenkandGitHub e8e63ca4fc Merge pull request #1517 from cryptomator/feature/translations
New Crowdin updates
2021-02-24 16:12:30 +01:00
Martin Beyer c82e5577a1 New Tab AutoLock in VaultOptions 2021-02-24 15:17:23 +01:00
Armin SchrenkandGitHub 6878f2e94b Merge pull request #1556 from cryptomator/feature/win-auto-theme
Feature/win auto theme
2021-02-24 14:31:17 +01:00
Armin Schrenk a17b416262 only remove system theme change listener, if one was previously registered. 2021-02-24 12:54:56 +01:00
Armin Schrenk fed572694f Merge branch 'develop' into feature/win-auto-theme
# Conflicts:
#	main/pom.xml
2021-02-24 12:25:04 +01:00
Armin Schrenk fe3d67d937 update build workflow 2021-02-24 12:21:13 +01:00
Armin Schrenk 3dcdeb1033 refactor pom to store targeted jdk build version in variable 2021-02-24 12:19:12 +01:00
Armin Schrenk 0898158c5a remove bintray as source repository in pom 2021-02-24 12:18:38 +01:00
Armin Schrenk 81091d4bdf bump integrations-* repos and implement new interface methods 2021-02-24 12:18:24 +01:00
Martin Beyer c9b1b1baa5 Fixes #1291 (Windows Automatic Theme) 2021-02-23 17:26:50 +01:00
Tobias Hagemann c81f3bd972 updated dependencies 2021-02-23 13:43:07 +01:00
Sebastian Stenzel 9f86b74320 New translations strings.properties (Greek)
[ci skip]
2021-02-23 09:32:09 +01:00
Sebastian Stenzel 2d8390a0f3 New translations strings.properties (Chinese Simplified)
[ci skip]
2021-02-22 11:47:50 +01:00
Sebastian Stenzel 8d3671175f New translations strings.properties (Swedish)
[ci skip]
2021-02-21 16:16:10 +01:00
Sebastian Stenzel 366011a222 New translations strings.properties (Swedish)
[ci skip]
2021-02-21 15:45:39 +01:00
Sebastian Stenzel c0c2e21055 New translations strings.properties (Korean)
[ci skip]
2021-02-20 02:29:34 +01:00
Sebastian Stenzel 63be96a151 New translations strings.properties (Korean)
[ci skip]
2021-02-20 01:58:05 +01:00
Sebastian Stenzel fc1df4bd99 New translations strings.properties (Catalan)
[ci skip]
2021-02-19 21:46:49 +01:00
Sebastian Stenzel 7657330931 New translations strings.properties (German)
[ci skip]
2021-02-19 13:17:33 +01:00
Sebastian Stenzel 4e44de3c3b New translations strings.properties (Portuguese, Brazilian)
[ci skip]
2021-02-19 01:07:24 +01:00
Sebastian Stenzel 8d902a72ca New translations strings.properties (Turkish)
[ci skip]
2021-02-18 19:39:40 +01:00
Sebastian Stenzel 7378031a72 New translations strings.properties (Spanish)
[ci skip]
2021-02-18 17:15:20 +01:00
Sebastian Stenzel f898c07c27 New translations strings.properties (German)
[ci skip]
2021-02-18 16:41:50 +01:00
Sebastian Stenzel c8f02d1045 New translations strings.properties (Czech)
[ci skip]
2021-02-18 14:56:07 +01:00
Sebastian Stenzel 4cc13b986b New translations strings.properties (Slovak)
[ci skip]
2021-02-18 14:22:12 +01:00
Sebastian Stenzel af7b6780f3 New translations strings.properties (Italian)
[ci skip]
2021-02-18 14:22:10 +01:00
Sebastian Stenzel 4a17d01004 New translations strings.properties (French)
[ci skip]
2021-02-18 13:42:57 +01:00
Sebastian Stenzel 1d68408e21 New translations strings.properties (Japanese)
[ci skip]
2021-02-18 13:42:49 +01:00
Sebastian Stenzel 821b1ee660 New translations strings.properties (Russian)
[ci skip]
2021-02-18 13:42:45 +01:00
Sebastian Stenzel c6616bd467 New translations strings.properties (Slovak)
[ci skip]
2021-02-18 13:42:44 +01:00
Sebastian Stenzel 4bb2589f16 New translations strings.properties (Polish)
[ci skip]
2021-02-18 13:42:37 +01:00
Sebastian Stenzel 896c3b3565 New translations strings.properties (Norwegian Bokmal)
[ci skip]
2021-02-18 13:09:32 +01:00
Sebastian Stenzel 6ee717a693 New translations strings.properties (French)
[ci skip]
2021-02-18 13:09:31 +01:00
Sebastian Stenzel 07ec858e1e New translations strings.properties (Spanish)
[ci skip]
2021-02-18 13:09:29 +01:00
Sebastian Stenzel a7c1e43ebc New translations strings.properties (Arabic)
[ci skip]
2021-02-18 13:09:28 +01:00
Sebastian Stenzel ac1cd3b073 New translations strings.properties (Catalan)
[ci skip]
2021-02-18 13:09:27 +01:00
Sebastian Stenzel 7474519faf New translations strings.properties (Czech)
[ci skip]
2021-02-18 13:09:26 +01:00
Sebastian Stenzel 340e474c33 New translations strings.properties (German)
[ci skip]
2021-02-18 13:09:24 +01:00
Sebastian Stenzel c90ab75427 New translations strings.properties (Greek)
[ci skip]
2021-02-18 13:09:23 +01:00
Sebastian Stenzel 848b3f77d3 New translations strings.properties (Hungarian)
[ci skip]
2021-02-18 13:09:21 +01:00
Sebastian Stenzel fb8cdb31ca New translations strings.properties (Italian)
[ci skip]
2021-02-18 13:09:20 +01:00
Sebastian Stenzel ba5f8053fb New translations strings.properties (Japanese)
[ci skip]
2021-02-18 13:09:19 +01:00
Sebastian Stenzel 38165becca New translations strings.properties (Korean)
[ci skip]
2021-02-18 13:09:17 +01:00
Sebastian Stenzel f731ac5c90 New translations strings.properties (Dutch)
[ci skip]
2021-02-18 13:09:16 +01:00
Sebastian Stenzel 0291702736 New translations strings.properties (Polish)
[ci skip]
2021-02-18 13:09:15 +01:00
Sebastian Stenzel ab63929861 New translations strings.properties (Portuguese)
[ci skip]
2021-02-18 13:09:12 +01:00
Sebastian Stenzel ca36fb8af3 New translations strings.properties (Slovak)
[ci skip]
2021-02-18 13:09:11 +01:00
Sebastian Stenzel 8cb29ff83b New translations strings.properties (Swedish)
[ci skip]
2021-02-18 13:09:10 +01:00
Sebastian Stenzel 304fa67dd7 New translations strings.properties (Turkish)
[ci skip]
2021-02-18 13:09:09 +01:00
Sebastian Stenzel a80ec32d2c New translations strings.properties (Chinese Simplified)
[ci skip]
2021-02-18 13:09:07 +01:00
Sebastian Stenzel dc4f21162e New translations strings.properties (Chinese Traditional)
[ci skip]
2021-02-18 13:09:06 +01:00
Sebastian Stenzel 3b8d7e0241 New translations strings.properties (Portuguese, Brazilian)
[ci skip]
2021-02-18 13:09:05 +01:00
Sebastian Stenzel 6891c68cf1 New translations strings.properties (Norwegian Nynorsk)
[ci skip]
2021-02-18 13:09:01 +01:00
Sebastian Stenzel 18b26fbc58 New translations strings.properties (Latvian)
[ci skip]
2021-02-18 13:09:00 +01:00
Sebastian Stenzel 1db8da6b6b New translations strings.properties (Bosnian)
[ci skip]
2021-02-18 13:08:57 +01:00
Sebastian Stenzel 14bce7e91d New translations strings.properties (Russian)
[ci skip]
2021-02-18 13:08:56 +01:00
Sebastian Stenzel 2674bc6f23 New translations strings.properties (Punjabi)
[ci skip]
2021-02-18 13:08:55 +01:00
Tobias HagemannandGitHub 74e1d6f991 Merge pull request #1545 from cryptomator/feature/save-password-clarification
"Save Password" Clarification
2021-02-18 13:07:04 +01:00
Tobias Hagemann 25dba028f8 added deep-linking to vault options tabs, changed "password saved" label to hyperlink 2021-02-18 11:32:14 +01:00
Tobias Hagemann bf51cc13d1 renamed "save password" to "remember password", switched placements of "vault options" hyperlink/button and "password saved" label 2021-02-18 09:15:19 +01:00
Sebastian Stenzel 24be36cccb New translations strings.properties (Spanish)
[ci skip]
2021-02-15 18:19:27 +01:00
Sebastian Stenzel 797e15c775 New translations strings.properties (Chinese Traditional)
[ci skip]
2021-02-15 17:08:04 +01:00
Sebastian Stenzel 2395dbcae9 New translations strings.properties (Italian)
[ci skip]
2021-02-15 16:09:11 +01:00
Sebastian Stenzel efacbbe2b6 New translations strings.properties (Bosnian)
[ci skip]
2021-02-15 15:40:45 +01:00
Sebastian Stenzel 2518086e46 New translations strings.properties (Polish)
[ci skip]
2021-02-15 15:40:44 +01:00
Sebastian Stenzel c733247611 New translations strings.properties (Japanese)
[ci skip]
2021-02-15 15:40:42 +01:00
Sebastian Stenzel 4f44e71e13 New translations strings.properties (Czech)
[ci skip]
2021-02-15 15:40:40 +01:00
Sebastian Stenzel 02aa46ece8 New translations strings.properties (Bosnian)
[ci skip]
2021-02-15 15:09:58 +01:00
Sebastian Stenzel 635f64c847 New translations strings.properties (German)
[ci skip]
2021-02-15 15:09:56 +01:00
Sebastian Stenzel 0a8516ae9a New translations strings.properties (French)
[ci skip]
2021-02-15 15:09:55 +01:00
Sebastian Stenzel c1edb30472 New translations strings.properties (Bosnian)
[ci skip]
2021-02-15 14:41:51 +01:00
Sebastian Stenzel 93c78b63ca New translations strings.properties (Russian)
[ci skip]
2021-02-15 14:41:50 +01:00
Sebastian Stenzel 3ccae93757 New translations strings.properties (Norwegian Bokmal)
[ci skip]
2021-02-15 14:09:30 +01:00
Sebastian Stenzel 450dec2baf New translations strings.properties (French)
[ci skip]
2021-02-15 14:09:29 +01:00
Sebastian Stenzel 36121527ca New translations strings.properties (Spanish)
[ci skip]
2021-02-15 14:09:27 +01:00
Sebastian Stenzel f30451f7e1 New translations strings.properties (Catalan)
[ci skip]
2021-02-15 14:09:25 +01:00
Sebastian Stenzel 74d7f63f64 New translations strings.properties (Czech)
[ci skip]
2021-02-15 14:09:24 +01:00
Sebastian Stenzel 350a4ab762 New translations strings.properties (German)
[ci skip]
2021-02-15 14:09:23 +01:00
Sebastian Stenzel 0e0e75b89c New translations strings.properties (Greek)
[ci skip]
2021-02-15 14:09:22 +01:00
Sebastian Stenzel e76440d928 New translations strings.properties (Hungarian)
[ci skip]
2021-02-15 14:09:20 +01:00
Sebastian Stenzel 0cbace67a5 New translations strings.properties (Italian)
[ci skip]
2021-02-15 14:09:19 +01:00
Sebastian Stenzel 84a3082589 New translations strings.properties (Japanese)
[ci skip]
2021-02-15 14:09:17 +01:00
Sebastian Stenzel cdfcca06d1 New translations strings.properties (Korean)
[ci skip]
2021-02-15 14:09:16 +01:00
Sebastian Stenzel 630bfa4cee New translations strings.properties (Dutch)
[ci skip]
2021-02-15 14:09:15 +01:00
Sebastian Stenzel 90cb7beb1f New translations strings.properties (Polish)
[ci skip]
2021-02-15 14:09:14 +01:00
Sebastian Stenzel d37fa33278 New translations strings.properties (Slovak)
[ci skip]
2021-02-15 14:09:11 +01:00
Sebastian Stenzel eed9c906cc New translations strings.properties (Swedish)
[ci skip]
2021-02-15 14:09:09 +01:00
Sebastian Stenzel 2b7ed5f4dd New translations strings.properties (Turkish)
[ci skip]
2021-02-15 14:09:08 +01:00
Sebastian Stenzel 6a7a309a2b New translations strings.properties (Chinese Simplified)
[ci skip]
2021-02-15 14:09:07 +01:00
Sebastian Stenzel 0382069995 New translations strings.properties (Chinese Traditional)
[ci skip]
2021-02-15 14:09:05 +01:00
Sebastian Stenzel 7c5f40d7d1 New translations strings.properties (Portuguese, Brazilian)
[ci skip]
2021-02-15 14:09:04 +01:00
Sebastian Stenzel 09e9530660 New translations strings.properties (Russian)
[ci skip]
2021-02-15 14:08:57 +01:00
Sebastian Stenzel 947d25b335 New translations strings.properties (Punjabi)
[ci skip]
2021-02-15 14:08:56 +01:00
Sebastian Stenzel 80cbc6699a fixed label
[ci skip]
2021-02-15 13:53:05 +01:00
Sebastian Stenzel da0933fa92 New translations strings.properties (Punjabi)
[ci skip]
2021-02-08 04:36:28 +01:00
Sebastian Stenzel 9ad217ca55 Merge branch 'develop' into feature/vault-format-8
[ci skip]
2021-02-04 12:38:01 +01:00
Sebastian Stenzel adc9f32fb3 Merge branch 'master' into develop 2021-02-04 12:31:18 +01:00
Sebastian Stenzel 65369bdbff Merge branch 'release/1.5.12' 2021-02-04 12:27:42 +01:00
Sebastian Stenzel d18e618ef1 preparing 1.5.12 2021-02-04 12:27:02 +01:00
Armin Schrenk 970216dd59 Merge tag '1.5.12' into develop
1.5.12
2021-02-04 10:49:52 +01:00
Armin Schrenk 6840a649c7 Merge branch 'release/1.5.12' 2021-02-04 10:49:08 +01:00
Sebastian Stenzel 1a0bc92bde Merge branch 'develop' into feature/vault-format-8 2021-02-01 12:08:23 +01:00
Sebastian Stenzel e4709ed6fe Refactored FxmlFile and FxmlLoaderFactory 2021-02-01 12:06:38 +01:00
Sebastian Stenzel 21038212c1 remove unused property
[ci skip]
2021-02-01 11:54:21 +01:00
Sebastian Stenzel b15471b4ff add new (optional) "choose masterkey file" step to unlock dialog 2021-01-29 17:44:45 +01:00
Armin Schrenk 19ebc7e562 preparing 1.5.12 2021-01-27 15:30:56 +01:00
Armin SchrenkandGitHub 0fa052d2d1 Merge pull request #1518 from cryptomator/fix/1515-suppressed-messages
Fixed suppressed "invalid mountpoint" messages
2021-01-27 15:22:47 +01:00
Armin Schrenk 402861b9c0 Update third party licenses 2021-01-27 12:37:50 +01:00
Armin Schrenk aca1666dea closes #1479 2021-01-27 12:36:22 +01:00
Sebastian Stenzel ff17b60f56 Refactored UnlockWorkflow using new vault format 8 APIs 2021-01-27 12:09:09 +01:00
Sebastian Stenzel 3284578445 Merge branch 'develop' into feature/vault-format-8
# Conflicts:
#	main/commons/src/main/java/org/cryptomator/common/vaults/Vault.java
2021-01-25 21:42:13 +01:00
Sebastian Stenzel 70f6a4877c Make sure not to catch Errors 2021-01-25 21:38:46 +01:00
Sebastian Stenzel 85c5dc8dfb removed tmp workaround 2021-01-25 21:32:33 +01:00
Sebastian Stenzel 4b670a59a3 adjusted to new cryptolib/cryptofs API 2021-01-25 21:31:16 +01:00
JaniruTEC 23c113948f Replaced catch with wildcard catch and added additional logger call
See #1509 for further information and reasoning
2021-01-25 16:21:35 +01:00
JaniruTEC d86ea20c31 Fixed suppressed "invalid mountpoint" messages
Fixed #1515
2021-01-23 22:13:07 +01:00
Sebastian Stenzel 3f928cf958 Merge branch 'develop' into feature/vault-format-8
[ci skip]
2021-01-22 22:47:54 +01:00
Sebastian Stenzel 01929c2288 New translations strings.properties (Hungarian)
[ci skip]
2021-01-22 13:48:57 +01:00
Sebastian Stenzel 2634433b2c New translations strings.properties (Hungarian)
[ci skip]
2021-01-22 13:19:41 +01:00
Armin SchrenkandGitHub c1f44f76b9 Merge pull request #1512 from cryptomator/feature/refactor-reveal 2021-01-22 11:42:20 +01:00
Sebastian Stenzel b2f27c0a3d removed dead code
[ci skip]
2021-01-22 09:34:18 +01:00
Sebastian Stenzel b1d7cfc81b change scope of HostServiceRevealer to @FxApplicationScoped
because unlock always happens after application start anyway
2021-01-22 09:31:43 +01:00
Armin Schrenk 7cd5c66836 Refactor reveal() methods:
* new class HostServiceRevealer implemeting the Volume.Revealer-Interface
* this class is injected in vault service and always used for revealing
* removed Revealer parameter from several reveal methods
2021-01-21 17:25:23 +01:00
Armin Schrenk 95cef34234 remove unnecessary awtReavealer and trayModule 2021-01-21 16:09:16 +01:00
Armin Schrenk 8977440697 Rename RevealerFacade to Revealer 2021-01-21 15:29:04 +01:00
Armin Schrenk d5eb84a000 change reveal method in vault service:
* revealer is no member anymore
* reveal() takes as second argument revealer object
* several other classes hand over a revealer object
* added awt-revealer if application is not yet started
2021-01-21 15:26:35 +01:00
Sebastian Stenzel 81fb6b8794 get rid of RevealException 2021-01-21 15:06:37 +01:00
Armin Schrenk 92b390d5bb update third-party licenses 2021-01-21 12:44:32 +01:00
Armin Schrenk 8867532210 add javadoc 2021-01-21 12:44:11 +01:00
Armin Schrenk 77db435b4f Refactor reveal call stack to apply facade pattern. 2021-01-21 12:41:52 +01:00
Sebastian Stenzel cb2bc17283 New translations strings.properties (Hungarian)
[ci skip]
2021-01-21 11:06:22 +01:00
Tobias HagemannandGitHub aaa93239d0 Merge pull request #1516 from stacksnack/feature/translations
New translations strings.properties (Hungarian)
2021-01-21 11:03:27 +01:00
Sebastian Stenzel 93445e22d4 update library versions 2021-01-21 06:37:41 +01:00
stacksnackandGitHub 64897cfa21 New translations strings.properties (Hungarian)
Add hungarian translation
2021-01-20 21:37:41 +01:00
Armin Schrenk 7349a29831 Ensure that on windows systems always the gui chooses the mountpoint for webdav 2021-01-19 15:52:52 +01:00
Armin Schrenk 73554b4759 split WebDAV Volume mount method into servlet start and servlet mount 2021-01-19 15:52:20 +01:00
Armin Schrenk 0312f045aa add a logger to WebDAV-Volume 2021-01-19 15:28:50 +01:00
Armin Schrenk 1134c1b2ff closes #1471
hand the javafx hostservice showDocument() method from ui package to the underlying nio-adapter-libraries through
2021-01-19 15:27:46 +01:00
Sebastian Stenzel efebbc059a keep CTR+HMAC for now (until GCM is supported on all platforms) 2021-01-19 15:09:47 +01:00
Sebastian Stenzel 6e860d293a Merge branch 'develop' into feature/vault-format-8
[ci skip]
2021-01-19 15:05:15 +01:00
Armin Schrenk 8bb925fd93 fixes #1509 2021-01-18 18:41:21 +01:00
Sebastian Stenzel ca5d9eba36 New translations strings.properties (Norwegian Bokmal)
[ci skip]
2021-01-16 04:07:35 +01:00
Sebastian Stenzel 1a49e24d8a New translations strings.properties (Norwegian Bokmal)
[ci skip]
2021-01-16 03:37:26 +01:00
Sebastian Stenzel 24b0ed2502 New translations strings.properties (German)
[ci skip]
2021-01-14 18:18:01 +01:00
Sebastian Stenzel a226d5403a New translations strings.properties (Japanese)
[ci skip]
2021-01-14 14:02:17 +01:00
Sebastian Stenzel 0f3085cc73 fixes #1476 2021-01-14 09:56:57 +01:00
Sebastian Stenzel f0a040cf29 cleanup
[ci skip]
2021-01-14 09:56:36 +01:00
Sebastian StenzelandGitHub 0676748dde New Crowdin updates (#1466)
[ci skip]
2021-01-14 09:24:42 +01:00
Armin Schrenk 589b8384eb Only determine filenamelength limit if the the vault is mounted not read-only. 2021-01-11 14:15:37 +01:00
Julian RaufelderandGitHub 9e3947f337 Happy 2021 🎉 2021-01-11 10:08:35 +01:00
Tobias Hagemann 790cc4e772 simplified issue template
[ci skip]
2021-01-06 12:01:07 +01:00
Tobias Hagemann 72f4988632 fixes #1452 2021-01-05 14:14:14 +01:00
Sebastian StenzelandGitHub b3fa6bbf32 Merge pull request #1472 from cryptomator/feature/minimize
Add Minimize Button
2020-12-18 15:58:02 +01:00
Sebastian Stenzel c2dc487c79 make field volatile that might be modified concurrently 2020-12-18 13:37:23 +01:00
Sebastian Stenzel e74dd3be9e remove unused param 2020-12-18 13:36:16 +01:00
Sebastian Stenzel 1eeee61572 Add option to show minimize button despite tray icon being present
fixes #1179
2020-12-17 14:50:33 +01:00
Sebastian Stenzel 984b7a2d0e Removed @Named("trayMenuSupported") from FxApplication component 2020-12-17 14:46:52 +01:00
Sebastian Stenzel 45c714a123 Added checkbox in settings to start without a tray icon
references #1113, #1078, #1079, #1344
2020-12-16 16:53:49 +01:00
Sebastian Stenzel 96bb97d50a Added new setting showTrayIcon defaulting to new environment property cryptomator.showTrayIcon 2020-12-16 13:48:33 +01:00
Sebastian Stenzel 046acb9bbf mark fuse.experimental deprecated
[ci skip]
2020-12-16 13:33:50 +01:00
Armin SchrenkandGitHub ce4ec16c62 Update bug.md
Add info to also specify desktop environment on Linux systems in section system setup
2020-12-16 12:16:32 +01:00
Tobias HagemannandGitHub 96c8c9a9a9 Update bug.md 2020-12-16 09:07:39 +01:00
Tobias HagemannandGitHub 44db97327d Update feature.md 2020-12-16 09:06:11 +01:00
Sebastian Stenzel f441700c25 Merge branch 'master' into develop 2020-12-15 13:23:21 +01:00
Sebastian Stenzel 76b023bdbd Merge branch 'release/1.5.11' 2020-12-15 12:42:13 +01:00
Sebastian Stenzel 241d9781bb bump integrations-win version 2020-12-15 12:41:39 +01:00
Sebastian Stenzel ff94532560 Merge branch 'release/1.5.11' 2020-12-15 10:53:40 +01:00
Tobias Hagemann e949023321 updated third-party list [ci skip] 2020-12-15 10:37:27 +01:00
Sebastian Stenzel da31407d63 Preparing 1.5.11 2020-12-15 08:57:35 +01:00
Sebastian Stenzel 8c7c5da89a not sure what makes this "real" [ci skip] 2020-12-15 08:04:16 +01:00
Sebastian StenzelandGitHub e3a0e1ec5a New Crowdin updates (#1413)
[ci skip]
2020-12-14 17:38:49 +01:00
Sebastian Stenzel 4cee27d8dd bump webdav dependencies 2020-12-14 17:30:29 +01:00
Armin Schrenk b0fce66d77 Add OWASP Dependency-Check Maven Plugin
* only active if profile dependency check is active
* added suppresion.xml for false positives
* added tmp fix for jwt lib
2020-12-14 17:02:35 +01:00
Armin SchrenkandGitHub bf47ba0145 Merge pull request #1440 from cryptomator/feature/#1439-finish-migration
closes #1439
2020-12-14 15:41:52 +01:00
Armin Schrenk fc7b484c9a unwrap the Platform.runLater() statement because it is always executed on JavaFX thread 2020-12-14 15:34:03 +01:00
Armin Schrenk 4402c19d90 Simplifications and clean up 2020-12-14 11:47:02 +01:00
Armin Schrenk 4e89de9e47 activate force locking for dokany 2020-12-14 10:23:27 +01:00
Armin Schrenk a27c9d63d9 Bump dokany-nio-adapter version 2020-12-14 10:09:13 +01:00
Armin Schrenk da6aa0f002 bump integrations-win version 2020-12-11 16:23:57 +01:00
Armin Schrenk 0bf3533f45 Workaround for #1421 2020-12-11 13:25:02 +01:00
Sebastian Stenzel 295cb0ef6d fixes #1446, fixes #1415 2020-12-09 17:17:51 +01:00
Armin SchrenkandGitHub 6fac84e9c2 Replace "may" by "can"
... the end of a great and fierce war.
2020-12-09 15:39:49 +01:00
Sebastian Stenzel 77b2e67c49 updated labels 2020-12-09 15:16:45 +01:00
Armin SchrenkandGitHub c48c9b1568 Merge pull request #1416 from cryptomator/feature/#1228-forcedUnmountDialog
Feature/#1228 forced unmount dialog
2020-12-09 15:04:30 +01:00
Armin Schrenk 6da7eae2f8 Minor changes in lettering 2020-12-09 14:55:22 +01:00
Armin Schrenk aec56c48c5 Merge branch 'develop' into feature/#1228-forcedUnmountDialog
# Conflicts:
#	main/ui/src/main/java/org/cryptomator/ui/fxapp/FxApplication.java
2020-12-09 14:51:00 +01:00
Sebastian Stenzel c0a9a95e4f Adjusted to CryptoFS 2.0.0 2020-12-08 14:39:46 +01:00
Sebastian Stenzel 3b73544766 Simplified observation of visible stages 2020-12-08 12:56:44 +01:00
Sebastian Stenzel fbc471635a fixed test 2020-12-08 12:51:34 +01:00
Sebastian Stenzel 3c5b9ed3a6 remove rarely used, complex class 2020-12-08 12:51:11 +01:00
Sebastian Stenzel 8479122561 temp fix for vulnerability in upstream lib
[ci skip]
2020-12-08 08:30:16 +01:00
Tobias HagemannandGitHub 91c883d5cc Create config.yml 2020-12-07 18:11:25 +01:00
Sebastian StenzelandGitHub 1cd4da0796 Merge branch 'develop' into feature/#1228-forcedUnmountDialog 2020-12-07 17:55:29 +01:00
Armin SchrenkandGitHub 935aaccdae Update bug template
* Make introduction section more visible
* emphasize task to complete for successful bug ticket
2020-12-02 15:05:59 +01:00
Tobias Hagemann ab3dd779d2 partially reverted 900fdd7f, fixing "stutter" startup on macos 2020-12-02 14:59:17 +01:00
Armin Schrenk 1fbcf6d517 closes #1439 2020-11-27 15:53:33 +01:00
Armin SchrenkandGitHub 82538091c9 Merge pull request #1427 from cryptomator/feature/#1323-singleQuitWindow
Show only one quit dialogue at a time
2020-11-24 15:31:31 +01:00
Sebastian Stenzel 62ade6113b cleanup
[ci skip]
2020-11-24 15:07:23 +01:00
Sebastian Stenzel 4779bbf415 Don't bother FxApplication with stuff that is meant to be dealt with internally within QuitComponent 2020-11-24 15:04:09 +01:00
Armin Schrenk c6b786a771 Reworked implemenation by using dagger now:
* create and inject QuitResponse container
* QuitComponent manges now if quit window needs to be created
* controller only handles the most recent QuitResponse
2020-11-24 13:34:12 +01:00
Armin Schrenk 6381227897 Stylin:
* change css styleclass of dialogue headings to `label-large`
* remove newly introduced style class `label-medium`
2020-11-23 16:14:31 +01:00
Armin Schrenk e82167b5e6 correct wrong method name 2020-11-20 17:29:56 +01:00
Armin Schrenk dc4fd482b5 Filter any whitespaces when entering text in donationkey form. 2020-11-20 17:17:16 +01:00
Armin Schrenk a71f8b350e Show only one quit dialogue at a time 2020-11-20 16:12:49 +01:00
Armin Schrenk c9ec8fecef fix wrong method name 2020-11-20 16:09:31 +01:00
e72d32f2d1 Remove empty line
Co-authored-by: Sebastian Stenzel <overheadhunter@users.noreply.github.com>
2020-11-20 14:34:34 +01:00
2545aa2a7e Removed default clause from switch expression on enums
Co-authored-by: Sebastian Stenzel <overheadhunter@users.noreply.github.com>
2020-11-20 14:33:57 +01:00
Armin Schrenk 51aac15622 Changed forced lock description and clean up 2020-11-20 12:23:44 +01:00
Armin Schrenk afa0cfeafb Replace lock failed dialogue stub and integrate it into workflow 2020-11-20 12:23:18 +01:00
Armin Schrenk 19e24ba12c refactor structure of LockWorkflow class 2020-11-20 12:22:26 +01:00
Armin Schrenk c47ce2c730 clean up 2020-11-20 11:25:39 +01:00
Armin Schrenk 5d00b3dd76 activate ability to abort vault locking if it is mounted with dokany and still busy
references #1228
2020-11-19 17:20:08 +01:00
Armin Schrenk 4db57cc0dc Further improvements:
* adding Log messages
* change lock workflow to type of Task<Void>
* set vault state based solely on task state
* replaced dialogue stubs with real text
2020-11-19 16:31:16 +01:00
Armin Schrenk 432a9a27f1 Add forceLock Dialogue:
* integrate it in workflow if normal lock throws exception
* add stubs if also forced lock fails
2020-11-19 12:52:16 +01:00
Armin Schrenk 57bfa3276d Integrate new lockWorkflow into application (gui and tray) 2020-11-19 11:42:00 +01:00
Sebastian Stenzel 02fc9b263a re-added applicable choosers to exception text 2020-11-18 18:12:41 +01:00
Sebastian Stenzel 4c66f81736 simplified line 2020-11-18 18:09:30 +01:00
Sebastian Stenzel 2de151aebe use less generic name 2020-11-18 18:08:00 +01:00
Armin Schrenk c44911dcac Prepare strucutre and classes for lock workflow 2020-11-18 17:16:58 +01:00
Armin Schrenk bcf2a3d20c Setting default onFailed handler in lock tasks 2020-11-18 17:16:43 +01:00
JaniruTEC 422ce4a387 Moved actual choosing of MPCs to MountPointHelper 2020-11-18 16:27:43 +01:00
JaniruTEC 21387bd76c Renamed IrregularUnmountCleaner to MountPointHelper 2020-11-18 16:18:31 +01:00
JaniruTEC 52cd560cb2 Generifyed #chooseMountPoint() 2020-11-18 16:09:09 +01:00
JaniruTEC 6c440dfbbb Re-Added check for non-emtpy dirs 2020-11-18 15:53:33 +01:00
Sebastian Stenzel a074450452 Merge branch 'master' into develop 2020-11-18 15:03:37 +01:00
Sebastian Stenzel b781cf6f25 Merge branch 'hotfix/1.5.10' 2020-11-18 15:03:11 +01:00
Sebastian Stenzel 9b653f488b Merge branch 'develop' into hotfix/1.5.10 2020-11-18 15:02:33 +01:00
Armin Schrenk 17c580267f prevent race conditions 2020-11-18 14:35:16 +01:00
Sebastian Stenzel 490d1b8f87 cancel unlock workflow, if closing window with shortcut 2020-11-18 14:21:18 +01:00
Armin Schrenk b0ad86f16b Perform cleanup of tmp mount points dir only once. 2020-11-18 14:07:34 +01:00
Sebastian Stenzel df2b4ac086 cleanup 2020-11-18 13:17:35 +01:00
Sebastian Stenzel aee4ececba Merge branch 'fix/1409' into hotfix/1.5.10
fixes #1409
2020-11-18 13:16:36 +01:00
Sebastian Stenzel b2992aa6ae Merge branch 'fix/1408' into hotfix/1.5.10
fixes #1408

# Conflicts:
#	main/buildkit/pom.xml
#	main/commons/pom.xml
#	main/launcher/pom.xml
#	main/pom.xml
#	main/ui/pom.xml
2020-11-18 13:16:19 +01:00
Sebastian Stenzel 4c546d281a Bumped version 2020-11-18 13:15:33 +01:00
Sebastian Stenzel c90e445a67 Removed -Dcryptomator.mountPointsDir="/Volumes/" from macOS run profiles
[ci skip]
2020-11-18 13:10:01 +01:00
Sebastian Stenzel d3c2b0509e Lazily call IrregularUnmountCleaner from (and only from!) TemporaryMountPointChooser 2020-11-18 13:08:48 +01:00
Sebastian Stenzel c6d1c2ca6b added MacVolumeMountChooser and refactored "priority" of mount point choosers: now all priorities are set in MountPointChooserModule (as a map key) 2020-11-18 13:07:12 +01:00
Sebastian Stenzel 86dec80726 avoid weird iteration counter manipulation 2020-11-18 10:33:04 +01:00
JaniruTEC 9083976989 Fixed #1409 by addig an additonal check 2020-11-18 00:46:24 +01:00
JaniruTEC d9c5d76417 Fixed irregular quoting 2020-11-17 22:41:41 +01:00
JaniruTEC c19c3754c6 Fixed high-spirited concatenation 2020-11-17 22:27:41 +01:00
JaniruTEC 947e0e2369 Fixed #1408 2020-11-17 22:00:41 +01:00
JaniruTEC 6eca8f2e0c Added support for quote escaped values for mount arguments 2020-11-17 21:56:43 +01:00
Sebastian Stenzel 9f61ad1941 Merge branch 'master' into develop
[ci skip]
2020-11-17 17:03:40 +01:00
Sebastian Stenzel 41492a951a Merge branch 'release/1.5.9' 2020-11-17 17:02:14 +01:00
Sebastian Stenzel cbbfec5531 Merge branch 'develop' into release/1.5.9 2020-11-16 17:16:54 +01:00
Sebastian StenzelandGitHub d7a4dff080 New Crowdin updates (#1401)
New translations strings.properties
[ci skip]
2020-11-16 17:15:37 +01:00
Armin SchrenkandGitHub 8e56218fbb Update launcher-linux.sh
drastically reducing the allowed stacksize to 2m
2020-11-11 17:13:11 +01:00
Sebastian Stenzel 9c40386106 fix CI release build 2020-11-10 12:54:01 +01:00
Sebastian Stenzel c865805f55 Preparing 1.5.9 2020-11-10 12:41:10 +01:00
Sebastian StenzelandGitHub 8e352301cd New Crowdin updates (#1392)
[ci skip]
2020-11-10 12:39:15 +01:00
Armin SchrenkandGitHub 52db1e8bdd Merge pull request #1396 from cryptomator/feature/#1013-#1061-cleanupAndInformation 2020-11-10 12:33:23 +01:00
Armin Schrenk 1947623be8 final cleanup:
* renamed methods
* apply code style
2020-11-10 12:24:49 +01:00
Armin Schrenk 4f8602684d Merge branch 'develop' into feature/#1013-#1061-cleanupAndInformation 2020-11-10 12:08:23 +01:00
Armin Schrenk 75f66e40bf Add additional mountName crunching to be urlconform when WebDAV is used 2020-11-10 12:05:30 +01:00
Sebastian Stenzel 73587437cb fixes #1400 2020-11-10 08:27:47 +01:00
Sebastian Stenzel 18f6e70bba Merge branch 'develop' of https://github.com/cryptomator/cryptomator into develop
# Conflicts:
#	main/ui/src/main/resources/i18n/strings.properties
2020-11-09 17:53:18 +01:00
Sebastian Stenzel e067b94aca fixed labels 2020-11-09 17:52:48 +01:00
Armin Schrenk b04d5669fb Format lables the same way 2020-11-09 17:40:57 +01:00
Armin SchrenkandGitHub ad44af338d Merge pull request #1399 from cryptomator/feature/io-stats
closes #1070
2020-11-09 17:20:10 +01:00
Sebastian Stenzel 4f4ddbc3e0 allow GCing of Stats Window while remaining reusability and preventing opening multiple windows per vault 2020-11-09 13:49:28 +01:00
Sebastian Stenzel 4e9af1c713 cleanup 2020-11-09 13:12:42 +01:00
Sebastian Stenzel 9a94b6f95e fixed typo 2020-11-09 13:10:35 +01:00
Sebastian Stenzel 371b826aa0 Merge branch 'develop' into feature/io-stats 2020-11-09 13:05:44 +01:00
Sebastian Stenzel d3fb90bf6d fixed NPE if winDriveLetter is null (on Linux/Mac) 2020-11-09 13:05:06 +01:00
Sebastian Stenzel d24c478faa more dependency updates 2020-11-09 12:01:38 +01:00
Sebastian Stenzel 48d0aa423c fixed getter name 2020-11-09 11:54:15 +01:00
Sebastian StenzelandGitHub 5695fa2916 Merge branch 'develop' into feature/io-stats 2020-11-09 11:48:17 +01:00
Armin Schrenk bcea1a4b32 Bumping dependencies:
* javafx to 15
* webdav-nio-server to 1.0.13
2020-11-09 11:17:52 +01:00
Armin Schrenk 2f8d4568fc Updating CryptoFS Dependency.
Closes #1293
2020-11-09 10:33:27 +01:00
Armin Schrenk 5b55318e52 Bumping integrations-linux dependency, removing unused legacy property
closes #1308
2020-11-09 10:28:07 +01:00
Armin Schrenk 459f2ea2c3 Updating Dokany-nio-adapter dependency
References #1228
2020-11-09 10:27:52 +01:00
Martin Beyer d26147a34a bumped up depencency of cryptofs to 1.9.13 2020-11-08 20:51:47 +01:00
JaniruTEC afb9d4f010 Fixed exception on startup if mount folder doesn't exist
IrregularUnmountCleaner should not be called if there is no folder that could contain mountpoints.
2020-11-06 18:44:47 +01:00
JaniruTEC db3bf9723e Merge branch 'feature/additional-error-messages' into develop 2020-11-06 17:34:23 +01:00
JaniruTEC 3a5937b35f Added runLater to implementation of ErrorComponent#showErrorScene() 2020-11-06 17:09:44 +01:00
Sebastian StenzelandGitHub f5cddda7a8 Merge branch 'develop' into feature/#1013-#1061-cleanupAndInformation 2020-11-06 15:17:45 +01:00
Sebastian Stenzel e9fa1d6476 removed old jni dependency 2020-11-06 14:53:45 +01:00
Sebastian Stenzel 084c1881ba removed unused imports
[ci skip]
2020-11-06 14:47:47 +01:00
Sebastian Stenzel ce131e4653 Implemented AutoStart integration for macOS 2020-11-06 14:46:32 +01:00
Tobias Hagemann a121c7d0fe added tooltip to path in vault list cell 2020-11-06 14:42:21 +01:00
Sebastian Stenzel 603bf99b25 Replaced MacFunctionsUiState using new integrations api 2020-11-06 14:18:23 +01:00
Sebastian Stenzel 9076fe5b46 Reintroduced trimming of vault display name 2020-11-06 11:07:45 +01:00
Sebastian Stenzel 6848f1a38e Renamed IrregularUnmountCleaner and relayouted code 2020-11-06 11:07:22 +01:00
Sebastian Stenzel f4103fc917 reducing complexity of normalizedDisplayName 2020-11-06 09:54:25 +01:00
Sebastian Stenzel c838da9df4 reducing complexity for "vault name max length" 2020-11-06 09:52:31 +01:00
Sebastian Stenzel 78df4e24b3 keep iconography consistent by reusing already existing icons 2020-11-06 09:51:51 +01:00
Sebastian Stenzel c0e2d01297 Migrated from deprecated MacFunctions to UiAppearanceProvider for UI theme switching 2020-11-05 17:49:39 +01:00
JaniruTEC 313f8b36d2 Replaced dependency with call to getter 2020-11-05 17:11:35 +01:00
JaniruTEC 343794c1fe Redo "Added UI error messages"
This reverts commit d331c302
2020-11-05 17:04:31 +01:00
Armin Schrenk 813c01aaed Use mountName instead of display name 2020-11-05 13:23:30 +01:00
Armin Schrenk 510ea8a6f6 refined normalize Method, fxied Tests for it:
* all unicode spaces are now replaced with \u0020
* if the end string only contains whitspaces, "_" will be returned
2020-11-05 12:44:51 +01:00
Armin Schrenk a22fbea467 The display/vault name is now constrained:
* should not be empty
* is stripped of leading & trailing whitespaces
* is truncated to 50 characters
2020-11-05 11:55:25 +01:00
Armin Schrenk f64144d1da Revert 1554437884 2020-11-05 11:52:38 +01:00
Armin Schrenk c01dd225c9 Refactor normalizedMountname to only exclude certain, filesystem reserved characters or Unicode control sequences 2020-11-05 11:47:18 +01:00
Sebastian Stenzel 18b408a83a Adjusted keychain display names
[ci skip]
2020-11-05 11:15:39 +01:00
Sebastian StenzelandGitHub efaf107b20 Merge pull request #1393 from cryptomator/feature/modular-keychains
Modularized Keychain Access, references #1301
2020-11-05 11:10:15 +01:00
Sebastian Stenzel 86cba5e8a7 partial revert of 6ccd2486 2020-11-04 16:11:16 +01:00
Sebastian Stenzel f4cee6d161 made KeychainManager immutable
[ci skip]
2020-11-04 14:15:28 +01:00
Sebastian Stenzel 28c40b2277 WHY? 2020-11-04 14:13:53 +01:00
Armin Schrenk 8853054ed4 fixing test 2020-11-03 14:53:51 +01:00
Armin Schrenk 3eb44b06af Fixes #1061:
* temp mount point is first tried without any addition
* then with id Suffix in brackets
* then with underscores, id suffix and count
2020-11-03 12:50:52 +01:00
Armin Schrenk 1554437884 Use regular display name and only normalize if webdav is used:
* rename StringBinding mountName to normalizedDisplayName
* replace in all other occurences mountName with DisplayName
2020-11-03 12:44:09 +01:00
Armin Schrenk 268bae8879 Change Invalid mount point error window:
* Add heading
* change icon to times_with_circle
* reformat text
2020-11-03 12:13:22 +01:00
Sebastian Stenzel b382e436e2 minor CI fixes 2020-11-03 11:27:10 +01:00
Sebastian Stenzel 6ccd248675 use maven profiles to build different buildkits 2020-11-03 11:21:08 +01:00
Armin Schrenk c760e63995 only use supported keychainAccessProviders 2020-11-03 10:54:32 +01:00
Armin Schrenk 959dee153e fixing bug where stored password is not used 2020-11-03 10:03:14 +01:00
Armin Schrenk aa22f656e8 Moving the code for unregular unmount leftovers from mountpoint chooser to an own class and execute it at each application start. 2020-11-02 17:34:34 +01:00
Armin Schrenk d24734e16f Revert "Adding method to clean up _our_ tmp mounting dirs to mitigate #1061 and #1013"
This reverts commit 01522e8c97.
2020-11-02 17:25:43 +01:00
Armin Schrenk 01522e8c97 Adding method to clean up _our_ tmp mounting dirs to mitigate #1061 and #1013 2020-11-02 14:49:57 +01:00
Sebastian Stenzel 14e056551d no longer track coverage for deleted keychain module 2020-11-02 14:07:21 +01:00
Sebastian Stenzel 82a42ea183 Removed keychain module. Implemented new KeychainManager in various UI controller classes 2020-11-02 14:03:39 +01:00
Sebastian Stenzel bfde26be79 Added new keychain module and refactored UI parts 2020-11-02 13:09:30 +01:00
Sebastian Stenzel 51e43a0567 include system integration lib automatically depending on current OS 2020-11-02 13:08:50 +01:00
Sebastian Stenzel 9a375cb3f6 updated label
[ci skip]
2020-11-02 09:43:54 +01:00
Sebastian Stenzel 2b8f39a149 ignored some derived files 2020-11-02 09:41:07 +01:00
2720a999d1 Updated codestyle (#1388)
Co-authored-by: Sebastian Stenzel <overheadhunter@users.noreply.github.com>
2020-11-02 08:45:41 +01:00
Ralph PlawetzkiandGitHub f675bd5017 Feature/change password backend 2 (#1375)
* Add option to choose from available password backends on Linux
Implements #1301
2020-11-02 08:19:26 +01:00
JaniruTECandGitHub 16be3e7a97 Merge pull request #1384 from cryptomator/fix/missing-exceptions
Fix/missing exceptions
2020-10-29 16:58:51 +01:00
JaniruTEC 551d9d1af1 Added default Errorhandler to all Tasks and Services 2020-10-28 16:21:14 +01:00
JaniruTEC 0acc8ddb0a Fixed UnlockWorkflow
Partly reverted 253abd4930
2020-10-28 15:50:20 +01:00
JaniruTEC f0e1bcb899 Moved call to #setOnFailed() to UpdateStatsService implementation 2020-10-28 15:40:59 +01:00
JaniruTEC d331c30224 Revert "Added UI error messages"
This reverts commit eb8f5f523d.
2020-10-28 15:21:59 +01:00
JaniruTEC d0d39a1c72 Merge branch 'develop' into fix/missing-exceptions 2020-10-27 17:04:32 +01:00
JaniruTEC 8904df91b4 Reverted accidental changes to Project_Default.xml [Skip CI] 2020-10-27 16:18:55 +01:00
JaniruTEC 786365c095 Added ability to skip CI
Added check for "Skip CI", added comment
Added filter for skipping CI
2020-10-27 16:12:35 +01:00
JaniruTEC eb8f5f523d Added UI error messages
Added UI error message to GeneralPreferencesController for ToggleAutoStartTask
Added UI error message to RecoveryKeyCreationController
2020-10-26 21:19:24 +01:00
JaniruTEC 9c22adc97d Added/Fixed error logging
Added error logging to VaultStats and GeneralPreferencesController
Fixed possible missing error logging in VaultService
2020-10-26 21:17:22 +01:00
Sebastian StenzelandGitHub 265212cc0f New Crowdin updates (#1302)
* New translations strings.properties [ci skip]
2020-10-26 10:00:58 +01:00
Sebastian StenzelandGitHub 9c860cc17c Merge pull request #1380 from cryptomator/snyk-fix-bc2c8d6dd6d679e9ec6736de3d13592d
[Snyk] Security upgrade com.google.guava:guava from 29.0-jre to 30.0-jre
2020-10-24 09:55:05 +02:00
Sebastian StenzelandGitHub 7f63153bc1 Update main/pom.xml 2020-10-24 09:47:09 +02:00
snyk-bot 9531d44ab5 fix: main/pom.xml to reduce vulnerabilities
The following vulnerabilities are fixed with an upgrade:
- https://snyk.io/vuln/SNYK-JAVA-COMGOOGLEGUAVA-1015415
2020-10-24 01:50:58 +00:00
JaniruTEC 253abd4930 Refactored UnlockWorkflow
Replaced protected state methods (scheduled, etc.) with lambdas in the constructor
Replaced try-multi-catch with if-instanceof in onFailed-lambda
2020-10-22 18:58:46 +02:00
JaniruTEC 022ba81f2f Reformatted classes ErrorComponent and Tasks 2020-10-22 18:33:20 +02:00
Armin SchrenkandGitHub 26160e9bbc Merge pull request #1346 from purejava/fix-isSupported
Evade DBusException
2020-10-21 10:56:16 +02:00
JaniruTEC 0a32de2c92 Addded dev run configs, removed fuse-setting from win prod config 2020-10-16 22:38:39 +02:00
JaniruTECandGitHub 60aeb6a04b Merge pull request #1307 from cryptomator/feature/fuse-on-win
Added (experimental) support for using FUSE on Windows (using WinFSP)
2020-10-14 15:29:37 +02:00
JaniruTEC 0206fc0b8f Bumped required version of fuse-nio-adapter to 1.2.5 2020-10-14 15:26:28 +02:00
JaniruTEC 06b3343a6d Partly Revert "Finished feature: Fuse on Win"
Revert changes to TemporaryMountPointChooser introduced by 598bec3050
2020-10-13 18:30:00 +02:00
JaniruTEC 598bec3050 Finished feature: Fuse on Win
Bumped required version of fuse-nio-adapter to 1.2.4
Added comments
Changed log messages to be more descriptive
2020-10-12 21:34:56 +02:00
Reid RankinandGitHub 0e5d72c22a shorten FS_TYPE_NAME to "CryptomatorFS" (#1371)
This fixes part of #1033 by shortening the FS_TYPE_NAME so that it can be returned inside a 48-byte-long FILE_FS_ATTRIBUTE_INFORMATION buffer, which only has room for up to 17 UTF-16 characters in the file system name field.
2020-10-12 14:12:09 +02:00
JaniruTEC 21f4fab9ed Fixed bug: Strange error message if no MPC was applicable 2020-10-09 18:40:50 +02:00
JaniruTEC 58e2ec4742 Changed contract of priorities in MPC, added null-check
See: ab538cd215 (original commit)
See: 6b6867b826 (reverting commit)
2020-10-08 19:14:03 +02:00
JaniruTEC 6b6867b826 Reverted ab538cd215 2020-10-08 18:51:03 +02:00
Ralph Plawetzki 92321a7569 Remove unneeded access modifier 2020-10-08 12:57:50 +02:00
JaniruTEC 7781572b6d Replaced call to Validate with call to Preconditions
See: https://github.com/cryptomator/cryptomator/pull/1307#discussion_r500760560
2020-10-07 23:27:08 +02:00
JaniruTEC b5efe39eb8 Refactored Vault, MPCs, Unlock to integrate better with latest changes
Removed delegate to Volume#getMountPointRequirement() from Vault
Added getter for the Vault's Volume (#getVolume())

Changed CustomMountPointChooser to use VaultSettings instead of Vault for the constructor/field declaration
Updated CustomMountPointChooser#isApplicable() to be disabled when using FUSE on Windows (without useExperimentalFuse)
Updated CustomMountPointChooser to call Volume#getMountPointRequirement() directly

Replaced OS-Check in TemporaryMountPointChooser with MPR-Check

Replaced call to Vault#getMountPointRequirement() with call to Vault#getVolume() (and Volume#getMountPointRequirement()) in UnlockInvalidMountPointController and UnlockWorkflow
Cleaned up UnlockWorkflow
2020-10-07 23:19:24 +02:00
Ralph Plawetzki cae86cd71f Get more information logged in case something goes wrong 2020-10-07 18:55:18 +02:00
Ralph Plawetzki 667617b480 Update kdewallet to latest 1.1.1 2020-10-07 18:32:16 +02:00
JaniruTEC 9329311491 Merge branch 'feature/volume-type-getter' into feature/fuse-on-win 2020-10-07 16:59:54 +02:00
JaniruTEC 22438d1eba Added api for getting the implemented VolumeImpl (type) of a Volume 2020-10-07 16:46:58 +02:00
JaniruTEC d295084312 Changed contracts in MPC interface
Added Volume parameter to the method signature of all MPC methods and updated implementations to use the change.

Changed contract of the MPC interface: Validation of the MPC (call to #isApplicable()) moved from the Module to the Volume.
Updated docs to reflect those changes. Fixed typos.
Updated method/qualifier names.
Updated implementation of #provideOrdered(Valid)MountPointChoosers() to reflect this change and to build the set differently.
Updated #determineMountPoint() to work with the new set.
2020-10-06 19:52:59 +02:00
JaniruTEC ab538cd215 Fixed bug: Dropped MPCs if priorities were equal
Fixed bug that caused MPCs with equal priorities to be dropped (even if they weren't equal).
Added additional criteria (hashCode) for cases were priorities are equal.

See the docs of ImmutableSortedSet for further information.
2020-10-06 19:40:03 +02:00
Armin Schrenk f9cb438a0b Closes #1065 for real by adding missing style in dark theme for debug mode 2020-10-01 18:37:32 +02:00
JaniruTEC 354de225ed Reverted changes to WebDavVolume#getMountPoint()
See: https://github.com/cryptomator/cryptomator/pull/1307#discussion_r472888268
2020-09-30 14:09:01 +02:00
Armin Schrenk 0b7f8d71ed closes #1065 2020-09-29 12:12:59 +02:00
JaniruTEC 9657a13912 Updated MPCModule to return a SortedSet and switched collector
See: https://github.com/cryptomator/cryptomator/pull/1307#discussion_r474452898
2020-09-28 23:34:47 +02:00
Ralph Plawetzki c5a3b29554 Make logger static 2020-09-16 18:56:54 +02:00
Ralph Plawetzki ae957c2588 Print error message instead of stacktrace
Fixes #1345
2020-09-16 06:55:37 +02:00
Tobias Hagemann da84133732 allows running launcher-mac.sh from any path 2020-09-15 16:23:31 +02:00
Tobias HagemannandGitHub 10275eb80f Merge pull request #1326 from TheShellLand/linux-libs
allows running launcher-linux.sh from any path
2020-09-15 09:28:04 +02:00
Sebastian Stenzel 29a9c7dffe auto-close bugs violating the issue template
[ci skip]
2020-09-13 11:50:26 +02:00
JaniruTEC d5b8996a39 Fixed violation of method contract
See: https://github.com/cryptomator/cryptomator/pull/1307#discussion_r472857043
2020-09-11 22:23:48 +02:00
JaniruTEC f012977aac Fixed spelling
See: https://github.com/cryptomator/cryptomator/pull/1307#discussion_r472825411
2020-09-11 21:47:30 +02:00
JaniruTEC 8680bd1dee Updated MountPointChooserModule and MPCs
Updated MountPointChooserModule and MPCs to use bindings (@'Binds) instead of providers (@'Provides)
Updated CustomDriveLetterChooser and TemporaryMountPointChooser  to use VaultSettings instead of Vaults

See: https://github.com/cryptomator/cryptomator/pull/1307#discussion_r472872166
2020-09-07 22:25:01 +02:00
JaniruTEC 528510eb53 Renamed binding fuseAndWindows to restrictToStableFuseOnWindows
Renamed binding fuseAndWindows to restrictToStableFuseOnWindows in MountOptionsController

See: https://github.com/cryptomator/cryptomator/pull/1307#discussion_r477135521
2020-09-07 22:24:59 +02:00
ainiml e8d17cfb7b allows running launcher-linux.sh from any path 2020-09-06 19:25:50 -04:00
JaniruTEC cdbcd20241 Fixed faulty access introduced by parallel release of 1.5.8 2020-09-05 22:15:02 +02:00
JaniruTEC fef3ade5c6 Merge branch 'develop' into feature/fuse-on-win
Fixed conflicts in WebDavVolume
2020-09-04 22:28:53 +02:00
Tobias Hagemann 194d7f0da9 Merge branch 'hotfix/1.5.8' into develop 2020-08-28 16:01:35 +02:00
Tobias Hagemann 8ad20c27da Merge branch 'hotfix/1.5.8' 2020-08-28 15:57:54 +02:00
Tobias Hagemann f891a9f1a7 refactored that fix from 2a335eb7af 2020-08-28 14:25:26 +02:00
Tobias Hagemann 2a335eb7af fixed test 2020-08-28 14:06:09 +02:00
Tobias Hagemann 6578ac0121 use mountName in FUSE on macOS instead of displayName 2020-08-28 13:55:17 +02:00
Tobias Hagemann 83f9514a42 fixed icon views of labels in new password screen that could only appear once
(cherry picked from commit 4723416d45)
2020-08-28 13:41:43 +02:00
Tobias Hagemann c92f1aa655 updated third-party licenses 2020-08-28 13:34:41 +02:00
Tobias Hagemann 688993ba37 preparing 1.5.8 2020-08-28 12:58:50 +02:00
Armin Schrenk ddfc8d5bc3 Merge branch 'feature/#1289-introduceVaultname' into hotfix/1.5.8 2020-08-28 11:59:56 +02:00
Armin Schrenk c3141e3601 minor adjustments 2020-08-28 11:58:46 +02:00
Armin Schrenk f49974180b Fixing test 2020-08-28 11:19:56 +02:00
Armin Schrenk eb6ade49f6 refactor to use parameterized test 2020-08-27 16:18:20 +02:00
Armin Schrenk 6553c04256 add code to migrate legacy settings.json files to new property. 2020-08-27 15:53:20 +02:00
Armin Schrenk a8cb015a06 rename property and getters in vault class for display name. 2020-08-27 15:52:16 +02:00
Martin Beyer ee81dca71c Nice implementation of only one stats window per vault 2020-08-26 17:23:39 +02:00
Sebastian StenzelandArmin Schrenk ce06ddf312 updated webdav dependencies
(cherry picked from commit 8c4d35d3db)
2020-08-26 12:51:28 +02:00
Armin SchrenkandGitHub fee2d4bc0c Merge pull request #1311 from cryptomator/feature/alternativeAutostartWin
Feature/alternative autostart win
2020-08-26 11:44:37 +02:00
Armin Schrenk a2a990bd0c Correct spelling 2020-08-26 11:36:46 +02:00
Armin SchrenkandGitHub cedbe6523d Merge pull request #1294 from purejava/access-kde-wallets
This adds the missing part to linux system keychain access: use KDE wallets
2020-08-26 10:03:55 +02:00
JaniruTEC ec64055d93 Renamed property "position" (defined by MPC) to "priority" 2020-08-21 22:41:15 +02:00
JaniruTEC 6f542ac8b8 Replaced "assert" with IllegalStateException 2020-08-21 21:57:12 +02:00
Ralph Plawetzki 8a3c101764 Merge remote branch 'cryptomator/develop' into access-kde-wallets 2020-08-21 19:30:46 +02:00
infeo 49a8689090 Remove legacy concepts:
* in vaultSettings, displayName does not listen on path
* the caller/creater of vault settings must set the name explicitly
* add localizable default vault name
2020-08-21 13:30:05 +02:00
infeo 8f5c4997b1 closes #1300 2020-08-21 11:32:51 +02:00
infeo 900fdd7f6f minor changes
* removing unused imports
* exchanging addListener() by Easybind.subscribe()
2020-08-21 11:17:55 +02:00
Tobias Hagemann 4723416d45 fixed icon views of labels in new password screen that could only appear once 2020-08-21 10:13:45 +02:00
JaniruTEC 8483f71f57 Refactored CustomMountPointChooser
See: https://github.com/cryptomator/cryptomator/pull/1307#discussion_r472832435
2020-08-21 00:55:33 +02:00
JaniruTEC 5dac594cc9 Removed Phasesystem, specified docs, removed default #isApplicable()
See: https://github.com/cryptomator/cryptomator/pull/1307#discussion_r472835069 https://github.com/cryptomator/cryptomator/pull/1307#discussion_r472839837 https://github.com/cryptomator/cryptomator/pull/1307#discussion_r472820689 https://github.com/cryptomator/cryptomator/pull/1307#discussion_r472872901
2020-08-21 00:00:13 +02:00
infeo 06f4e160d6 Migrate to easybind fork 2020-08-20 21:25:54 +02:00
infeo 1d38ee2fcb Further improvements:
* corrected bad english
* improved documentation
* restricted visibility of specific exception
2020-08-20 13:49:31 +02:00
Sebastian Stenzelandinfeo 921b70ebaa updated webdav dependencies
(cherry picked from commit 8c4d35d3db)
2020-08-20 13:38:40 +02:00
infeo 0f56d424da Refactored AutoStartStrategy:
* prevented on best effort basis inconsistent states
* extracted the registry setting as an own strategy (by methods)
* refactored the overriden methods to call the strategies (registry or folder) depending on the different variables
* removed Powershell specific ToggleException
* added documentation
2020-08-20 12:18:57 +02:00
JaniruTEC 4cd43a2b1c Merge branch 'develop' into feature/fuse-on-win 2020-08-19 15:53:26 +02:00
JaniruTEC 1ef359e68b Added messages to rethrown IOExceptions 2020-08-19 15:47:09 +02:00
JaniruTEC 58ce1e45b8 Updated Codestyle to not use any arrangements 2020-08-19 15:34:08 +02:00
Martin Beyer bd854e7f7a updates secret-service for linux keychains and fixes #1268 2020-08-19 15:31:42 +02:00
JaniruTEC 3ecc0cf906 Cleaned up MountPointRequirement
See: https://github.com/cryptomator/cryptomator/pull/1307#discussion_r472827299
See: https://github.com/cryptomator/cryptomator/pull/1307#discussion_r472826920
2020-08-19 14:45:10 +02:00
JaniruTEC ea6925f905 Replaced #wrapAsIMPE() with explicit call to IMPExc
See: https://github.com/cryptomator/cryptomator/pull/1307#discussion_r472872373 https://github.com/cryptomator/cryptomator/pull/1307#discussion_r472859488 https://github.com/cryptomator/cryptomator/pull/1307#discussion_r472827776
2020-08-19 11:44:18 +02:00
JaniruTEC f45b78d8c0 Removed accidental debugcode, updated lookup for env-var
See: https://github.com/cryptomator/cryptomator/pull/1307#discussion_r472848604
See: https://github.com/cryptomator/cryptomator/pull/1307#discussion_r472851003
2020-08-19 11:44:01 +02:00
JaniruTEC 75ca8a91f8 Merge remote-tracking branch 'upstream/develop' into feature/fuse-on-win 2020-08-19 11:42:55 +02:00
JaniruTEC 16462d05c8 Refactored changes, cleaned up
Changed visibility of methods
Removed Logger from AbstractVolume
Moved mountPoint and #getMountPoint()
Renamed fuseMnt to mount in FuseVol (as in DokanyVol)
Removed unnecessary mountPoint-field from WebDavVolume
2020-08-18 21:27:13 +02:00
JaniruTEC cbef54f05c Added Logger, moved cleanup, moved choosing 2020-08-18 21:27:03 +02:00
JaniruTEC f601ff4ce3 Moved #isSupported() in the file, moved #determineMountPoint() 2020-08-18 21:26:52 +02:00
JaniruTEC 84fbf7392b Updated usage of FuseNotSupportedException 2020-08-18 16:57:56 +02:00
JaniruTEC bbf9379f56 Changed DokanyVolumes and FuseVolumes to use mountnames
Changed DokanyVolumes and FuseVolumes to use mountnames for automatic, folder-based mounting instead of ids.
2020-08-18 16:57:55 +02:00
JaniruTEC 6aa14fcfb1 Updated Errorhandling of UnlockWorkflow 2020-08-18 16:57:55 +02:00
Tobias Hagemann 710c7d0da7 added button to main window title if debug mode is enabled, fixes #1065 2020-08-18 16:08:23 +02:00
Tobias Hagemann 841d4eb9c7 updated third-party licenses 2020-08-18 13:59:37 +02:00
Sebastian Stenzel 8c4d35d3db updated webdav dependencies 2020-08-18 10:36:55 +02:00
JaniruTEC 4110057fa1 Refactored multiple classes
Refactored UnlockWorkflow, CustomMountPointChooser, DokanyVolume and UnlockInvalidMountPointController

Changed UnlockWorkflow#handleGenericError() to accept Throwables

Added check for parent to CustomMountPointChooser (when using FUSE on Win)

Removed legacy constant from DokanyVolume

Added asserts to UnlockInvalidMountPointController and UnlockWorkflow
2020-08-16 18:40:11 +02:00
Tobias Hagemann 9b1d6d2f2f Merge branch 'release/1.5.7' into develop 2020-08-14 12:59:07 +02:00
Tobias Hagemann 1c45455cb2 Merge branch 'release/1.5.7' 2020-08-14 12:58:26 +02:00
Tobias Hagemann 411aca8695 preparing 1.5.7 2020-08-14 12:55:46 +02:00
Sebastian StenzelandTobias Hagemann 3de69021df New Crowdin updates (#1255)
[ci skip]
2020-08-14 12:49:55 +02:00
Tobias Hagemann 8418038736 dependency update 2020-08-14 12:47:11 +02:00
Ralph Plawetzki 3bf2b499a7 Reverse order to initialize backend
The GNOME keyring feature was implemented first and we don't want to confuse users who used it before
2020-08-14 07:40:46 +02:00
JaniruTEC 430da2b78d Implemented MPC-System in FuseVolume and DokanyVolume, did refactoring
Implemented MPC-System in FuseVolume and DokanyVolume
Removed methods from FuseVol and DokanyVol
Renamed methods
Added chooser logic instead

Added imports for VolumeException to multiple classes
Added support for throwing and handling of InvalidMountPointException from Volume up to UnlockWorkflow (changed method signatures, added try-catchs, etc.)
2020-08-12 23:42:38 +02:00
JaniruTEC 51047dcbce Added additional debug messages 2020-08-12 23:42:38 +02:00
JaniruTEC 708bcaa630 Updated CustomMountPointChooser to use MPR instead of OS-Checks
Updated CustomMountPointChooser to use MountPointRequirements instead of OS-Checks.

This led to the discovery of the bug that was fixed in 724b20c826.
2020-08-12 23:42:37 +02:00
JaniruTEC 724b20c826 Fixed possible racecondition at Vault initialization
Fixed possible racecondition at Vault initialization: VaulSettings were read before the Vault was fully initialized resulting in breakage of the code if the excact order was to be changed.
2020-08-12 21:43:24 +02:00
Tobias Hagemann 69f8c46f15 ui adjustments in vault detail missing 2020-08-12 17:35:11 +02:00
JaniruTEC b7f2fb0bdf Added cleanup to TemporaryMountPointChooser 2020-08-11 23:35:43 +02:00
JaniruTEC 222ffd8c53 Implemented MountPointChooserModule 2020-08-11 23:35:42 +02:00
JaniruTEC 00e0a0f79a Fixed doc for MountPointChooser 2020-08-11 23:35:42 +02:00
JaniruTEC d6bbc4383b Added implementations for MountPointChooser
Added AvailableDriveLetterChooser for automatic DriveLetter-choice
Added CustomDriveLetterChooser for a chosen DriveLetter
Added CustomMountPointChooser for a chosen directory
Added TemporaryMountPointChooser for automatic directory-choice
2020-08-11 23:03:12 +02:00
JaniruTEC b51a2602a9 Documented MountPointChooser 2020-08-11 23:03:12 +02:00
JaniruTEC c3fbddc671 Refactored PerVault, Vault and VaultSettings
Made @`PerVault public
Added import for VaultException to Vault
Added convenience method to VaultSettings
2020-08-11 22:26:15 +02:00
JaniruTEC ce262b691a Added base classes for MountPointChoosers and added module to component 2020-08-11 22:26:15 +02:00
Martin Beyer 65de6fef9b Allowing only one io-stats window per vault to be open at the same time. 2020-08-11 17:32:39 +02:00
Armin Schrenk 31d95ae5b0 Remove restrictions of vault name filed to only contain alpha numeric characters 2020-08-11 12:04:02 +02:00
Armin Schrenk 429098733c Improve the vault/mount name system:
* fix bug where the default name is not replaced by the actual folder name
* introduce new field in settings "mountName" as binding on displayName
* change volumes to use mountName instead of displayName
2020-08-11 11:19:54 +02:00
JaniruTEC 597899d2bf Fixed random set order and updated #getAvailableDriveLetter()
Fixed bug introduced by 32a810fe1d:
The Set of existing DriveLetters was in random order because Collectors#toUnmodifiableSet is an unordered collector.

Changed #getAvailableDriveLetter() to use Stream#findFirst() instead of #findAny()
2020-08-11 02:24:44 +02:00
Ralph Plawetzki b1c66b181d Depend on kdewallet 1.0.1, hence dbus-java 3.2.3
that fixes issues when dealing with multiple signals of the same name but different signatures
2020-08-09 11:18:17 +02:00
Ralph Plawetzki 100b836979 Adjust buildkit to exclude kdewallet for Windows and macOS 2020-08-07 18:49:07 +02:00
Ralph Plawetzki 817907c25a Add access functionality for KDE kwallets 2020-08-07 18:32:54 +02:00
Tobias Hagemann 25195fffe2 added icon to password strength label in new password controller 2020-08-07 17:47:49 +02:00
Tobias Hagemann 0e784a6ffc also disable finish button in change password if old password field is empty 2020-08-07 17:09:55 +02:00
Tobias Hagemann 351f96fa8b switch to light theme if donation key has changed and is invalid 2020-08-07 09:30:22 +02:00
Tobias Hagemann 703fb4fb51 fixed https://github.com/cryptomator/cryptomator/commit/0091c401df3589e9e4236698690d242af77ffc1e#r40816364 2020-08-06 18:32:57 +02:00
Tobias Hagemann a975df6f8c added "Automatic" theme on macOS 2020-08-06 18:30:34 +02:00
Armin Schrenk fb90128b63 Move option to change display name of a vault from mount options to general options 2020-08-06 15:33:28 +02:00
Armin Schrenk ea4c91fb37 change meaning of mount name setting:
* it is now considered the gerenal vault name
* methods (except parsing) are renamed accordingly
2020-08-06 15:20:32 +02:00
Armin Schrenk 7c1d6973ba fixes #1289 by decoupling storage path from vault name 2020-08-06 15:18:30 +02:00
JaniruTEC 4f2120b729 Added support for folderbased backup-mountpoint to DokanyVol and FuseVol 2020-08-03 22:20:20 +02:00
JaniruTEC 51f7d74e4a Changed cryptomator.mountPointsDir-property in Windows Configs
Changed cryptomator.mountPointsDir-property in Windows Configs from "~/Mount" to "~/Cryptomator
2020-08-03 21:22:22 +02:00
JaniruTEC 32a810fe1d Changed FuseVolume to choose a DriveLetter instead of a folder
Changed FuseVolume to choose a DriveLetter instead of a folder if the the mountpoint is chosen by the app.
Reworked priorities when choosing
Changed DokanyVolume to use the new methods supplied by WindowsDriveLetters
2020-07-29 22:15:12 +02:00
JaniruTEC 570482521a Delegated choice of DriveLetter to WDL and made internal Set immutable
Delegated choice of DriveLetter to WindowsDriveLetters
Made internal Set ("C_TO_Z") immutable, that is returned by getAvailableDriveLetters()
Changed direct reference to C_TO_Z to use getAvailableDriveLetters() instead
2020-07-29 22:14:51 +02:00
Martin Beyer 3bd2a2f911 Fixes #1262 by adding new buttons, if a vault cannot be found 2020-07-29 10:21:16 +02:00
JaniruTEC 1ac6d086bd Disabled some experimental FUSE Features on Windows
Disabled some experimental FUSE Features on Windows unless they are explicitly enabled by using the flag '-Dfuse.experimental="true"'

They are enabled in the default IntelliJ-Config (disabled on Build)
2020-07-28 19:15:56 +02:00
JaniruTEC 8374599183 Modified creation of temporary mountpoint, fixed bugs, added comments
Changed FuseVolume#prepareTemporaryMountPoint to handle FUSE on Windows correctly (WinFSP requires the folder to NOT exist...)
See: https://github.com/billziss-gh/winfsp/issues/320

Added comments
Fixed bug: Message showing a malformed path
2020-07-26 23:03:36 +02:00
Martin Beyer 0091c401df Fixes #1267 by binding the settings.preferredVolumeImpl to VolumeImpl.WEBDAV, if preferredVolimeImpl isn't available 2020-07-22 15:26:21 +02:00
Martin Beyer 00dd67e345 Refactoring 2020-07-21 15:16:53 +02:00
Martin Beyer 158677bd54 Using new methods from CryptoFs to get correct statistics 2020-07-21 11:10:05 +02:00
JaniruTEC a1b375316c Specified the messages of failed UnlockWorkflows
Specified the messages of failed UnlockWorkflows by adding the ability to distinguish between the different MountPointRequirements

Translation for all languages but German and Englisch required
2020-07-20 22:06:15 +02:00
JaniruTEC dae2814b0f Added MountPointRequirement-Enum
Added MountPointRequirement-Enum and added method getMountPointRequirement() to Volume (and all implementing classes) to query the requirment for the specific VolumeProvider.
2020-07-20 22:01:10 +02:00
JaniruTEC 341a98848d Modified check of provided mountpoint
Changed FuseVolume#checkProvidedMountPoint to handle FUSE on Windows correctly (WinFSP requires the folder to NOT exist...)
2020-07-20 22:00:35 +02:00
JaniruTEC 902e66906a Refactored method FuseVolume#prepareTemporaryMountPoint
Refactored method FuseVolume#prepareTemporaryMountPoint to be more readable (removed duplicated code)
2020-07-20 21:55:49 +02:00
JaniruTEC c59d3cd03f Removed check for OS from FuseVolume#isSupportedStatic 2020-07-20 21:23:35 +02:00
Martin Beyer ed9f16e012 Displaying additional stats with a new DataLabel 2020-07-20 16:09:45 +02:00
Martin Beyer ed77a4aacd Added basic counting of additional total stats (not correct) 2020-07-20 16:08:25 +02:00
Martin Beyer ff2fa70bd6 preperation for displaying en-de-crypted bytes per second 2020-07-20 11:00:59 +02:00
Martin Beyer 3519346df9 cleaned up unlock window 2020-07-20 10:59:48 +02:00
JaniruTEC 45f6caa7bd Added basic support for FUSE-Mounting on Windows 2020-07-18 19:05:18 +02:00
JaniruTEC e2e7755af2 Added cryptomator.mountPointsDir-property to Windows Configs 2020-07-18 18:57:11 +02:00
Armin Schrenk 4ab7bfaa20 reformat 2020-07-17 11:58:11 +02:00
Armin Schrenk 7e0ffb43a6 fixing bug where the mountName of the vault is initially set as the default one 2020-07-17 11:57:53 +02:00
Martin Beyer 526c8328f6 Refactoring - Removing unnecessary environment variable 2020-07-13 15:21:24 +02:00
JaniruTEC 81bad4eb25 Fixed bug: Some exceptions caused by unlock were not shown
If an unmatched exception occurred during unlocking it was neither logged nor shown to the user.
2020-07-09 22:34:57 +02:00
Martin Beyer dcaa6e81a3 Improving Exception calling and logging 2020-07-08 14:53:15 +02:00
Martin Beyer e78155396d Implementing #1251 2020-07-08 14:01:10 +02:00
Sebastian Stenzel d3063c8117 Make sure not to launch the FX app more than once. 2020-07-07 16:01:32 +02:00
Armin SchrenkandGitHub cd1ed088c3 Update bug.md
Change bullet point "Drive" to "Volume type" such that users are less confused by this field. Also added where this info can be found.
2020-07-03 10:37:02 +02:00
Martin Beyer e831debb94 fixes #1244 by renaming the refresh button and adding a method call 2020-06-30 09:36:46 +02:00
Martin 8d15a6612f Implements #1244 by adding a small button to regain focus 2020-06-28 11:05:27 +02:00
Sebastian Stenzel 9c034f3be6 split up read and write charts and added cache efficiency chart
(because we will add further read/write-specific stats like total number of files read/written, bytes encrypted/decrypted, etc)
2020-06-25 17:16:42 +02:00
Sebastian Stenzel 60dd9349a8 Merge branch 'develop' into feature/io-stats 2020-06-25 17:15:22 +02:00
Sebastian Stenzel 330b1cbf7d derived resources after dependency update
[ci skip]
2020-06-25 17:15:07 +02:00
Sebastian Stenzel 9ffa38d54e Merge branch 'develop' into feature/io-stats 2020-06-22 17:24:18 +02:00
Sebastian Stenzel c925727269 Merge branch 'master' into develop 2020-06-22 17:23:58 +02:00
Martin Beyer 7a69692999 Prettied up the statistics window for both Ui Themes 2020-06-17 11:04:36 +02:00
Sebastian Stenzel d00d9d98dc make sure to release all strong referenced to the I/O chart when closing the window 2020-06-16 15:35:12 +02:00
Sebastian Stenzel 1846c5c14c formatting 2020-06-16 15:05:24 +02:00
Sebastian Stenzel 0d9db783f7 Merge branch 'develop' into feature/io-stats 2020-06-16 15:04:47 +02:00
Martin Beyer 55e9cabf51 Updated Graph to use Timeline + minor UI changes + wording 2020-06-16 14:13:17 +02:00
Sebastian Stenzel 5180f2061a add series only once (in scene initialization instead of on every tick) - thus fixing IAE 2020-06-10 13:58:02 +02:00
Martin BeyerandSebastian Stenzel 05154cf6aa Added Graph to statistics window 2020-06-10 13:38:58 +02:00
Martin BeyerandSebastian Stenzel f61e955945 First Dummy window to show statistics 2020-06-10 13:38:57 +02:00
488 changed files with 14742 additions and 6111 deletions
+5 -4
View File
@@ -1,5 +1,6 @@
commit_message: "[ci skip]"
escape_special_characters: 0
commit_message: '[ci skip]'
files:
- source: /main/ui/src/main/resources/i18n/strings.properties
translation: /main/ui/src/main/resources/i18n/strings_%two_letters_code%.properties
- source: /src/main/resources/i18n/strings.properties
translation: /src/main/resources/i18n/strings_%two_letters_code%.properties
escape_quotes: 0
escape_special_characters: 0
+1 -1
View File
@@ -22,7 +22,7 @@ include:
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or
* The use of sexual language or imagery and unwelcome sexual attention or
advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
+7 -12
View File
@@ -5,14 +5,11 @@ labels: type:bug
---
<!--
Please make sure to:
- Comply with our code of conduct: https://github.com/cryptomator/cryptomator/blob/develop/.github/CODE_OF_CONDUCT.md
- Search for existing similar issues first: https://github.com/cryptomator/cryptomator/issues?q=
Do you want to ask a QUESTION? Are you looking for SUPPORT?
We're happy to help you via our support channels! Please read: https://github.com/cryptomator/cryptomator/blob/develop/SUPPORT.md
By filing an issue, you are expected to comply with our code of conduct: https://github.com/cryptomator/cryptomator/blob/develop/.github/CODE_OF_CONDUCT.md
Of course, we also expect you to search for existing similar issues first! ;) https://github.com/cryptomator/cryptomator/issues?q=
⚠️ IMPORTANT: If you don't stick to this template, the issue will get closed.
-->
### Description
@@ -21,9 +18,9 @@ Of course, we also expect you to search for existing similar issues first! ;) ht
### System Setup
* Operating system and version: [Windows/macOS/Linux + Version]
* Operating system and version: [Windows/macOS/Linux + Version ( + Desktop Environment, if Linux)]
* Cryptomator version: [Shown in the settings]
* Drive: [Dokany/FUSE/WebDAV]
* Volume type: [Dokany/FUSE/WebDAV, shown in the settings]
### Steps to Reproduce
@@ -48,7 +45,6 @@ Of course, we also expect you to search for existing similar issues first! ;) ht
[Any additional information, log files, screenshots, configuration, or data that might be necessary to reproduce the issue.]
<!--
If you want to add the log file or screenshots, please add them as attachments. If your log file seems empty and doesn't show any errors, you may enable the debug mode first. Here is how to do that: https://community.cryptomator.org/t/how-do-i-enable-debug-mode/36
Then reproduce the problem to ensure all important information is contained in there. You may use test data or redact sensitive information from the log file.
@@ -57,5 +53,4 @@ Log file location:
- Windows: %appdata%/Cryptomator
- macOS: ~/Library/Logs/Cryptomator
- Linux: ~/.local/share/Cryptomator/logs
-->
-->
+8
View File
@@ -0,0 +1,8 @@
blank_issues_enabled: false
contact_links:
- name: Help & Support
url: https://community.cryptomator.org/
about: You will find answers in our community forum
- name: User Manual
url: https://docs.cryptomator.org/
about: Read the Cryptomator documentation here
+4 -9
View File
@@ -5,14 +5,9 @@ labels: type:feature-request
---
<!--
Do you want to ask a QUESTION? Are you looking for SUPPORT?
We're happy to help you via our support channels! Please read: https://github.com/cryptomator/cryptomator/blob/develop/SUPPORT.md
By filing a feature request, you are expected to comply with our code of conduct: https://github.com/cryptomator/cryptomator/blob/develop/.github/CODE_OF_CONDUCT.md
Of course, we also expect you to search for existing similar feature requests first! ;)
Please make sure to:
- Comply with our code of conduct: https://github.com/cryptomator/cryptomator/blob/develop/.github/CODE_OF_CONDUCT.md
- Search for existing similar issues first: https://github.com/cryptomator/cryptomator/issues?q=
-->
### Summary
@@ -29,4 +24,4 @@ Of course, we also expect you to search for existing similar feature requests fi
### Additional Context
[Add any other context or screenshots about the feature request here.]
[Add any other context or screenshots about the feature request here.]
View File
+1 -1
View File
@@ -14,5 +14,5 @@ For _everything else_, please visit our official [Cryptomator Community](https:/
- Discussions about the apps
- [Development discussions](https://community.cryptomator.org/c/development)
- General questions
- Discussions regarding our design decissions
- Discussions regarding our design decisions
- Our roadmap
+55 -19
View File
@@ -7,11 +7,12 @@ jobs:
build:
name: Build and Test
runs-on: ubuntu-latest
if: "!contains(github.event.head_commit.message, '[ci skip]') && !contains(github.event.head_commit.message, '[skip ci]')"
steps:
- uses: actions/checkout@v2
- uses: actions/setup-java@v1
with:
java-version: 14
java-version: 16
- uses: actions/cache@v1
with:
path: ~/.m2/repository
@@ -19,44 +20,46 @@ jobs:
restore-keys: |
${{ runner.os }}-maven-
- name: Ensure to use tagged version
run: mvn versions:set --file main/pom.xml -DnewVersion=${GITHUB_REF##*/} # use shell parameter expansion to strip of 'refs/tags'
run: mvn versions:set -DnewVersion=${GITHUB_REF##*/} # use shell parameter expansion to strip of 'refs/tags'
if: startsWith(github.ref, 'refs/tags/')
- name: Build and Test
run: mvn -B install --file main/pom.xml -Pcoverage
- name: Run Codacy Coverage Reporter
run: |
curl -o ~/codacy-coverage-reporter.jar https://repo.maven.apache.org/maven2/com/codacy/codacy-coverage-reporter/7.1.0/codacy-coverage-reporter-7.1.0-assembly.jar
$JAVA_HOME/bin/java -jar ~/codacy-coverage-reporter.jar report -l Java -r main/commons/target/site/jacoco/jacoco.xml --partial
$JAVA_HOME/bin/java -jar ~/codacy-coverage-reporter.jar report -l Java -r main/keychain/target/site/jacoco/jacoco.xml --partial
$JAVA_HOME/bin/java -jar ~/codacy-coverage-reporter.jar report -l Java -r main/ui/target/site/jacoco/jacoco.xml --partial
$JAVA_HOME/bin/java -jar ~/codacy-coverage-reporter.jar report -l Java -r main/launcher/target/site/jacoco/jacoco.xml --partial
$JAVA_HOME/bin/java -jar ~/codacy-coverage-reporter.jar final
run: mvn -B clean install jacoco:report -Pcoverage,dependency-check
- name: Upload code coverage report
id: codacyCoverageReporter
run: bash <(curl -Ls https://coverage.codacy.com/get.sh)
env:
CODACY_PROJECT_TOKEN: ${{ secrets.CODACY_PROJECT_TOKEN }}
- name: Assemble Buildkit
run: mvn -B package -DskipTests --file main/pom.xml --resume-from=buildkit -Prelease
continue-on-error: true
### TODO: move to matrix build:
- name: Assemble buildkit-linux.zip
run: mvn -B clean package -DskipTests -Plinux
- name: Upload buildkit-linux.zip
uses: actions/upload-artifact@v1
with:
name: buildkit-linux.zip
path: main/buildkit/target/buildkit-linux.zip
path: target/buildkit-linux.zip
- name: Assemble buildkit-mac.zip
run: mvn -B clean package -DskipTests -Pmac
- name: Upload buildkit-mac.zip
uses: actions/upload-artifact@v1
with:
name: buildkit-mac.zip
path: main/buildkit/target/buildkit-mac.zip
path: target/buildkit-mac.zip
- name: Assemble buildkit-win.zip
run: mvn -B clean package -DskipTests -Pwindows
- name: Upload buildkit-win.zip
uses: actions/upload-artifact@v1
with:
name: buildkit-win.zip
path: main/buildkit/target/buildkit-win.zip
path: target/buildkit-win.zip
release:
name: Draft a Release on GitHub Releases
runs-on: ubuntu-latest
needs: build
if: startsWith(github.ref, 'refs/tags/')
if: startsWith(github.ref, 'refs/tags/') && github.repository == 'cryptomator/cryptomator'
steps:
- uses: actions/checkout@v2
- name: Download buildkit-linux.zip
uses: actions/download-artifact@v1
with:
@@ -72,6 +75,15 @@ jobs:
with:
name: buildkit-win.zip
path: .
- name: Create tarball
run: git archive --prefix="cryptomator-${{ github.ref }}/" -o "cryptomator-${{ github.ref }}.tar.gz" ${{ github.ref }}
- name: Sign tarball with key 615D449FE6E6A235
run: |
echo "${GPG_PRIVATE_KEY}" | gpg --batch --quiet --import
echo "${GPG_PASSPHRASE}" | gpg --batch --quiet --passphrase-fd 0 --pinentry-mode loopback -u 615D449FE6E6A235 --detach-sign -a "cryptomator-${{ github.ref }}.tar.gz"
env:
GPG_PRIVATE_KEY: ${{ secrets.RELEASES_GPG_PRIVATE_KEY }}
GPG_PASSPHRASE: ${{ secrets.RELEASES_GPG_PASSPHRASE }}
- name: Create Release
id: create_release
uses: actions/create-release@v1
@@ -82,6 +94,21 @@ jobs:
release_name: ${{ github.ref }}
body: |
:construction: Work in Progress
TODO:
* [ ] add Linux appimage, zsync file and signature file
* [ ] add Windows installer and signature file
* [ ] add MacOs disk image and signature file
## What's new
## Bugfixes
## Misc
---
:scroll: A complete list of closed issues is available [here](LINK)
draft: true
prerelease: false
- name: Upload buildkit-linux.zip to GitHub Releases
@@ -110,4 +137,13 @@ jobs:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: buildkit-win.zip
asset_name: buildkit-win.zip
asset_content_type: application/zip
asset_content_type: application/zip
- name: Upload tarball signature to GitHub Releases
uses: actions/upload-release-asset@v1.0.1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: "cryptomator-${{ github.ref }}.tar.gz.asc"
asset_name: "cryptomator-${{ github.ref }}.tar.gz.asc"
asset_content_type: application/octet-stream
+37
View File
@@ -0,0 +1,37 @@
name: Bug Report Triage
on:
issues:
types: [opened]
jobs:
closeTemplateViolation:
name: Validate bug report against issue template
runs-on: ubuntu-latest
if: contains(github.event.issue.labels.*.name, 'type:bug')
steps:
- name: Check "Description"
if: |
!contains(github.event.issue.body, env.MUST_CONTAIN)
|| contains(toJson(github.event.issue.body), env.MUST_NOT_CONTAIN)
run: exit 1
env:
MUST_CONTAIN: '### Description'
MUST_NOT_CONTAIN: '### Description\r\n\r\n[Summarize your problem.]\r\n\r\n### System Setup'
- name: Check "Steps to Reproduce"
if: |
!contains(github.event.issue.body, env.MUST_CONTAIN)
|| contains(toJson(github.event.issue.body), env.MUST_NOT_CONTAIN)
run: exit 1
env:
MUST_CONTAIN: '### Steps to Reproduce'
MUST_NOT_CONTAIN: '### Steps to Reproduce\r\n\r\n1. [First step]\r\n2. [Second step]\r\n3. [and so on…]\r\n\r\n#### Expected Behavior'
- name: Close issue if one of the checks failed
if: ${{ failure() }}
uses: peter-evans/close-issue@v1
with:
comment: |
This bug report did ignore our issue template. 😞
Auto-closing this issue, since it is most likely not useful.
_This decision was made by a bot. If you think the bot is wrong, let us know and we'll reopen this issue._
+7 -1
View File
@@ -17,6 +17,12 @@ pom.xml.versionsBackup
# IntelliJ Settings Files (https://intellij-support.jetbrains.com/hc/en-us/articles/206544839-How-to-manage-projects-under-Version-Control-Systems) #
.idea/**/workspace.xml
.idea/**/tasks.xml
.idea/dictionaries
.idea/**/shelf
.idea/dictionaries/**
!.idea/dictionaries/dict_*
.idea/compiler.xml
.idea/encodings.xml
.idea/jarRepositories.xml
.idea/uiDesigner.xml
.idea/**/libraries/
*.iml
+28 -1
View File
@@ -9,14 +9,36 @@
<option name="RIGHT_MARGIN" value="220" />
<option name="FORMATTER_TAGS_ENABLED" value="true" />
<JavaCodeStyleSettings>
<option name="CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND" value="30" />
<option name="CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND" value="999" />
<option name="NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND" value="10" />
<option name="PACKAGES_TO_USE_IMPORT_ON_DEMAND">
<value />
</option>
<option name="IMPORT_LAYOUT_TABLE">
<value>
<package name="" withSubpackages="true" static="false" />
<emptyLine />
<package name="javax" withSubpackages="true" static="false" />
<package name="javafx" withSubpackages="true" static="false" />
<package name="java" withSubpackages="true" static="false" />
<emptyLine />
<package name="" withSubpackages="true" static="true" />
</value>
</option>
<option name="JD_ALIGN_PARAM_COMMENTS" value="false" />
<option name="JD_ALIGN_EXCEPTION_COMMENTS" value="false" />
</JavaCodeStyleSettings>
<Properties>
<option name="KEEP_BLANK_LINES" value="true" />
</Properties>
<XML>
<option name="XML_ATTRIBUTE_WRAP" value="0" />
</XML>
<codeStyleSettings language="CSS">
<indentOptions>
<option name="USE_TAB_CHARACTER" value="true" />
</indentOptions>
</codeStyleSettings>
<codeStyleSettings language="Groovy">
<indentOptions>
<option name="USE_TAB_CHARACTER" value="true" />
@@ -30,12 +52,17 @@
<codeStyleSettings language="JAVA">
<option name="KEEP_LINE_BREAKS" value="false" />
<option name="BLANK_LINES_AFTER_CLASS_HEADER" value="1" />
<option name="BINARY_OPERATION_SIGN_ON_NEXT_LINE" value="true" />
<option name="KEEP_SIMPLE_BLOCKS_IN_ONE_LINE" value="true" />
<option name="KEEP_SIMPLE_METHODS_IN_ONE_LINE" value="true" />
<option name="KEEP_SIMPLE_LAMBDAS_IN_ONE_LINE" value="true" />
<option name="ENUM_CONSTANTS_WRAP" value="2" />
<indentOptions>
<option name="USE_TAB_CHARACTER" value="true" />
</indentOptions>
<arrangement>
<rules />
</arrangement>
</codeStyleSettings>
<codeStyleSettings language="JSON">
<indentOptions>
-41
View File
@@ -1,41 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<annotationProcessing>
<profile name="Annotation profile for Cryptomator" enabled="true">
<sourceOutputDir name="target/generated-sources/annotations" />
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
<outputRelativeToContentRoot value="true" />
<processorPath useClasspath="false">
<entry name="$MAVEN_REPOSITORY$/com/google/dagger/dagger-compiler/2.27/dagger-compiler-2.27.jar" />
<entry name="$MAVEN_REPOSITORY$/com/google/dagger/dagger/2.27/dagger-2.27.jar" />
<entry name="$MAVEN_REPOSITORY$/javax/inject/javax.inject/1/javax.inject-1.jar" />
<entry name="$MAVEN_REPOSITORY$/com/google/dagger/dagger-producers/2.27/dagger-producers-2.27.jar" />
<entry name="$MAVEN_REPOSITORY$/com/google/guava/failureaccess/1.0.1/failureaccess-1.0.1.jar" />
<entry name="$MAVEN_REPOSITORY$/com/google/guava/guava/27.1-jre/guava-27.1-jre.jar" />
<entry name="$MAVEN_REPOSITORY$/com/google/guava/listenablefuture/9999.0-empty-to-avoid-conflict-with-guava/listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar" />
<entry name="$MAVEN_REPOSITORY$/com/google/code/findbugs/jsr305/3.0.1/jsr305-3.0.1.jar" />
<entry name="$MAVEN_REPOSITORY$/org/checkerframework/checker-qual/2.5.2/checker-qual-2.5.2.jar" />
<entry name="$MAVEN_REPOSITORY$/com/google/errorprone/error_prone_annotations/2.2.0/error_prone_annotations-2.2.0.jar" />
<entry name="$MAVEN_REPOSITORY$/com/google/j2objc/j2objc-annotations/1.1/j2objc-annotations-1.1.jar" />
<entry name="$MAVEN_REPOSITORY$/org/codehaus/mojo/animal-sniffer-annotations/1.17/animal-sniffer-annotations-1.17.jar" />
<entry name="$MAVEN_REPOSITORY$/org/checkerframework/checker-compat-qual/2.5.3/checker-compat-qual-2.5.3.jar" />
<entry name="$MAVEN_REPOSITORY$/com/google/dagger/dagger-spi/2.27/dagger-spi-2.27.jar" />
<entry name="$MAVEN_REPOSITORY$/com/squareup/javapoet/1.11.1/javapoet-1.11.1.jar" />
<entry name="$MAVEN_REPOSITORY$/com/google/googlejavaformat/google-java-format/1.5/google-java-format-1.5.jar" />
<entry name="$MAVEN_REPOSITORY$/com/google/errorprone/javac-shaded/9-dev-r4023-3/javac-shaded-9-dev-r4023-3.jar" />
<entry name="$MAVEN_REPOSITORY$/javax/annotation/jsr250-api/1.0/jsr250-api-1.0.jar" />
<entry name="$MAVEN_REPOSITORY$/net/ltgt/gradle/incap/incap/0.2/incap-0.2.jar" />
<entry name="$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib/1.3.50/kotlin-stdlib-1.3.50.jar" />
<entry name="$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib-common/1.3.50/kotlin-stdlib-common-1.3.50.jar" />
<entry name="$MAVEN_REPOSITORY$/org/jetbrains/annotations/13.0/annotations-13.0.jar" />
<entry name="$MAVEN_REPOSITORY$/org/jetbrains/kotlinx/kotlinx-metadata-jvm/0.1.0/kotlinx-metadata-jvm-0.1.0.jar" />
</processorPath>
<module name="keychain" />
<module name="launcher" />
<module name="commons" />
<module name="ui" />
</profile>
</annotationProcessing>
</component>
</project>
+15
View File
@@ -0,0 +1,15 @@
<component name="ProjectDictionaryState">
<dictionary name="dict_de">
<words>
<w>tresorinhalt</w>
<w>tresorkonfigurationsdatei</w>
<w>tresorlaufwerk</w>
<w>tresorliste</w>
<w>tresorname</w>
<w>tresoroptionen</w>
<w>tresorstatistik</w>
<w>ungespeicherten</w>
<w>ungespeicherter</w>
</words>
</dictionary>
</component>
+106
View File
@@ -0,0 +1,106 @@
<component name="ProjectDictionaryState">
<dictionary name="dict_project">
<words>
<w>addvault</w>
<w>addvaultwizard</w>
<w>adoptopenjdk</w>
<w>affero</w>
<w>aquafx</w>
<w>autolock</w>
<w>autolocked</w>
<w>autolocking</w>
<w>baos</w>
<w>bkup</w>
<w>buildkit</w>
<w>changepassword</w>
<w>checkerframework</w>
<w>crit</w>
<w>crowdin</w>
<w>cryptofs</w>
<w>cryptomator</w>
<w>cryptomator's</w>
<w>cryptor</w>
<w>csprng</w>
<w>dcryptomator</w>
<w>dfuse</w>
<w>dirid</w>
<w>djdk</w>
<w>dokany</w>
<w>dragboard</w>
<w>easybind</w>
<w>encr</w>
<w>errorprone</w>
<w>failureaccess</w>
<w>fbidis</w>
<w>fldinst</w>
<w>fldrslt</w>
<w>fontawesomefx</w>
<w>gdrive</w>
<w>gvfs</w>
<w>hmmss</w>
<w>httpcomponents</w>
<w>httpcore</w>
<w>iclouddrive</w>
<w>jensd</w>
<w>jffi</w>
<w>keyloading</w>
<w>kibs</w>
<w>listcell</w>
<w>listenablefuture</w>
<w>lopp</w>
<w>mainwindow</w>
<w>masterkey</w>
<w>masterkeyfile</w>
<w>mibs</w>
<w>mountpath</w>
<w>mpc's</w>
<w>needsmigration</w>
<w>noncommercially</w>
<w>noël</w>
<w>nulab</w>
<w>oatomic</w>
<w>oauto</w>
<w>objectgraph</w>
<w>odefault</w>
<w>ogid</w>
<w>onoappledouble</w>
<w>ordonly</w>
<w>ouid</w>
<w>ovolname</w>
<w>passthrough</w>
<w>patreon</w>
<w>pcloud</w>
<w>probot</w>
<w>recoverykey</w>
<w>relicensing</w>
<w>removevault</w>
<w>revealer</w>
<w>serceman</w>
<w>setolabs</w>
<w>skymatic</w>
<w>socio</w>
<w>spof</w>
<w>stenzel</w>
<w>styleclass</w>
<w>sublicenses</w>
<w>sublicensing</w>
<w>systemkeychain</w>
<w>tada</w>
<w>tidelift</w>
<w>tmpmountpoint</w>
<w>tobiasdiez</w>
<w>toggler</w>
<w>traymenu</w>
<w>unknownerror</w>
<w>unlockable</w>
<w>vaultconfig</w>
<w>vaultlist</w>
<w>vaultname</w>
<w>vaultoptions</w>
<w>wrongfilealert</w>
<w>xattr</w>
<w>zillmann</w>
<w>zxcvbn</w>
</words>
</dictionary>
</component>
-13
View File
@@ -1,13 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding" defaultCharsetForPropertiesFiles="UTF-8">
<file url="file://$PROJECT_DIR$/main" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/main/commons/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/main/keychain/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/main/keychain/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/main/launcher/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/main/ui/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/main/ui/src/main/resources" charset="UTF-8" />
<file url="PROJECT" charset="UTF-8" />
</component>
</project>
+1 -1
View File
@@ -1,7 +1,7 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="SpellCheckingInspection" enabled="false" level="TYPO" enabled_by_default="false">
<inspection_tool class="SpellCheckingInspection" enabled="true" level="TYPO" enabled_by_default="true">
<option name="processCode" value="true" />
<option name="processLiterals" value="true" />
<option name="processComments" value="true" />
-30
View File
@@ -1,30 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RemoteRepositoriesConfiguration">
<remote-repository>
<option name="id" value="bintray" />
<option name="name" value="Bintray JCenter" />
<option name="url" value="https://jcenter.bintray.com" />
</remote-repository>
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Maven Central Repository" />
<option name="url" value="https://repo.maven.apache.org/maven2" />
</remote-repository>
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Maven Central repository" />
<option name="url" value="https://repo1.maven.org/maven2" />
</remote-repository>
<remote-repository>
<option name="id" value="jcenter" />
<option name="name" value="jcenter" />
<option name="url" value="https://jcenter.bintray.com" />
</remote-repository>
<remote-repository>
<option name="id" value="jboss.community" />
<option name="name" value="JBoss Community repository" />
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
</remote-repository>
</component>
</project>
+2 -2
View File
@@ -4,11 +4,11 @@
<component name="MavenProjectsManager">
<option name="originalFiles">
<list>
<option value="$PROJECT_DIR$/main/pom.xml" />
<option value="$PROJECT_DIR$/pom.xml" />
</list>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_14" default="false" project-jdk-name="14" project-jdk-type="JavaSDK">
<component name="ProjectRootManager" version="2" languageLevel="JDK_16" project-jdk-name="16" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>
-8
View File
@@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/Desktop.iml" filepath="$PROJECT_DIR$/.idea/Desktop.iml" />
</modules>
</component>
</project>
+2 -2
View File
@@ -1,8 +1,8 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Cryptomator Linux" type="Application" factoryName="Application">
<option name="MAIN_CLASS_NAME" value="org.cryptomator.launcher.Cryptomator" />
<module name="launcher" />
<option name="VM_PARAMETERS" value="-Djdk.gtk.version=2 -Duser.language=en -Dcryptomator.settingsPath=&quot;~/.config/Cryptomator/settings.json&quot; -Dcryptomator.ipcPortPath=&quot;~/.config/Cryptomator/ipcPort.bin&quot; -Dcryptomator.logDir=&quot;~/.local/share/Cryptomator/logs&quot; -Dcryptomator.mountPointsDir=&quot;~/.local/share/Cryptomator/mnt&quot; -Xss20m -Xmx512m" />
<module name="cryptomator" />
<option name="VM_PARAMETERS" value="-Djdk.gtk.version=2 -Duser.language=en -Dcryptomator.settingsPath=&quot;~/.config/Cryptomator/settings.json&quot; -Dcryptomator.ipcPortPath=&quot;~/.config/Cryptomator/ipcPort.bin&quot; -Dcryptomator.logDir=&quot;~/.local/share/Cryptomator/logs&quot; -Dcryptomator.mountPointsDir=&quot;~/.local/share/Cryptomator/mnt&quot; -Dcryptomator.showTrayIcon=true -Xss20m -Xmx512m" />
<method v="2">
<option name="Make" enabled="true" />
</method>
+10
View File
@@ -0,0 +1,10 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Cryptomator Linux Dev" type="Application" factoryName="Application">
<option name="MAIN_CLASS_NAME" value="org.cryptomator.launcher.Cryptomator" />
<module name="cryptomator" />
<option name="VM_PARAMETERS" value="-Djdk.gtk.version=2 -Duser.language=en -Dcryptomator.settingsPath=&quot;~/.config/Cryptomator-Dev/settings.json&quot; -Dcryptomator.ipcPortPath=&quot;~/.config/Cryptomator-Dev/ipcPort.bin&quot; -Dcryptomator.logDir=&quot;~/.local/share/Cryptomator-Dev/logs&quot; -Dcryptomator.mountPointsDir=&quot;~/.local/share/Cryptomator-Dev/mnt&quot; -Dcryptomator.showTrayIcon=true -Dfuse.experimental=&quot;true&quot; -Xss20m -Xmx512m" />
<method v="2">
<option name="Make" enabled="true" />
</method>
</configuration>
</component>
+2 -2
View File
@@ -1,8 +1,8 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Cryptomator Windows" type="Application" factoryName="Application">
<option name="MAIN_CLASS_NAME" value="org.cryptomator.launcher.Cryptomator" />
<module name="launcher" />
<option name="VM_PARAMETERS" value="-Duser.language=en -Dcryptomator.settingsPath=&quot;~/AppData/Roaming/Cryptomator/settings.json&quot; -Dcryptomator.ipcPortPath=&quot;~/AppData/Roaming/Cryptomator/ipcPort.bin&quot; -Dcryptomator.logDir=&quot;~/AppData/Roaming/Cryptomator&quot; -Dcryptomator.keychainPath=&quot;~/AppData/Roaming/Cryptomator/keychain.json&quot; -Xss2m -Xmx512m" />
<module name="cryptomator" />
<option name="VM_PARAMETERS" value="-Duser.language=en -Dcryptomator.settingsPath=&quot;~/AppData/Roaming/Cryptomator/settings.json&quot; -Dcryptomator.ipcPortPath=&quot;~/AppData/Roaming/Cryptomator/ipcPort.bin&quot; -Dcryptomator.logDir=&quot;~/AppData/Roaming/Cryptomator&quot; -Dcryptomator.keychainPath=&quot;~/AppData/Roaming/Cryptomator/keychain.json&quot; -Dcryptomator.mountPointsDir=&quot;~/Cryptomator&quot; -Dcryptomator.showTrayIcon=true -Xss2m -Xmx512m" />
<method v="2">
<option name="Make" enabled="true" />
</method>
+10
View File
@@ -0,0 +1,10 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Cryptomator Windows Dev" type="Application" factoryName="Application">
<option name="MAIN_CLASS_NAME" value="org.cryptomator.launcher.Cryptomator" />
<module name="cryptomator" />
<option name="VM_PARAMETERS" value="-Duser.language=en -Dcryptomator.settingsPath=&quot;~/AppData/Roaming/Cryptomator-Dev/settings.json&quot; -Dcryptomator.ipcPortPath=&quot;~/AppData/Roaming/Cryptomator-Dev/ipcPort.bin&quot; -Dcryptomator.logDir=&quot;~/AppData/Roaming/Cryptomator-Dev&quot; -Dcryptomator.keychainPath=&quot;~/AppData/Roaming/Cryptomator-Dev/keychain.json&quot; -Dcryptomator.mountPointsDir=&quot;~/Cryptomator-Dev&quot; -Dfuse.experimental=&quot;true&quot; -Dcryptomator.showTrayIcon=true -Xss2m -Xmx512m" />
<method v="2">
<option name="Make" enabled="true" />
</method>
</configuration>
</component>
+2 -3
View File
@@ -4,9 +4,8 @@
<env name="LD_LIBRARY_PATH" value="/usr/local/lib" />
</envs>
<option name="MAIN_CLASS_NAME" value="org.cryptomator.launcher.Cryptomator" />
<module name="launcher" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
<option name="VM_PARAMETERS" value="-Duser.language=en -Dcryptomator.settingsPath=&quot;~/Library/Application Support/Cryptomator/settings.json&quot; -Dcryptomator.ipcPortPath=&quot;~/Library/Application Support/Cryptomator/ipcPort.bin&quot; -Dcryptomator.logDir=&quot;~/Library/Logs/Cryptomator&quot; -Dcryptomator.mountPointsDir=&quot;/Volumes/&quot; -Xss2m -Xmx512m -ea" />
<module name="cryptomator" />
<option name="VM_PARAMETERS" value="-Duser.language=en -Dcryptomator.settingsPath=&quot;~/Library/Application Support/Cryptomator/settings.json&quot; -Dcryptomator.ipcPortPath=&quot;~/Library/Application Support/Cryptomator/ipcPort.bin&quot; -Dcryptomator.logDir=&quot;~/Library/Logs/Cryptomator&quot; -Dcryptomator.showTrayIcon=true -Xss2m -Xmx512m -ea" />
<method v="2">
<option name="Make" enabled="true" />
</method>
+13
View File
@@ -0,0 +1,13 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Cryptomator macOS Dev" type="Application" factoryName="Application">
<envs>
<env name="LD_LIBRARY_PATH" value="/usr/local/lib" />
</envs>
<option name="MAIN_CLASS_NAME" value="org.cryptomator.launcher.Cryptomator" />
<module name="cryptomator" />
<option name="VM_PARAMETERS" value="-Duser.language=en -Dcryptomator.settingsPath=&quot;~/Library/Application Support/Cryptomator-Dev/settings.json&quot; -Dcryptomator.ipcPortPath=&quot;~/Library/Application Support/Cryptomator-Dev/ipcPort.bin&quot; -Dcryptomator.logDir=&quot;~/Library/Logs/Cryptomator-Dev&quot; -Dcryptomator.showTrayIcon=true -Xss2m -Xmx512m -ea" />
<method v="2">
<option name="Make" enabled="true" />
</method>
</configuration>
</component>
+26 -9
View File
@@ -1,8 +1,8 @@
[![cryptomator](cryptomator.png)](https://cryptomator.org/)
[![Build](https://github.com/cryptomator/cryptomator/workflows/Build/badge.svg)](https://github.com/cryptomator/cryptomator/actions?query=workflow%3ABuild)
[![Known Vulnerabilities](https://snyk.io/test/github/cryptomator/cryptomator/badge.svg?targetFile=main%2Fpom.xml)](https://snyk.io/test/github/cryptomator/cryptomator?targetFile=main%2Fpom.xml)
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/2a0adf3cec6a4143b91035d3924178f1)](https://www.codacy.com/app/cryptomator/cryptomator?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=cryptomator/cryptomator&amp;utm_campaign=Badge_Grade)
[![Known Vulnerabilities](https://snyk.io/test/github/cryptomator/cryptomator/badge.svg)](https://snyk.io/test/github/cryptomator/cryptomator)
[![Codacy Badge](https://app.codacy.com/project/badge/Grade/2a0adf3cec6a4143b91035d3924178f1)](https://www.codacy.com/gh/cryptomator/cryptomator/dashboard)
[![Twitter](https://img.shields.io/badge/twitter-@Cryptomator-blue.svg?style=flat)](http://twitter.com/Cryptomator)
[![Crowdin](https://badges.crowdin.net/cryptomator/localized.svg)](https://translate.cryptomator.org/)
[![Latest Release](https://img.shields.io/github/release/cryptomator/cryptomator.svg)](https://github.com/cryptomator/cryptomator/releases/latest)
@@ -17,11 +17,26 @@ Cryptomator is provided free of charge as an open-source project despite the hig
### Gold Sponsors
[<img src="https://cryptomator.org/img/sponsors/geewhiz.svg" alt="gee-whiz" height="96">](https://www.gee-whiz.de/)
<table>
<tbody>
<tr>
<td><a href="https://www.gee-whiz.de/"><img src="https://cryptomator.org/img/sponsors/geewhiz.svg" alt="gee-whiz" height="80"></a></td>
<td><a href="https://proxy-hub.com/"><img src="https://cryptomator.org/img/sponsors/proxyhub.svg" alt="Proxy-Hub" height="80"></a></td>
</tr>
</tbody>
</table>
### Silver Sponsors
[![TheBestVPN](https://cryptomator.org/img/sponsors/thebestvpn.png)](https://thebestvpn.com/)
<table>
<tbody>
<tr>
<td><a href="https://thebestvpn.com/"><img src="https://cryptomator.org/img/sponsors/thebestvpn@2x.png" alt="TheBestVPN" height="64"></a></td>
</tr>
</tbody>
</table>
- [Jameson Lopp](https://www.lopp.net/)
---
@@ -33,7 +48,7 @@ Download native binaries of Cryptomator on [cryptomator.org](https://cryptomator
## Features
- Works with Dropbox, Google Drive, OneDrive, ownCloud, Nextcloud and any other cloud storage service which synchronizes with a local directory
- Works with Dropbox, Google Drive, OneDrive, MEGA, pCloud, ownCloud, Nextcloud and any other cloud storage service which 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
@@ -65,18 +80,20 @@ For more information on the security details visit [cryptomator.org](https://doc
### Dependencies
* JDK 14 (e.g. adoptopenjdk)
* JDK 16 (e.g. adoptopenjdk)
* 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), [Linux](https://github.com/cryptomator/builder-containers))
### Run Maven
```
cd main
mvn clean install -Prelease
mvn clean install
# or mvn clean install -Pwindows
# or mvn clean install -Pmac
# or mvn clean install -Plinux
```
This will build all the jars and bundle them together with their OS-specific dependencies under `main/buildkit/target`. This can now be used to build native packages.
This will build all the jars and bundle them together with their OS-specific dependencies under `target`. This can now be used to build native packages.
### Start Cryptomator
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<assembly xmlns="http://maven.apache.org/ASSEMBLY/2.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
<assembly xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/ASSEMBLY/2.0.0"
xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.0.0 http://maven.apache.org/xsd/assembly-2.0.0.xsd">
<id>tarball</id>
<includeBaseDirectory>false</includeBaseDirectory>
@@ -14,13 +14,6 @@
</includes>
<outputDirectory>libs</outputDirectory>
</fileSet>
<fileSet>
<directory>target/</directory>
<includes>
<include>ffi-version.txt</include>
</includes>
<outputDirectory>libs</outputDirectory>
</fileSet>
<fileSet>
<directory>target/</directory>
<includes>
@@ -37,14 +30,14 @@
<fileMode>0755</fileMode>
</fileSet>
<fileSet>
<directory>target/libs</directory>
<directory>target/</directory>
<includes>
<include>*.jar</include>
<include>cryptomator-*.jar</include>
</includes>
<outputDirectory>libs</outputDirectory>
</fileSet>
<fileSet>
<directory>target/linux-libs</directory>
<directory>target/libs</directory>
<includes>
<include>*.jar</include>
</includes>
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<assembly xmlns="http://maven.apache.org/ASSEMBLY/2.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
<assembly xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/ASSEMBLY/2.0.0"
xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.0.0 http://maven.apache.org/xsd/assembly-2.0.0.xsd">
<id>tarball</id>
<includeBaseDirectory>false</includeBaseDirectory>
@@ -14,13 +14,6 @@
</includes>
<outputDirectory>libs</outputDirectory>
</fileSet>
<fileSet>
<directory>target/</directory>
<includes>
<include>ffi-version.txt</include>
</includes>
<outputDirectory>libs</outputDirectory>
</fileSet>
<fileSet>
<directory>target/</directory>
<includes>
@@ -37,14 +30,14 @@
<fileMode>0755</fileMode>
</fileSet>
<fileSet>
<directory>target/libs</directory>
<directory>target/</directory>
<includes>
<include>*.jar</include>
<include>cryptomator-*.jar</include>
</includes>
<outputDirectory>libs</outputDirectory>
</fileSet>
<fileSet>
<directory>target/mac-libs</directory>
<directory>target/libs</directory>
<includes>
<include>*.jar</include>
</includes>
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<assembly xmlns="http://maven.apache.org/ASSEMBLY/2.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
<assembly xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/ASSEMBLY/2.0.0"
xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.0.0 http://maven.apache.org/xsd/assembly-2.0.0.xsd">
<id>tarball</id>
<includeBaseDirectory>false</includeBaseDirectory>
@@ -14,13 +14,6 @@
</includes>
<outputDirectory>libs</outputDirectory>
</fileSet>
<fileSet>
<directory>target/</directory>
<includes>
<include>ffi-version.txt</include>
</includes>
<outputDirectory>libs</outputDirectory>
</fileSet>
<fileSet>
<directory>target/</directory>
<includes>
@@ -37,14 +30,14 @@
<fileMode>0755</fileMode>
</fileSet>
<fileSet>
<directory>target/libs</directory>
<directory>target/</directory>
<includes>
<include>*.jar</include>
<include>cryptomator-*.jar</include>
</includes>
<outputDirectory>libs</outputDirectory>
</fileSet>
<fileSet>
<directory>target/win-libs</directory>
<directory>target/libs</directory>
<includes>
<include>*.jar</include>
</includes>
-174
View File
@@ -1,174 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<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.5.6</version>
</parent>
<artifactId>buildkit</artifactId>
<packaging>pom</packaging>
<name>Cryptomator Build Kit</name>
<description>Builds a package that can be built with Ant locally</description>
<dependencies>
<dependency>
<groupId>org.cryptomator</groupId>
<artifactId>launcher</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<!-- copy resources -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<id>copy-resources</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}</outputDirectory>
<resources>
<resource>
<directory>${project.basedir}/src/main/resources</directory>
<includes>
<include>version.txt</include>
<include>ffi-version.txt</include>
<include>launcher-mac.sh</include>
<include>launcher-linux.sh</include>
<include>launcher-win.bat</include>
<include>LICENSE.txt</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
<!-- copy libraries to target/libs/: -->
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.1.1</version>
<executions>
<execution>
<id>copy-libs</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/libs</outputDirectory>
<excludeClassifiers>linux,mac,win</excludeClassifiers>
<excludeArtifactIds>dbus-java,secret-service,hkdf,java-utils</excludeArtifactIds>
</configuration>
</execution>
<execution>
<id>copy-linux-libs</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/linux-libs</outputDirectory>
<includeGroupIds>org.openjfx</includeGroupIds>
<classifier>linux</classifier>
</configuration>
</execution>
<execution>
<id>copy-linux-secret-service</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/linux-libs</outputDirectory>
<includeArtifactIds>dbus-java,secret-service,hkdf,java-utils</includeArtifactIds>
</configuration>
</execution>
<execution>
<id>copy-mac-libs</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/mac-libs</outputDirectory>
<includeGroupIds>org.openjfx</includeGroupIds>
<classifier>mac</classifier>
</configuration>
</execution>
<execution>
<id>copy-win-libs</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/win-libs</outputDirectory>
<includeGroupIds>org.openjfx</includeGroupIds>
<classifier>win</classifier>
</configuration>
</execution>
</executions>
</plugin>
<!-- create buildkit.zip: -->
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.1.1</version>
<executions>
<execution>
<id>assemble-linux</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptors>
<descriptor>assembly-linux.xml</descriptor>
</descriptors>
<appendAssemblyId>false</appendAssemblyId>
<finalName>buildkit-linux</finalName>
</configuration>
</execution>
<execution>
<id>assemble-mac</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptors>
<descriptor>assembly-mac.xml</descriptor>
</descriptors>
<appendAssemblyId>false</appendAssemblyId>
<finalName>buildkit-mac</finalName>
</configuration>
</execution>
<execution>
<id>assemble-win</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptors>
<descriptor>assembly-win.xml</descriptor>
</descriptors>
<appendAssemblyId>false</appendAssemblyId>
<finalName>buildkit-win</finalName>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
@@ -1 +0,0 @@
${cryptomator.jni.version}
-86
View File
@@ -1,86 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<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.5.6</version>
</parent>
<artifactId>commons</artifactId>
<name>Cryptomator Commons</name>
<description>Shared utilities</description>
<dependencies>
<dependency>
<groupId>org.cryptomator</groupId>
<artifactId>cryptofs</artifactId>
</dependency>
<dependency>
<groupId>org.cryptomator</groupId>
<artifactId>fuse-nio-adapter</artifactId>
</dependency>
<dependency>
<groupId>org.cryptomator</groupId>
<artifactId>dokany-nio-adapter</artifactId>
</dependency>
<dependency>
<groupId>org.cryptomator</groupId>
<artifactId>webdav-nio-adapter</artifactId>
</dependency>
<dependency>
<groupId>org.cryptomator</groupId>
<artifactId>jni</artifactId>
</dependency>
<!-- JavaFx -->
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-base</artifactId>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-graphics</artifactId>
</dependency>
<!-- EasyBind -->
<dependency>
<groupId>org.fxmisc.easybind</groupId>
<artifactId>easybind</artifactId>
</dependency>
<!-- JWT -->
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
</dependency>
<!-- Google -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
</dependency>
<!-- Apache Commons -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<!-- DI -->
<dependency>
<groupId>com.google.dagger</groupId>
<artifactId>dagger</artifactId>
</dependency>
<!-- Logging -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
@@ -1,7 +0,0 @@
package org.cryptomator.common;
public interface Constants {
String MASTERKEY_FILENAME = "masterkey.cryptomator";
}
@@ -1,32 +0,0 @@
/*******************************************************************************
* Copyright (c) 2019 Skymatic GmbH.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the accompanying LICENSE file.
*******************************************************************************/
package org.cryptomator.common;
import dagger.Module;
import dagger.Provides;
import org.cryptomator.jni.JniFunctions;
import org.cryptomator.jni.MacFunctions;
import org.cryptomator.jni.WinFunctions;
import javax.inject.Singleton;
import java.util.Optional;
@Module
public class JniModule {
@Provides
@Singleton
Optional<MacFunctions> provideOptionalMacFunctions() {
return JniFunctions.macFunctions();
}
@Provides
@Singleton
Optional<WinFunctions> provideOptionalWinFunctions() {
return JniFunctions.winFunctions();
}
}
@@ -1,79 +0,0 @@
/*******************************************************************************
* Copyright (c) 2017 Skymatic UG (haftungsbeschränkt).
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the accompanying LICENSE file.
*******************************************************************************/
package org.cryptomator.common;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Supplier;
import java.util.function.UnaryOperator;
import com.google.common.base.Throwables;
public final class LazyInitializer {
private LazyInitializer() {
}
/**
* Same as {@link #initializeLazily(AtomicReference, SupplierThrowingException, Class)} except that no checked exception may be thrown by the factory function.
*
* @param <T> Type of the value
* @param reference A reference to a maybe not yet initialized value.
* @param factory A factory providing a value for the reference, if it doesn't exist yet. The factory may be invoked multiple times, but only one result will survive.
* @return The initialized value
*/
public static <T> T initializeLazily(AtomicReference<T> reference, Supplier<T> factory) {
SupplierThrowingException<T, RuntimeException> factoryThrowingRuntimeExceptions = () -> factory.get();
return initializeLazily(reference, factoryThrowingRuntimeExceptions, RuntimeException.class);
}
/**
* Threadsafe lazy initialization pattern as proposed on http://stackoverflow.com/a/30247202/4014509
*
* @param <T> Type of the value
* @param <E> Type of the any expected exception that may occur during initialization
* @param reference A reference to a maybe not yet initialized value.
* @param factory A factory providing a value for the reference, if it doesn't exist yet. The factory may be invoked multiple times, but only one result will survive.
* @param exceptionType Expected exception type.
* @return The initialized value
* @throws E Exception thrown by the factory function.
*/
public static <T, E extends Exception> T initializeLazily(AtomicReference<T> reference, SupplierThrowingException<T, E> factory, Class<E> exceptionType) throws E {
final T existing = reference.get();
if (existing != null) {
return existing;
} else {
try {
return reference.updateAndGet(invokeFactoryIfNull(factory));
} catch (InitializationException e) {
Throwables.throwIfUnchecked(e.getCause());
Throwables.throwIfInstanceOf(e.getCause(), exceptionType);
throw e;
}
}
}
private static <T, E extends Exception> UnaryOperator<T> invokeFactoryIfNull(SupplierThrowingException<T, E> factory) throws InitializationException {
return currentValue -> {
if (currentValue == null) {
try {
return factory.get();
} catch (Exception e) {
throw new InitializationException(e);
}
} else {
return currentValue;
}
};
}
private static class InitializationException extends RuntimeException {
public InitializationException(Throwable cause) {
super(cause);
}
}
}
@@ -1,18 +0,0 @@
package org.cryptomator.common.settings;
public enum UiTheme {
LIGHT("preferences.general.theme.light"),
DARK("preferences.general.theme.dark");
// CUSTOM("Custom (%s)");
private String displayName;
UiTheme(String displayName) {
this.displayName = displayName;
}
public String getDisplayName() {
return displayName;
}
}
@@ -1,112 +0,0 @@
package org.cryptomator.common.vaults;
import com.google.common.base.Strings;
import org.cryptomator.common.settings.VaultSettings;
import org.cryptomator.cryptofs.CryptoFileSystem;
import org.cryptomator.frontend.dokany.Mount;
import org.cryptomator.frontend.dokany.MountFactory;
import org.cryptomator.frontend.dokany.MountFailedException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.inject.Inject;
import java.io.IOException;
import java.nio.file.DirectoryNotEmptyException;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.NotDirectoryException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Optional;
import java.util.concurrent.ExecutorService;
public class DokanyVolume implements Volume {
private static final Logger LOG = LoggerFactory.getLogger(DokanyVolume.class);
private static final String FS_TYPE_NAME = "Cryptomator File System";
private final VaultSettings vaultSettings;
private final MountFactory mountFactory;
private final WindowsDriveLetters windowsDriveLetters;
private Mount mount;
private Path mountPoint;
@Inject
public DokanyVolume(VaultSettings vaultSettings, ExecutorService executorService, WindowsDriveLetters windowsDriveLetters) {
this.vaultSettings = vaultSettings;
this.mountFactory = new MountFactory(executorService);
this.windowsDriveLetters = windowsDriveLetters;
}
@Override
public boolean isSupported() {
return DokanyVolume.isSupportedStatic();
}
@Override
public void mount(CryptoFileSystem fs, String mountFlags) throws VolumeException, IOException {
this.mountPoint = determineMountPoint();
String mountName = vaultSettings.mountName().get();
try {
this.mount = mountFactory.mount(fs.getPath("/"), mountPoint, mountName, FS_TYPE_NAME, mountFlags.strip());
} catch (MountFailedException e) {
if (vaultSettings.getCustomMountPath().isPresent()) {
LOG.warn("Failed to mount vault into {}. Is this directory currently accessed by another process (e.g. Windows Explorer)?", mountPoint);
}
throw new VolumeException("Unable to mount Filesystem", e);
}
}
private Path determineMountPoint() throws VolumeException, IOException {
Optional<String> optionalCustomMountPoint = vaultSettings.getCustomMountPath();
if (optionalCustomMountPoint.isPresent()) {
Path customMountPoint = Paths.get(optionalCustomMountPoint.get());
checkProvidedMountPoint(customMountPoint);
return customMountPoint;
} else if (!Strings.isNullOrEmpty(vaultSettings.winDriveLetter().get())) {
return Path.of(vaultSettings.winDriveLetter().get().charAt(0) + ":\\");
} else {
//auto assign drive letter
if (!windowsDriveLetters.getAvailableDriveLetters().isEmpty()) {
return Path.of(windowsDriveLetters.getAvailableDriveLetters().iterator().next() + ":\\");
} else {
//TODO: Error Handling
throw new VolumeException("No free drive letter available.");
}
}
}
private void checkProvidedMountPoint(Path mountPoint) throws IOException {
if (!Files.isDirectory(mountPoint)) {
throw new NotDirectoryException(mountPoint.toString());
}
try (DirectoryStream<Path> ds = Files.newDirectoryStream(mountPoint)) {
if (ds.iterator().hasNext()) {
throw new DirectoryNotEmptyException(mountPoint.toString());
}
}
}
@Override
public void reveal() throws VolumeException {
boolean success = mount.reveal();
if (!success) {
throw new VolumeException("Reveal failed.");
}
}
@Override
public void unmount() {
mount.close();
}
@Override
public Optional<Path> getMountPoint() {
return Optional.ofNullable(mountPoint);
}
public static boolean isSupportedStatic() {
return MountFactory.isApplicable();
}
}
@@ -1,177 +0,0 @@
package org.cryptomator.common.vaults;
import com.google.common.base.Splitter;
import org.apache.commons.lang3.SystemUtils;
import org.cryptomator.common.Environment;
import org.cryptomator.common.settings.VaultSettings;
import org.cryptomator.cryptofs.CryptoFileSystem;
import org.cryptomator.frontend.fuse.mount.CommandFailedException;
import org.cryptomator.frontend.fuse.mount.EnvironmentVariables;
import org.cryptomator.frontend.fuse.mount.FuseMountFactory;
import org.cryptomator.frontend.fuse.mount.FuseNotSupportedException;
import org.cryptomator.frontend.fuse.mount.Mount;
import org.cryptomator.frontend.fuse.mount.Mounter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.inject.Inject;
import java.io.IOException;
import java.nio.file.DirectoryNotEmptyException;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.NotDirectoryException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Optional;
public class FuseVolume implements Volume {
private static final Logger LOG = LoggerFactory.getLogger(FuseVolume.class);
private static final int MAX_TMPMOUNTPOINT_CREATION_RETRIES = 10;
private static final boolean IS_MAC = System.getProperty("os.name").toLowerCase().contains("mac");
private final VaultSettings vaultSettings;
private final Environment environment;
private Mount fuseMnt;
private Path mountPoint;
private boolean createdTemporaryMountPoint;
@Inject
public FuseVolume(VaultSettings vaultSettings, Environment environment) {
this.vaultSettings = vaultSettings;
this.environment = environment;
}
@Override
public void mount(CryptoFileSystem fs, String mountFlags) throws IOException, FuseNotSupportedException, VolumeException {
Optional<String> optionalCustomMountPoint = vaultSettings.getCustomMountPath();
if (optionalCustomMountPoint.isPresent()) {
Path customMountPoint = Paths.get(optionalCustomMountPoint.get());
checkProvidedMountPoint(customMountPoint);
this.mountPoint = customMountPoint;
LOG.debug("Successfully checked custom mount point: {}", mountPoint);
} else {
this.mountPoint = prepareTemporaryMountPoint();
LOG.debug("Successfully created mount point: {}", mountPoint);
}
mount(fs.getPath("/"), mountFlags);
}
private void checkProvidedMountPoint(Path mountPoint) throws IOException {
if (!Files.isDirectory(mountPoint)) {
throw new NotDirectoryException(mountPoint.toString());
}
try (DirectoryStream<Path> ds = Files.newDirectoryStream(mountPoint)) {
if (ds.iterator().hasNext()) {
throw new DirectoryNotEmptyException(mountPoint.toString());
}
}
}
private Path prepareTemporaryMountPoint() throws IOException, VolumeException {
Path mountPoint = chooseNonExistingTemporaryMountPoint();
// https://github.com/osxfuse/osxfuse/issues/306#issuecomment-245114592:
// In order to allow non-admin users to mount FUSE volumes in `/Volumes`,
// starting with version 3.5.0, FUSE will create non-existent mount points automatically.
if (IS_MAC && mountPoint.getParent().equals(Paths.get("/Volumes"))) {
return mountPoint;
} else {
Files.createDirectories(mountPoint);
this.createdTemporaryMountPoint = true;
return mountPoint;
}
}
private Path chooseNonExistingTemporaryMountPoint() throws VolumeException {
Path parent = environment.getMountPointsDir().orElseThrow();
String basename = vaultSettings.getId();
for (int i = 0; i < MAX_TMPMOUNTPOINT_CREATION_RETRIES; i++) {
Path mountPoint = parent.resolve(basename + "_" + i);
if (Files.notExists(mountPoint)) {
return mountPoint;
}
}
LOG.error("Failed to find feasible mountpoint at {}/{}_x. Giving up after {} attempts.", parent, basename, MAX_TMPMOUNTPOINT_CREATION_RETRIES);
throw new VolumeException("Did not find feasible mount point.");
}
private void mount(Path root, String mountFlags) throws VolumeException {
try {
Mounter mounter = FuseMountFactory.getMounter();
EnvironmentVariables envVars = EnvironmentVariables.create() //
.withFlags(splitFlags(mountFlags)).withMountPoint(mountPoint) //
.build();
this.fuseMnt = mounter.mount(root, envVars);
} catch (CommandFailedException e) {
throw new VolumeException("Unable to mount Filesystem", e);
}
}
private String[] splitFlags(String str) {
return Splitter.on(' ').splitToList(str).toArray(String[]::new);
}
@Override
public void reveal() throws VolumeException {
try {
fuseMnt.revealInFileManager();
} catch (CommandFailedException e) {
LOG.debug("Revealing the vault in file manger failed: " + e.getMessage());
throw new VolumeException(e);
}
}
@Override
public boolean supportsForcedUnmount() {
return true;
}
@Override
public synchronized void unmountForced() throws VolumeException {
try {
fuseMnt.unmountForced();
fuseMnt.close();
} catch (CommandFailedException e) {
throw new VolumeException(e);
}
cleanupTemporaryMountPoint();
}
@Override
public synchronized void unmount() throws VolumeException {
try {
fuseMnt.unmount();
fuseMnt.close();
} catch (CommandFailedException e) {
throw new VolumeException(e);
}
cleanupTemporaryMountPoint();
}
private void cleanupTemporaryMountPoint() {
if (createdTemporaryMountPoint) {
try {
Files.delete(mountPoint);
LOG.debug("Successfully deleted mount point: {}", mountPoint);
} catch (IOException e) {
LOG.warn("Could not delete mount point: {}", e.getMessage());
}
}
}
@Override
public boolean isSupported() {
return FuseVolume.isSupportedStatic();
}
@Override
public Optional<Path> getMountPoint() {
return Optional.ofNullable(mountPoint);
}
public static boolean isSupportedStatic() {
return (SystemUtils.IS_OS_MAC_OSX || SystemUtils.IS_OS_LINUX) && FuseMountFactory.isFuseSupported();
}
}
@@ -1,34 +0,0 @@
package org.cryptomator.common.vaults;
public enum VaultState {
/**
* No vault found at the provided path
*/
MISSING,
/**
* Vault requires migration to a newer vault format
*/
NEEDS_MIGRATION,
/**
* Vault ready to be unlocked
*/
LOCKED,
/**
* Vault in transition between two other states
*/
PROCESSING,
/**
* Vault is unlocked
*/
UNLOCKED,
/**
* Unknown state due to preceeding unrecoverable exceptions.
*/
ERROR;
}
@@ -1,97 +0,0 @@
package org.cryptomator.common.vaults;
import javafx.application.Platform;
import javafx.beans.Observable;
import javafx.beans.property.LongProperty;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleLongProperty;
import javafx.concurrent.ScheduledService;
import javafx.concurrent.Task;
import javafx.util.Duration;
import org.cryptomator.cryptofs.CryptoFileSystem;
import org.cryptomator.cryptofs.CryptoFileSystemStats;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.inject.Inject;
import java.util.Optional;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.atomic.AtomicReference;
@PerVault
public class VaultStats {
private static final Logger LOG = LoggerFactory.getLogger(VaultStats.class);
private final AtomicReference<CryptoFileSystem> fs;
private final ObjectProperty<VaultState> state;
private final ScheduledService<Optional<CryptoFileSystemStats>> updateService;
private final LongProperty bytesPerSecondRead = new SimpleLongProperty();
private final LongProperty bytesPerSecondWritten = new SimpleLongProperty();
@Inject
VaultStats(AtomicReference<CryptoFileSystem> fs, ObjectProperty<VaultState> state, ExecutorService executor) {
this.fs = fs;
this.state = state;
this.updateService = new UpdateStatsService();
updateService.setExecutor(executor);
updateService.setPeriod(Duration.seconds(1));
state.addListener(this::vaultStateChanged);
}
private void vaultStateChanged(@SuppressWarnings("unused") Observable observable) {
if (VaultState.UNLOCKED.equals(state.get())) {
assert fs.get() != null;
LOG.debug("start recording stats");
updateService.restart();
} else {
LOG.debug("stop recording stats");
updateService.cancel();
}
}
private void updateStats(Optional<CryptoFileSystemStats> stats) {
assert Platform.isFxApplicationThread();
bytesPerSecondRead.set(stats.map(CryptoFileSystemStats::pollBytesRead).orElse(0l));
bytesPerSecondWritten.set(stats.map(CryptoFileSystemStats::pollBytesWritten).orElse(0l));
}
private class UpdateStatsService extends ScheduledService<Optional<CryptoFileSystemStats>> {
@Override
protected Task<Optional<CryptoFileSystemStats>> createTask() {
return new Task<>() {
@Override
protected Optional<CryptoFileSystemStats> call() {
return Optional.ofNullable(fs.get()).map(CryptoFileSystem::getStats);
}
};
}
@Override
protected void succeeded() {
assert getValue() != null;
updateStats(getValue());
super.succeeded();
}
}
/* Observables */
public LongProperty bytesPerSecondReadProperty() {
return bytesPerSecondRead;
}
public long getBytesPerSecondRead() {
return bytesPerSecondRead.get();
}
public LongProperty bytesPerSecondWrittenProperty() {
return bytesPerSecondWritten;
}
public long getBytesPerSecondWritten() {
return bytesPerSecondWritten.get();
}
}
@@ -1,62 +0,0 @@
/*******************************************************************************
* Copyright (c) 2017 Skymatic UG (haftungsbeschränkt).
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the accompanying LICENSE file.
*******************************************************************************/
package org.cryptomator.common.settings;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;
import org.hamcrest.CoreMatchers;
import org.hamcrest.MatcherAssert;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import java.nio.file.Paths;
public class VaultSettingsJsonAdapterTest {
private final VaultSettingsJsonAdapter adapter = new VaultSettingsJsonAdapter();
@Test
public void testDeserialize() throws IOException {
String json = "{\"id\": \"foo\", \"path\": \"/foo/bar\", \"mountName\": \"test\", \"winDriveLetter\": \"X\", \"shouldBeIgnored\": true, \"individualMountPath\": \"/home/test/crypto\", \"mountFlags\":\"--foo --bar\"}";
JsonReader jsonReader = new JsonReader(new StringReader(json));
VaultSettings vaultSettings = adapter.read(jsonReader);
Assertions.assertEquals("foo", vaultSettings.getId());
Assertions.assertEquals(Paths.get("/foo/bar"), vaultSettings.path().get());
Assertions.assertEquals("test", vaultSettings.mountName().get());
Assertions.assertEquals("X", vaultSettings.winDriveLetter().get());
Assertions.assertEquals("/home/test/crypto", vaultSettings.customMountPath().get());
Assertions.assertEquals("--foo --bar", vaultSettings.mountFlags().get());
}
@Test
public void testSerialize() throws IOException {
VaultSettings vaultSettings = new VaultSettings("test");
vaultSettings.path().set(Paths.get("/foo/bar"));
vaultSettings.mountName().set("mountyMcMountFace");
vaultSettings.mountFlags().set("--foo --bar");
StringWriter buf = new StringWriter();
JsonWriter jsonWriter = new JsonWriter(buf);
adapter.write(jsonWriter, vaultSettings);
String result = buf.toString();
MatcherAssert.assertThat(result, CoreMatchers.containsString("\"id\":\"test\""));
if(System.getProperty("os.name").contains("Windows")){
MatcherAssert.assertThat(result, CoreMatchers.containsString("\"path\":\"\\\\foo\\\\bar\""));
} else {
MatcherAssert.assertThat(result, CoreMatchers.containsString("\"path\":\"/foo/bar\""));
}
MatcherAssert.assertThat(result, CoreMatchers.containsString("\"mountName\":\"mountyMcMountFace\""));
MatcherAssert.assertThat(result, CoreMatchers.containsString("\"mountFlags\":\"--foo --bar\""));
}
}
-63
View File
@@ -1,63 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<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.5.6</version>
</parent>
<artifactId>keychain</artifactId>
<name>System Keychain Access</name>
<dependencies>
<dependency>
<groupId>org.cryptomator</groupId>
<artifactId>commons</artifactId>
</dependency>
<!-- JavaFx -->
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-base</artifactId>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-graphics</artifactId>
</dependency>
<!-- Apache -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<!-- Google -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
<!-- DI -->
<dependency>
<groupId>com.google.dagger</groupId>
<artifactId>dagger</artifactId>
</dependency>
<!-- secret-service lib -->
<dependency>
<groupId>de.swiesend</groupId>
<artifactId>secret-service</artifactId>
</dependency>
<!-- Logging -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
@@ -1,12 +0,0 @@
package org.cryptomator.keychain;
/**
* Indicates an error during communication with the operating system's keychain.
*/
public class KeychainAccessException extends Exception {
KeychainAccessException(Throwable cause) {
super(cause);
}
}
@@ -1,46 +0,0 @@
/*******************************************************************************
* Copyright (c) 2017 Skymatic UG (haftungsbeschränkt).
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the accompanying LICENSE file.
*******************************************************************************/
package org.cryptomator.keychain;
interface KeychainAccessStrategy {
/**
* Associates a passphrase with a given key.
*
* @param key Key used to retrieve the passphrase via {@link #loadPassphrase(String)}.
* @param passphrase The secret to store in this keychain.
*/
void storePassphrase(String key, CharSequence passphrase) throws KeychainAccessException;
/**
* @param key Unique key previously used while {@link #storePassphrase(String, CharSequence) storing a passphrase}.
* @return The stored passphrase for the given key or <code>null</code> if no value for the given key could be found.
*/
char[] loadPassphrase(String key) throws KeychainAccessException;
/**
* Deletes a passphrase with a given key.
*
* @param key Unique key previously used while {@link #storePassphrase(String, CharSequence) storing a passphrase}.
*/
void deletePassphrase(String key) throws KeychainAccessException;
/**
* Updates a passphrase with a given key. Noop, if there is no item for the given key.
*
* @param key Unique key previously used while {@link #storePassphrase(String, CharSequence) storing a passphrase}.
* @param passphrase The secret to be updated in this keychain.
*/
void changePassphrase(String key, CharSequence passphrase) throws KeychainAccessException;
/**
* @return <code>true</code> if this KeychainAccessStrategy works on the current machine.
* @implNote This method must not throw any exceptions and should fail fast
* returning <code>false</code> if it can't determine availability of the checked strategy
*/
boolean isSupported();
}
@@ -1,45 +0,0 @@
/*******************************************************************************
* Copyright (c) 2017 Skymatic UG (haftungsbeschränkt).
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the accompanying LICENSE file.
*******************************************************************************/
package org.cryptomator.keychain;
import dagger.Binds;
import dagger.Module;
import dagger.Provides;
import dagger.multibindings.IntoSet;
import org.cryptomator.common.JniModule;
import javax.inject.Singleton;
import java.util.Optional;
import java.util.Set;
@Module(includes = {JniModule.class})
public abstract class KeychainModule {
@Binds
@IntoSet
abstract KeychainAccessStrategy bindMacSystemKeychainAccess(MacSystemKeychainAccess keychainAccessStrategy);
@Binds
@IntoSet
abstract KeychainAccessStrategy bindWindowsProtectedKeychainAccess(WindowsProtectedKeychainAccess keychainAccessStrategy);
@Binds
@IntoSet
abstract KeychainAccessStrategy bindLinuxSecretServiceKeychainAccess(LinuxSecretServiceKeychainAccess keychainAccessStrategy);
@Provides
@Singleton
static Optional<KeychainAccessStrategy> provideSupportedKeychain(Set<KeychainAccessStrategy> keychainAccessStrategies) {
return keychainAccessStrategies.stream().filter(KeychainAccessStrategy::isSupported).findFirst();
}
@Provides
@Singleton
public static Optional<KeychainManager> provideKeychainManager(Optional<KeychainAccessStrategy> keychainAccess) {
return keychainAccess.map(KeychainManager::new);
}
}
@@ -1,58 +0,0 @@
package org.cryptomator.keychain;
import org.apache.commons.lang3.SystemUtils;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.util.Optional;
/**
* A facade to LinuxSecretServiceKeychainAccessImpl that doesn't depend on libraries that are unavailable on Mac and Windows.
*/
@Singleton
public class LinuxSecretServiceKeychainAccess implements KeychainAccessStrategy {
// the actual implementation is hidden in this delegate object which is loaded via reflection,
// as it depends on libraries that aren't necessarily available:
private final Optional<KeychainAccessStrategy> delegate;
@Inject
public LinuxSecretServiceKeychainAccess() {
this.delegate = constructGnomeKeyringKeychainAccess();
}
private static Optional<KeychainAccessStrategy> constructGnomeKeyringKeychainAccess() {
try {
Class<?> clazz = Class.forName("org.cryptomator.keychain.LinuxSecretServiceKeychainAccessImpl");
KeychainAccessStrategy instance = (KeychainAccessStrategy) clazz.getDeclaredConstructor().newInstance();
return Optional.of(instance);
} catch (Exception e) {
return Optional.empty();
}
}
@Override
public boolean isSupported() {
return SystemUtils.IS_OS_LINUX && delegate.map(KeychainAccessStrategy::isSupported).orElse(false);
}
@Override
public void storePassphrase(String key, CharSequence passphrase) throws KeychainAccessException {
delegate.orElseThrow(IllegalStateException::new).storePassphrase(key, passphrase);
}
@Override
public char[] loadPassphrase(String key) throws KeychainAccessException {
return delegate.orElseThrow(IllegalStateException::new).loadPassphrase(key);
}
@Override
public void deletePassphrase(String key) throws KeychainAccessException {
delegate.orElseThrow(IllegalStateException::new).deletePassphrase(key);
}
@Override
public void changePassphrase(String key, CharSequence passphrase) throws KeychainAccessException {
delegate.orElseThrow(IllegalStateException::new).changePassphrase(key, passphrase);
}
}
@@ -1,79 +0,0 @@
package org.cryptomator.keychain;
import org.freedesktop.secret.simple.SimpleCollection;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
class LinuxSecretServiceKeychainAccessImpl implements KeychainAccessStrategy {
private final String LABEL_FOR_SECRET_IN_KEYRING = "Cryptomator";
@Override
public boolean isSupported() {
try (@SuppressWarnings("unused") SimpleCollection keyring = new SimpleCollection()) {
// seems like we're able to access the keyring.
return true;
} catch (IOException | RuntimeException e) {
return false;
}
}
@Override
public void storePassphrase(String key, CharSequence passphrase) throws KeychainAccessException {
try (SimpleCollection keyring = new SimpleCollection()) {
List<String> list = keyring.getItems(createAttributes(key));
if (list == null) {
keyring.createItem(LABEL_FOR_SECRET_IN_KEYRING, passphrase, createAttributes(key));
}
} catch (IOException e) {
throw new KeychainAccessException(e);
}
}
@Override
public char[] loadPassphrase(String key) throws KeychainAccessException {
try (SimpleCollection keyring = new SimpleCollection()) {
List<String> list = keyring.getItems(createAttributes(key));
if (list != null) {
return keyring.getSecret(list.get(0));
} else {
return null;
}
} catch (IOException e) {
throw new KeychainAccessException(e);
}
}
@Override
public void deletePassphrase(String key) throws KeychainAccessException {
try (SimpleCollection keyring = new SimpleCollection()) {
List<String> list = keyring.getItems(createAttributes(key));
if (list != null) {
keyring.deleteItem(list.get(0));
}
} catch (IOException e) {
throw new KeychainAccessException(e);
}
}
@Override
public void changePassphrase(String key, CharSequence passphrase) throws KeychainAccessException {
try (SimpleCollection keyring = new SimpleCollection()) {
List<String> list = keyring.getItems(createAttributes(key));
if (list != null) {
keyring.updateItem(list.get(0), LABEL_FOR_SECRET_IN_KEYRING, passphrase, createAttributes(key));
}
} catch (IOException e) {
throw new KeychainAccessException(e);
}
}
private Map<String, String> createAttributes(String key) {
Map<String, String> attributes = new HashMap();
attributes.put("Vault", key);
return attributes;
}
}
@@ -1,58 +0,0 @@
/*******************************************************************************
* Copyright (c) 2017 Skymatic UG (haftungsbeschränkt).
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the accompanying LICENSE file.
*******************************************************************************/
package org.cryptomator.keychain;
import java.util.Optional;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.apache.commons.lang3.SystemUtils;
import org.cryptomator.jni.MacFunctions;
import org.cryptomator.jni.MacKeychainAccess;
@Singleton
class MacSystemKeychainAccess implements KeychainAccessStrategy {
private final Optional<MacFunctions> macFunctions;
@Inject
public MacSystemKeychainAccess(Optional<MacFunctions> macFunctions) {
this.macFunctions = macFunctions;
}
private MacKeychainAccess keychain() {
return macFunctions.orElseThrow(IllegalStateException::new).keychainAccess();
}
@Override
public void storePassphrase(String key, CharSequence passphrase) {
keychain().storePassword(key, passphrase);
}
@Override
public char[] loadPassphrase(String key) {
return keychain().loadPassword(key);
}
@Override
public boolean isSupported() {
return SystemUtils.IS_OS_MAC_OSX && macFunctions.isPresent();
}
@Override
public void deletePassphrase(String key) {
keychain().deletePassword(key);
}
@Override
public void changePassphrase(String key, CharSequence passphrase) {
if (keychain().deletePassword(key)) {
keychain().storePassword(key, passphrase);
}
}
}
@@ -1,209 +0,0 @@
/*******************************************************************************
* Copyright (c) 2017 Skymatic UG (haftungsbeschränkt).
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the accompanying LICENSE file.
*******************************************************************************/
package org.cryptomator.keychain;
import com.google.common.io.BaseEncoding;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import com.google.gson.annotations.SerializedName;
import com.google.gson.reflect.TypeToken;
import org.apache.commons.lang3.SystemUtils;
import org.cryptomator.common.Environment;
import org.cryptomator.jni.WinDataProtection;
import org.cryptomator.jni.WinFunctions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.UncheckedIOException;
import java.io.Writer;
import java.lang.reflect.Type;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.file.Files;
import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;
import java.util.stream.Collectors;
import static java.nio.charset.StandardCharsets.UTF_8;
@Singleton
class WindowsProtectedKeychainAccess implements KeychainAccessStrategy {
private static final Logger LOG = LoggerFactory.getLogger(WindowsProtectedKeychainAccess.class);
private static final Gson GSON = new GsonBuilder().setPrettyPrinting() //
.registerTypeHierarchyAdapter(byte[].class, new ByteArrayJsonAdapter()) //
.disableHtmlEscaping().create();
private final Optional<WinFunctions> winFunctions;
private final List<Path> keychainPaths;
private Map<String, KeychainEntry> keychainEntries;
@Inject
public WindowsProtectedKeychainAccess(Optional<WinFunctions> winFunctions, Environment environment) {
this.winFunctions = winFunctions;
this.keychainPaths = environment.getKeychainPath().collect(Collectors.toList());
}
private WinDataProtection dataProtection() {
return winFunctions.orElseThrow(IllegalStateException::new).dataProtection();
}
@Override
public void storePassphrase(String key, CharSequence passphrase) {
loadKeychainEntriesIfNeeded();
ByteBuffer buf = UTF_8.encode(CharBuffer.wrap(passphrase));
byte[] cleartext = new byte[buf.remaining()];
buf.get(cleartext);
KeychainEntry entry = new KeychainEntry();
entry.salt = generateSalt();
entry.ciphertext = dataProtection().protect(cleartext, entry.salt);
Arrays.fill(buf.array(), (byte) 0x00);
Arrays.fill(cleartext, (byte) 0x00);
keychainEntries.put(key, entry);
saveKeychainEntries();
}
@Override
public char[] loadPassphrase(String key) {
loadKeychainEntriesIfNeeded();
KeychainEntry entry = keychainEntries.get(key);
if (entry == null) {
return null;
}
byte[] cleartext = dataProtection().unprotect(entry.ciphertext, entry.salt);
if (cleartext == null) {
return null;
}
CharBuffer buf = UTF_8.decode(ByteBuffer.wrap(cleartext));
char[] passphrase = new char[buf.remaining()];
buf.get(passphrase);
Arrays.fill(cleartext, (byte) 0x00);
Arrays.fill(buf.array(), (char) 0x00);
return passphrase;
}
@Override
public void deletePassphrase(String key) {
loadKeychainEntriesIfNeeded();
keychainEntries.remove(key);
saveKeychainEntries();
}
@Override
public void changePassphrase(String key, CharSequence passphrase) {
loadKeychainEntriesIfNeeded();
if (keychainEntries.remove(key) != null) {
storePassphrase(key, passphrase);
}
}
@Override
public boolean isSupported() {
return SystemUtils.IS_OS_WINDOWS && winFunctions.isPresent() && !keychainPaths.isEmpty();
}
private byte[] generateSalt() {
byte[] result = new byte[2 * Long.BYTES];
UUID uuid = UUID.randomUUID();
ByteBuffer buf = ByteBuffer.wrap(result);
buf.putLong(uuid.getMostSignificantBits());
buf.putLong(uuid.getLeastSignificantBits());
return result;
}
private void loadKeychainEntriesIfNeeded() {
if (keychainEntries == null) {
for (Path keychainPath : keychainPaths) {
Optional<Map<String, KeychainEntry>> keychain = loadKeychainEntries(keychainPath);
if (keychain.isPresent()) {
keychainEntries = keychain.get();
break;
}
}
}
if (keychainEntries == null) {
LOG.info("Unable to load existing keychain file, creating new keychain.");
keychainEntries = new HashMap<>();
}
}
private Optional<Map<String, KeychainEntry>> loadKeychainEntries(Path keychainPath) {
LOG.debug("Attempting to load keychain from {}", keychainPath);
Type type = new TypeToken<Map<String, KeychainEntry>>() {
}.getType();
try (InputStream in = Files.newInputStream(keychainPath, StandardOpenOption.READ); //
Reader reader = new InputStreamReader(in, UTF_8)) {
return Optional.of(GSON.fromJson(reader, type));
} catch (NoSuchFileException | JsonParseException e) {
return Optional.empty();
} catch (IOException e) {
throw new UncheckedIOException("Could not read keychain from path " + keychainPath, e);
}
}
private void saveKeychainEntries() {
if (keychainPaths.isEmpty()) {
throw new IllegalStateException("Can't save keychain if no keychain path is specified.");
}
saveKeychainEntries(keychainPaths.get(0));
}
private void saveKeychainEntries(Path keychainPath) {
try (OutputStream out = Files.newOutputStream(keychainPath, StandardOpenOption.WRITE, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING); //
Writer writer = new OutputStreamWriter(out, UTF_8)) {
GSON.toJson(keychainEntries, writer);
} catch (IOException e) {
throw new UncheckedIOException("Could not read keychain from path " + keychainPath, e);
}
}
private static class KeychainEntry {
@SerializedName("ciphertext")
byte[] ciphertext;
@SerializedName("salt")
byte[] salt;
}
private static class ByteArrayJsonAdapter implements JsonSerializer<byte[]>, JsonDeserializer<byte[]> {
private static final BaseEncoding BASE64 = BaseEncoding.base64();
@Override
public byte[] deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
return BASE64.decode(json.getAsString());
}
@Override
public JsonElement serialize(byte[] src, Type typeOfSrc, JsonSerializationContext context) {
return new JsonPrimitive(BASE64.encode(src));
}
}
}
@@ -1,56 +0,0 @@
/*******************************************************************************
* Copyright (c) 2017 Skymatic UG (haftungsbeschränkt).
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the accompanying LICENSE file.
*******************************************************************************/
package org.cryptomator.keychain;
import org.cryptomator.common.Environment;
import org.cryptomator.jni.WinDataProtection;
import org.cryptomator.jni.WinFunctions;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import org.mockito.Mockito;
import org.mockito.stubbing.Answer;
import java.nio.file.Path;
import java.util.Optional;
import java.util.stream.Stream;
public class WindowsProtectedKeychainAccessTest {
private WindowsProtectedKeychainAccess keychain;
@BeforeEach
public void setup(@TempDir Path tempDir) {
Path keychainPath = tempDir.resolve("keychainfile.tmp");
Environment env = Mockito.mock(Environment.class);
Mockito.when(env.getKeychainPath()).thenReturn(Stream.of(keychainPath));
WinFunctions winFunctions = Mockito.mock(WinFunctions.class);
WinDataProtection winDataProtection = Mockito.mock(WinDataProtection.class);
Mockito.when(winFunctions.dataProtection()).thenReturn(winDataProtection);
Answer<byte[]> answerReturningFirstArg = invocation -> ((byte[]) invocation.getArgument(0)).clone();
Mockito.when(winDataProtection.protect(Mockito.any(), Mockito.any())).thenAnswer(answerReturningFirstArg);
Mockito.when(winDataProtection.unprotect(Mockito.any(), Mockito.any())).thenAnswer(answerReturningFirstArg);
keychain = new WindowsProtectedKeychainAccess(Optional.of(winFunctions), env);
}
@Test
public void testStoreAndLoad() {
String storedPw1 = "topSecret";
String storedPw2 = "bottomSecret";
keychain.storePassphrase("myPassword", storedPw1);
keychain.storePassphrase("myOtherPassword", storedPw2);
String loadedPw1 = new String(keychain.loadPassphrase("myPassword"));
String loadedPw2 = new String(keychain.loadPassphrase("myOtherPassword"));
Assertions.assertEquals(storedPw1, loadedPw1);
Assertions.assertEquals(storedPw2, loadedPw2);
keychain.deletePassphrase("myPassword");
Assertions.assertNull(keychain.loadPassphrase("myPassword"));
Assertions.assertNotNull(keychain.loadPassphrase("myOtherPassword"));
Assertions.assertNull(keychain.loadPassphrase("nonExistingPassword"));
}
}
@@ -1,33 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!--
Copyright (c) 2014 Markus Kreusch
This file is licensed under the terms of the MIT license.
See the LICENSE.txt file for more info.
Contributors:
Sebastian Stenzel - log4j config for WebDAV unit tests
-->
<Configuration status="WARN">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%16d %-5p [%c{1}:%L] %m%n" />
<ThresholdFilter level="WARN" onMatch="DENY" onMismatch="ACCEPT" />
</Console>
<Console name="StdErr" target="SYSTEM_ERR">
<PatternLayout pattern="%16d %-5p [%c{1}:%L] %m%n" />
<ThresholdFilter level="WARN" onMatch="ACCEPT" onMismatch="DENY" />
</Console>
</Appenders>
<Loggers>
<!-- show our own debug messages: -->
<Logger name="org.cryptomator" level="DEBUG" />
<!-- mute dependencies: -->
<Root level="INFO">
<AppenderRef ref="Console" />
<AppenderRef ref="StdErr" />
</Root>
</Loggers>
</Configuration>
-48
View File
@@ -1,48 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<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.5.6</version>
</parent>
<artifactId>launcher</artifactId>
<name>Cryptomator Launcher</name>
<dependencies>
<dependency>
<groupId>org.cryptomator</groupId>
<artifactId>commons</artifactId>
</dependency>
<dependency>
<groupId>org.cryptomator</groupId>
<artifactId>ui</artifactId>
</dependency>
<!-- Libs -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<!-- DI -->
<dependency>
<groupId>com.google.dagger</groupId>
<artifactId>dagger</artifactId>
</dependency>
<!-- Logging -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</dependency>
</dependencies>
</project>
-365
View File
@@ -1,365 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<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>
<groupId>org.cryptomator</groupId>
<artifactId>main</artifactId>
<version>1.5.6</version>
<packaging>pom</packaging>
<name>Cryptomator</name>
<organization>
<name>cryptomator.org</name>
<url>https://cryptomator.org</url>
</organization>
<developers>
<developer>
<name>Sebastian Stenzel</name>
<email>sebastian.stenzel@gmail.com</email>
<timezone>+1</timezone>
</developer>
</developers>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!-- cryptomator dependencies -->
<cryptomator.cryptofs.version>1.9.12</cryptomator.cryptofs.version>
<cryptomator.jni.version>2.2.2</cryptomator.jni.version>
<cryptomator.fuse.version>1.2.3</cryptomator.fuse.version>
<cryptomator.dokany.version>1.1.15</cryptomator.dokany.version>
<cryptomator.webdav.version>1.0.11</cryptomator.webdav.version>
<!-- 3rd party dependencies -->
<javafx.version>14</javafx.version>
<commons-lang3.version>3.10</commons-lang3.version>
<secret-service.version>1.0.0</secret-service.version>
<jwt.version>3.10.3</jwt.version>
<easybind.version>1.0.3</easybind.version>
<guava.version>29.0-jre</guava.version>
<dagger.version>2.22</dagger.version>
<gson.version>2.8.6</gson.version>
<slf4j.version>1.7.30</slf4j.version>
<logback.version>1.2.3</logback.version>
<!-- test dependencies -->
<junit.jupiter.version>5.6.2</junit.jupiter.version>
<mockito.version>3.3.3</mockito.version>
<hamcrest.version>2.2</hamcrest.version>
</properties>
<repositories>
<repository>
<id>jcenter</id>
<url>https://jcenter.bintray.com</url>
</repository>
</repositories>
<dependencyManagement>
<dependencies>
<!-- modules -->
<dependency>
<groupId>org.cryptomator</groupId>
<artifactId>commons</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.cryptomator</groupId>
<artifactId>keychain</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.cryptomator</groupId>
<artifactId>ui</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.cryptomator</groupId>
<artifactId>launcher</artifactId>
<version>${project.version}</version>
</dependency>
<!-- Cryptomator Libs -->
<dependency>
<groupId>org.cryptomator</groupId>
<artifactId>siv-mode</artifactId>
<version>1.4.0</version>
</dependency>
<dependency>
<groupId>org.cryptomator</groupId>
<artifactId>cryptofs</artifactId>
<version>${cryptomator.cryptofs.version}</version>
</dependency>
<dependency>
<groupId>org.cryptomator</groupId>
<artifactId>fuse-nio-adapter</artifactId>
<version>${cryptomator.fuse.version}</version>
</dependency>
<dependency>
<groupId>org.cryptomator</groupId>
<artifactId>dokany-nio-adapter</artifactId>
<version>${cryptomator.dokany.version}</version>
</dependency>
<dependency>
<groupId>org.cryptomator</groupId>
<artifactId>webdav-nio-adapter</artifactId>
<version>${cryptomator.webdav.version}</version>
</dependency>
<dependency>
<groupId>org.cryptomator</groupId>
<artifactId>jni</artifactId>
<version>${cryptomator.jni.version}</version>
</dependency>
<!-- JavaFX -->
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-base</artifactId>
<version>${javafx.version}</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-graphics</artifactId>
<version>${javafx.version}</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>${javafx.version}</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-fxml</artifactId>
<version>${javafx.version}</version>
</dependency>
<!-- Logging -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>${logback.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback.version}</version>
</dependency>
<!-- Apache Commons -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>${commons-lang3.version}</version>
</dependency>
<!-- Linux System Keychain -->
<dependency>
<groupId>de.swiesend</groupId>
<artifactId>secret-service</artifactId>
<version>${secret-service.version}</version>
</dependency>
<!-- JWT -->
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>${jwt.version}</version>
</dependency>
<!-- EasyBind -->
<dependency>
<groupId>org.fxmisc.easybind</groupId>
<artifactId>easybind</artifactId>
<version>${easybind.version}</version>
</dependency>
<!-- Google -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>${guava.version}</version>
</dependency>
<dependency>
<groupId>com.google.dagger</groupId>
<artifactId>dagger</artifactId>
<version>${dagger.version}</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>${gson.version}</version>
</dependency>
<!-- JUnit / Mockito / Hamcrest -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>${junit.jupiter.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>${mockito.version}</version>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest</artifactId>
<version>${hamcrest.version}</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-swing</artifactId>
<version>${javafx.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- common dependencies for all modules -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<modules>
<module>commons</module>
<module>keychain</module>
<module>ui</module>
<module>launcher</module>
</modules>
<profiles>
<profile>
<id>release</id>
<modules>
<module>buildkit</module>
</modules>
</profile>
<profile>
<id>coverage</id>
<build>
<plugins>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<build>
<pluginManagement>
<plugins>
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.1.2</version>
<executions>
<execution>
<id>copy-libs</id>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/libs</outputDirectory>
<includeScope>runtime</includeScope>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>license-maven-plugin</artifactId>
<version>2.0.0</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.0</version>
<configuration>
<archive>
<manifest>
<!-- adds Implementation-Version which can be read during runtime -->
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.5</version>
<executions>
<execution>
<id>prepare-agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>report</id>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
<configuration>
<excludes>
<exclude>**/*_*</exclude>
<exclude>**/Dagger*</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<release>14</release>
<annotationProcessorPaths>
<path>
<groupId>com.google.dagger</groupId>
<artifactId>dagger-compiler</artifactId>
<version>${dagger.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.2</version>
</plugin>
</plugins>
</build>
</project>
-123
View File
@@ -1,123 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<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.5.6</version>
</parent>
<artifactId>ui</artifactId>
<name>Cryptomator GUI</name>
<dependencies>
<dependency>
<groupId>org.cryptomator</groupId>
<artifactId>keychain</artifactId>
</dependency>
<dependency>
<groupId>org.cryptomator</groupId>
<artifactId>commons</artifactId>
</dependency>
<dependency>
<groupId>org.cryptomator</groupId>
<artifactId>jni</artifactId>
</dependency>
<!-- JavaFx -->
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-fxml</artifactId>
</dependency>
<!-- EasyBind -->
<dependency>
<groupId>org.fxmisc.easybind</groupId>
<artifactId>easybind</artifactId>
</dependency>
<!-- Google -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
</dependency>
<!-- Apache Commons -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<!-- DI -->
<dependency>
<groupId>com.google.dagger</groupId>
<artifactId>dagger</artifactId>
</dependency>
<!-- Zxcvbn -->
<dependency>
<groupId>com.nulab-inc</groupId>
<artifactId>zxcvbn</artifactId>
<version>1.3.0</version>
</dependency>
<!-- Logging -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<scope>test</scope>
</dependency>
<!-- Testing -->
<dependency>
<groupId>com.google.jimfs</groupId>
<artifactId>jimfs</artifactId>
<version>1.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-swing</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>license-maven-plugin</artifactId>
<executions>
<execution>
<id>add-third-party</id>
<goals>
<goal>add-third-party</goal>
</goals>
<phase>generate-resources</phase>
<configuration>
<outputDirectory>${project.basedir}/src/main/resources/license</outputDirectory>
<thirdPartyFilename>THIRD-PARTY.txt</thirdPartyFilename>
<includedScopes>compile</includedScopes>
<excludedGroups>org\.cryptomator</excludedGroups>
<licenseMerges>
<licenseMerge>Apache License v2.0|Apache License, Version 2.0|The Apache Software License, Version 2.0|Apache 2.0|Apache Software License - Version 2.0</licenseMerge>
<licenseMerge>MIT License|The MIT License (MIT)|The MIT License|MIT license</licenseMerge>
<licenseMerge>LGPL 2.1|LGPL, version 2.1|GNU Lesser/Library General Public License version 2|GNU Lesser General Public License Version 2.1</licenseMerge>
<licenseMerge>GPLv2|GNU General Public License Version 2</licenseMerge>
<licenseMerge>GPLv2+CE|CDDL + GPLv2 with classpath exception</licenseMerge>
</licenseMerges>
<fileTemplate>${project.basedir}/src/license/template.ftl</fileTemplate>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
@@ -1,100 +0,0 @@
package org.cryptomator.ui.changepassword;
import javafx.beans.binding.Bindings;
import javafx.beans.binding.BooleanBinding;
import javafx.beans.property.ObjectProperty;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.CheckBox;
import javafx.stage.Stage;
import org.cryptomator.common.vaults.Vault;
import org.cryptomator.cryptofs.CryptoFileSystemProvider;
import org.cryptomator.cryptolib.api.InvalidPassphraseException;
import org.cryptomator.keychain.KeychainAccessException;
import org.cryptomator.keychain.KeychainManager;
import org.cryptomator.ui.common.Animations;
import org.cryptomator.ui.common.ErrorComponent;
import org.cryptomator.ui.common.FxController;
import org.cryptomator.ui.controls.NiceSecurePasswordField;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.inject.Inject;
import javax.inject.Named;
import java.io.IOException;
import java.nio.CharBuffer;
import java.util.Optional;
import static org.cryptomator.common.Constants.MASTERKEY_FILENAME;
@ChangePasswordScoped
public class ChangePasswordController implements FxController {
private static final Logger LOG = LoggerFactory.getLogger(ChangePasswordController.class);
private final Stage window;
private final Vault vault;
private final ObjectProperty<CharSequence> newPassword;
private final ErrorComponent.Builder errorComponent;
private final Optional<KeychainManager> keychain;
public NiceSecurePasswordField oldPasswordField;
public CheckBox finalConfirmationCheckbox;
public Button finishButton;
@Inject
public ChangePasswordController(@ChangePasswordWindow Stage window, @ChangePasswordWindow Vault vault, @Named("newPassword") ObjectProperty<CharSequence> newPassword, ErrorComponent.Builder errorComponent, Optional<KeychainManager> keychain) {
this.window = window;
this.vault = vault;
this.newPassword = newPassword;
this.errorComponent = errorComponent;
this.keychain = keychain;
}
@FXML
public void initialize() {
BooleanBinding hasNotConfirmedCheckbox = finalConfirmationCheckbox.selectedProperty().not();
BooleanBinding isInvalidNewPassword = Bindings.createBooleanBinding(() -> newPassword.get() == null || newPassword.get().length() == 0, newPassword);
finishButton.disableProperty().bind(hasNotConfirmedCheckbox.or(isInvalidNewPassword));
}
@FXML
public void cancel() {
window.close();
}
@FXML
public void finish() {
try {
CryptoFileSystemProvider.changePassphrase(vault.getPath(), MASTERKEY_FILENAME, oldPasswordField.getCharacters(), newPassword.get());
LOG.info("Successfully changed password for {}", vault.getDisplayableName());
window.close();
updatePasswordInSystemkeychain();
} catch (IOException e) {
LOG.error("IO error occured during password change. Unable to perform operation.", e);
errorComponent.cause(e).window(window).returnToScene(window.getScene()).build().showErrorScene();
} catch (InvalidPassphraseException e) {
Animations.createShakeWindowAnimation(window).play();
oldPasswordField.selectAll();
oldPasswordField.requestFocus();
}
}
private void updatePasswordInSystemkeychain() {
if (keychain.isPresent()) {
try {
keychain.get().changePassphrase(vault.getId(), CharBuffer.wrap(newPassword.get()));
LOG.info("Successfully updated password in system keychain for {}", vault.getDisplayableName());
} catch (KeychainAccessException e) {
LOG.error("Failed to update password in system keychain.", e);
}
}
}
/* Getter/Setter */
public Vault getVault() {
return vault;
}
}
@@ -1,32 +0,0 @@
package org.cryptomator.ui.common;
import javafx.beans.binding.StringBinding;
import javafx.beans.value.ObservableObjectValue;
/**
* Contains a variety of method to create {@link java.util.function.Function#identity() identity}-bindings
* to facilitate the Weak References used internally in JavaFX's Bindings.
*/
public final class WeakBindings {
/**
* Create a new StringBinding that listens to changes from the given observable without being strongly referenced by it.
*
* @param observable The observable
* @return a StringBinding weakly referenced from the given observable
*/
public static StringBinding bindString(ObservableObjectValue<String> observable) {
return new StringBinding() {
{
bind(observable);
}
@Override
protected String computeValue() {
return observable.get();
}
};
}
}
@@ -1,135 +0,0 @@
package org.cryptomator.ui.fxapp;
import dagger.Lazy;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.beans.binding.Bindings;
import javafx.beans.binding.BooleanBinding;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableSet;
import javafx.stage.Stage;
import org.cryptomator.common.LicenseHolder;
import org.cryptomator.common.settings.Settings;
import org.cryptomator.common.settings.UiTheme;
import org.cryptomator.common.vaults.Vault;
import org.cryptomator.jni.JniException;
import org.cryptomator.jni.MacApplicationUiAppearance;
import org.cryptomator.jni.MacApplicationUiState;
import org.cryptomator.jni.MacFunctions;
import org.cryptomator.ui.common.VaultService;
import org.cryptomator.ui.mainwindow.MainWindowComponent;
import org.cryptomator.ui.preferences.PreferencesComponent;
import org.cryptomator.ui.preferences.SelectedPreferencesTab;
import org.cryptomator.ui.quit.QuitComponent;
import org.cryptomator.ui.unlock.UnlockComponent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.inject.Inject;
import javax.inject.Provider;
import java.awt.desktop.QuitResponse;
import java.util.Optional;
@FxApplicationScoped
public class FxApplication extends Application {
private static final Logger LOG = LoggerFactory.getLogger(FxApplication.class);
private final Settings settings;
private final Lazy<MainWindowComponent> mainWindow;
private final Lazy<PreferencesComponent> preferencesWindow;
private final Provider<UnlockComponent.Builder> unlockWindowBuilderProvider;
private final Provider<QuitComponent.Builder> quitWindowBuilderProvider;
private final Optional<MacFunctions> macFunctions;
private final VaultService vaultService;
private final LicenseHolder licenseHolder;
private final BooleanBinding hasVisibleStages;
@Inject
FxApplication(Settings settings, Lazy<MainWindowComponent> mainWindow, Lazy<PreferencesComponent> preferencesWindow, Provider<UnlockComponent.Builder> unlockWindowBuilderProvider, Provider<QuitComponent.Builder> quitWindowBuilderProvider, Optional<MacFunctions> macFunctions, VaultService vaultService, LicenseHolder licenseHolder, ObservableSet<Stage> visibleStages) {
this.settings = settings;
this.mainWindow = mainWindow;
this.preferencesWindow = preferencesWindow;
this.unlockWindowBuilderProvider = unlockWindowBuilderProvider;
this.quitWindowBuilderProvider = quitWindowBuilderProvider;
this.macFunctions = macFunctions;
this.vaultService = vaultService;
this.licenseHolder = licenseHolder;
this.hasVisibleStages = Bindings.isNotEmpty(visibleStages);
}
public void start() {
LOG.trace("FxApplication.start()");
Platform.setImplicitExit(false);
hasVisibleStages.addListener(this::hasVisibleStagesChanged);
settings.theme().addListener(this::themeChanged);
loadSelectedStyleSheet(settings.theme().get());
}
@Override
public void start(Stage stage) {
throw new UnsupportedOperationException("Use start() instead.");
}
private void hasVisibleStagesChanged(@SuppressWarnings("unused") ObservableValue<? extends Boolean> observableValue, @SuppressWarnings("unused") boolean oldValue, boolean newValue) {
if (newValue) {
macFunctions.map(MacFunctions::uiState).ifPresent(MacApplicationUiState::transformToForegroundApplication);
} else {
macFunctions.map(MacFunctions::uiState).ifPresent(MacApplicationUiState::transformToAgentApplication);
}
}
public void showPreferencesWindow(SelectedPreferencesTab selectedTab) {
Platform.runLater(() -> {
preferencesWindow.get().showPreferencesWindow(selectedTab);
LOG.debug("Showing Preferences");
});
}
public void showMainWindow() {
Platform.runLater(() -> {
mainWindow.get().showMainWindow();
LOG.debug("Showing MainWindow");
});
}
public void startUnlockWorkflow(Vault vault, Optional<Stage> owner) {
Platform.runLater(() -> {
unlockWindowBuilderProvider.get().vault(vault).owner(owner).build().startUnlockWorkflow();
LOG.debug("Showing UnlockWindow for {}", vault.getDisplayableName());
});
}
public void showQuitWindow(QuitResponse response) {
Platform.runLater(() -> {
quitWindowBuilderProvider.get().quitResponse(response).build().showQuitWindow();
LOG.debug("Showing QuitWindow");
});
}
public VaultService getVaultService() {
return vaultService;
}
private void themeChanged(@SuppressWarnings("unused") ObservableValue<? extends UiTheme> observable, @SuppressWarnings("unused") UiTheme oldValue, UiTheme newValue) {
loadSelectedStyleSheet(newValue);
}
private void loadSelectedStyleSheet(UiTheme desiredTheme) {
UiTheme theme = licenseHolder.isValidLicense() ? desiredTheme : UiTheme.LIGHT;
switch (theme) {
case DARK -> {
Application.setUserAgentStylesheet(getClass().getResource("/css/dark_theme.css").toString());
macFunctions.map(MacFunctions::uiAppearance).ifPresent(JniException.ignore(MacApplicationUiAppearance::setToDarkAqua));
}
case LIGHT -> {
Application.setUserAgentStylesheet(getClass().getResource("/css/light_theme.css").toString());
macFunctions.map(MacFunctions::uiAppearance).ifPresent(JniException.ignore(MacApplicationUiAppearance::setToAqua));
}
}
}
}
@@ -1,33 +0,0 @@
package org.cryptomator.ui.launcher;
import dagger.Module;
import dagger.Provides;
import org.cryptomator.common.JniModule;
import org.cryptomator.keychain.KeychainModule;
import org.cryptomator.ui.fxapp.FxApplicationComponent;
import org.cryptomator.ui.traymenu.TrayMenuComponent;
import javax.inject.Named;
import javax.inject.Singleton;
import java.util.Locale;
import java.util.ResourceBundle;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
@Module(includes = {JniModule.class, KeychainModule.class}, subcomponents = {TrayMenuComponent.class, FxApplicationComponent.class})
public abstract class UiLauncherModule {
@Provides
@Singleton
static ResourceBundle provideLocalization() {
return ResourceBundle.getBundle("i18n.strings");
}
@Provides
@Singleton
@Named("launchEventQueue")
static BlockingQueue<AppLaunchEvent> provideFileOpenRequests() {
return new ArrayBlockingQueue<>(10);
}
}
@@ -1,20 +0,0 @@
package org.cryptomator.ui.mainwindow;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.ReadOnlyObjectProperty;
import org.cryptomator.common.vaults.Vault;
import org.cryptomator.ui.common.FxController;
import javax.inject.Inject;
@MainWindowScoped
public class VaultDetailMissingVaultController implements FxController {
private final ReadOnlyObjectProperty<Vault> vault;
@Inject
public VaultDetailMissingVaultController(ObjectProperty<Vault> vault) {
this.vault = vault;
}
}
@@ -1,45 +0,0 @@
package org.cryptomator.ui.mainwindow;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.ReadOnlyObjectProperty;
import javafx.fxml.FXML;
import org.cryptomator.common.vaults.Vault;
import org.cryptomator.ui.common.FxController;
import org.cryptomator.ui.common.VaultService;
import javax.inject.Inject;
@MainWindowScoped
public class VaultDetailUnlockedController implements FxController {
private final ReadOnlyObjectProperty<Vault> vault;
private final VaultService vaultService;
@Inject
public VaultDetailUnlockedController(ObjectProperty<Vault> vault, VaultService vaultService) {
this.vault = vault;
this.vaultService = vaultService;
}
@FXML
public void revealAccessLocation() {
vaultService.reveal(vault.get());
}
@FXML
public void lock() {
vaultService.lock(vault.get(), false);
// TODO count lock attempts, and allow forced lock
}
/* Getter/Setter */
public ReadOnlyObjectProperty<Vault> vaultProperty() {
return vault;
}
public Vault getVault() {
return vault.get();
}
}
@@ -1,102 +0,0 @@
package org.cryptomator.ui.mainwindow;
import javafx.beans.binding.Bindings;
import javafx.beans.binding.BooleanBinding;
import javafx.beans.property.ObjectProperty;
import javafx.beans.value.ObservableValue;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.scene.control.ListView;
import org.cryptomator.common.vaults.Vault;
import org.cryptomator.common.vaults.VaultListManager;
import org.cryptomator.common.vaults.VaultState;
import org.cryptomator.ui.addvaultwizard.AddVaultWizardComponent;
import org.cryptomator.ui.common.FxController;
import org.cryptomator.ui.removevault.RemoveVaultComponent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.inject.Inject;
import java.io.IOException;
@MainWindowScoped
public class VaultListController implements FxController {
private static final Logger LOG = LoggerFactory.getLogger(VaultListController.class);
private final ObservableList<Vault> vaults;
private final ObjectProperty<Vault> selectedVault;
private final VaultListCellFactory cellFactory;
private final AddVaultWizardComponent.Builder addVaultWizard;
private final RemoveVaultComponent.Builder removeVault;
private final BooleanBinding noVaultSelected;
private final BooleanBinding emptyVaultList;
public ListView<Vault> vaultList;
@Inject
VaultListController(ObservableList<Vault> vaults, ObjectProperty<Vault> selectedVault, VaultListCellFactory cellFactory, AddVaultWizardComponent.Builder addVaultWizard, RemoveVaultComponent.Builder removeVault) {
this.vaults = vaults;
this.selectedVault = selectedVault;
this.cellFactory = cellFactory;
this.addVaultWizard = addVaultWizard;
this.removeVault = removeVault;
this.noVaultSelected = selectedVault.isNull();
this.emptyVaultList = Bindings.isEmpty(vaults);
selectedVault.addListener(this::selectedVaultDidChange);
}
public void initialize() {
vaultList.setItems(vaults);
vaultList.setCellFactory(cellFactory);
selectedVault.bind(vaultList.getSelectionModel().selectedItemProperty());
vaults.addListener((ListChangeListener.Change<? extends Vault> c) -> {
while (c.next()) {
if (c.wasAdded()) {
Vault anyAddedVault = c.getAddedSubList().get(0);
vaultList.getSelectionModel().select(anyAddedVault);
}
}
});
}
private void selectedVaultDidChange(@SuppressWarnings("unused") ObservableValue<? extends Vault> observableValue, @SuppressWarnings("unused") Vault oldValue, Vault newValue) {
if (newValue == null) {
return;
}
VaultListManager.redetermineVaultState(newValue);
}
@FXML
public void didClickAddVault() {
addVaultWizard.build().showAddVaultWizard();
}
@FXML
public void didClickRemoveVault() {
Vault v = selectedVault.get();
if (v != null) {
removeVault.vault(v).build().showRemoveVault();
} else {
LOG.debug("Cannot remove a vault if none is selected.");
}
}
// Getter and Setter
public BooleanBinding emptyVaultListProperty() {
return emptyVaultList;
}
public boolean isEmptyVaultList() {
return emptyVaultList.get();
}
public BooleanBinding noVaultSelectedProperty() {
return noVaultSelected;
}
public boolean isNoVaultSelected() {
return noVaultSelected.get();
}
}
@@ -1,43 +0,0 @@
package org.cryptomator.ui.preferences;
import org.cryptomator.jni.MacFunctions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
class AutoStartMacStrategy implements AutoStartStrategy {
private static final Logger LOG = LoggerFactory.getLogger(AutoStartMacStrategy.class);
private final MacFunctions macFunctions;
public AutoStartMacStrategy(MacFunctions macFunctions) {
this.macFunctions = macFunctions;
}
@Override
public CompletionStage<Boolean> isAutoStartEnabled() {
boolean enabled = macFunctions.launchServices().isLoginItemEnabled();
return CompletableFuture.completedFuture(enabled);
}
@Override
public void enableAutoStart() throws TogglingAutoStartFailedException {
if (macFunctions.launchServices().enableLoginItem()) {
LOG.debug("Added login item.");
} else {
throw new TogglingAutoStartFailedException("Failed to add login item.");
}
}
@Override
public void disableAutoStart() throws TogglingAutoStartFailedException {
if (macFunctions.launchServices().disableLoginItem()) {
LOG.debug("Removed login item.");
} else {
throw new TogglingAutoStartFailedException("Failed to remove login item.");
}
}
}
@@ -1,26 +0,0 @@
package org.cryptomator.ui.preferences;
import dagger.Module;
import dagger.Provides;
import org.apache.commons.lang3.SystemUtils;
import org.cryptomator.jni.MacFunctions;
import java.util.Optional;
@Module
abstract class AutoStartModule {
@Provides
@PreferencesScoped
public static Optional<AutoStartStrategy> provideAutoStartStrategy(Optional<MacFunctions> macFunctions) {
if (SystemUtils.IS_OS_MAC_OSX && macFunctions.isPresent()) {
return Optional.of(new AutoStartMacStrategy(macFunctions.get()));
} else if (SystemUtils.IS_OS_WINDOWS) {
Optional<String> exeName = ProcessHandle.current().info().command();
return exeName.map(AutoStartWinStrategy::new);
} else {
return Optional.empty();
}
}
}
@@ -1,24 +0,0 @@
package org.cryptomator.ui.preferences;
import java.util.concurrent.CompletionStage;
public interface AutoStartStrategy {
CompletionStage<Boolean> isAutoStartEnabled();
void enableAutoStart() throws TogglingAutoStartFailedException;
void disableAutoStart() throws TogglingAutoStartFailedException;
class TogglingAutoStartFailedException extends Exception {
public TogglingAutoStartFailedException(String message) {
super(message);
}
public TogglingAutoStartFailedException(String message, Throwable cause) {
super(message, cause);
}
}
}
@@ -1,91 +0,0 @@
package org.cryptomator.ui.preferences;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
class AutoStartWinStrategy implements AutoStartStrategy {
private static final Logger LOG = LoggerFactory.getLogger(AutoStartWinStrategy.class);
private static final String HKCU_AUTOSTART_KEY = "\"HKCU\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run\"";
private static final String AUTOSTART_VALUE = "Cryptomator";
private final String exePath;
public AutoStartWinStrategy(String exePath) {
this.exePath = exePath;
}
@Override
public CompletionStage<Boolean> isAutoStartEnabled() {
ProcessBuilder regQuery = new ProcessBuilder("reg", "query", HKCU_AUTOSTART_KEY, //
"/v", AUTOSTART_VALUE);
try {
Process proc = regQuery.start();
return proc.onExit().thenApply(p -> p.exitValue() == 0);
} catch (IOException e) {
LOG.warn("Failed to query {} from registry key {}", AUTOSTART_VALUE, HKCU_AUTOSTART_KEY);
return CompletableFuture.completedFuture(false);
}
}
@Override
public void enableAutoStart() throws TogglingAutoStartFailedException {
ProcessBuilder regAdd = new ProcessBuilder("reg", "add", HKCU_AUTOSTART_KEY, //
"/v", AUTOSTART_VALUE, //
"/t", "REG_SZ", //
"/d", "\"" + exePath + "\"", //
"/f");
String command = regAdd.command().stream().collect(Collectors.joining(" "));
try {
Process proc = regAdd.start();
boolean finishedInTime = waitForProcess(proc, 5, TimeUnit.SECONDS);
if (finishedInTime) {
LOG.debug("Added {} to registry key {}.", AUTOSTART_VALUE, HKCU_AUTOSTART_KEY);
} else {
throw new TogglingAutoStartFailedException("Adding registry value failed.");
}
} catch (IOException e) {
throw new TogglingAutoStartFailedException("Adding registry value failed. " + command, e);
}
}
@Override
public void disableAutoStart() throws TogglingAutoStartFailedException {
ProcessBuilder regRemove = new ProcessBuilder("reg", "delete", HKCU_AUTOSTART_KEY, //
"/v", AUTOSTART_VALUE, //
"/f");
String command = regRemove.command().stream().collect(Collectors.joining(" "));
try {
Process proc = regRemove.start();
boolean finishedInTime = waitForProcess(proc, 5, TimeUnit.SECONDS);
if (finishedInTime) {
LOG.debug("Removed {} from registry key {}.", AUTOSTART_VALUE, HKCU_AUTOSTART_KEY);
} else {
throw new TogglingAutoStartFailedException("Removing registry value failed.");
}
} catch (IOException e) {
throw new TogglingAutoStartFailedException("Removing registry value failed. " + command, e);
}
}
private static boolean waitForProcess(Process proc, int timeout, TimeUnit timeUnit) {
boolean finishedInTime = false;
try {
finishedInTime = proc.waitFor(timeout, timeUnit);
} catch (InterruptedException e) {
LOG.error("Timeout while reading registry", e);
Thread.currentThread().interrupt();
} finally {
if (!finishedInTime) {
proc.destroyForcibly();
}
}
return finishedInTime;
}
}
@@ -1,45 +0,0 @@
package org.cryptomator.ui.preferences;
import javafx.application.Application;
import javafx.beans.value.ObservableValue;
import javafx.fxml.FXML;
import javafx.scene.control.TextArea;
import org.cryptomator.common.LicenseHolder;
import org.cryptomator.ui.common.FxController;
import javax.inject.Inject;
@PreferencesScoped
public class DonationKeyPreferencesController implements FxController {
private static final String DONATION_URI = "https://store.cryptomator.org/desktop";
private final Application application;
private final LicenseHolder licenseHolder;
public TextArea donationKeyField;
@Inject
DonationKeyPreferencesController(Application application, LicenseHolder licenseHolder) {
this.application = application;
this.licenseHolder = licenseHolder;
}
@FXML
public void initialize() {
donationKeyField.setText(licenseHolder.getLicenseKey().orElse(null));
donationKeyField.textProperty().addListener(this::registrationKeyChanged);
}
private void registrationKeyChanged(@SuppressWarnings("unused") ObservableValue<? extends String> observable, @SuppressWarnings("unused") String oldValue, String newValue) {
licenseHolder.validateAndStoreLicense(newValue);
}
@FXML
public void getDonationKey() {
application.getHostServices().showDocument(DONATION_URI);
}
public LicenseHolder getLicenseHolder() {
return licenseHolder;
}
}
@@ -1,171 +0,0 @@
package org.cryptomator.ui.preferences;
import javafx.application.Platform;
import javafx.beans.property.ObjectProperty;
import javafx.beans.value.ObservableValue;
import javafx.concurrent.Task;
import javafx.fxml.FXML;
import javafx.geometry.NodeOrientation;
import javafx.scene.control.CheckBox;
import javafx.scene.control.ChoiceBox;
import javafx.scene.control.RadioButton;
import javafx.scene.control.Toggle;
import javafx.scene.control.ToggleGroup;
import javafx.util.StringConverter;
import javafx.application.Application;
import org.cryptomator.common.LicenseHolder;
import org.cryptomator.common.settings.Settings;
import org.cryptomator.common.settings.UiTheme;
import org.cryptomator.common.Environment;
import org.cryptomator.ui.common.FxController;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.inject.Inject;
import javax.inject.Named;
import java.util.Optional;
import java.util.ResourceBundle;
import java.util.concurrent.ExecutorService;
@PreferencesScoped
public class GeneralPreferencesController implements FxController {
private static final Logger LOG = LoggerFactory.getLogger(GeneralPreferencesController.class);
private final Settings settings;
private final boolean trayMenuSupported;
private final Optional<AutoStartStrategy> autoStartStrategy;
private final ObjectProperty<SelectedPreferencesTab> selectedTabProperty;
private final LicenseHolder licenseHolder;
private final ExecutorService executor;
private final ResourceBundle resourceBundle;
private final Application application;
private final Environment environment;
public ChoiceBox<UiTheme> themeChoiceBox;
public CheckBox startHiddenCheckbox;
public CheckBox debugModeCheckbox;
public CheckBox autoStartCheckbox;
public ToggleGroup nodeOrientation;
public RadioButton nodeOrientationLtr;
public RadioButton nodeOrientationRtl;
@Inject
GeneralPreferencesController(Settings settings, @Named("trayMenuSupported") boolean trayMenuSupported, Optional<AutoStartStrategy> autoStartStrategy, ObjectProperty<SelectedPreferencesTab> selectedTabProperty, LicenseHolder licenseHolder, ExecutorService executor, ResourceBundle resourceBundle, Application application, Environment environment) {
this.settings = settings;
this.trayMenuSupported = trayMenuSupported;
this.autoStartStrategy = autoStartStrategy;
this.selectedTabProperty = selectedTabProperty;
this.licenseHolder = licenseHolder;
this.executor = executor;
this.resourceBundle = resourceBundle;
this.application = application;
this.environment = environment;
}
@FXML
public void initialize() {
themeChoiceBox.getItems().addAll(UiTheme.values());
themeChoiceBox.valueProperty().bindBidirectional(settings.theme());
themeChoiceBox.setConverter(new UiThemeConverter(resourceBundle));
startHiddenCheckbox.selectedProperty().bindBidirectional(settings.startHidden());
debugModeCheckbox.selectedProperty().bindBidirectional(settings.debugMode());
autoStartStrategy.ifPresent(autoStart -> {
autoStart.isAutoStartEnabled().thenAccept(enabled -> {
Platform.runLater(() -> autoStartCheckbox.setSelected(enabled));
});
});
nodeOrientationLtr.setSelected(settings.userInterfaceOrientation().get() == NodeOrientation.LEFT_TO_RIGHT);
nodeOrientationRtl.setSelected(settings.userInterfaceOrientation().get() == NodeOrientation.RIGHT_TO_LEFT);
nodeOrientation.selectedToggleProperty().addListener(this::toggleNodeOrientation);
}
public boolean isTrayMenuSupported() {
return this.trayMenuSupported;
}
public boolean isAutoStartSupported() {
return autoStartStrategy.isPresent();
}
private void toggleNodeOrientation(@SuppressWarnings("unused") ObservableValue<? extends Toggle> observable, @SuppressWarnings("unused") Toggle oldValue, Toggle newValue) {
if (nodeOrientationLtr.equals(newValue)) {
settings.userInterfaceOrientation().set(NodeOrientation.LEFT_TO_RIGHT);
} else if (nodeOrientationRtl.equals(newValue)) {
settings.userInterfaceOrientation().set(NodeOrientation.RIGHT_TO_LEFT);
} else {
LOG.warn("Unexpected toggle option {}", newValue);
}
}
@FXML
public void toggleAutoStart() {
autoStartStrategy.ifPresent(autoStart -> {
boolean enableAutoStart = autoStartCheckbox.isSelected();
Task<Void> toggleTask = new ToggleAutoStartTask(autoStart, enableAutoStart);
toggleTask.setOnFailed(evt -> autoStartCheckbox.setSelected(!enableAutoStart)); // restore previous state
executor.execute(toggleTask);
});
}
public LicenseHolder getLicenseHolder() {
return licenseHolder;
}
@FXML
public void showDonationTab() {
selectedTabProperty.set(SelectedPreferencesTab.DONATION_KEY);
}
@FXML
public void showLogfileDirectory(){
environment.getLogDir().ifPresent(logDirPath -> application.getHostServices().showDocument(logDirPath.toUri().toString()));
}
/* Helper classes */
private static class UiThemeConverter extends StringConverter<UiTheme> {
private final ResourceBundle resourceBundle;
UiThemeConverter(ResourceBundle resourceBundle) {
this.resourceBundle = resourceBundle;
}
@Override
public String toString(UiTheme impl) {
return resourceBundle.getString(impl.getDisplayName());
}
@Override
public UiTheme fromString(String string) {
throw new UnsupportedOperationException();
}
}
private static class ToggleAutoStartTask extends Task<Void> {
private final AutoStartStrategy autoStart;
private final boolean enable;
public ToggleAutoStartTask(AutoStartStrategy autoStart, boolean enable) {
this.autoStart = autoStart;
this.enable = enable;
}
@Override
protected Void call() throws Exception {
if (enable) {
autoStart.enableAutoStart();
} else {
autoStart.disableAutoStart();
}
return null;
}
}
}
@@ -1,29 +0,0 @@
/*******************************************************************************
* Copyright (c) 2017 Skymatic UG (haftungsbeschränkt).
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the accompanying LICENSE file.
*******************************************************************************/
package org.cryptomator.ui.traymenu;
import dagger.Subcomponent;
import java.awt.SystemTray;
@TrayMenuScoped
@Subcomponent
public interface TrayMenuComponent {
TrayIconController trayIconController();
default void addIconToSystemTray() {
assert SystemTray.isSupported();
trayIconController().initializeTrayIcon();
}
@Subcomponent.Builder
interface Builder {
TrayMenuComponent build();
}
}
@@ -1,39 +0,0 @@
package org.cryptomator.ui.unlock;
import dagger.Lazy;
import javafx.fxml.FXML;
import javafx.scene.Scene;
import javafx.stage.Stage;
import org.cryptomator.common.vaults.Vault;
import org.cryptomator.ui.common.FxController;
import org.cryptomator.ui.common.FxmlFile;
import org.cryptomator.ui.common.FxmlScene;
import javax.inject.Inject;
@UnlockScoped
public class UnlockInvalidMountPointController implements FxController {
private final Stage window;
private final Lazy<Scene> unlockScene;
private final Vault vault;
@Inject
UnlockInvalidMountPointController(@UnlockWindow Stage window, @FxmlScene(FxmlFile.UNLOCK) Lazy<Scene> unlockScene, @UnlockWindow Vault vault) {
this.window = window;
this.unlockScene = unlockScene;
this.vault = vault;
}
@FXML
public void back() {
window.setScene(unlockScene.get());
}
/* Getter/Setter */
public String getMountPoint() {
return vault.getVaultSettings().getCustomMountPath().orElse("AUTO");
}
}
@@ -1,134 +0,0 @@
package org.cryptomator.ui.unlock;
import dagger.Binds;
import dagger.Module;
import dagger.Provides;
import dagger.multibindings.IntoMap;
import javafx.scene.Scene;
import javafx.stage.Modality;
import javafx.stage.Stage;
import org.cryptomator.common.vaults.Vault;
import org.cryptomator.keychain.KeychainAccessException;
import org.cryptomator.keychain.KeychainManager;
import org.cryptomator.ui.common.DefaultSceneFactory;
import org.cryptomator.ui.common.FXMLLoaderFactory;
import org.cryptomator.ui.common.FxController;
import org.cryptomator.ui.common.FxControllerKey;
import org.cryptomator.ui.common.FxmlFile;
import org.cryptomator.ui.common.FxmlScene;
import org.cryptomator.ui.common.StageFactory;
import org.cryptomator.ui.common.UserInteractionLock;
import org.cryptomator.ui.forgetPassword.ForgetPasswordComponent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.inject.Named;
import javax.inject.Provider;
import java.util.Map;
import java.util.Optional;
import java.util.ResourceBundle;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
@Module(subcomponents = {ForgetPasswordComponent.class})
abstract class UnlockModule {
private static final Logger LOG = LoggerFactory.getLogger(UnlockModule.class);
public enum PasswordEntry {PASSWORD_ENTERED, CANCELED}
@Provides
@UnlockScoped
static UserInteractionLock<PasswordEntry> providePasswordEntryLock() {
return new UserInteractionLock<>(null);
}
@Provides
@Named("savedPassword")
@UnlockScoped
static Optional<char[]> provideStoredPassword(Optional<KeychainManager> keychain, @UnlockWindow Vault vault) {
return keychain.map(k -> {
try {
return k.loadPassphrase(vault.getId());
} catch (KeychainAccessException e) {
LOG.error("Failed to load entry from system keychain.", e);
return null;
}
});
}
@Provides
@UnlockScoped
static AtomicReference<char[]> providePassword(@Named("savedPassword") Optional<char[]> storedPassword) {
return new AtomicReference(storedPassword.orElse(null));
}
@Provides
@Named("savePassword")
@UnlockScoped
static AtomicBoolean provideSavePasswordFlag(@Named("savedPassword") Optional<char[]> storedPassword) {
return new AtomicBoolean(storedPassword.isPresent());
}
@Provides
@UnlockWindow
@UnlockScoped
static FXMLLoaderFactory provideFxmlLoaderFactory(Map<Class<? extends FxController>, Provider<FxController>> factories, DefaultSceneFactory sceneFactory, ResourceBundle resourceBundle) {
return new FXMLLoaderFactory(factories, sceneFactory, resourceBundle);
}
@Provides
@UnlockWindow
@UnlockScoped
static Stage provideStage(StageFactory factory, @UnlockWindow Vault vault, @Named("unlockWindowOwner") Optional<Stage> owner) {
Stage stage = factory.create();
stage.setTitle(vault.getDisplayableName());
stage.setResizable(false);
if (owner.isPresent()) {
stage.initOwner(owner.get());
stage.initModality(Modality.WINDOW_MODAL);
} else {
stage.initModality(Modality.APPLICATION_MODAL);
}
return stage;
}
@Provides
@FxmlScene(FxmlFile.UNLOCK)
@UnlockScoped
static Scene provideUnlockScene(@UnlockWindow FXMLLoaderFactory fxmlLoaders) {
return fxmlLoaders.createScene("/fxml/unlock.fxml");
}
@Provides
@FxmlScene(FxmlFile.UNLOCK_SUCCESS)
@UnlockScoped
static Scene provideUnlockSuccessScene(@UnlockWindow FXMLLoaderFactory fxmlLoaders) {
return fxmlLoaders.createScene("/fxml/unlock_success.fxml");
}
@Provides
@FxmlScene(FxmlFile.UNLOCK_INVALID_MOUNT_POINT)
@UnlockScoped
static Scene provideInvalidMountPointScene(@UnlockWindow FXMLLoaderFactory fxmlLoaders) {
return fxmlLoaders.createScene("/fxml/unlock_invalid_mount_point.fxml");
}
// ------------------
@Binds
@IntoMap
@FxControllerKey(UnlockController.class)
abstract FxController bindUnlockController(UnlockController controller);
@Binds
@IntoMap
@FxControllerKey(UnlockSuccessController.class)
abstract FxController bindUnlockSuccessController(UnlockSuccessController controller);
@Binds
@IntoMap
@FxControllerKey(UnlockInvalidMountPointController.class)
abstract FxController bindUnlockInvalidMountPointController(UnlockInvalidMountPointController controller);
}
@@ -1,198 +0,0 @@
package org.cryptomator.ui.unlock;
import dagger.Lazy;
import javafx.application.Platform;
import javafx.concurrent.Task;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.stage.Window;
import org.cryptomator.common.vaults.Vault;
import org.cryptomator.common.vaults.VaultState;
import org.cryptomator.common.vaults.Volume;
import org.cryptomator.cryptolib.api.CryptoException;
import org.cryptomator.cryptolib.api.InvalidPassphraseException;
import org.cryptomator.keychain.KeychainAccessException;
import org.cryptomator.keychain.KeychainManager;
import org.cryptomator.ui.common.Animations;
import org.cryptomator.ui.common.ErrorComponent;
import org.cryptomator.ui.common.FxmlFile;
import org.cryptomator.ui.common.FxmlScene;
import org.cryptomator.ui.common.UserInteractionLock;
import org.cryptomator.ui.common.VaultService;
import org.cryptomator.ui.unlock.UnlockModule.PasswordEntry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.inject.Inject;
import javax.inject.Named;
import java.io.IOException;
import java.nio.CharBuffer;
import java.nio.file.DirectoryNotEmptyException;
import java.nio.file.FileSystemException;
import java.nio.file.NotDirectoryException;
import java.util.Arrays;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
/**
* A multi-step task that consists of background activities as well as user interaction.
* <p>
* This class runs the unlock process and controls when to display which UI.
*/
@UnlockScoped
public class UnlockWorkflow extends Task<Boolean> {
private static final Logger LOG = LoggerFactory.getLogger(UnlockWorkflow.class);
private final Stage window;
private final Vault vault;
private final VaultService vaultService;
private final AtomicReference<char[]> password;
private final AtomicBoolean savePassword;
private final Optional<char[]> savedPassword;
private final UserInteractionLock<PasswordEntry> passwordEntryLock;
private final Optional<KeychainManager> keychain;
private final Lazy<Scene> unlockScene;
private final Lazy<Scene> successScene;
private final Lazy<Scene> invalidMountPointScene;
private final ErrorComponent.Builder errorComponent;
@Inject
UnlockWorkflow(@UnlockWindow Stage window, @UnlockWindow Vault vault, VaultService vaultService, AtomicReference<char[]> password, @Named("savePassword") AtomicBoolean savePassword, @Named("savedPassword") Optional<char[]> savedPassword, UserInteractionLock<PasswordEntry> passwordEntryLock, Optional<KeychainManager> keychain, @FxmlScene(FxmlFile.UNLOCK) Lazy<Scene> unlockScene, @FxmlScene(FxmlFile.UNLOCK_SUCCESS) Lazy<Scene> successScene, @FxmlScene(FxmlFile.UNLOCK_INVALID_MOUNT_POINT) Lazy<Scene> invalidMountPointScene, ErrorComponent.Builder errorComponent) {
this.window = window;
this.vault = vault;
this.vaultService = vaultService;
this.password = password;
this.savePassword = savePassword;
this.savedPassword = savedPassword;
this.passwordEntryLock = passwordEntryLock;
this.keychain = keychain;
this.unlockScene = unlockScene;
this.successScene = successScene;
this.invalidMountPointScene = invalidMountPointScene;
this.errorComponent = errorComponent;
}
@Override
protected Boolean call() throws InterruptedException, IOException, Volume.VolumeException {
try {
if (attemptUnlock()) {
handleSuccess();
return true;
} else {
cancel(false); // set Tasks state to cancelled
return false;
}
} catch (NotDirectoryException | DirectoryNotEmptyException e) {
handleInvalidMountPoint(e);
throw e; // rethrow to trigger correct exception handling in Task
} catch (CryptoException | Volume.VolumeException | IOException e) {
handleGenericError(e);
throw e; // rethrow to trigger correct exception handling in Task
} finally {
wipePassword(password.get());
wipePassword(savedPassword.orElse(null));
}
}
private boolean attemptUnlock() throws InterruptedException, IOException, Volume.VolumeException {
boolean proceed = password.get() != null || askForPassword(false) == PasswordEntry.PASSWORD_ENTERED;
while (proceed) {
try {
vault.unlock(CharBuffer.wrap(password.get()));
return true;
} catch (InvalidPassphraseException e) {
proceed = askForPassword(true) == PasswordEntry.PASSWORD_ENTERED;
}
}
return false;
}
private PasswordEntry askForPassword(boolean animateShake) throws InterruptedException {
Platform.runLater(() -> {
window.setScene(unlockScene.get());
window.show();
Window owner = window.getOwner();
if (owner != null) {
window.setX(owner.getX() + (owner.getWidth() - window.getWidth()) / 2);
window.setY(owner.getY() + (owner.getHeight() - window.getHeight()) / 2);
} else {
window.centerOnScreen();
}
if (animateShake) {
Animations.createShakeWindowAnimation(window).play();
}
});
return passwordEntryLock.awaitInteraction();
}
private void handleSuccess() {
LOG.info("Unlock of '{}' succeeded.", vault.getDisplayableName());
if (savePassword.get()) {
savePasswordToSystemkeychain();
}
switch (vault.getVaultSettings().actionAfterUnlock().get()) {
case ASK -> Platform.runLater(() -> {
window.setScene(successScene.get());
window.show();
});
case REVEAL -> {
Platform.runLater(window::close);
vaultService.reveal(vault);
}
case IGNORE -> Platform.runLater(window::close);
}
}
private void savePasswordToSystemkeychain() {
if (keychain.isPresent()) {
try {
keychain.get().storePassphrase(vault.getId(), CharBuffer.wrap(password.get()));
} catch (KeychainAccessException e) {
LOG.error("Failed to store passphrase in system keychain.", e);
}
}
}
private void handleInvalidMountPoint(FileSystemException e) {
LOG.error("Unlock failed. Mount point not an empty directory: {}", e.getMessage());
Platform.runLater(() -> {
window.setScene(invalidMountPointScene.get());
});
}
private void handleGenericError(Exception e) {
LOG.error("Unlock failed for technical reasons.", e);
Platform.runLater(() -> {
errorComponent.cause(e).window(window).returnToScene(window.getScene()).build().showErrorScene();
});
}
private void wipePassword(char[] pw) {
if (pw != null) {
Arrays.fill(pw, ' ');
}
}
@Override
protected void scheduled() {
vault.setState(VaultState.PROCESSING);
}
@Override
protected void succeeded() {
vault.setState(VaultState.UNLOCKED);
}
@Override
protected void failed() {
vault.setState(VaultState.LOCKED);
}
@Override
protected void cancelled() {
vault.setState(VaultState.LOCKED);
}
}
@@ -1,57 +0,0 @@
package org.cryptomator.ui.vaultoptions;
import javafx.fxml.FXML;
import javafx.scene.control.CheckBox;
import javafx.scene.control.ChoiceBox;
import javafx.util.StringConverter;
import org.cryptomator.common.settings.UiTheme;
import org.cryptomator.common.settings.WhenUnlocked;
import org.cryptomator.common.vaults.Vault;
import org.cryptomator.ui.common.FxController;
import javax.inject.Inject;
import java.util.ResourceBundle;
@VaultOptionsScoped
public class GeneralVaultOptionsController implements FxController {
private final Vault vault;
private final ResourceBundle resourceBundle;
public CheckBox unlockOnStartupCheckbox;
public ChoiceBox<WhenUnlocked> actionAfterUnlockChoiceBox;
@Inject
GeneralVaultOptionsController(@VaultOptionsWindow Vault vault, ResourceBundle resourceBundle) {
this.vault = vault;
this.resourceBundle = resourceBundle;
}
@FXML
public void initialize() {
unlockOnStartupCheckbox.selectedProperty().bindBidirectional(vault.getVaultSettings().unlockAfterStartup());
actionAfterUnlockChoiceBox.getItems().addAll(WhenUnlocked.values());
actionAfterUnlockChoiceBox.valueProperty().bindBidirectional(vault.getVaultSettings().actionAfterUnlock());
actionAfterUnlockChoiceBox.setConverter(new WhenUnlockedConverter(resourceBundle));
}
private static class WhenUnlockedConverter extends StringConverter<WhenUnlocked> {
private final ResourceBundle resourceBundle;
public WhenUnlockedConverter(ResourceBundle resourceBundle) {
this.resourceBundle = resourceBundle;
}
@Override
public String toString(WhenUnlocked obj) {
return resourceBundle.getString(obj.getDisplayName());
}
@Override
public WhenUnlocked fromString(String string) {
throw new UnsupportedOperationException();
}
}
}
@@ -1,13 +0,0 @@
package org.cryptomator.ui.vaultoptions;
import org.cryptomator.ui.common.FxController;
import javax.inject.Inject;
@VaultOptionsScoped
public class VaultOptionsController implements FxController {
@Inject
VaultOptionsController() {}
}
@@ -1,25 +0,0 @@
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.StackPane?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.shape.Circle?>
<?import org.cryptomator.ui.controls.FontAwesome5IconView?>
<VBox xmlns="http://javafx.com/javafx"
xmlns:fx="http://javafx.com/fxml"
fx:controller="org.cryptomator.ui.mainwindow.VaultDetailMissingVaultController"
alignment="TOP_CENTER"
spacing="9">
<children>
<StackPane alignment="CENTER">
<Circle styleClass="glyph-icon-primary" radius="48"/>
<FontAwesome5IconView styleClass="glyph-icon-white" glyph="FILE" glyphSize="48"/>
<FontAwesome5IconView styleClass="glyph-icon-primary" glyph="SEARCH" glyphSize="24">
<StackPane.margin>
<Insets top="12"/>
</StackPane.margin>
</FontAwesome5IconView>
</StackPane>
<Label text="%main.vaultDetail.missing.info" wrapText="true"/>
</children>
</VBox>
@@ -1,24 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.CheckBox?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.control.ChoiceBox?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.control.Label?>
<VBox xmlns="http://javafx.com/javafx"
xmlns:fx="http://javafx.com/fxml"
fx:controller="org.cryptomator.ui.vaultoptions.GeneralVaultOptionsController"
spacing="6">
<padding>
<Insets topRightBottomLeft="12"/>
</padding>
<children>
<CheckBox text="%vaultOptions.general.unlockAfterStartup" fx:id="unlockOnStartupCheckbox"/>
<HBox spacing="6" alignment="CENTER_LEFT">
<Label text="%vaultOptions.general.actionAfterUnlock"/>
<ChoiceBox fx:id="actionAfterUnlockChoiceBox"/>
</HBox>
</children>
</VBox>
@@ -1,148 +0,0 @@
# Locale Specific CSS files such as CJK, RTL,...
# Generics
## Button
generic.button.apply=Použiť
generic.button.back=Späť
generic.button.cancel=Zrušiť
generic.button.change=Zmeniť
generic.button.close=Zavrieť
generic.button.copy=Kopírovať
generic.button.copied=Skopírované!
generic.button.done=Hotovo
generic.button.next=Ďalej
generic.button.print=Tlač
## Error
generic.error.title=Vyskytla sa neočakávaná chyba
generic.error.instruction=Toto sa nemalo stať. Nahláste text chyby uvedený nižšie a uveďte popis krokov, ktoré viedli k tejto chybe.
# Tray Menu
traymenu.showMainWindow=Zobraziť
traymenu.showPreferencesWindow=Predvoľby
traymenu.lockAllVaults=Zamknúť všetky
traymenu.quitApplication=Ukončiť
traymenu.vault.unlock=Odomknúť
traymenu.vault.lock=Uzamknúť
traymenu.vault.reveal=Odkryť
# Add Vault Wizard
addvaultwizard.title=Pridať trezor
## Welcome
addvaultwizard.welcome.newButton=Vytvoriť nový trezor
addvaultwizard.welcome.existingButton=Otvoriť existujúci trezor
## New
### Name
addvaultwizard.new.nameInstruction=Zvoľte názov pre trezor
addvaultwizard.new.namePrompt=Názov trezoru
### Location
addvaultwizard.new.locationInstruction=Kde by mal Cryptomator uchovávať šifrované súbory vášho trezoru?
addvaultwizard.new.locationLabel=Umiestnenie úložiska
addvaultwizard.new.directoryPickerLabel=Vlastné umiestnenie
addvaultwizard.new.directoryPickerButton=Vybrať…
addvaultwizard.new.directoryPickerTitle=Vybrať adresár
addvaultwizard.new.fileAlreadyExists=Na tejto ceste nie je možné vytvoriť trezor, pretože niektorý objekt už existuje.
addvaultwizard.new.locationDoesNotExist=Peňaženka sa nedá vytvoriť na danej ceste pretože ani jedna cesta neexistuje.
addvaultwizard.new.invalidName=Neplatný názov trezoru. Zvážte bežný názov adresára.
### Password
addvaultwizard.new.createVaultBtn=Vytvoriť trezor
addvaultwizard.new.generateRecoveryKeyChoice=Bez hesla nebudete mať prístup k svojim údajom. Chcete obnovovací kľúč pre prípad straty hesla?
addvaultwizard.new.generateRecoveryKeyChoice.yes=Áno, prosím, istota je istota
addvaultwizard.new.generateRecoveryKeyChoice.no=Nie, ďakujem, nestratím svoje heslo
### Information
addvault.new.readme.storageLocation.fileName=Dôležité.rtf
addvault.new.readme.storageLocation.1=⚠️ SÚBORY TREZORU ⚠️
addvault.new.readme.storageLocation.2=Toto je umiestnenie úložiska vášho trezoru.
addvault.new.readme.storageLocation.3=NEVYKONÁVAJTE
addvault.new.readme.storageLocation.4=zmeniť akékoľvek súbory v tomto adresári alebo
addvault.new.readme.storageLocation.5=vložiť do tohto adresára akékoľvek súbory na šifrovanie.
addvault.new.readme.storageLocation.6=Ak chcete šifrovať súbory a zobraziť obsah trezoru, postupujte takto:
addvault.new.readme.storageLocation.7=1. Pridajte tento trezor do Cryptomatoru.
addvault.new.readme.storageLocation.8=2. Odomknite trezor v Cryptomatore.
addvault.new.readme.storageLocation.9=3. Otvorte prístupové miesto kliknutím na tlačidlo „Odkryť“.
addvault.new.readme.storageLocation.10=Ak potrebujete pomoc, navštívte dokumentáciu: %s
addvault.new.readme.accessLocation.fileName=VITAJTE.rtf
addvault.new.readme.accessLocation.1=🔐️ ZAŠIFROVANÝ ZVÄZOK 🔐️
addvault.new.readme.accessLocation.2=Toto je prístupové miesto vášho trezoru.
addvault.new.readme.accessLocation.3=Všetky súbory pridané do tohto zväzku budú šifrované programom Cryptomator. Môžete na tom pracovať ako na akomkoľvek inom disku / priečinku. Toto je iba dešifrované zobrazenie jeho obsahu, vaše súbory zostávajú stále šifrované na pevnom disku.
addvault.new.readme.accessLocation.4=Tento súbor môžete kedykoľvek odstrániť.
## Existing
addvaultwizard.existing.instruction=Vyberte súbor „masterkey.cryptomator“ existujúceho trezoru.
addvaultwizard.existing.chooseBtn=Vybrať…
## Success
addvaultwizard.success.nextStepsInstructions=Pridaný trezor "%s".\nAk chcete získať prístup alebo pridať obsah, musíte tento trezor odomknúť. Prípadne ju môžete odomknúť kedykoľvek neskôr.
addvaultwizard.success.unlockNow=Odomknúť teraz
# Remove Vault
removeVault.title=Odstrániť trezor
removeVault.information=To spôsobí, že Cryptomator iba zabudne na tento trezor. Môžete ho pridať znova neskôr. Z pevného disku sa neodstránia žiadne šifrované súbory.
removeVault.confirmBtn=Odstrániť trezor
# Change Password
changepassword.title=Zmeniť heslo
changepassword.enterOldPassword=Zadaj aktuálne heslo pre "%s"
changepassword.finalConfirmation=Chápem, že ak zabudnem svoje heslo, nebudem mať prístup k svojim údajom
# Forget Password
forgetPassword.title=Zabudnuté heslo
forgetPassword.information=Týmto vymažete uložené heslo tohto trezoru z vášho systému kľúčov.
forgetPassword.confirmBtn=Zabudnuté heslo
# Unlock
unlock.title=Odomknúť trezor
unlock.passwordPrompt=Zadajte heslo pre "%s":
unlock.savePassword=Uložiť heslo
unlock.unlockBtn=Odomknúť
## Success
unlock.success.message=Úspešne sa odomkol "%s"! Váš trezor je teraz prístupný.
unlock.success.revealBtn=Odhaliť trezor
## Invalid Mount Point
# Migration
## Start
## Run
## Sucess
migration.success.unlockNow=Odomknúť teraz
## Missing file system capabilities
## Impossible
# Preferences
preferences.title=Predvoľby
## General
## Volume
## Updates
## Donation Key
## About
# Main Window
main.closeBtn.tooltip=Zavrieť
main.preferencesBtn.tooltip=Predvoľby
## Drag 'n' Drop
## Vault List
main.vaultlist.contextMenu.remove=Odstrániť trezor
main.vaultlist.addVaultBtn=Pridať trezor
## Vault Detail
### Welcome
### Locked
main.vaultDetail.unlockBtn=Odomknúť…
main.vaultDetail.unlockNowBtn=Odomknúť teraz
main.vaultDetail.passwordSavedInKeychain=Heslo uložené
### Unlocked
main.vaultDetail.lockBtn=Uzamknúť
### Missing
### Needs Migration
# Wrong File Alert
# Vault Options
## General
## Mount
vaultOptions.mount.mountPoint.directoryPickerButton=Vybrať…
## Master Key
vaultOptions.masterkey.changePasswordBtn=Zmeniť heslo
vaultOptions.masterkey.forgetSavedPasswordBtn=Zabudnúť uložené heslo
# Recovery Key
# New Password
# Quit
@@ -1,91 +0,0 @@
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see http://www.gnu.org/licenses/.
Cryptomator uses 52 third-party dependencies under the following licenses:
Apache License v2.0:
- HKDF-RFC5869 (at.favre.lib:hkdf:1.1.0 - https://github.com/patrickfav/hkdf)
- jffi (com.github.jnr:jffi:1.2.23 - http://github.com/jnr/jffi)
- jnr-a64asm (com.github.jnr:jnr-a64asm:1.0.0 - http://nexus.sonatype.org/oss-repository-hosting.html/jnr-a64asm)
- jnr-constants (com.github.jnr:jnr-constants:0.9.15 - http://github.com/jnr/jnr-constants)
- jnr-enxio (com.github.jnr:jnr-enxio:0.21 - http://github.com/jnr/jnr-enxio)
- jnr-ffi (com.github.jnr:jnr-ffi:2.1.12 - http://github.com/jnr/jnr-ffi)
- jnr-unixsocket (com.github.jnr:jnr-unixsocket:0.23 - http://github.com/jnr/jnr-unixsocket)
- FindBugs-jsr305 (com.google.code.findbugs:jsr305:3.0.2 - http://findbugs.sourceforge.net/)
- Gson (com.google.code.gson:gson:2.8.6 - https://github.com/google/gson/gson)
- Dagger (com.google.dagger:dagger:2.27 - https://github.com/google/dagger)
- error-prone annotations (com.google.errorprone:error_prone_annotations:2.3.4 - http://nexus.sonatype.org/oss-repository-hosting.html/error_prone_parent/error_prone_annotations)
- Guava InternalFutureFailureAccess and InternalFutures (com.google.guava:failureaccess:1.0.1 - https://github.com/google/guava/failureaccess)
- Guava: Google Core Libraries for Java (com.google.guava:guava:28.2-jre - https://github.com/google/guava/guava)
- Guava ListenableFuture only (com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava - https://github.com/google/guava/listenablefuture)
- J2ObjC Annotations (com.google.j2objc:j2objc-annotations:1.3 - https://github.com/google/j2objc/)
- Apache Commons CLI (commons-cli:commons-cli:1.4 - http://commons.apache.org/proper/commons-cli/)
- Apache Commons IO (commons-io:commons-io:2.6 - http://commons.apache.org/proper/commons-io/)
- javax.inject (javax.inject:javax.inject:1 - http://code.google.com/p/atinject/)
- Java Native Access (net.java.dev.jna:jna:5.1.0 - https://github.com/java-native-access/jna)
- Java Native Access Platform (net.java.dev.jna:jna-platform:5.1.0 - https://github.com/java-native-access/jna)
- Apache Commons Lang (org.apache.commons:commons-lang3:3.9 - http://commons.apache.org/proper/commons-lang/)
- Apache HttpCore (org.apache.httpcomponents:httpcore:4.4.13 - http://hc.apache.org/httpcomponents-core-ga)
- Jackrabbit WebDAV Library (org.apache.jackrabbit:jackrabbit-webdav:2.21.0 - http://jackrabbit.apache.org/jackrabbit-webdav/)
- Jetty :: Http Utility (org.eclipse.jetty:jetty-http:9.4.28.v20200408 - http://www.eclipse.org/jetty)
- Jetty :: IO Utility (org.eclipse.jetty:jetty-io:9.4.28.v20200408 - http://www.eclipse.org/jetty)
- Jetty :: Security (org.eclipse.jetty:jetty-security:9.4.28.v20200408 - http://www.eclipse.org/jetty)
- Jetty :: Server Core (org.eclipse.jetty:jetty-server:9.4.28.v20200408 - http://www.eclipse.org/jetty)
- Jetty :: Servlet Handling (org.eclipse.jetty:jetty-servlet:9.4.28.v20200408 - http://www.eclipse.org/jetty)
- Jetty :: Utilities (org.eclipse.jetty:jetty-util:9.4.28.v20200408 - http://www.eclipse.org/jetty)
- Jetty :: Webapp Application Support (org.eclipse.jetty:jetty-webapp:9.4.28.v20200408 - http://www.eclipse.org/jetty)
- Jetty :: XML utilities (org.eclipse.jetty:jetty-xml:9.4.28.v20200408 - http://www.eclipse.org/jetty)
BSD:
- asm (org.ow2.asm:asm:7.1 - http://asm.ow2.org/)
- asm-analysis (org.ow2.asm:asm-analysis:7.1 - http://asm.ow2.org/)
- asm-commons (org.ow2.asm:asm-commons:7.1 - http://asm.ow2.org/)
- asm-tree (org.ow2.asm:asm-tree:7.1 - http://asm.ow2.org/)
- asm-util (org.ow2.asm:asm-util:7.1 - http://asm.ow2.org/)
Eclipse Public License - Version 1.0:
- Jetty :: Http Utility (org.eclipse.jetty:jetty-http:9.4.28.v20200408 - http://www.eclipse.org/jetty)
- Jetty :: IO Utility (org.eclipse.jetty:jetty-io:9.4.28.v20200408 - http://www.eclipse.org/jetty)
- Jetty :: Security (org.eclipse.jetty:jetty-security:9.4.28.v20200408 - http://www.eclipse.org/jetty)
- Jetty :: Server Core (org.eclipse.jetty:jetty-server:9.4.28.v20200408 - http://www.eclipse.org/jetty)
- Jetty :: Servlet Handling (org.eclipse.jetty:jetty-servlet:9.4.28.v20200408 - http://www.eclipse.org/jetty)
- Jetty :: Utilities (org.eclipse.jetty:jetty-util:9.4.28.v20200408 - http://www.eclipse.org/jetty)
- Jetty :: Webapp Application Support (org.eclipse.jetty:jetty-webapp:9.4.28.v20200408 - http://www.eclipse.org/jetty)
- Jetty :: XML utilities (org.eclipse.jetty:jetty-xml:9.4.28.v20200408 - http://www.eclipse.org/jetty)
Eclipse Public License - v 2.0:
- jnr-posix (com.github.jnr:jnr-posix:3.0.54 - http://nexus.sonatype.org/oss-repository-hosting.html/jnr-posix)
GPLv2:
- jnr-posix (com.github.jnr:jnr-posix:3.0.54 - http://nexus.sonatype.org/oss-repository-hosting.html/jnr-posix)
GPLv2+CE:
- Java Servlet API (javax.servlet:javax.servlet-api:3.1.0 - http://servlet-spec.java.net)
- javafx-base (org.openjfx:javafx-base:14 - https://openjdk.java.net/projects/openjfx/javafx-base/)
- javafx-controls (org.openjfx:javafx-controls:14 - https://openjdk.java.net/projects/openjfx/javafx-controls/)
- javafx-fxml (org.openjfx:javafx-fxml:14 - https://openjdk.java.net/projects/openjfx/javafx-fxml/)
- javafx-graphics (org.openjfx:javafx-graphics:14 - https://openjdk.java.net/projects/openjfx/javafx-graphics/)
LGPL 2.1:
- dbus-java (com.github.hypfvieh:dbus-java:3.2.1 - https://github.com/hypfvieh/dbus-java/dbus-java)
- jnr-posix (com.github.jnr:jnr-posix:3.0.54 - http://nexus.sonatype.org/oss-repository-hosting.html/jnr-posix)
- Java Native Access (net.java.dev.jna:jna:5.1.0 - https://github.com/java-native-access/jna)
- Java Native Access Platform (net.java.dev.jna:jna-platform:5.1.0 - https://github.com/java-native-access/jna)
MIT License:
- java jwt (com.auth0:java-jwt:3.10.2 - https://github.com/auth0/java-jwt)
- java-utils (com.github.hypfvieh:java-utils:1.0.6 - https://github.com/hypfvieh/java-utils)
- jnr-x86asm (com.github.jnr:jnr-x86asm:1.0.2 - http://github.com/jnr/jnr-x86asm)
- jnr-fuse (com.github.serceman:jnr-fuse:0.5.4 - no url defined)
- zxcvbn4j (com.nulab-inc:zxcvbn:1.3.0 - https://github.com/nulab/zxcvbn4j)
- secret-service (de.swiesend:secret-service:1.0.0 - https://github.com/swiesend/secret-service)
- Checker Qual (org.checkerframework:checker-qual:2.10.0 - https://checkerframework.org)
- SLF4J API Module (org.slf4j:slf4j-api:1.7.30 - http://www.slf4j.org)
The BSD 2-Clause License:
- EasyBind (org.fxmisc.easybind:easybind:1.0.3 - http://www.fxmisc.org/easybind/)
Cryptomator uses other third-party assets under the following licenses:
SIL OFL 1.1 License:
- Font Awesome 5.12.0 (https://fontawesome.com/)
+601
View File
@@ -0,0 +1,601 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0" 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>
<groupId>org.cryptomator</groupId>
<artifactId>cryptomator</artifactId>
<version>1.6.0-SNAPSHOT</version>
<name>Cryptomator Desktop App</name>
<organization>
<name>cryptomator.org</name>
<url>https://cryptomator.org</url>
</organization>
<developers>
<developer>
<name>Sebastian Stenzel</name>
<email>sebastian.stenzel@gmail.com</email>
<timezone>+1</timezone>
</developer>
</developers>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.jdk.version>16</project.jdk.version>
<!-- cryptomator dependencies -->
<cryptomator.cryptofs.version>2.1.0-beta8</cryptomator.cryptofs.version>
<cryptomator.integrations.version>1.0.0-rc1</cryptomator.integrations.version>
<cryptomator.integrations.win.version>1.0.0-beta2</cryptomator.integrations.win.version>
<cryptomator.integrations.mac.version>1.0.0-beta2</cryptomator.integrations.mac.version>
<cryptomator.integrations.linux.version>1.0.0-beta1</cryptomator.integrations.linux.version>
<cryptomator.fuse.version>1.3.1</cryptomator.fuse.version>
<cryptomator.dokany.version>1.3.1</cryptomator.dokany.version>
<cryptomator.webdav.version>1.2.4</cryptomator.webdav.version>
<!-- 3rd party dependencies -->
<javafx.version>16</javafx.version>
<commons-lang3.version>3.12.0</commons-lang3.version>
<jwt.version>3.17.0</jwt.version>
<easybind.version>2.2</easybind.version>
<guava.version>30.1.1-jre</guava.version>
<dagger.version>2.37</dagger.version>
<gson.version>2.8.6</gson.version>
<slf4j.version>1.7.31</slf4j.version>
<logback.version>1.2.3</logback.version>
<!-- test dependencies -->
<junit.jupiter.version>5.7.2</junit.jupiter.version>
<mockito.version>3.11.2</mockito.version>
<hamcrest.version>2.2</hamcrest.version>
</properties>
<dependencies>
<!-- Cryptomator Libs -->
<dependency>
<groupId>org.cryptomator</groupId>
<artifactId>cryptofs</artifactId>
<version>${cryptomator.cryptofs.version}</version>
</dependency>
<dependency>
<groupId>org.cryptomator</groupId>
<artifactId>fuse-nio-adapter</artifactId>
<version>${cryptomator.fuse.version}</version>
</dependency>
<dependency>
<groupId>org.cryptomator</groupId>
<artifactId>dokany-nio-adapter</artifactId>
<version>${cryptomator.dokany.version}</version>
</dependency>
<dependency>
<groupId>org.cryptomator</groupId>
<artifactId>webdav-nio-adapter</artifactId>
<version>${cryptomator.webdav.version}</version>
</dependency>
<dependency>
<groupId>org.cryptomator</groupId>
<artifactId>integrations-api</artifactId>
<version>${cryptomator.integrations.version}</version>
</dependency>
<!-- JavaFX -->
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-base</artifactId>
<version>${javafx.version}</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-graphics</artifactId>
<version>${javafx.version}</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>${javafx.version}</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-fxml</artifactId>
<version>${javafx.version}</version>
</dependency>
<!-- Logging -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>${logback.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback.version}</version>
</dependency>
<!-- Apache Commons -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>${commons-lang3.version}</version>
</dependency>
<!-- JWT -->
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>${jwt.version}</version>
</dependency>
<!-- EasyBind -->
<dependency>
<groupId>com.tobiasdiez</groupId>
<artifactId>easybind</artifactId>
<version>${easybind.version}</version>
</dependency>
<!-- Zxcvbn -->
<dependency>
<groupId>com.nulab-inc</groupId>
<artifactId>zxcvbn</artifactId>
<version>1.3.0</version>
</dependency>
<!-- Google -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>${guava.version}</version>
</dependency>
<dependency>
<groupId>com.google.dagger</groupId>
<artifactId>dagger</artifactId>
<version>${dagger.version}</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>${gson.version}</version>
</dependency>
<!-- JUnit / Mockito / Hamcrest -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>${junit.jupiter.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>${mockito.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest</artifactId>
<version>${hamcrest.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-swing</artifactId>
<version>${javafx.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.jimfs</groupId>
<artifactId>jimfs</artifactId>
<version>1.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>3.2.0</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.1.2</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.3.0</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.2</version>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>license-maven-plugin</artifactId>
<version>2.0.0</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.0</version>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.6</version>
</plugin>
<plugin>
<groupId>org.owasp</groupId>
<artifactId>dependency-check-maven</artifactId>
<version>6.0.3</version>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<release>${project.jdk.version}</release>
<annotationProcessorPaths>
<path>
<groupId>com.google.dagger</groupId>
<artifactId>dagger-compiler</artifactId>
<version>${dagger.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<!-- adds Implementation-Version which can be read during runtime -->
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<executions>
<execution>
<id>copy-resources</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}</outputDirectory>
<resources>
<resource>
<directory>${project.basedir}/src/package</directory>
<includes>
<include>version.txt</include>
<include>ffi-version.txt</include>
<include>launcher-mac.sh</include>
<include>launcher-linux.sh</include>
<include>launcher-win.bat</include>
<include>LICENSE.txt</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-libs</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<includeScope>runtime</includeScope>
<outputDirectory>${project.build.directory}/libs</outputDirectory>
<excludeClassifiers>linux,mac,win</excludeClassifiers>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>license-maven-plugin</artifactId>
<executions>
<execution>
<id>add-third-party</id>
<goals>
<goal>add-third-party</goal>
</goals>
<phase>generate-resources</phase>
<configuration>
<outputDirectory>${project.basedir}/src/main/resources/license</outputDirectory>
<thirdPartyFilename>THIRD-PARTY.txt</thirdPartyFilename>
<includedScopes>compile</includedScopes>
<excludedGroups>org\.cryptomator</excludedGroups>
<licenseMerges>
<licenseMerge>Apache License v2.0|Apache License, Version 2.0|The Apache Software License, Version 2.0|Apache 2.0|Apache Software License - Version 2.0</licenseMerge>
<licenseMerge>MIT License|The MIT License (MIT)|The MIT License|MIT license</licenseMerge>
<licenseMerge>LGPL 2.1|LGPL, version 2.1|GNU Lesser/Library General Public License version 2|GNU Lesser General Public License Version 2.1</licenseMerge>
<licenseMerge>GPLv2|GNU General Public License Version 2</licenseMerge>
<licenseMerge>GPLv2+CE|CDDL + GPLv2 with classpath exception</licenseMerge>
</licenseMerges>
<fileTemplate>${project.basedir}/src/license/template.ftl</fileTemplate>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>coverage</id>
<build>
<plugins>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<executions>
<execution>
<id>prepare-agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>report</id>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
<configuration>
<excludes>
<exclude>**/*_*</exclude>
<exclude>**/Dagger*</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>dependency-check</id>
<build>
<plugins>
<plugin>
<groupId>org.owasp</groupId>
<artifactId>dependency-check-maven</artifactId>
<configuration>
<cveValidForHours>24</cveValidForHours>
<failBuildOnCVSS>0</failBuildOnCVSS>
<skipTestScope>true</skipTestScope>
<detail>true</detail>
<suppressionFile>suppression.xml</suppressionFile>
</configuration>
<executions>
<execution>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>mac</id>
<activation>
<os>
<family>mac</family>
</os>
<property>
<name>idea.version</name>
</property>
</activation>
<dependencies>
<dependency>
<groupId>org.cryptomator</groupId>
<artifactId>integrations-mac</artifactId>
<version>${cryptomator.integrations.mac.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<id>assemble-mac</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptors>
<descriptor>assembly-mac.xml</descriptor>
</descriptors>
<appendAssemblyId>false</appendAssemblyId>
<finalName>buildkit-mac</finalName>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-mac-libs</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/libs</outputDirectory>
<includeGroupIds>org.openjfx</includeGroupIds>
<classifier>mac</classifier>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>linux</id>
<activation>
<os>
<family>unix</family>
<name>Linux</name>
</os>
<property>
<name>idea.version</name>
</property>
</activation>
<dependencies>
<dependency>
<groupId>org.cryptomator</groupId>
<artifactId>integrations-linux</artifactId>
<version>${cryptomator.integrations.linux.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<id>assemble-linux</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptors>
<descriptor>assembly-linux.xml</descriptor>
</descriptors>
<appendAssemblyId>false</appendAssemblyId>
<finalName>buildkit-linux</finalName>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-linux-libs</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/libs</outputDirectory>
<includeGroupIds>org.openjfx</includeGroupIds>
<classifier>linux</classifier>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>windows</id>
<activation>
<os>
<family>windows</family>
</os>
<property>
<name>idea.version</name>
</property>
</activation>
<dependencies>
<dependency>
<groupId>org.cryptomator</groupId>
<artifactId>integrations-win</artifactId>
<version>${cryptomator.integrations.win.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<id>assemble-win</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptors>
<descriptor>assembly-win.xml</descriptor>
</descriptors>
<appendAssemblyId>false</appendAssemblyId>
<finalName>buildkit-win</finalName>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-win-libs</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/libs</outputDirectory>
<includeGroupIds>org.openjfx</includeGroupIds>
<classifier>win</classifier>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
@@ -20,16 +20,16 @@ along with this program. If not, see http://www.gnu.org/licenses/.
Cryptomator uses ${dependencyMap?size} third-party dependencies under the following licenses:
<#list licenseMap as e>
<#assign license = e.getKey()/>
<#assign projects = e.getValue()/>
<#if projects?size &gt; 0>
${license}:
<#list projects as project>
- ${artifactFormat(project)}
</#list>
</#if>
<#assign license = e.getKey()/>
<#assign projects = e.getValue()/>
<#if projects?size &gt; 0>
${license}:
<#list projects as project>
- ${artifactFormat(project)}
</#list>
</#if>
</#list>
Cryptomator uses other third-party assets under the following licenses:
SIL OFL 1.1 License:
- Font Awesome 5.12.0 (https://fontawesome.com/)
SIL OFL 1.1 License:
- Font Awesome 5.12.0 (https://fontawesome.com/)
@@ -5,25 +5,30 @@
*******************************************************************************/
package org.cryptomator.common;
import com.tobiasdiez.easybind.EasyBind;
import dagger.Module;
import dagger.Provides;
import javafx.beans.binding.Binding;
import javafx.beans.binding.Bindings;
import javafx.collections.ObservableList;
import org.apache.commons.lang3.SystemUtils;
import org.cryptomator.common.keychain.KeychainModule;
import org.cryptomator.common.settings.Settings;
import org.cryptomator.common.settings.SettingsProvider;
import org.cryptomator.common.vaults.Vault;
import org.cryptomator.common.vaults.VaultComponent;
import org.cryptomator.common.vaults.VaultListManager;
import org.cryptomator.common.vaults.VaultListModule;
import org.cryptomator.cryptolib.common.MasterkeyFileAccess;
import org.cryptomator.frontend.webdav.WebDavServer;
import org.fxmisc.easybind.EasyBind;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.inject.Named;
import javax.inject.Singleton;
import javafx.beans.binding.Binding;
import javafx.beans.binding.Bindings;
import javafx.collections.ObservableList;
import java.net.InetSocketAddress;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Comparator;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@@ -33,7 +38,7 @@ import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
@Module(subcomponents = {VaultComponent.class})
@Module(subcomponents = {VaultComponent.class}, includes = {VaultListModule.class, KeychainModule.class})
public abstract class CommonsModule {
private static final Logger LOG = LoggerFactory.getLogger(CommonsModule.class);
@@ -41,15 +46,34 @@ public abstract class CommonsModule {
private static final int NUM_CORE_BG_THREADS = 6;
private static final long BG_THREAD_KEEPALIVE_SECONDS = 60l;
@SuppressWarnings("SpellCheckingInspection")
@Provides
@Singleton
@Named("licensePublicKey")
static String provideLicensePublicKey() {
// in PEM format without the dash-escaped begin/end lines
return "MIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQB7NfnqiZbg2KTmoflmZ71PbXru7oW" //
+ "fmnV2yv3eDjlDfGruBrqz9TtXBZV/eYWt31xu1osIqaT12lKBvZ511aaAkIBeOEV" //
+ "gwcBIlJr6kUw7NKzeJt7r2rrsOyQoOG2nWc/Of/NBqA3mIZRHk5Aq1YupFdD26QE" //
+ "r0DzRyj4ixPIt38CQB8=";
return """
MIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQB7NfnqiZbg2KTmoflmZ71PbXru7oW\
fmnV2yv3eDjlDfGruBrqz9TtXBZV/eYWt31xu1osIqaT12lKBvZ511aaAkIBeOEV\
gwcBIlJr6kUw7NKzeJt7r2rrsOyQoOG2nWc/Of/NBqA3mIZRHk5Aq1YupFdD26QE\
r0DzRyj4ixPIt38CQB8=\
""";
}
@Provides
@Singleton
static SecureRandom provideCSPRNG() {
try {
return SecureRandom.getInstanceStrong();
} catch (NoSuchAlgorithmException e) {
throw new IllegalStateException("A strong algorithm must exist in every Java platform.", e);
}
}
@Provides
@Singleton
static MasterkeyFileAccess provideMasterkeyFileAccess(SecureRandom csprng) {
return new MasterkeyFileAccess(Constants.PEPPER, csprng);
}
@Provides
@@ -65,12 +89,6 @@ public abstract class CommonsModule {
return settingsProvider.get();
}
@Provides
@Singleton
static ObservableList<Vault> provideVaultList(VaultListManager vaultListManager) {
return vaultListManager.getVaultList();
}
@Provides
@Singleton
static ScheduledExecutorService provideScheduledExecutorService(ShutdownHook shutdownHook) {
@@ -0,0 +1,10 @@
package org.cryptomator.common;
public interface Constants {
String MASTERKEY_FILENAME = "masterkey.cryptomator";
String MASTERKEY_BACKUP_SUFFIX = ".bkup";
String VAULTCONFIG_FILENAME = "vault.cryptomator";
byte[] PEPPER = new byte[0];
}
@@ -21,14 +21,13 @@ import java.util.stream.StreamSupport;
public class Environment {
private static final Logger LOG = LoggerFactory.getLogger(Environment.class);
private static final String USER_HOME = System.getProperty("user.home");
private static final Path RELATIVE_HOME_DIR = Paths.get("~");
private static final Path ABSOLUTE_HOME_DIR = Paths.get(USER_HOME);
private static final char PATH_LIST_SEP = ':';
private static final int DEFAULT_MIN_PW_LENGTH = 8;
@Inject
public Environment() {
LOG.debug("user.home: {}", System.getProperty("user.home"));
LOG.debug("java.library.path: {}", System.getProperty("java.library.path"));
LOG.debug("user.language: {}", System.getProperty("user.language"));
LOG.debug("user.region: {}", System.getProperty("user.region"));
@@ -40,6 +39,8 @@ public class Environment {
LOG.debug("cryptomator.mountPointsDir: {}", System.getProperty("cryptomator.mountPointsDir"));
LOG.debug("cryptomator.minPwLength: {}", System.getProperty("cryptomator.minPwLength"));
LOG.debug("cryptomator.buildNumber: {}", System.getProperty("cryptomator.buildNumber"));
LOG.debug("cryptomator.showTrayIcon: {}", System.getProperty("cryptomator.showTrayIcon"));
LOG.debug("fuse.experimental: {}", Boolean.getBoolean("fuse.experimental"));
}
public boolean useCustomLogbackConfig() {
@@ -74,6 +75,15 @@ public class Environment {
return getInt("cryptomator.minPwLength", DEFAULT_MIN_PW_LENGTH);
}
public boolean showTrayIcon() {
return Boolean.getBoolean("cryptomator.showTrayIcon");
}
@Deprecated // TODO: remove as soon as custom mount path works properly on Win+Fuse
public boolean useExperimentalFuse() {
return Boolean.getBoolean("fuse.experimental");
}
private int getInt(String propertyName, int defaultValue) {
String value = System.getProperty(propertyName);
try {
@@ -87,16 +97,21 @@ public class Environment {
String value = System.getProperty(propertyName);
return Optional.ofNullable(value).map(Paths::get);
}
// visible for testing
Stream<Path> getPaths(String propertyName) {
// visible for testing
public Path getHomeDir() {
return getPath("user.home").orElseThrow();
}
// visible for testing
public Stream<Path> getPaths(String propertyName) {
Stream<String> rawSettingsPaths = getRawList(propertyName, PATH_LIST_SEP);
return rawSettingsPaths.filter(Predicate.not(Strings::isNullOrEmpty)).map(Paths::get).map(this::replaceHomeDir);
}
private Path replaceHomeDir(Path path) {
if (path.startsWith(RELATIVE_HOME_DIR)) {
return ABSOLUTE_HOME_DIR.resolve(RELATIVE_HOME_DIR.relativize(path));
return getHomeDir().resolve(RELATIVE_HOME_DIR.relativize(path));
} else {
return path;
}
@@ -108,8 +123,8 @@ public class Environment {
return Stream.empty();
} else {
Iterable<String> iter = Splitter.on(separator).split(value);
Spliterator<String> spliter = Spliterators.spliteratorUnknownSize(iter.iterator(), Spliterator.ORDERED | Spliterator.IMMUTABLE);
return StreamSupport.stream(spliter, false);
Spliterator<String> spliterator = Spliterators.spliteratorUnknownSize(iter.iterator(), Spliterator.ORDERED | Spliterator.IMMUTABLE);
return StreamSupport.stream(spliterator, false);
}
}
}
@@ -33,8 +33,8 @@ class LicenseChecker {
try {
byte[] keyBytes = BaseEncoding.base64().decode(pemEncodedPublicKey);
PublicKey key = KeyFactory.getInstance("EC").generatePublic(new X509EncodedKeySpec(keyBytes));
if (key instanceof ECPublicKey) {
return (ECPublicKey) key;
if (key instanceof ECPublicKey k) {
return k;
} else {
throw new IllegalStateException("Key not an EC public key.");
}
@@ -1,15 +1,15 @@
package org.cryptomator.common;
import com.auth0.jwt.interfaces.DecodedJWT;
import org.cryptomator.common.settings.Settings;
import javax.inject.Inject;
import javax.inject.Singleton;
import javafx.beans.binding.Bindings;
import javafx.beans.binding.BooleanBinding;
import javafx.beans.binding.StringBinding;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import org.cryptomator.common.settings.Settings;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.util.Optional;
@Singleton
@@ -8,10 +8,10 @@
*******************************************************************************/
package org.cryptomator.common;
import java.util.Comparator;
import org.apache.commons.lang3.StringUtils;
import java.util.Comparator;
/**
* Compares version strings according to <a href="http://semver.org/spec/v2.0.0.html">SemVer 2.0.0</a>.
*/
@@ -60,17 +60,17 @@ public class SemVerComparator implements Comparator<String> {
final int commonCompCount = Math.min(vComps1.length, vComps2.length);
for (int i = 0; i < commonCompCount; i++) {
int subversionComparisionResult = 0;
int subversionComparisonResult = 0;
try {
final int v1 = Integer.parseInt(vComps1[i]);
final int v2 = Integer.parseInt(vComps2[i]);
subversionComparisionResult = v1 - v2;
subversionComparisonResult = v1 - v2;
} catch (NumberFormatException ex) {
// ok, lets compare this fragment lexicographically
subversionComparisionResult = vComps1[i].compareTo(vComps2[i]);
subversionComparisonResult = vComps1[i].compareTo(vComps2[i]);
}
if (subversionComparisionResult != 0) {
return subversionComparisionResult;
if (subversionComparisonResult != 0) {
return subversionComparisonResult;
}
}
@@ -1,60 +1,78 @@
package org.cryptomator.keychain;
package org.cryptomator.common.keychain;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import org.cryptomator.integrations.keychain.KeychainAccessException;
import org.cryptomator.integrations.keychain.KeychainAccessProvider;
import javax.inject.Inject;
import javax.inject.Singleton;
import javafx.application.Platform;
import javafx.beans.binding.ObjectExpression;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.ReadOnlyBooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Arrays;
public class KeychainManager implements KeychainAccessStrategy {
@Singleton
public class KeychainManager implements KeychainAccessProvider {
private static final Logger LOG = LoggerFactory.getLogger(KeychainManager.class);
private final ObjectExpression<KeychainAccessProvider> keychain;
private final LoadingCache<String, BooleanProperty> passphraseStoredProperties;
private final KeychainAccessStrategy keychain;
private LoadingCache<String, BooleanProperty> passphraseStoredProperties;
KeychainManager(KeychainAccessStrategy keychain) {
assert keychain.isSupported();
this.keychain = keychain;
@Inject
KeychainManager(ObjectExpression<KeychainAccessProvider> selectedKeychain) {
this.keychain = selectedKeychain;
this.passphraseStoredProperties = CacheBuilder.newBuilder() //
.weakValues() //
.build(CacheLoader.from(this::createStoredPassphraseProperty));
keychain.addListener(ignored -> passphraseStoredProperties.invalidateAll());
}
private KeychainAccessProvider getKeychainOrFail() throws KeychainAccessException {
var result = keychain.getValue();
if (result == null) {
throw new NoKeychainAccessProviderException();
}
return result;
}
@Override
public void storePassphrase(String key, CharSequence passphrase) throws KeychainAccessException {
keychain.storePassphrase(key, passphrase);
getKeychainOrFail().storePassphrase(key, passphrase);
setPassphraseStored(key, true);
}
@Override
public char[] loadPassphrase(String key) throws KeychainAccessException {
char[] passphrase = keychain.loadPassphrase(key);
char[] passphrase = getKeychainOrFail().loadPassphrase(key);
setPassphraseStored(key, passphrase != null);
return passphrase;
}
@Override
public void deletePassphrase(String key) throws KeychainAccessException {
keychain.deletePassphrase(key);
getKeychainOrFail().deletePassphrase(key);
setPassphraseStored(key, false);
}
@Override
public void changePassphrase(String key, CharSequence passphrase) throws KeychainAccessException {
keychain.changePassphrase(key, passphrase);
setPassphraseStored(key, true);
if (isPassphraseStored(key)) {
getKeychainOrFail().changePassphrase(key, passphrase);
setPassphraseStored(key, true);
}
}
@Override
public boolean isSupported() {
return true;
return keychain.getValue() != null;
}
@Override
public boolean isLocked() {
return keychain.getValue() == null || keychain.get().isLocked();
}
/**
@@ -69,7 +87,7 @@ public class KeychainManager implements KeychainAccessStrategy {
public boolean isPassphraseStored(String key) throws KeychainAccessException {
char[] storedPw = null;
try {
storedPw = keychain.loadPassphrase(key);
storedPw = getKeychainOrFail().loadPassphrase(key);
return storedPw != null;
} finally {
if (storedPw != null) {
@@ -77,14 +95,13 @@ public class KeychainManager implements KeychainAccessStrategy {
}
}
}
private void setPassphraseStored(String key, boolean value) {
BooleanProperty property = passphraseStoredProperties.getIfPresent(key);
if (property != null) {
if (Platform.isFxApplicationThread()) {
property.set(value);
} else {
LOG.warn("");
Platform.runLater(() -> property.set(value));
}
}
@@ -99,7 +116,7 @@ public class KeychainManager implements KeychainAccessStrategy {
*
* @param key The key to look up
* @return An observable property which is <code>true</code> when it almost certain that a password for <code>key</code> is stored.
* @see #isPassphraseStored(String)
* @see #isPassphraseStored(String)
*/
public ReadOnlyBooleanProperty getPassphraseStoredProperty(String key) {
return passphraseStoredProperties.getUnchecked(key);
@@ -107,7 +124,6 @@ public class KeychainManager implements KeychainAccessStrategy {
private BooleanProperty createStoredPassphraseProperty(String key) {
try {
LOG.warn("LOAD"); // TODO remove
return new SimpleBooleanProperty(isPassphraseStored(key));
} catch (KeychainAccessException e) {
return new SimpleBooleanProperty(false);
@@ -0,0 +1,44 @@
package org.cryptomator.common.keychain;
import dagger.Module;
import dagger.Provides;
import org.cryptomator.common.settings.Settings;
import org.cryptomator.integrations.keychain.KeychainAccessProvider;
import javax.inject.Singleton;
import javafx.beans.binding.Bindings;
import javafx.beans.binding.ObjectExpression;
import java.util.ServiceLoader;
import java.util.Set;
import java.util.stream.Collectors;
@Module
public class KeychainModule {
@Provides
@Singleton
static Set<ServiceLoader.Provider<KeychainAccessProvider>> provideAvailableKeychainAccessProviderFactories() {
return ServiceLoader.load(KeychainAccessProvider.class).stream().collect(Collectors.toUnmodifiableSet());
}
@Provides
@Singleton
static Set<KeychainAccessProvider> provideSupportedKeychainAccessProviders(Set<ServiceLoader.Provider<KeychainAccessProvider>> availableFactories) {
return availableFactories.stream() //
.map(ServiceLoader.Provider::get) //
.filter(KeychainAccessProvider::isSupported) //
.collect(Collectors.toUnmodifiableSet());
}
@Provides
@Singleton
static ObjectExpression<KeychainAccessProvider> provideKeychainAccessProvider(Settings settings, Set<KeychainAccessProvider> providers) {
return Bindings.createObjectBinding(() -> {
var selectedProviderClass = settings.keychainProvider().get();
var selectedProvider = providers.stream().filter(provider -> provider.getClass().getName().equals(selectedProviderClass)).findAny();
var fallbackProvider = providers.stream().findAny().orElse(null);
return selectedProvider.orElse(fallbackProvider);
}, settings.keychainProvider());
}
}
@@ -0,0 +1,13 @@
package org.cryptomator.common.keychain;
import org.cryptomator.integrations.keychain.KeychainAccessException;
/**
* Thrown by {@link KeychainManager} if attempted to access a keychain despite no supported keychain access provider being available.
*/
public class NoKeychainAccessProviderException extends KeychainAccessException {
public NoKeychainAccessProviderException() {
super("Did not find any supported keychain access provider.");
}
}
@@ -0,0 +1,29 @@
package org.cryptomator.common.mountpoint;
import org.apache.commons.lang3.SystemUtils;
import org.cryptomator.common.vaults.Volume;
import org.cryptomator.common.vaults.WindowsDriveLetters;
import javax.inject.Inject;
import java.nio.file.Path;
import java.util.Optional;
class AvailableDriveLetterChooser implements MountPointChooser {
private final WindowsDriveLetters windowsDriveLetters;
@Inject
public AvailableDriveLetterChooser(WindowsDriveLetters windowsDriveLetters) {
this.windowsDriveLetters = windowsDriveLetters;
}
@Override
public boolean isApplicable(Volume caller) {
return SystemUtils.IS_OS_WINDOWS;
}
@Override
public Optional<Path> chooseMountPoint(Volume caller) {
return this.windowsDriveLetters.getAvailableDriveLetterPath();
}
}
@@ -0,0 +1,30 @@
package org.cryptomator.common.mountpoint;
import org.apache.commons.lang3.SystemUtils;
import org.cryptomator.common.settings.VaultSettings;
import org.cryptomator.common.vaults.Volume;
import javax.inject.Inject;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Optional;
class CustomDriveLetterChooser implements MountPointChooser {
private final VaultSettings vaultSettings;
@Inject
public CustomDriveLetterChooser(VaultSettings vaultSettings) {
this.vaultSettings = vaultSettings;
}
@Override
public boolean isApplicable(Volume caller) {
return SystemUtils.IS_OS_WINDOWS;
}
@Override
public Optional<Path> chooseMountPoint(Volume caller) {
return this.vaultSettings.getWinDriveLetter().map(letter -> letter.charAt(0) + ":\\").map(Paths::get);
}
}
@@ -0,0 +1,95 @@
package org.cryptomator.common.mountpoint;
import org.apache.commons.lang3.SystemUtils;
import org.cryptomator.common.Environment;
import org.cryptomator.common.settings.VaultSettings;
import org.cryptomator.common.settings.VolumeImpl;
import org.cryptomator.common.vaults.Volume;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.inject.Inject;
import java.io.IOException;
import java.nio.file.DirectoryNotEmptyException;
import java.nio.file.DirectoryStream;
import java.nio.file.FileAlreadyExistsException;
import java.nio.file.Files;
import java.nio.file.LinkOption;
import java.nio.file.NotDirectoryException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Optional;
class CustomMountPointChooser implements MountPointChooser {
private static final Logger LOG = LoggerFactory.getLogger(CustomMountPointChooser.class);
private final VaultSettings vaultSettings;
private final Environment environment;
@Inject
public CustomMountPointChooser(VaultSettings vaultSettings, Environment environment) {
this.vaultSettings = vaultSettings;
this.environment = environment;
}
@Override
public boolean isApplicable(Volume caller) {
//Disable if useExperimentalFuse is required (Win + Fuse), but set to false
return caller.getImplementationType() != VolumeImpl.FUSE || !SystemUtils.IS_OS_WINDOWS || environment.useExperimentalFuse();
}
@Override
public Optional<Path> chooseMountPoint(Volume caller) {
//VaultSettings#getCustomMountPath already checks whether the saved custom mountpoint should be used
return this.vaultSettings.getCustomMountPath().map(Paths::get);
}
@Override
public boolean prepare(Volume caller, Path mountPoint) throws InvalidMountPointException {
switch (caller.getMountPointRequirement()) {
case PARENT_NO_MOUNT_POINT -> prepareParentNoMountPoint(mountPoint);
case EMPTY_MOUNT_POINT -> prepareEmptyMountPoint(mountPoint);
case NONE -> {
//Requirement "NONE" doesn't make any sense here.
//No need to prepare/verify a Mountpoint without requiring one...
throw new InvalidMountPointException(new IllegalStateException("Illegal MountPointRequirement"));
}
default -> {
//Currently the case for "PARENT_OPT_MOUNT_POINT"
throw new InvalidMountPointException(new IllegalStateException("Not implemented"));
}
}
LOG.debug("Successfully checked custom mount point: {}", mountPoint);
return false;
}
private void prepareParentNoMountPoint(Path mountPoint) throws InvalidMountPointException {
//This the case on Windows when using FUSE
//See https://github.com/billziss-gh/winfsp/issues/320
Path parent = mountPoint.getParent();
if (!Files.isDirectory(parent)) {
throw new InvalidMountPointException(new NotDirectoryException(parent.toString()));
}
//We must use #notExists() here because notExists =/= !exists (see docs)
if (!Files.notExists(mountPoint, LinkOption.NOFOLLOW_LINKS)) {
//File exists OR can't be determined
throw new InvalidMountPointException(new FileAlreadyExistsException(mountPoint.toString()));
}
}
private void prepareEmptyMountPoint(Path mountPoint) throws InvalidMountPointException {
//This is the case for Windows when using Dokany and for Linux and Mac
if (!Files.isDirectory(mountPoint)) {
throw new InvalidMountPointException(new NotDirectoryException(mountPoint.toString()));
}
try (DirectoryStream<Path> ds = Files.newDirectoryStream(mountPoint)) {
if (ds.iterator().hasNext()) {
throw new InvalidMountPointException(new DirectoryNotEmptyException(mountPoint.toString()));
}
} catch (IOException exception) {
throw new InvalidMountPointException("IOException while checking folder content", exception);
}
}
}
@@ -0,0 +1,16 @@
package org.cryptomator.common.mountpoint;
public class InvalidMountPointException extends Exception {
public InvalidMountPointException(String message) {
super(message);
}
public InvalidMountPointException(Throwable cause) {
super(cause);
}
public InvalidMountPointException(String message, Throwable cause) {
super(message, cause);
}
}
@@ -0,0 +1,42 @@
package org.cryptomator.common.mountpoint;
import org.apache.commons.lang3.SystemUtils;
import org.cryptomator.common.settings.VaultSettings;
import org.cryptomator.common.vaults.Volume;
import javax.inject.Inject;
import java.nio.file.Path;
import java.util.Optional;
class MacVolumeMountChooser implements MountPointChooser {
private static final Path VOLUME_PATH = Path.of("/Volumes");
private final VaultSettings vaultSettings;
private final MountPointHelper helper;
@Inject
public MacVolumeMountChooser(VaultSettings vaultSettings, MountPointHelper helper) {
this.vaultSettings = vaultSettings;
this.helper = helper;
}
@Override
public boolean isApplicable(Volume caller) {
return SystemUtils.IS_OS_MAC;
}
@Override
public Optional<Path> chooseMountPoint(Volume caller) {
return Optional.of(helper.chooseTemporaryMountPoint(vaultSettings, VOLUME_PATH));
}
@Override
public boolean prepare(Volume caller, Path mountPoint) {
// https://github.com/osxfuse/osxfuse/issues/306#issuecomment-245114592:
// In order to allow non-admin users to mount FUSE volumes in `/Volumes`,
// starting with version 3.5.0, FUSE will create non-existent mount points automatically.
// Therefore we don't need to prepare anything.
return false;
}
}
@@ -0,0 +1,138 @@
package org.cryptomator.common.mountpoint;
import dagger.multibindings.IntKey;
import org.cryptomator.common.vaults.Volume;
import java.nio.file.Path;
import java.util.Optional;
import java.util.SortedSet;
/**
* Base interface for the Mountpoint-Choosing-Operation that results in the choice and
* preparation of a mountpoint or an exception otherwise.<br>
* <p>All <i>MountPointChoosers (MPCs)</i> need to implement this class and must be added to
* the pool of possible MPCs by the {@link MountPointChooserModule MountPointChooserModule.}
* The MountPointChooserModule will sort them according to their {@link IntKey IntKey priority.}
* The priority must be defined by the developer to reflect a useful execution order.<br>
* A specific priority <b>must not</b> be assigned to more than one MPC at a time;
* the result of having two MPCs with equal priority is undefined.
*
* <p>MPCs are executed by a {@link Volume} in descending order of their priority
* (higher priorities are tried first) to find and prepare a suitable mountpoint for the volume.
* The volume has access to a {@link SortedSet} of MPCs in this specific order,
* that is provided by the Module. The Set contains all available Choosers, even if they
* are not {@link #isApplicable(Volume) applicable} for the Vault/Volume. The Volume must
* check whether a MPC is applicable by invoking {@code #isApplicable(Volume)} on it
* <i>before</i> calling {@code #chooseMountPoint(Volume)}.
*
* <p>At execution of a MPC {@link #chooseMountPoint(Volume)} is called to choose a mountpoint
* according to the MPC's <i>strategy.</i> The <i>strategy</i> can involve reading configs,
* searching the filesystem, processing user-input or similar operations.
* If {@code #chooseMountPoint(Volume)} returns a non-null path (everything but
* {@linkplain Optional#empty()}) the MPC's {@link #prepare(Volume, Path)} method is called and the
* MountPoint is verified and/or prepared. In this case <i>no other MPC's will be called for
* this volume, even if {@code #prepare(Volume, Path)} fails.</i>
*
* <p>If {@code #chooseMountPoint(Volume)} yields no result, the next MPC is executed
* <i>without</i> first calling the {@code #prepare(Volume, Path)} method of the current MPC.
* This is repeated until<br>
* <ul>
* <li><b>either</b> a mountpoint is returned by {@code #chooseMountPoint(Volume)}
* and {@code #prepare(Volume, Path)} succeeds or fails, ending the entire operation</li>
* <li><b>or</b> no MPC remains and an {@link InvalidMountPointException} is thrown.</li>
* </ul>
* If the {@code #prepare(Volume, Path)} method of a MPC fails, the entire
* Mountpoint-Choosing-Operation is aborted and the method should do all necessary cleanup
* before throwing the exception.
* If the preparation succeeds {@link #cleanup(Volume, Path)} can be used after unmount to do any
* remaining cleanup.
*/
public interface MountPointChooser {
/**
* Called by the {@link Volume} to determine whether this MountPointChooser is
* applicable for mounting the Vault/Volume, especially with regard to the
* current system configuration and particularities of the Volume type.
*
* <p>Developers should override this method to check for system configurations
* that are unsuitable for this MPC.
*
* @param caller The Volume that is calling the method to determine applicability of the MPC
* @return a boolean flag; true if applicable, else false.
* @see #chooseMountPoint(Volume)
*/
boolean isApplicable(Volume caller);
/**
* Called by a {@link Volume} to choose a mountpoint according to the
* MountPointChoosers strategy.
*
* <p>This method must only be called for MPCs that were deemed
* {@link #isApplicable(Volume) applicable} by the {@link Volume Volume.}
* Developers should override this method to find or extract a mountpoint for
* the volume <b>without</b> preparing it. Preparation should be done by
* {@link #prepare(Volume, Path)} instead.
* Exceptions in this method should be handled gracefully and result in returning
* {@link Optional#empty()} instead of throwing an exception.
*
* @param caller The Volume that is calling the method to choose a mountpoint
* @return the chosen path or {@link Optional#empty()} if an exception occurred
* or no mountpoint could be found.
* @see #isApplicable(Volume)
* @see #prepare(Volume, Path)
*/
Optional<Path> chooseMountPoint(Volume caller);
/**
* Called by a {@link Volume} to prepare and/or verify the chosen mountpoint.<br>
* This method is only called if the {@link #chooseMountPoint(Volume)} method
* of the same MountPointChooser returned a path.
*
* <p>Developers should override this method to prepare the mountpoint for
* the volume and check for any obstacles that could hinder the mount operation.
* The mountpoint is deemed "prepared" if it can be used to mount a volume
* without any further filesystem actions or user interaction. If this is not possible,
* this method should fail. In other words: This method should not return without
* either failing or finalizing the preparation of the mountpoint.
* Generally speaking exceptions should be wrapped as
* {@link InvalidMountPointException} to allow efficient handling by the caller.
*
* <p>Often the preparation of a mountpoint involves creating files or others
* actions that require cleaning up after the volume is unmounted.
* In this case developers should override the {@link #cleanup(Volume, Path)}
* method and return {@code true} to the volume to indicate that the
* {@code #cleanup} method of this MPC should be called after unmount.
*
* <p><b>Please note:</b> If this method fails the entire
* Mountpoint-Choosing-Operation is aborted without calling
* {@link #cleanup(Volume, Path)} or any other MPCs. Therefore this method should
* do all necessary cleanup before throwing the exception.
*
* @param caller The Volume that is calling the method to prepare a mountpoint
* @param mountPoint the mountpoint chosen by {@link #chooseMountPoint(Volume)}
* @return a boolean flag; true if cleanup is needed, false otherwise
* @throws InvalidMountPointException if the preparation fails
* @see #chooseMountPoint(Volume)
* @see #cleanup(Volume, Path)
*/
default boolean prepare(Volume caller, Path mountPoint) throws InvalidMountPointException {
return false; //NO-OP
}
/**
* Called by a {@link Volume} to do any cleanup needed after unmount.
*
* <p>This method is only called if the {@link #prepare(Volume, Path)} method
* of the same MountPointChooser returned {@code true}. Typically developers want to
* delete any files created prior to mount or do similar tasks.<br>
* Exceptions in this method should be handled gracefully.
*
* @param caller The Volume that is calling the method to cleanup the prepared mountpoint
* @param mountPoint the mountpoint that was prepared by {@link #prepare(Volume, Path)}
* @see #prepare(Volume, Path)
*/
default void cleanup(Volume caller, Path mountPoint) {
//NO-OP
}
}
@@ -0,0 +1,64 @@
package org.cryptomator.common.mountpoint;
import com.google.common.collect.Iterables;
import dagger.Binds;
import dagger.Module;
import dagger.Provides;
import dagger.multibindings.IntKey;
import dagger.multibindings.IntoMap;
import org.cryptomator.common.vaults.PerVault;
import javax.inject.Named;
import java.util.Comparator;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;
/**
* Dagger-Module for {@link MountPointChooser MountPointChoosers.}<br>
* See there for additional information.
*
* @see MountPointChooser
*/
@Module
public abstract class MountPointChooserModule {
@Binds
@IntoMap
@IntKey(1000)
@PerVault
public abstract MountPointChooser bindCustomMountPointChooser(CustomMountPointChooser chooser);
@Binds
@IntoMap
@IntKey(900)
@PerVault
public abstract MountPointChooser bindCustomDriveLetterChooser(CustomDriveLetterChooser chooser);
@Binds
@IntoMap
@IntKey(800)
@PerVault
public abstract MountPointChooser bindAvailableDriveLetterChooser(AvailableDriveLetterChooser chooser);
@Binds
@IntoMap
@IntKey(101)
@PerVault
public abstract MountPointChooser bindMacVolumeMountChooser(MacVolumeMountChooser chooser);
@Binds
@IntoMap
@IntKey(100)
@PerVault
public abstract MountPointChooser bindTemporaryMountPointChooser(TemporaryMountPointChooser chooser);
@Provides
@PerVault
@Named("orderedMountPointChoosers")
public static Iterable<MountPointChooser> provideOrderedMountPointChoosers(Map<Integer, MountPointChooser> choosers) {
SortedMap<Integer, MountPointChooser> sortedChoosers = new TreeMap<>(Comparator.reverseOrder());
sortedChoosers.putAll(choosers);
return Iterables.unmodifiableIterable(sortedChoosers.values());
}
}

Some files were not shown because too many files have changed in this diff Show More