Compare commits

...
Author SHA1 Message Date
JaniruTEC 2bad933c85 First prototype: Moved logic of "getCiphertextPath"
Moved logic of "getCiphertextPath" from Vault to VaultState
2023-07-21 17:09:07 +02:00
JaniruTEC ca3a11de90 Made AtomicReference to mountHandle final
[ci skip]
2023-07-21 16:37:08 +02:00
mindmonkandGitHub 91ece74f57 Merge pull request #2998 from cryptomator/feature/update-reminder
Update Reminder
2023-07-21 09:46:48 +02:00
Jan-Peter Klein b9f77cb1d6 Merge branch 'develop' into feature/update-reminder 2023-07-20 11:32:12 +02:00
Jan-Peter Klein b6d09016cd rearranged layout elements and changed window width 2023-07-20 11:31:52 +02:00
Jan-Peter Klein 0a07103a4f moved logic of update checking from FxApplication class to UpdateReminderComponent 2023-07-20 11:06:55 +02:00
Jan-Peter Klein 96253f636a removed unused provide method 2023-07-20 11:05:50 +02:00
Armin SchrenkandGitHub bd932b1067 Fixes #3021 2023-07-18 17:06:03 +02:00
Jan-Peter Klein ade277daf4 changed naming pattern and wording 2023-07-18 10:29:14 +02:00
Jan-Peter Klein 14776fc571 refactored UpdateReminderComponent.Builder to Factory 2023-07-17 15:40:11 +02:00
Jan-Peter Klein c18f489e9d Merge branch 'develop' into feature/update-reminder 2023-07-17 15:32:25 +02:00
Jan-Peter Klein bfc1e25335 some code cleanup 2023-07-17 12:23:23 +02:00
Jan-Peter Klein 4c2e6088a9 reformat code and optimized imports 2023-07-17 11:26:59 +02:00
Armin Schrenk f1d4bd4cd4 Closes #2989 2023-07-13 12:22:46 +02:00
mindmonkandGitHub 2a0e0738be Merge pull request #2987 from cryptomator/feature/custom-shortening-threshold
Feature/custom shortening threshold
2023-07-13 12:15:07 +02:00
Jan-Peter Klein 1fec9781bf Merge branch 'develop' into feature/custom-shortening-threshold 2023-07-12 16:07:03 +02:00
Jan-Peter Klein 886c69f298 reordered ui elements and added expert settings section to strings.properties 2023-07-12 16:04:29 +02:00
JaniruTEC 58c7774e0d Added arg3 to FormattedLabel 2023-07-11 21:50:52 +02:00
Jan-Peter Klein df31b214f5 changed button wording from "Not now" to "Ask Me Later" 2023-07-11 15:23:50 +02:00
Jan-Peter Klein 25474ce014 changed wording and window size 2023-07-11 14:53:36 +02:00
Jan-Peter Klein 5f62f038d5 removed message below the input field and inserted in the invalid message 2023-07-11 14:41:43 +02:00
Jan-Peter Klein eebba45909 added comment to explain code that sets shorteningThreshold to 0
removed unnecessary introduction text
2023-07-11 14:10:26 +02:00
Jan-Peter Klein 982e88d1c5 changed icon to question mark 2023-07-10 15:47:12 +02:00
Jan-Peter Klein 632d39bc9f added lastUpdateCheck to settings and integrated check in FXApplication start 2023-07-10 14:50:06 +02:00
Jan-Peter Klein f25afb720f optimized isValidShorteningThreshold method and renamed DEFAULT_SHORTENING_THRESHOLD to MAX_SHORTENING_THRESHOLD 2023-07-10 13:14:58 +02:00
Jan-Peter Klein bc361ea592 added ui elements for update reminder 2023-07-10 13:04:07 +02:00
Jan-Peter Klein 2202c91564 rearranged view
added pencil icon
optimized code
cleaned up strings.properties
2023-07-07 16:22:53 +02:00
Jan-Peter Klein f817bc5378 implement requested changes from PR review 2023-07-06 11:03:34 +02:00
JaniruTECandGitHub c30c90d2c3 Merge pull request #2985 from cryptomator/feature/2981-differ-options-preferences
Fix 2981
2023-07-05 16:27:55 +02:00
Jan-Peter Klein 09b638eafa pr mentioned changes implemented 2023-07-05 16:19:11 +02:00
JaniruTEC 91de0c1813 Added called to #showMainWindow
See: https://github.com/cryptomator/cryptomator/pull/2985#discussion_r1252863161
2023-07-05 15:50:35 +02:00
JaniruTEC a3c953d437 Refactored decision model
See: https://github.com/cryptomator/cryptomator/pull/2985#pullrequestreview-1514141146
2023-07-05 15:49:43 +02:00
JaniruTEC 743da019f9 Cleaned up UnlockInvalidMountPointController
See:
https://github.com/cryptomator/cryptomator/pull/2985#discussion_r1252868655
https://github.com/cryptomator/cryptomator/pull/2985#discussion_r1252874468
2023-07-05 15:26:19 +02:00
Jan-Peter Klein 2c506fcc97 rearranged view elements an renamed advancedSettings to expertSettings 2023-07-05 13:17:10 +02:00
Jan-Peter Klein dd71df8382 Merge branch 'develop' into feature/custom-shortening-threshold 2023-07-05 11:55:51 +02:00
Armin Schrenk 2c984ad405 use system property path.separator and fix failing unit test on windows 2023-07-04 16:31:28 +02:00
JaniruTEC 171b0e61ad Finished implementation 2023-07-04 16:14:08 +02:00
JaniruTEC e5047c242c Moved subcomponent-bindings
Moved bindings for VaultOptionsComponent and HealthCheckComponent from MainWindowModule to FxApplicationModule
2023-07-04 15:35:23 +02:00
JaniruTEC 131145e8b8 Merge branch 'develop' into feature/2981-differ-options-preferences 2023-07-04 14:00:44 +02:00
JaniruTEC 11a0136cb9 Fixed run configurations
See: #2982
2023-07-04 13:55:42 +02:00
Armin Schrenk e92b80bdf4 fix local win build script to download jfxmods 2023-07-04 12:42:55 +02:00
Armin Schrenk 9d81b2312f fix local build script to parse two digit verison nums correctly 2023-07-04 12:41:58 +02:00
Armin Schrenk 511dbe355a Fixes #2982 2023-07-04 12:41:06 +02:00
JaniruTEC cca6d475b3 Updated UI 2023-07-03 21:14:12 +02:00
JaniruTEC 88c6246ceb Prepared UnlockInvalidMountPointController for new feature 2023-07-03 21:08:49 +02:00
Jan-Peter Klein 7bf2de6339 Merge branch 'develop' into feature/custom-shortening-threshold 2023-07-03 16:22:43 +02:00
Jan-Peter Klein 894d0528df refactoring 2023-07-03 15:34:01 +02:00
Armin Schrenk 168b9ef096 changed default folder mount location on macOS 2023-07-03 13:11:38 +02:00
Sebastian Stenzel 6c8005e1b2 use github.ref instead of inputs.ref
[ci skip]
2023-07-03 10:59:32 +02:00
Sebastian Stenzel ed8457ff36 remove dead test 2023-06-30 13:53:25 +02:00
Sebastian Stenzel a50bc8e05c reduce api surface 2023-06-30 13:53:06 +02:00
Sebastian Stenzel e382a3bab9 make settings' fields public, remove accessor methods 2023-06-30 13:52:15 +02:00
Sebastian StenzelandGitHub 9cd50e8ae4 Merge pull request #2974 from cryptomator/feature/replace-gson
Replace GSON with Jackson
2023-06-30 13:48:19 +02:00
Sebastian Stenzel 1a6836dac6 remove unnecessary annotation
[ci skip]
2023-06-30 12:39:48 +02:00
Armin SchrenkandGitHub 067814d5db Merge pull request #2957 from cryptomator/feature/preprocess-properties
Feature: Preprocess JVM properties at app start to adjust to OS environment.

Closes #2838
2023-06-30 12:38:55 +02:00
Armin Schrenk 29d63a0a83 final clean up 2023-06-30 11:57:09 +02:00
Armin Schrenk 8c3ede0d2a clean up 2023-06-30 11:20:28 +02:00
Armin Schrenk ee82965ef5 adding "integration tests" 2023-06-30 11:20:07 +02:00
Armin Schrenk ab048508a8 change getProperty(key, default) and add unit test 2023-06-30 10:57:36 +02:00
Sebastian Stenzel 47ae271126 cleanup
[ci skip]
2023-06-29 23:00:19 +02:00
Sebastian Stenzel ef22928e01 undo formatter-induced changes
[ci skip]
2023-06-29 22:53:19 +02:00
Sebastian Stenzel 287584429b update code style
remove line break from `new Object() {}`

[ci skip]
2023-06-29 22:45:57 +02:00
Sebastian Stenzel e23c0c23c9 remove GSON from dependencies 2023-06-29 22:44:22 +02:00
Sebastian Stenzel e9bb3195dd cleanup 2023-06-29 22:44:05 +02:00
Sebastian Stenzel b1ff94bdd6 replace GSON from settings 2023-06-29 22:41:19 +02:00
Armin Schrenk 79eea4814e renamed class 2023-06-29 18:56:32 +02:00
Armin Schrenk cee0486d71 adding unit tests for getProperty 2023-06-29 18:55:49 +02:00
Armin Schrenk 12e990a8b3 cleanup 2023-06-29 18:24:48 +02:00
Armin Schrenk 24fc2888ef more unit tests 2023-06-29 18:20:25 +02:00
Armin Schrenk 9b0c940195 readd unit tests for Environment.java 2023-06-29 18:13:54 +02:00
Armin Schrenk ce596698e3 stick to a unified path separator for cryptomator properties 2023-06-29 17:58:52 +02:00
Armin Schrenk 9383abbdbd let child method match parent 2023-06-29 15:55:07 +02:00
Armin Schrenk a31d3185dc move boilerplate code to own class 2023-06-29 15:51:46 +02:00
Armin Schrenk 3098628db1 Fix problem of circular class init 2023-06-29 15:32:15 +02:00
Sebastian Stenzel 3c53968dd2 replace GSON from update checker 2023-06-29 13:20:39 +02:00
Armin Schrenk 6c18e3a929 apply suggestion from sonarCloud 2023-06-29 13:04:00 +02:00
Sebastian Stenzel 99862869bc replace GSON from error dialog 2023-06-29 13:03:27 +02:00
Armin Schrenk c0368f2a50 Merge branch 'develop' into feature/preprocess-properties 2023-06-29 12:39:31 +02:00
Armin Schrenk c6c292b505 bump google guava to 32.0.1 2023-06-29 12:39:19 +02:00
Armin Schrenk ebc60c4fb3 make process function reliable testable and adjust unit test 2023-06-29 12:35:59 +02:00
Sebastian Stenzel 5f2497de90 replace GSON in "hub" 2023-06-29 12:26:45 +02:00
Sebastian Stenzel b2a184bdf0 ignore unknown fields during JWT deserialization 2023-06-29 12:02:33 +02:00
Armin Schrenk 01da51e6e7 Refactor properties preprocessing:
* decorate Properties class
* set the system properties to decorator
* for logging setup, skip enviroment and access props over decorator
2023-06-29 11:37:35 +02:00
Armin Schrenk 8417618615 Revert "fix missing logDir path resolution"
This reverts commit b3d8df0da0.
2023-06-28 16:04:10 +02:00
Jan-Peter Klein 386bdd3490 added new AdvancedSettings scene in AddVaultWizard 2023-06-28 12:24:14 +02:00
Tobias Hagemann fe3abcaaa8 added leitzcloud location preset 2023-06-27 09:36:14 +02:00
Tobias Hagemann 56ba12fe56 fixed location presets of google drive and pcloud on macos 2023-06-27 09:31:43 +02:00
Armin Schrenk 5e52f715ce Merge branch 'develop' into feature/preprocess-properties 2023-06-21 10:31:43 +02:00
Armin SchrenkandGitHub 2c2606d6ad Merge pull request #2961 from sschuberth/win-drive-occupied
Show a dedicated message when mounting to an occupied Windows drive

Fixes #2309
2023-06-20 18:25:00 +02:00
Armin Schrenk b3d8df0da0 fix missing logDir path resolution 2023-06-20 18:08:31 +02:00
Armin Schrenk ebea8ef7e5 adjust windows buildscripts to use appdata instead of userhome/hard/coded/path 2023-06-20 17:32:23 +02:00
Armin Schrenk ec645a4bb9 replace ~ by @{userhome} on unix systems 2023-06-20 16:37:32 +02:00
Armin Schrenk 2c0474ec46 add test 2023-06-20 12:37:07 +02:00
Sebastian Schuberth 4d09728880 Suppress a CVE false-positive for jackson-databind 2.14.2
Also see https://github.com/cryptomator/cryptomator/pull/2961#issuecomment-1597652134.
2023-06-19 22:31:50 +02:00
Sebastian Schuberth 173b1e8386 Show a dedicated message when mounting to an occupied Windows drive
The error message was restored from 6395f17. Fixes #2309.
2023-06-16 19:17:30 +02:00
mindmonkandGitHub 9b18a179c2 Merge pull request #2953 from cryptomator/feature/error-dialog
Improved Error Dialog
2023-06-16 15:55:43 +02:00
Jan-Peter Klein 12b38ad8c8 removed extra tabs generated by reformat code 2023-06-16 15:25:22 +02:00
Armin SchrenkandSebastian Stenzel 4065e15aa1 Apply code suggestion from review
Co-authored-by: Sebastian Stenzel <overheadhunter@users.noreply.github.com>
2023-06-16 13:12:00 +02:00
Jan-Peter Klein 6fda206b9e just one little change 2023-06-16 12:57:21 +02:00
Jan-Peter Klein 638a6d1195 optimized code 2023-06-16 12:56:07 +02:00
Jan-Peter Klein 27bc62e602 Merge branch 'develop' into feature/error-dialog 2023-06-16 12:48:28 +02:00
Tobias HagemannandGitHub 2e7af0affa Update SECURITY.md
[ci skip]
2023-06-16 11:41:33 +02:00
Tobias HagemannandGitHub 19c41a3cca Update SECURITY.md
[ci skip]
2023-06-16 11:20:26 +02:00
Jan-Peter Klein 3bf4473f9d implemented changes mentioned by overheadhunter 2023-06-16 11:13:24 +02:00
Jan-Peter Klein f92c436339 reformat code and optimize imports 2023-06-15 13:12:10 +02:00
Jan-Peter Klein f054a1af03 optimized tests and some code docu 2023-06-15 10:54:44 +02:00
Armin Schrenk c46eeb0401 first impl draft 2023-06-15 10:38:19 +02:00
Jan-Peter Klein d680c5812d cleaned up code and using parameterized tests 2023-06-14 16:10:11 +02:00
Jan-Peter Klein 3120751d3e resolved sonarclouds mentioned issues 2023-06-13 12:48:35 +02:00
Jan-Peter Klein 3c623b7ed1 cleaned up code 2023-06-12 21:04:54 +02:00
Jan-Peter Klein 150dd3e542 Merge branch 'develop' of https://github.com/cryptomator/cryptomator into feature/error-dialog 2023-06-12 13:52:23 +02:00
Jan-Peter Klein 8f3f23939c created some tests for ErrorController 2023-06-12 13:50:43 +02:00
Armin Schrenk 5d796efe30 Merge branch 'main' into develop 2023-06-07 12:56:23 +02:00
Armin Schrenk 702ae72063 Merge branch 'release/1.9.1' 2023-06-07 12:55:46 +02:00
Armin Schrenk b296dc775c finalize 1.9.1 2023-06-07 12:55:28 +02:00
Armin Schrenk e5e0d4076a prepare 1.9.1 2023-06-07 12:52:42 +02:00
Armin Schrenk da0eeb2e45 bump dependency-check 2023-06-07 12:50:24 +02:00
Armin Schrenk ff49094f35 fixes #2936 2023-06-07 12:50:09 +02:00
CryptobotandGitHub be1c5da54e New Crowdin updates (#2931)
New translations strings.properties

Filipino; Finnish; Hungarian; Slovak;

[ci skip]
2023-06-07 11:08:14 +02:00
Armin Schrenk 40abf582c5 bump guava 2023-06-01 17:48:14 +02:00
Armin Schrenk a8377be691 adjust init release notes file 2023-06-01 17:47:18 +02:00
Jan-Peter Klein 0e7a27b2e1 Merge branch 'develop' of https://github.com/cryptomator/cryptomator into feature/error-dialog 2023-05-30 12:06:50 +02:00
Jan-Peter Klein d82d11feb7 optimized implementation 2023-05-30 12:03:56 +02:00
Armin Schrenk 81c12f50fe Merge branch 'main' into develop [ci skip] 2023-05-30 10:46:07 +02:00
Armin Schrenk e2eac0e398 Merge branch 'release/1.9.0' 2023-05-30 10:44:02 +02:00
Armin Schrenk 9d573c497e finalize 1.9.0 2023-05-30 10:34:51 +02:00
Armin Schrenk 81087a9568 Merge branch 'develop' into release/1.9.0 2023-05-30 10:30:47 +02:00
CryptobotandGitHub 2806525397 New Crowdin updates (#2881)
New translations strings.properties

Bulgarian; Finnish; German; Japanese; Portuguese; Portuguese, Brazilian; Turkish; Ukrainian; 

[ci skip]
2023-05-30 10:29:07 +02:00
Armin Schrenk 0c0060262a prepare 1.9.0 2023-05-26 16:37:53 +02:00
Armin Schrenk 9af4ffe83b use correct webdav adapter version 2023-05-26 15:44:10 +02:00
Armin Schrenk c6f963793d bump dependencies 2023-05-26 13:10:11 +02:00
Armin Schrenk 8c34fc76c5 prevent regressions for google drive preset 2023-05-24 12:07:08 +02:00
Armin SchrenkandGitHub 785cf7a9a6 Merge pull request #2918 from cryptomator/feature/refactor-location-presets
Feature: Refactor finding and showing cloud location presets
2023-05-23 17:32:48 +02:00
Armin Schrenk c63837c4ce renaming class 2023-05-23 17:01:14 +02:00
Armin Schrenk b1a3ef9023 prevent dealing with unclosed directory streams 2023-05-23 12:35:14 +02:00
Armin Schrenk 32436f779f increase readability 2023-05-23 10:54:34 +02:00
Sebastian Stenzel ccc6f605ba Merge branch 'develop' into feature/refactor-location-presets 2023-05-23 10:19:00 +02:00
Sebastian Stenzel f338d2447b improved AutoUnlocker readability 2023-05-23 09:48:27 +02:00
Armin Schrenk 179240b325 Readd mac specifc google drive location provider 2023-05-23 09:44:37 +02:00
Armin Schrenk 32a65bddce Add OneDrive Mac location provider 2023-05-22 17:16:03 +02:00
Armin Schrenk 710cdf800d fix compile errors 2023-05-22 15:21:19 +02:00
Armin Schrenk 1d6edb8373 Apply code suggestions 2023-05-22 15:19:15 +02:00
Armin Schrenk a3d30612ec Add linux paths for Dropbox and OneDrive 2023-05-22 14:51:52 +02:00
Armin Schrenk 6acda9b13c also adjust styleClass of location label 2023-05-17 18:48:12 +02:00
Armin Schrenk 28cb812dab add uses field to module info 2023-05-17 18:38:24 +02:00
Armin Schrenk 68ea4af0ad use correct import 2023-05-17 17:26:37 +02:00
Armin Schrenk 0af0a9e440 refactor location ui in addVault workflow to new locationPreset framework 2023-05-17 17:21:02 +02:00
Armin Schrenk 0989c735c0 improve error handling when querying registry 2023-05-17 14:25:46 +02:00
Armin Schrenk a3492b9ea3 use correct registry keys for onedrive detection 2023-05-17 14:25:16 +02:00
Armin Schrenk e345e6415f use @CheckAvailability annotation correctly 2023-05-17 14:17:28 +02:00
Armin Schrenk 5b6d09308b Create SPI for cloud location presets 2023-05-16 17:16:42 +02:00
Armin SchrenkandGitHub 49bda58993 Merge pull request #2690 from Rexbas/auto-unlock
Auto unlock vaults that were missing at startup
2023-05-15 10:46:28 +02:00
Rexbas 32d7189a12 Add time unit parameter 2023-05-12 21:52:30 +02:00
Rexbas 1253b7db2b Make unlock method private and simplify missing vaults unlocker 2023-05-11 20:43:23 +02:00
Armin SchrenkandGitHub 067a7ad3ee Merge pull request #2897 from cryptomator/feature/jdk20
Upgrade to jdk20 and jfx20
2023-05-10 14:16:42 +02:00
Armin Schrenk a9ec76a344 update wix main file due to updated jpackage installer template 2023-05-09 17:40:13 +02:00
Armin Schrenk 085f762a35 further fixing debian 2023-05-09 15:48:06 +02:00
Armin Schrenk 7dd1c3576f always use the same JDK version in debian workflow 2023-05-09 15:02:15 +02:00
Armin Schrenk d23bd2865a update location preset for Dropbox 2023-05-09 14:56:44 +02:00
Armin Schrenk 4429d57b5e ensure mutability of temporary collection 2023-05-09 14:52:15 +02:00
Armin Schrenk 2ff71ed7b0 remove langauges with insufficient translation 2023-05-09 14:51:44 +02:00
Armin Schrenk 82de8b6994 remove unrelated change 2023-05-09 09:57:23 +02:00
Armin Schrenk d4cba2fd6e fix errors 2023-05-09 09:55:56 +02:00
ff80f634d2 Apply suggestions from code review
Co-authored-by: Sebastian Stenzel <overheadhunter@users.noreply.github.com>
2023-05-09 09:42:01 +02:00
Jan-Peter Klein b10523ea6c init commit 2023-05-09 09:00:56 +02:00
Armin Schrenk 6386dd3d50 update workflows 2023-05-08 19:41:58 +02:00
Armin Schrenk a3f05db189 bump javafx 2023-05-08 19:41:02 +02:00
Armin Schrenk 151ef6c7b2 upgrade to jdk20
* use pattern matching preview feature
* bump fuse-nio-adapter
2023-05-08 19:12:35 +02:00
Rexbas 72fd38baf1 Add timeout to periodic missing vaults check 2023-05-06 15:40:24 +02:00
Tobias HagemannandGitHub 532ffb1202 Merge pull request #2882 from bluen/develop
Respect user's locale when sorting language list
2023-05-05 11:51:17 +02:00
Tobias Hagemann 2a704d5eb4 init collator once 2023-05-05 11:45:02 +02:00
Sebastian Stenzel e8f8466d9a adjusted labels used in auto-generated release notes
[ci skip]
2023-05-05 10:56:44 +02:00
Sebastian Stenzel 9297562c99 improve auto-generated release notes
[ci skip]
2023-05-05 10:52:51 +02:00
Jürgen Kleer 7d62fc78de Set preferred locale in constructor, make it default in applyPreferred 2023-04-27 18:03:41 +02:00
Rexbas ba627d0d60 Add a scheduled service to auto unlock vaults that were missing at startup 2023-04-27 11:06:09 +02:00
Jürgen Kleer 8e7e7de358 Refactoring
make LANGUAGE_TAGS private and provide a getter
2023-04-26 17:34:47 +02:00
Jürgen Kleer 10c60d7492 https://github.com/cryptomator/cryptomator/issues/2813
> List of languages should have system default, English and then all other languages in alphabetic order.
> That is, in alphabetic order with respect to the language the list is localized in (seems to be English always)
2023-04-26 15:24:50 +02:00
Armin Schrenk aa03bd119a Merge branch 'main' into develop 2023-04-25 10:45:51 +02:00
Armin Schrenk 325ffda9af Merge branch 'release/1.8.0' 2023-04-25 10:45:08 +02:00
Armin Schrenk d1270ceeb2 finalize 1.8.0 2023-04-25 10:44:41 +02:00
Armin Schrenk 901a290dd9 prepare 1.8.0 2023-04-24 17:35:25 +02:00
CryptobotandGitHub 35b9dadfc2 New Crowdin updates (#2848)
New translations strings.properties

Arabic; Belarusian; Bengali; Bosnian; Catalan; Chinese Simplified; Chinese Traditional; Chinese Traditional, Hong Kong; Croatian; Czech; Danish; Dutch; Filipino; French; Galician; German; Greek; Hebrew; Hindi; Hungarian; Indonesian; Italian; Japanese; Korean; Latvian; Macedonian; Norwegian Bokmal; Norwegian Nynorsk; Persian; Polish; Portuguese; Portuguese, Brazilian; Punjabi; Romanian; Russian; Serbian (Cyrillic); Serbian (Latin); Sinhala; Slovak; Slovenian; Spanish; Swahili, Tanzania; Swedish; Tamil; Telugu; Thai; Turkish; Ukrainian; Vietnamese; 

[ci skip]
2023-04-24 17:33:59 +02:00
Armin SchrenkandGitHub 5f57678edc Merge pull request #2840 from cryptomator/feature/convert-hub-to-local
Feature: convert hub-based vault to password-based
2023-04-21 15:31:28 +02:00
Tobias Hagemann 30e1922bc9 fixed spacing
[ci skip]
2023-04-21 15:23:06 +02:00
Armin Schrenk 2e0908ab15 replace config manually instead of using CryptoFileSystem.init() 2023-04-21 09:40:34 +02:00
Julian Raufelder 689ce5b985 Revive status and no-response bot 2023-04-20 15:38:57 +02:00
Tobias Hagemann a71a23aa31 replaced password bullet point with a different char that exists in open sans
[ci skip]
2023-04-18 16:36:27 +02:00
Tobias Hagemann 864454e6fc updated strings
[ci skip]
2023-04-18 16:03:05 +02:00
Armin Schrenk 94c3381723 forgot one renaming 2023-04-18 15:40:44 +02:00
d9f945e70a Apply suggestions from code review
more renaming

Co-authored-by: Tobias Hagemann <tobias.hagemann@skymatic.de>
2023-04-18 15:34:20 +02:00
Armin Schrenk dc9b39202f rename classes 2023-04-18 14:34:48 +02:00
Armin Schrenk 2a01aba3cf clean up 2023-04-17 12:51:36 +02:00
Armin Schrenk 4305fd3285 close also vault options window to prevent invalid state of options window 2023-04-17 12:50:46 +02:00
a24cd1ba7f Apply suggestions from code review
Co-authored-by: Tobias Hagemann <tobias.hagemann@skymatic.de>
2023-04-14 16:47:45 +02:00
Tobias Hagemann 2ba0d963ec updated insets
[ci skip]
2023-04-13 16:12:08 +02:00
Julian Raufelder cd0c6fbd33 Merge branch 'hotfix/1.7.5' into develop 2023-04-07 11:45:08 +02:00
Julian Raufelder f4374a2606 Merge branch 'hotfix/1.7.5' 2023-04-07 11:41:24 +02:00
Julian Raufelder a1d5b8a4e2 Prepare 1.7.5 2023-04-07 11:39:21 +02:00
Julian Raufelder 34e430aff6 Revert "bump cryptofs"
This reverts commit db2560fccf.
2023-04-07 11:35:38 +02:00
Armin Schrenk c79766cdf6 Merge branch 'main' into develop 2023-04-05 09:58:30 +02:00
Armin Schrenk bf76bad626 Merge branch 'release/1.7.4' 2023-04-05 09:57:55 +02:00
Armin Schrenk c3f654b454 finalize release 2023-04-05 09:56:34 +02:00
Armin Schrenk d1d990d47c prepare 1.7.4 2023-04-04 18:17:24 +02:00
CryptobotandGitHub 6052c0589e New Crowdin updates (#2800)
New translations strings.properties

Belarusian; Catalan; Chinese Simplified; Chinese Traditional; Chinese Traditional, Hong Kong; Danish; Dutch; French; German; Greek; Hebrew; Hungarian; Italian; Japanese; Norwegian Bokmal; Polish; Portuguese; Portuguese, Brazilian; Romanian; Russian; Slovak; Spanish; Swahili, Tanzania; Swedish; Turkish; 

[ci skip]
2023-04-04 18:15:07 +02:00
Armin Schrenk db2560fccf bump cryptofs 2023-04-04 13:44:19 +02:00
Armin Schrenk 3a50c32e50 rework convert button logic 2023-04-04 12:42:23 +02:00
Armin Schrenk 65eca31d26 integrate internationalization 2023-04-04 12:17:22 +02:00
Armin Schrenk 3462e0b540 further design adjustment 2023-04-03 10:42:25 +02:00
Armin Schrenk 697529136e use regular jdk 2023-03-31 18:27:35 +02:00
Armin Schrenk 50d31bdc18 integrate debug installer feature into regular windows ci workflow 2023-03-31 18:24:10 +02:00
Armin Schrenk 84caf96d3f closes #2814
Zulu JDK does not create required directory structure, so use temurin + gluon jfx jmods instead
2023-03-31 18:21:30 +02:00
Armin Schrenk a1a5fd3609 adjust design 2023-03-30 17:35:32 +02:00
Armin Schrenk 6c11cc8f1d complete workflow 2023-03-30 16:47:30 +02:00
Armin Schrenk 2b391a6ee3 Merge branch 'develop' into feature/convert-hub-to-local 2023-03-30 15:54:20 +02:00
Armin Schrenk b7fc03213d bump fuse-nio-adapter
Fixes #2801
2023-03-30 11:28:07 +02:00
Armin SchrenkandGitHub dfe17569e1 Merge pull request #2789 from cryptomator/feature/2786-only-restart-macfuset
Feature: Only require app restart if switching between macFUSE and FUSE-T
2023-03-30 11:23:09 +02:00
Armin Schrenk 827f9ad141 adjust comment 2023-03-30 11:18:28 +02:00
Armin Schrenk c8a6d0339e Use in volume preferences controller same objet as in MountModule to store first used fuse mount service 2023-03-29 17:42:18 +02:00
Tobias Hagemann b5bbd21f25 refactored the refactoring to a macfuse/fuse-t workaround again 2023-03-29 16:50:02 +02:00
Tobias Hagemann 771468c8c6 refactored macfuse/fuse-t specific workaround to a generic fuse workaround 2023-03-29 16:16:04 +02:00
Armin Schrenk ea2a48771f Closes #2829 2023-03-29 12:03:35 +02:00
Tobias Hagemann 0e10da25b3 Update README.md
[ci skip]
2023-03-29 11:58:14 +02:00
Armin Schrenk 943a3e9cfd adjust visibility 2023-03-29 11:42:14 +02:00
Armin Schrenk c988fb50a7 increase readability 2023-03-29 11:39:18 +02:00
Armin Schrenk 219ee0da9a implement core functionality 2023-03-28 14:02:11 +02:00
Armin Schrenk 5665e92839 deduplicate and add convenience method 2023-03-28 14:01:57 +02:00
Armin Schrenk 04ff188624 rename method in recoveryKeyFactory 2023-03-28 13:59:59 +02:00
Armin Schrenk ec7d6eafec add new password screen for convert hub vault flow 2023-03-24 18:11:39 +01:00
Armin Schrenk 28bb2ff9b1 add stub for vault conversion (hub to local) 2023-03-24 17:22:05 +01:00
Armin Schrenk a92ebfdc7b replace builder by stateless, threadsafe factory 2023-03-24 16:42:04 +01:00
Armin Schrenk f1e97fa64b fix workflow 2023-03-22 10:44:54 +01:00
Armin Schrenk b9d5cf04c2 fix workflow 2023-03-22 10:40:52 +01:00
Armin Schrenk 75cd3e44d8 change win-debug workflow to use temurin and openjfx jmods from gluon 2023-03-22 10:39:00 +01:00
Armin Schrenk 3cf1b829b8 make recovery key ui validation reusable 2023-03-20 21:40:16 +01:00
Armin Schrenk 6e4e9cd261 Merge branch 'develop' into feature/hub-local-access 2023-03-20 20:43:34 +01:00
Armin Schrenk e15dd7565f add workflow to build a windows debug launcher 2023-03-20 10:35:42 +01:00
Tobias Hagemann 77bc60fe5b Update README.md 2023-03-17 17:56:46 +01:00
Tobias HagemannandGitHub 9f633a1ecb Update README.md 2023-03-17 17:06:34 +01:00
Armin Schrenk fcf59d12a8 remove winget workflow 2023-03-15 16:47:34 +01:00
Armin Schrenk 6721075831 Merge branch 'main' into develop 2023-03-15 13:51:59 +01:00
Armin Schrenk 4bb0026415 Merge branch 'release/1.7.3' 2023-03-15 13:51:20 +01:00
Armin Schrenk bebae14744 finalize release 2023-03-15 13:51:09 +01:00
Armin Schrenk 997315eaf5 prepare 1.7.3 2023-03-15 13:49:53 +01:00
CryptobotandGitHub 16d677c40f New Crowdin updates (#2766)
New translations strings.properties

Belarusian; Catalan; Chinese Simplified; Chinese Traditional; Chinese Traditional, Hong Kong; French; German; Hebrew; Norwegian Bokmal; Russian; Swahili, Tanzania; Turkish; 

[ci skip]
2023-03-15 13:47:22 +01:00
Armin Schrenk 42a1913c17 Fixes #2797 and fixes #2760 2023-03-15 13:42:03 +01:00
Armin Schrenk c3f6655e48 add developer 2023-03-15 12:34:13 +01:00
Armin Schrenk fa1b0f2de8 reestablish interrupt state 2023-03-15 12:29:19 +01:00
Armin Schrenk 385574a618 prevent infinite loop 2023-03-15 12:10:15 +01:00
Armin Schrenk a67477bf3b Fixes #2778
ensure that mountpoint is ready
2023-03-15 11:40:44 +01:00
Armin Schrenk 03a362e9b4 fix compilation 2023-03-13 13:01:13 +01:00
Armin Schrenk 2223bc5e78 use correct selection logic 2023-03-13 12:58:34 +01:00
Armin Schrenk fdc0d2d6b5 only require restart in case if macFUSE or FUSE-T
Closes #2786
2023-03-13 12:44:56 +01:00
Armin Schrenk 58ed48b097 UI:
* remove restart notice for volume type
* only show restart label, when switching between macFUSE and FUSET
2023-03-13 11:17:56 +01:00
Julian Raufelder 7a0d255bd3 Use the same source tarball for signing that is linked in the release 2023-03-07 13:44:36 +01:00
Armin Schrenk 228fa099cb Merge branch 'main' into develop 2023-03-07 12:24:26 +01:00
Armin Schrenk a60ff20f15 Merge branch 'release/1.7.2' 2023-03-07 12:23:30 +01:00
Armin Schrenk 2328a5e3a8 finalize release 2023-03-07 12:19:35 +01:00
Armin Schrenk e7e181b1a5 Merge branch 'develop' into release/1.7.2 2023-03-07 12:19:23 +01:00
Armin Schrenk f3e7c08b43 deactivate winget workflow 2023-03-07 12:19:05 +01:00
Armin Schrenk 2a41afcfa9 prepare 1.7.2 2023-03-07 11:52:04 +01:00
CryptobotandGitHub 5bf38a328c New Crowdin updates (#2743)
New translations strings.properties

Arabic; Belarusian; Bosnian; Catalan; Chinese Simplified; Chinese Traditional; Chinese Traditional, Hong Kong; Croatian; Czech; Danish; Dutch; French; German; Greek; Hebrew; Hungarian; Indonesian; Italian; Japanese; Korean; Latvian; Norwegian Bokmal; Norwegian Nynorsk; Polish; Portuguese; Portuguese, Brazilian; Punjabi; Romanian; Russian; Serbian (Cyrillic); Serbian (Latin); Slovak; Spanish; Swahili, Tanzania; Swedish; Tamil; Turkish; Ukrainian; Vietnamese; 

[ci skip]
2023-03-07 11:49:50 +01:00
Armin Schrenk f983b29034 use correct docs URL for volume type 2023-03-07 11:40:10 +01:00
Armin Schrenk 4bc217e489 fixes #2761 2023-03-07 11:36:59 +01:00
Armin Schrenk b24f52a4ec fixes 2741 2023-03-07 10:58:34 +01:00
Armin Schrenk 91e7fa3de3 fixes #2758, fixes #2754 2023-03-06 15:58:02 +01:00
Armin Schrenk 1365efab3f use recommended notation of unit prefixes 2023-03-06 15:54:43 +01:00
Armin Schrenk 852963b785 check for correct WinFsp version 2023-03-06 15:50:21 +01:00
Armin Schrenk c47d4eaf02 Merge branch 'main' into develop 2023-03-03 16:37:45 +01:00
Armin Schrenk 36da26c6b9 Merge branch 'release/1.7.1' 2023-03-03 16:19:49 +01:00
Armin Schrenk 33e1cb3131 finalize release 2023-03-03 16:19:37 +01:00
Armin Schrenk ed4b433df0 prepare 1.7.1 2023-03-03 16:14:01 +01:00
Armin Schrenk d2ece543c8 suppress false positive 2023-03-03 16:04:34 +01:00
Armin Schrenk 4bb2df7d8f Fixes #2730 2023-03-03 16:03:36 +01:00
CryptobotandGitHub 4d5c6ca29a New Crowdin updates (#2712)
New translations strings.properties

Danish; German; Hebrew; 

[ci skip]

Closes #2724
2023-03-03 16:02:09 +01:00
Armin Schrenk f0d597ba73 require fuse3 packge for deb to have fusermount3 2023-03-01 19:28:40 +01:00
Armin Schrenk 310329d0b5 use correct javafx patch version for debia build 2023-03-01 15:51:42 +01:00
Julian Raufelder 30f86a7f2a Fix issue template 2023-03-01 15:23:30 +01:00
Armin Schrenk 5237dc8cae Merge branch 'main' into develop 2023-03-01 12:07:46 +01:00
Armin Schrenk 67ff4da05b Merge branch 'release/1.7.0' 2023-03-01 12:06:40 +01:00
Armin Schrenk 947eb11198 set correct version in pom 2023-03-01 12:06:25 +01:00
Armin Schrenk c6a9af1a04 update metainfo.xml 2023-03-01 12:03:03 +01:00
Armin Schrenk 0ddf221e26 Merge branch 'develop' into release/1.7.0 2023-03-01 11:43:49 +01:00
CryptobotandGitHub 3f2b5ccde9 New Crowdin updates (#2698)
New translations strings.properties

Chinese Simplified; Chinese Traditional; Chinese Traditional, Hong Kong; French; Japanese; 

[ci skip]
2023-03-01 11:42:57 +01:00
Armin Schrenk 4fc07c27b3 Merge branch 'develop' into feature/hub-local-access 2023-02-27 15:35:40 +01:00
Armin SchrenkandGitHub 3d0b6dde28 Update README.md 2023-02-27 13:09:56 +01:00
Armin Schrenk 45534b0a2b suppress false positive 2023-02-27 12:19:13 +01:00
Armin Schrenk 6d906beeb8 bump dependency-check 2023-02-27 12:17:47 +01:00
Tobias Hagemann e577c64c35 arm64 dmg installer (link + bg) for fuse-t 2023-02-27 11:06:19 +01:00
Armin Schrenk b848e78372 Merge branch 'develop' into release/1.7.0 2023-02-24 14:16:38 +01:00
Armin Schrenk 39e9395b4b bump fuse-nio-adapter 2023-02-24 14:16:20 +01:00
CryptobotandGitHub ca3157cc70 New Crowdin updates (#2695)
New translations strings.properties

Arabic; Belarusian; Bengali; Bosnian; Catalan; Chinese Simplified; Chinese Traditional; Chinese Traditional, Hong Kong; Croatian; Czech; Danish; Dutch; Filipino; French; Galician; German; Greek; Hebrew; Hindi; Hungarian; Indonesian; Italian; Japanese; Korean; Latvian; Macedonian; Norwegian Bokmal; Norwegian Nynorsk; Persian; Polish; Portuguese; Portuguese, Brazilian; Punjabi; Romanian; Russian; Serbian (Cyrillic); Serbian (Latin); Sinhala; Slovak; Slovenian; Spanish; Swahili, Tanzania; Swedish; Tamil; Telugu; Thai; Turkish; Ukrainian; Vietnamese; 

[ci skip]
2023-02-24 14:15:50 +01:00
Armin Schrenk f94c1f07d6 add new wix extension to ci build 2023-02-24 13:23:10 +01:00
Armin Schrenk d43f197c11 fix 67e566832c 2023-02-24 13:14:14 +01:00
Armin Schrenk 67e566832c use correct path to get winfsp download url 2023-02-24 13:13:07 +01:00
Armin Schrenk 6f5a88af1d extend winfsp uninstall instruction by reboot step 2023-02-24 13:10:15 +01:00
Armin Schrenk 210b891616 block exe installation if winFsp is outdated 2023-02-24 12:50:20 +01:00
Armin Schrenk 20e820c903 update IDE specific files 2023-02-24 12:48:41 +01:00
Armin Schrenk 5307e93c1b bump fuse-nio-adapter
fix illegalArgumentException when setting loopbackHostName
2023-02-24 12:48:29 +01:00
Armin Schrenk ec1d25bf65 Merge branch 'develop' into feature/hub-local-access 2023-02-23 21:10:03 +01:00
Armin Schrenk 7aa554498b move new password files to changepassword package 2023-02-23 13:00:51 +01:00
Armin Schrenk 85ac3c244d rename forgetPassword package 2023-02-23 12:55:30 +01:00
Armin Schrenk 5db5346c88 refactor error component to own package 2023-02-23 12:53:29 +01:00
Armin Schrenk e221019b57 Merge branch 'develop' into release/1.7.0 2023-02-23 12:09:03 +01:00
Armin Schrenk eeaaced976 reorder settingsJsonAdapter switch statements 2023-02-23 12:08:48 +01:00
Armin Schrenk d246b54268 ignore lastWrittenByVersion when reading settings 2023-02-23 12:00:14 +01:00
Armin Schrenk 8f4bf144c3 Merge branch 'develop' into feature/hub-local-access 2023-02-23 11:38:33 +01:00
Armin Schrenk e94572960e enable drag and drop for linux aswell 2023-02-23 11:16:48 +01:00
Armin Schrenk 2d1c59bea9 Renamed objects related to license exceeded user flow 2023-02-23 10:45:55 +01:00
Armin Schrenk 921cbd6439 Merge branch 'develop' into release/1.7.0 2023-02-22 17:47:14 +01:00
Armin Schrenk f811144ffa pom cleanup [ci skip] 2023-02-22 17:46:56 +01:00
Armin Schrenk 2ecc711f50 bump dependencies 2023-02-22 17:28:34 +01:00
Armin Schrenk cfcc8782ef bump cryptomator dependencies to stable versions 2023-02-22 17:19:40 +01:00
Armin Schrenk a1379bac40 For Windows try to migrate all user settings, not only the ones of local users 2023-02-22 15:33:37 +01:00
Armin Schrenk fe3f2b5bd3 Merge branch 'develop' into release/1.7.0 2023-02-22 15:14:43 +01:00
CryptobotandGitHub 7fc07ae02c New Crowdin updates (#2689)
New translations strings.properties

Arabic; Belarusian; Bosnian; Catalan; Chinese Simplified; Chinese Traditional; Chinese Traditional, Hong Kong; Croatian; Czech; Danish; Dutch; French; German; Greek; Hebrew; Hungarian; Indonesian; Italian; Japanese; Korean; Latvian; Norwegian Bokmal; Norwegian Nynorsk; Polish; Portuguese, Brazilian; Punjabi; Romanian; Russian; Serbian (Cyrillic); Slovak; Slovenian; Spanish; Swahili, Tanzania; Swedish; Turkish; Vietnamese; 

[ci skip]
2023-02-22 15:12:58 +01:00
Armin Schrenk 268c66a108 add hub specific tab to vault options 2023-02-21 23:18:00 +01:00
Armin SchrenkandGitHub 2a70e2f0f4 Merge pull request #2686 from cryptomator/feature/recovery-key-wrong-key
Display message if recovery key is not valid
2023-02-17 15:41:39 +01:00
Tobias Hagemann ffe0302fba updated access modifier 2023-02-17 15:33:00 +01:00
Armin Schrenk c5b86bc355 Closes #2648 2023-02-17 14:46:45 +01:00
Armin Schrenk 5f86473e3e fix recovery key state logic 2023-02-17 12:49:38 +01:00
Armin Schrenk a91c74b6eb Revert "Update translation key"
This reverts commit 71a09eae67.
2023-02-17 11:19:21 +01:00
76949d6ccb Update src/main/java/org/cryptomator/ui/recoverykey/RecoveryKeyRecoverController.java
Co-authored-by: Tobias Hagemann <tobias.hagemann@skymatic.de>
2023-02-17 11:18:55 +01:00
Armin Schrenk 71a09eae67 Update translation key 2023-02-17 10:59:04 +01:00
8087fcecfb Apply suggestions from code review
Co-authored-by: Tobias Hagemann <tobias.hagemann@skymatic.de>
2023-02-17 10:56:18 +01:00
Armin Schrenk 29c73e1bc8 display different messages if recovery key is either not valid or does not belong to the vault 2023-02-16 11:51:03 +01:00
Armin Schrenk 8bbdb69cda Update doc links to 1.7 2023-02-16 09:55:42 +01:00
Armin Schrenk e9ee15dcd5 add info about html comments to error form 2023-02-16 09:42:28 +01:00
Armin Schrenk 03f6e0a33c Use Label instead of Text 2023-02-15 23:44:51 +01:00
Armin Schrenk c5b21b0d8c Add warning about error report deletion to the error controller 2023-02-15 11:44:37 +01:00
Armin Schrenk c5c5e297b7 Fix getCiphertextPath for Windows again. 2023-02-14 17:39:34 +01:00
Armin Schrenk 24839985e9 Merge branch 'develop' into release/1.7.0 2023-02-14 11:40:10 +01:00
Armin Schrenk a7b2802f34 show correct error message when using custom mountpoint with webdav (Http address) 2023-02-14 11:39:16 +01:00
Armin Schrenk c85d0b4beb bump webdav-nio-adapter 2023-02-14 11:22:11 +01:00
Armin Schrenk 3dff3a8664 Fixes #2682
* allow windows installer to remove same version
* add revisionNumber to installer version
2023-02-14 11:20:22 +01:00
Armin Schrenk 5b0bbf539b improve FailOnRunningApp action 2023-02-13 23:34:43 +01:00
Armin Schrenk 1ff7c40fd9 Fixes #2672 and fixes #2668 2023-02-13 10:42:17 +01:00
Armin SchrenkandGitHub d0875ef49e Merge pull request #2669 from cryptomator/feature/virtual-volume-doc-link
Add link to volume type documentation
2023-02-09 13:06:03 +01:00
Armin Schrenk e35ed9af72 enable localization of tooltip 2023-02-08 20:11:34 +01:00
Armin Schrenk ac43efe149 change UI to be not so clunky:
* only use question mark icon
* use tooltip at icon instead of explicit label
* icon is the hyperlink
2023-02-08 11:33:41 +01:00
Armin Schrenk 202a2ea79f Load revealPathServiceProvider at app startup 2023-02-08 11:14:54 +01:00
Armin Schrenk c19a86a348 add link to mounting documentation 2023-02-07 15:23:04 +01:00
Armin Schrenk 539dcaa85a Update issue template 2023-02-07 12:23:25 +01:00
Armin Schrenk fb91c1a461 Merge branch 'develop' into release/1.7.0 2023-02-06 14:45:56 +01:00
CryptobotandGitHub bd75370dfd New Crowdin updates (#2646)
New translations strings.properties

Catalan; Chinese Simplified; Dutch; Italian; Persian; Polish; Slovak;

[ci skip]
2023-02-06 14:44:45 +01:00
Armin Schrenk 7a9a9cf4eb Follow up of 69d73d0fb9: Remove standalone launchers 2023-02-06 12:31:56 +01:00
Armin Schrenk 489e9fce90 bump integrations-win to 1.2.0-beta2
Closes #2657
2023-02-03 13:19:53 +01:00
Armin Schrenk d378d84832 bump fuse-nio-adapter 2023-02-03 13:19:43 +01:00
Armin Schrenk 69d73d0fb9 Remove standalone launchers 2023-02-03 13:15:03 +01:00
Armin Schrenk 97c0cb4f5f add to settings.json the app version written to it last 2023-02-02 16:44:03 +01:00
Armin Schrenk b4faae7fa0 make debug logs readable by filter out internal fuse-nio locking 2023-02-02 10:36:31 +01:00
Armin Schrenk 55d76b65cc Add IOException to log message during revealPath 2023-02-01 22:31:27 +01:00
Armin Schrenk fd6e1e6741 fix bug 2023-02-01 19:23:28 +01:00
Armin Schrenk 155558caa8 add style class to text object 2023-02-01 13:50:56 +01:00
Armin Schrenk 28217b2de3 only perform mountpoint move and cleanup, if mountpoint is not a drive letter 2023-02-01 13:44:57 +01:00
Armin SchrenkandGitHub b9e57ce895 Merge pull request #2654 from cryptomator/feature/2652-migrate-dir-mounts
Feature/2652 migrate dir mounts
2023-02-01 11:17:11 +01:00
Armin Schrenk 95ea23ee6e add more comments regarding removal evaluation of this workaround 2023-02-01 11:07:23 +01:00
Armin Schrenk c269184217 ensure that settings.json is a file 2023-01-31 18:05:31 +01:00
Armin Schrenk 68d32957e4 fix errors 2023-01-31 16:37:25 +01:00
Armin Schrenk a771f0a5b7 doc doc doc 2023-01-31 13:59:18 +01:00
Armin Schrenk e56e6a8359 integrate script into installer 2023-01-31 13:58:56 +01:00
Armin Schrenk 5f9b77241f extend migration script to all local users 2023-01-31 13:40:25 +01:00
Armin Schrenk fb54ee04a6 Remove Dokany advertisement from msi installer 2023-01-30 13:32:56 +01:00
Armin Schrenk a106b04c7e prototpye for powershell script to be executed after installation 2023-01-30 13:30:06 +01:00
Armin Schrenk 285d48b70b Merge branch 'develop' into release/1.7.0 2023-01-27 13:27:31 +01:00
Armin Schrenk 0d8d7e4ee5 fix debian artifact upload 2023-01-27 13:27:03 +01:00
Armin Schrenk f232f9d958 Merge branch 'develop' into release/1.7.0 2023-01-27 12:31:00 +01:00
Armin Schrenk 88c3b0cc4f remove tag-name from release action to just add to current release on debian build 2023-01-27 12:30:44 +01:00
Armin Schrenk ef190db739 Merge branch 'develop' into release/1.7.0 2023-01-27 11:36:28 +01:00
CryptobotandGitHub b378354bb9 New Crowdin updates (#2562)
New translations strings.properties

Arabic; Belarusian; Bengali; Bosnian; Catalan; Chinese Simplified; Chinese Traditional; Chinese Traditional, Hong Kong; Croatian(Cyrillic); Czech; Danish; Dutch; Filipino; French; Galician; German; Greek; Hebrew; Hindi; Hungarian; Indonesian; Italian; Japanese; Korean( Latin); Latvian; Macedonian; Norwegian Bokmal; Norwegian Nynorsk; Persian; Polish; Portuguese; Portuguese, Brazilian; Punjabi; Romanian; Russian; Sinhala; Slovak; Slovenian; Spanish; Swahili, Tanzania; Swedish; Tamil; Telugu; Thai; Turkish; Ukrainian; Vietnamese; 

[ci skip]
2023-01-27 11:35:50 +01:00
Armin Schrenk 822e863e27 partially revert 220782b84f 2023-01-26 16:29:43 +01:00
Armin Schrenk 40fbe4f59d remove more libffi workaround leftovers 2023-01-26 16:05:53 +01:00
Tobias Hagemann bf779b5b41 updated dmg background 2023-01-26 15:57:10 +01:00
Tobias Hagemann ce5dbd14d8 reverted be7ac50928 2023-01-26 15:57:10 +01:00
Armin Schrenk 48744018a2 Merge branch 'release/1.7.0' into develop 2023-01-26 15:56:48 +01:00
Armin Schrenk bd9f79cb56 add cryptomator.mountPointsDir property to macOS installer scripts 2023-01-26 15:54:31 +01:00
Armin Schrenk f4c4f72539 remove libjffi stuff from appimage 2023-01-26 14:31:23 +01:00
Armin Schrenk 74718754ad fix merge 2023-01-26 13:48:30 +01:00
Armin Schrenk eb595379d6 Merge branch 'develop' into release/1.7.0
# Conflicts:
#	dist/linux/debian/control
#	dist/linux/debian/cryptomator.sh
2023-01-26 13:47:46 +01:00
Armin Schrenk 220782b84f reduce jars neede to stay on classpath due to missing module info 2023-01-26 13:28:55 +01:00
Armin SchrenkandGitHub 1c104737c1 Merge pull request #2639 from cryptomator/feature/mount-provider
Refactoring: Use mount service
2023-01-26 13:20:11 +01:00
Armin Schrenk 7c8a519919 bump webdav-nio-adapter 2023-01-26 13:10:32 +01:00
Armin Schrenk ae1fa5851f remove traces of ActualMountService from volume preferences controller 2023-01-26 13:02:21 +01:00
Armin Schrenk 86ccb1a58f changing volume provider requires restart due to macFUSE/FUSE-T lib loaded in same JVM 2023-01-26 12:05:34 +01:00
Armin Schrenk c3fb58f7d0 bump fuse-nio-adapter 2023-01-25 16:49:00 +01:00
Armin Schrenk b4c384acc9 use speciaized translation key 2023-01-25 12:44:09 +01:00
Armin Schrenk 8580e97791 cleanup 2023-01-23 14:39:46 +01:00
Armin Schrenk 5d348ee229 Bump WebDAV dependency 2023-01-23 14:39:21 +01:00
Armin Schrenk dda0ff545c add point of automatic mount point selection 2023-01-23 13:47:00 +01:00
Armin Schrenk 708b5938ac Add info about the dependency of volume type and mountOptions 2023-01-23 13:11:01 +01:00
Armin SchrenkandGitHub a3cb8cd2f1 Merge pull request #2641 from purejava/jdk.security.auth
Add jdk.security.auth module as it's required by dbus-java-core

Closes #2640
2023-01-23 11:10:59 +01:00
Armin Schrenk 3587d53d15 bump integrations-mac, fixes NoSuchServiceException for RevealPathService on macOS 2023-01-23 11:09:15 +01:00
Tobias HagemannandGitHub 2f5e2af8d9 Merge pull request #2638 from cryptomator/feature/traymenu-onbeforeopenmenu-macos-fix
Fixed vault list refresh when tray icon is clicked on macOS
2023-01-23 10:24:57 +01:00
Ralph PlawetzkiandGitHub 8139cb8c38 Add jdk.security.auth module to rules 2023-01-22 20:05:13 +01:00
Armin Schrenk 09d5f71335 do not reset mountflags to default ones when window opens 2023-01-22 19:24:35 +01:00
Ralph Plawetzki 3a638735b7 Add jdk.security.auth module to appimage.yml 2023-01-22 18:11:50 +01:00
Ralph Plawetzki f1f5f7e02f Add jdk.security.auth module as it's required by dbus-java-core 2023-01-22 17:59:20 +01:00
Tobias Hagemann 94fe8ca449 updated string
[ci skip]
2023-01-20 17:18:05 +01:00
Tobias Hagemann 1251e1b873 updated separator styling 2023-01-20 17:14:02 +01:00
Armin Schrenk 50405c0bd5 remove debug message 2023-01-20 17:07:19 +01:00
Armin Schrenk 774d24625c change styling of volume preferences 2023-01-20 17:07:04 +01:00
Tobias Hagemann ba4902a5bc Fixed vault list refresh when tray icon is clicked on macOS 2023-01-20 16:45:35 +01:00
Armin Schrenk 90408504e2 Merge branch 'develop' into feature/mount-provider
# Conflicts:
#	pom.xml
#	src/main/java/org/cryptomator/common/vaults/Vault.java
#	src/main/java/org/cryptomator/ui/mainwindow/VaultDetailUnlockedController.java
2023-01-20 15:27:48 +01:00
Armin Schrenk c8c44e0554 bump fuse-nio-adapter dependency 2023-01-20 15:01:31 +01:00
Armin Schrenk 7afab6fe78 add auto option to volume type selection 2023-01-20 12:29:17 +01:00
Armin Schrenk ad321dfe55 migrate 1.6.x volumeimpl to hardcoded mountservices 2023-01-20 11:49:15 +01:00
d6388d6205 Added drop zone for revealing encrypted files or folders (#2592)
* Added drop zone for revealing encrypted files or folders

* Split god drop zone into distinct drop zones in vault list and vault detail unlocked

* Prevent cursor from changing if content doesn't match during drag over

[ci skip]

* Removed unused methods / css classes

[ci skip]

* Updated method name

* Refactor Vault::getCiphertextPath to only accept strings starting with "/"

* bump cryptofs

* ensure that path cleartext path always starts with "/"

* added file chooser for revealing encrypted items

* Trying to fix path parsing again

* Updated drag & drop design for buttons

* use RevealPathService to reveal files in file manager

* fix compilation error

* Copy paths to clipboard if no revealService is present

* reintegrate wongFileAlert

* Only accept TrasnferMode.LINK

* updated drag-n-drop button styling

* added tooltip

* updated string

* cleanup

Co-authored-by: Armin Schrenk <armin.schrenk@skymatic.de>
2023-01-20 10:46:00 +01:00
Armin SchrenkandGitHub b8326907bf Merge pull request #2624 from purejava/update-appimage-build-script
Update build.sh to .github/workflows/appimage.yml
2023-01-19 13:37:10 +01:00
Armin Schrenk 5beeeae27f Sign integrations.dll during build 2023-01-16 18:47:41 +01:00
Armin Schrenk fb1f3c4757 fix bug using wrong mount flags 2023-01-16 14:14:03 +01:00
Armin Schrenk 5e32cbcdd0 show supported mount features in preferences/volume 2023-01-13 18:11:36 +01:00
Armin Schrenk 08d741ecf5 address TODOs 2023-01-13 16:24:15 +01:00
Armin Schrenk 23060a8497 reinitate workaround for MOUNT_WITHIN_PARENT 2023-01-13 15:59:44 +01:00
Armin Schrenk 47a32893f0 Refactor mounter class 2023-01-13 13:46:41 +01:00
Armin Schrenk 0f7ba4e00e remove updating driveletter strings 2023-01-13 12:53:41 +01:00
Armin Schrenk 0d75b999a3 cleanup 2023-01-13 12:50:38 +01:00
Armin Schrenk b6d97528d2 fix driveletter selection 2023-01-13 12:49:20 +01:00
Armin Schrenk 94c53989b1 MountOptions window: Reset to auto mount, if no dir selected 2023-01-13 11:27:30 +01:00
Armin Schrenk a72ea1b9f5 move mount prepartions to own class 2023-01-13 11:20:23 +01:00
Armin Schrenk 6395f17736 Handle illegelArgumentException when setting custom mountpoint 2023-01-12 17:21:54 +01:00
Armin Schrenk 5c61944757 fix minor ui bugs 2023-01-12 12:53:58 +01:00
Armin Schrenk c641695a40 migrate 1.6.x vault settings on-the-fly 2023-01-12 12:11:03 +01:00
Armin Schrenk d93ef2e905 Reinitiate force lock 2023-01-11 16:40:14 +01:00
Armin Schrenk 8b9377cf4e only fix custom mount flags, if explicitly desired. Otherwise use the ones provided by mount service 2023-01-11 16:35:12 +01:00
Armin Schrenk 991b03e000 use function paramter, not instance variable 2023-01-11 16:21:49 +01:00
Armin Schrenk 73d8c4098e resolve TODOs 2023-01-11 16:18:05 +01:00
Armin Schrenk 6a52d15510 Show mountpath in reveal button 2023-01-11 16:01:59 +01:00
Armin Schrenk d07b1b96dd Use first available mount provider if none is selected or selected is not present 2023-01-11 16:01:51 +01:00
Armin Schrenk 24d472ed8b Merge branch 'develop' into feature/mount-provider
# Conflicts:
#	dist/linux/appimage/build.sh
#	dist/linux/debian/rules
2023-01-11 16:01:27 +01:00
Armin Schrenk 6fe2d73c52 copy uri to clipboard when using fallback mounter 2023-01-11 15:59:39 +01:00
Armin Schrenk 523e5d7904 bump webdav- and dokany-adapter 2023-01-11 15:59:17 +01:00
Tobias Hagemann 304064d9ab updated dependency-check version 2023-01-09 11:59:51 +01:00
Tobias Hagemann 0d49c60d4d reverted 1a6258eb17 2023-01-09 11:32:11 +01:00
Ralph Plawetzki 0e0e00f116 Remove stuff not needed when run locally
From: changes requested for PR #2624
2023-01-08 14:10:38 +01:00
Ralph Plawetzki 77c0a3e265 Update build.sh to .github/workflows/appimage.yml 2023-01-07 15:31:32 +01:00
Tobias Hagemann 1807888860 updated sponsors
[ci skip]
2023-01-05 11:16:22 +01:00
Tobias Hagemann be7ac50928 added new app icon for macos, fixes #2517 2023-01-04 16:32:40 +01:00
Julian Raufelder 9182c415eb Hello 2023 🎉 2023-01-04 13:35:58 +01:00
Armin Schrenk 1a6258eb17 revert eea568ca4e and e2898f0c8b 2023-01-04 12:52:16 +01:00
Armin SchrenkandGitHub 9c0c6a91fb Merge pull request #2580 from jacob-willden/develop
Add more info to Migration Screen
2023-01-03 16:47:18 +01:00
Armin Schrenk 53436520c9 fix using the wrong property 2023-01-03 12:38:18 +01:00
Armin Schrenk fd5aeaf90a Merge branch 'develop' into feature/mount-setting-per-vault 2023-01-02 13:47:30 +01:00
Armin Schrenk f3fcfc913b Remove unused class 2023-01-02 12:10:46 +01:00
Armin SchrenkandGitHub 0b0870e313 Merge pull request #2575 from VsevolodGolovanov/issue_2557_unlocked_status_indicator_in_tray_icon
Unlocked status indicator in tray icon 

Closes #2557
2022-12-30 11:40:51 +01:00
Armin SchrenkandGitHub 6704bb1f8c Merge pull request #2612 from cryptomator/feature/2597-no-keychain-dialog
Feature: Show dialog for hub vaults, if keychain is disabled'

Closes #2597
2022-12-30 11:32:40 +01:00
Armin Schrenk 48d1938b99 Refine dialog text 2022-12-30 11:19:37 +01:00
Armin Schrenk 6199277002 Add Button to open preferences 2022-12-29 18:26:13 +01:00
Armin Schrenk 9fefe8e462 Show info dialog when keychain is deactivated 2022-12-29 18:20:46 +01:00
Armin Schrenk 5fcd53be18 load device key before showing UI to prevent uncatched failure of UI loading 2022-12-29 18:17:47 +01:00
Jacob Willden 7147636428 Switch term for new vault migration dialog 2022-12-21 18:56:17 -07:00
Jacob Willden 690bd833e8 Add more info to Migration Screen 2022-12-16 13:28:57 -07:00
1e12590681 Update src/main/java/org/cryptomator/ui/traymenu/AwtTrayMenuController.java
Co-authored-by: Tobias Hagemann <tobias.hagemann@gmail.com>
2022-12-15 13:34:52 +04:00
Tobias Hagemann eea568ca4e GCM is explicitly ready! 2022-12-14 22:27:34 +01:00
Armin Schrenk 8009205da7 Merge branch 'main' into develop
# Conflicts:
#	pom.xml
2022-12-14 20:07:24 +01:00
Armin Schrenk c0f73a2802 Merge branch 'hotfix/1.6.17' 2022-12-14 20:06:35 +01:00
Armin Schrenk 8e902877a3 Update dependency-check plugin and exclude false positive
(cherry picked from commit ebcd0adf78)
2022-12-14 20:06:23 +01:00
Armin Schrenk fd76c89393 update metainfo 2022-12-14 20:02:12 +01:00
Armin Schrenk 975baf594c Fixes #2576 2022-12-14 19:58:22 +01:00
Vsevolod Golovanov 5a99c7bb61 Unlocked status indicator in tray icon #2557
Now tracking unlockedness and updating the icon accordingly.
2022-12-14 21:18:37 +04:00
Tobias Hagemann e2898f0c8b GCM is ready! 2022-12-14 17:36:06 +01:00
Tobias Hagemann cf2b236df5 added tray icons for unlocked state 2022-12-14 17:28:59 +01:00
Tobias Hagemann 819fa803f3 cleaned up tray icons 2022-12-14 16:47:07 +01:00
Armin Schrenk 980e2b184b use correct tag name for gh release in debian workflow 2022-12-13 12:48:29 +01:00
Sebastian Stenzel ebad677e84 fix path to downloaded jmod files 2022-12-12 09:14:24 +01:00
Sebastian Stenzel 4fda4a2b2e fix makefile 2022-12-12 09:09:25 +01:00
Sebastian Stenzel ffaf7ad360 adjust package dependencies to new mount api and jfuse 2022-12-12 09:03:56 +01:00
Sebastian Stenzel 76689705f5 remove LD_PRELOAD workaround, which should no longer be required with jfuse 2022-12-12 08:54:18 +01:00
Armin Schrenk 0d6d7b0dd6 directly use inputs object 2022-12-09 16:56:45 +01:00
Armin Schrenk 9dfd8adcce revert 0725a63b09 and fix workflow 2022-12-09 16:56:02 +01:00
Armin Schrenk 433eecc6a8 adjust matching rules for version type detection
(cherry picked from commit cd358916260e713d4119c20b1bcb5b448a017365)
2022-12-09 16:50:39 +01:00
Armin Schrenk 36ed4554b2 Fixes #2570
Dabian build: Make libffi7 a runtime dependency and preload it.
2022-12-09 15:12:04 +01:00
301 changed files with 9101 additions and 3737 deletions
+10 -5
View File
@@ -37,12 +37,17 @@ body:
id: volume-type
attributes:
label: Volume Type
description: What is selected under Settings → Virtual Drive?
multiple: true
description: What volume type is selected under Settings → Virtual Drive?
options:
- FUSE
- Dokany
- WebDAV
- WinFsp
- WinFsp (Local Drive)
- FUSE-T
- macFUSE
- WebDAV (Windows Explorer)
- WebDAV (AppleScript)
- WebDAV (gio)
- WebDAV (HTTP Address)
- Dokany (1.5)
validations:
required: false
- type: textarea
+19 -117
View File
@@ -2,123 +2,25 @@
## Reporting a Vulnerability
For reporting security-related vulnerabilities or exploits that [haven't been reported yet](https://github.com/cryptomator/cryptomator/labels/type%3Asecurity-issue), contact us at: security@cryptomator.org
We take security seriously at Cryptomator. We appreciate your efforts to responsibly disclose your findings, and will make every effort to acknowledge your contributions.
<details>
<summary>PGP Key</summary>
To report a security vulnerability, please use the [GitHub Security Advisory feature](https://github.com/cryptomator/cryptomator/security/advisories). This feature allows you to privately discuss, fix, and publish information about security vulnerabilities.
```
-----BEGIN PGP PUBLIC KEY BLOCK-----
Comment: GPGTools - https://gpgtools.org
If you prefer to report the vulnerability via email, please send an email to security@cryptomator.org.
mQINBFbgeicBEADM9AcU6DTgM5KZnBaJc6x9DBLr+TCMHntTt7YM9GLTlO2Z43Jt
oYoyqdRWAY28veqpLEFgRvvVD3fdBj/KUOxF1cr2JsErwXqbjwaLq0o/0KIXz7UK
a6pQSemZKfpOtJrfacofOTwvG6AuG9uakBYNMyxuojyOkoh3xsYS1KZ7TwPgCdET
t8/zva41Pa5kh5+GeSZJdCuygG6ynPBJEpmK5V7Qizvics5fziXecF+QaFZijafv
YahfxokvF9pXCQTmV4m57NQma9uK0w83U9nJCPjEd+x3wK0Hxrc1ojy8ZFTA1YND
AQg/MTABgHbQQkXDQhjS/TloOObqtbMBqNSbcSXpaR4teaCWKBl1MSq00nJLj8db
vPJGqfg7UbXhlALggp029/kskYlR5SmbxWquLbl0Xre3fDHuHEiWcJL6MS3454Wt
Mno13/4UhOlRFh5g0pLmPz7seOTJjDqc9abn/RXOLq0+3qX0gC0bDm5aCE5dQ2MV
FMbrrlw/dZESNLZvtB3gOsramSry1R3HVZ0QJ2vMaF2cxewebqcYbuecUNj6bxpv
5LEhEmqz6dG1meLLWDsvQLPEUWEIJnfpBiDSm342yxJq4pXnVF+aqAQsCL3FpmvZ
2j0FgFOs7iXOcFUJIiR0xUmWPk1NWYcUowqmRW8pMM9nFUzFF99iggPznwARAQAB
tC1DcnlwdG9tYXRvciBTdXBwb3J0IDxzdXBwb3J0QGNyeXB0b21hdG9yLm9yZz6J
AkAEEwEKACoCGwMFCQcrKAAFCwkIBwMFFQoJCAsFFgIDAQACHgECF4AFAleu2cQC
GQEACgkQI7Xb75TU2B3+7A/7BKRWdo5/moCCEbBzYQ7vRMLFdwmjFFlSZ7aGC0fP
YHdeUwxPbO0cATwmNpGMma7rBn1FDg3Vto6/wottGxm+XIRwlyY84CD1VZAihZ/e
WvjOO28/7VgRy6PGKzlhpDSoT8GwFOgO69e7bEff1Zj562RZe7nXc4tDivILMB++
KgmmSgtddygmNQCS3RD3KssGo+l+cSjsg09F5WAJ6nQe8Jq2hICq+o/P6UXPI5lX
bhvWYDn4/8sRHsIlGpQYYDDe0fz7IQKuSLAHpF5upNDxj6dYb05F8PPVrk6MW6nL
/kf1fZ27DlLN5/NFvhhBRuwxxoAFqPS7Iel3z7L0JkRUYmGLVB5m9Cqiw6FK8JRv
OtvakdDoKb5lVAoN5NeBfNBSqEcXVF/EdfTfIyyo7hZRA6xFMEVbmYbzt0sj0djV
ZOey2TOFrTCpkHfUUDgKvk5sn+F3u8mmPIbqquEzlFJSFjcyiYYDv22rg1In+zKV
Xmw4BFZRDS6IVSQRGlskRGJBixCaGyDYxHXXT2cg4Rk9uiCX11+0E9qlAsg6xPe6
rnaYDT8dU0AFyVpDpshflXH3kVQSpiqZS3jkAk1/54ODO8pE80Zrnd5m5AMuNcmX
+9MkZKE+h0882UskDs1dyt26GU2hoy4lAeRUaut7zIK/WO6nnuLaTvGWT95RDz+q
kD2JAiIEEwEKAAwFAleu2iYFgweGH4AACgkQZnuGbqgkCgnmCA//U22uhyEC/Tp3
Cbt5lctQmqbgMbjRBaHQyW52tPFMaq8vXMbo/5TTtVC6xsp2PJT84cxAd8KX8hWq
cPtF4wWCJGng/AzyxQ5dWfGvA/ll32ygjtJN3P/AvA9KlhG+6XYmS8cPkBkJBi6B
2yCdZT1cXc/TPAFzjgAwz7K9g3awG0OeOc/CXymH0DD/snkiwKQoucStolYywZGc
GszjMQgeT4zOc1wtEz24uL3dMNDlDcQMAh56YvK2oB0iMYmAFyX/IS+f2bM9paXi
HX+mg/z53iwgf5ZXbslNDbMTJ5GNksjEGjCFfDHAdNdgT+lcW4l2U7q4PYUaN4LA
DE9j2OlOlQ9qjucOgoCStirnTP7XHd4p31lgdz8+THOQowB5Ji95OkiNQAFCfxBt
mcA/bWnJZQDm7L8RVzHovBpAaK6vUjxEvR+DXdESSzyZwkpsZwGZcyqGRT26R1/L
JE5WvjKufNc5v3Cat320MjyrLZwVGRgvEpDMoCw3nTWl9AtOj5vgaakEWr7AnqET
xk7UFbYmdTlQqkWuLKubz9Rx/FbrBmvd6vwTHy1Dfl6QyMWNCClatgN00Hxped/6
CErg+R/RXd8apGxnOuWDqoujPn5LOHzgJolp1Ox16nTiZe2G+LbDr3hqRFi1wW6w
ioMB4KpkdA03uyxJSWmDEMiR1l3Oxom0KUNyeXB0b21hdG9yIFByZXNzIDxwcmVz
c0BjcnlwdG9tYXRvci5vcmc+iQI9BBMBCgAnBQJXrtnDAhsDBQkHKygABQsJCAcD
BRUKCQgLBRYCAwEAAh4BAheAAAoJECO12++U1NgdQYMQAKCIzNJF8rURQcFLSv3J
sPBjRy2HCzCWm21MuhU+bsaZx7U9M9dgEjzLfxN9s19VsBH3WKLgok2FgiYSGka3
6Oy/P8VFLFmHs7dS9i2fro2eF7i4zj/ZD/9t0jM4ZIgLpbzr5sTBld292nsfXGob
xOJeOx3oWYyR2FO9VQxXjC3JvJyZkFgoy0tauS4Mvii4cF56wJGcxDTbe1s7UaRC
a/fh4zgISZSBE3rYhCawkN4mqMDM5RDjrdtjKUPWk345HcjjQ4Wos8xw4YbGbNr9
Pc7m2URYJJ0jFM4tnoRF6cmA3bT9tm8pcOFg+K/ycVrltVEy+A8Wj8UGjyP1uI1t
EqWHN3LZpIGfW0w9AGrw7OUI9czXcukfngj/DsOU3WMBDIM8pW9+zBpr75yIS6lz
C0IqksLXSqX0b/Rby4O+wb6UZ1ZFkaim2GGtAZV+nGXtdnEXSNFiP7ykzjZ02m/1
7CKyj3VmdAgT56zEIypFSfxm9gOWsJPmfhSyuE8bFyoitgNxpheZk6xZy4upVMPR
WK3hutScU0yDv2HVCiA3o3Ggy42nmz9HpGF6W2DmBx4bhMaVs6I2VFyKdQzmJD/3
FCWjwz8PiEgVGHGPnD+WdPFLhrc/44gF4h/VuLjkubtULGuTVvgjeTIJ5LR1Gmwc
YOk6eD7MAJPzJVj5/PYFtIbKiQIiBBMBCgAMBQJXrtonBYMHhh+AAAoJEGZ7hm6o
JAoJBh4P/1w88YMTKUHpFTfJEwH2hK36BZN96Bf/k+vP7n1Xxp3NheInJblHFOt/
ccsup6am+APrk8gGtlIVmtVc3nO8WMsWxfJxGDecyRsNbessnODv/llyg3tzVU/H
tLk7gLiK0TcIsOLfeNXGTxRRSKWjVFsNfuixNCzzHa7tFq6ddVn9VRZ8fqJB2p21
OogWSDqUo9q9Wfb4RkYHguDx+8Jzoo/MxR1TSt8gUO2xDvEbqgeQiMCLF8R0lO3Y
zz0FrpyOsFU1CxVp+wo55bWv1UdwgQKQt4o0m5/zDJ2RAtscXpd4YcTE+XxKeK+4
qhihhkhLGpKsxzK5m9/qwMbodHwoBCBzfalkUR9xOq9yQIeEoC8XYL62NqB3BCSU
KfWFIHxUkE9WH5zHWaV+bhrlNgk7nz3xBfPf1P2mNIc1VUHoNqOZOmWwz2VaKLSW
f3GIqx9wGythFbLdXmUoC3W//DDYgQnvImvkncMqQ5nRHPf8uHcLQK5WZyIxpgWT
eKon5G/cj0BTptcBhapMwSIyfaC5FV7so0/CkOA6R9Fyq2VpGoHy7XPhFS+6ieLi
KUWhCvbuf2deWbSaJ0peMdzy1p72UXwrsEM0M3Fz+Jd8zvCaFzf5Fx27+pAAdlfg
4bT3/2gSf7S+cU3+DnYOH0NeRt2Z2mjEKg9OwttTO/oDboQHdZlrtDRDcnlwdG9t
YXRvciBTZWN1cml0eS1UZWFtIDxzZWN1cml0eUBjcnlwdG9tYXRvci5vcmc+iQI9
BBMBCgAnBQJXrtnWAhsDBQkHKygABQsJCAcDBRUKCQgLBRYCAwEAAh4BAheAAAoJ
ECO12++U1NgddzoQAI78+Nvm6VvNuptXJjEmrpHRyKCnHF9wH5kxvF8WZCgpOkJ4
vONmyS+9ZlepnT83MpGm/MzdIMCnDJmDmqmA5ISBRcD7k9Gjzz5rPKwE2zDyo0M0
wF1L2UEUqAlcvE0e4twZcP2DGoNqdSf6IaWsXhQMb1a/rTMsoGZLuTB8kCbv6Ntl
ULahcRToTB2shsbZjzE896P6X5hDCfGWl0Jhcbf53pnXX1dOsEw3et9AGru1IUMs
UGM+wpgTwagRj+XB/WY1x9IznKtiHTq83Fvt+3bkg0+NIcV3GDqXDIUtqIwy8gDd
4KgBU+LkyxXFDa4OxLc53n6b+Iy1nDosM+SiqSzdCCgEs/dY1tQBn/7P1GT18dEe
tFgeH/c6wLvEpDIc9urAsYXf8H+1uy7glWpWTq8DE0yhCr4adjCqlIsVHQQO4UUW
NfqMGEFpJ+3HjSSwnvDGY78lLQh5d4vqWV435aNaMqZg0gJIA0FtiP1fRtmT73BG
N/tBNiBxretFR4B+x/TWqPd5iJV7/MAn/pa1WSOcaxzJrVUsjXdgLQCqcHWd4/w1
f4DU9cJjl3sxZlMdAlg8Q1bF+pmjQQ4WKZkqMtwpoUilfVXmL42ay1LBCgW68/uJ
OTyGfp8ntUsbbm5raGsny3TLqnacyG9hxcPGNTzD1+MrbUvfsc7+4U0dCZTuiQIi
BBMBCgAMBQJXrtonBYMHhh+AAAoJEGZ7hm6oJAoJ1DQP/R+1drZiZQU45ChMbfTb
XQjJRsUOGZp3PTWtx4KrVFvE8ea0PF+DZX5gLJYIU+iZmPXRpzFu6dKPbcZ7RfRt
5RRH102zDZzijt2CQd7YLO8wxUFoWX9X7DGgxXEcNjl9kFVmnyHgiTwTzuZ0Zy4y
PvoiwrhcZmXEYbOeV40gLFie6wuzz5IIcs01e30xIs+1/1gwmgI5UnG3jveUgmcj
f/lvg3POKiwrY5Uzw1FSruJx21X06wTpDcfOACID4L7aY9eg2B/qL2Xj8nuhejqG
+1AVTMk2o6pxkvevHmxYQfEpuWGCw0RCBn9ObWwz6Zn5J9pjGbMrM+b1/M2Ouv3N
cpoGgCSahKNsRMKO7RMrBG0jtLcasPSgZFYPJSZAAb+YhxKUbpPHzDIwTEjgM7CL
gKSyRTKyp5IoFK53bpXL/ZIjkAhMvyDult6+BL6vI0+h3BBA9I0FF2Qhe139xLv/
DS7aDiYAE9vGMGoeCBfxJPwUsDU3hrGe/wgL7fR6nmN7R2QffisBHKHsklORy9t3
w3YFRd5sBAxv+EOcdkgXEmqKOfVQ8KU9adQcxPDGMAK/esjVwxUxsaf2PF5noxxW
3zL2ureUO/mMoH5Cwr0BuM3HFb82t1JJd4IXlLEyNvDMFMwD2d7h37bGK7Y5hEsl
zL7Dm+wQRY8sxg4QOZHbJjQXuQINBFbgeicBEADnkxGSEL1zwACaiVqADKC6/pgO
MMWjxoENBT6r8Vnp1D5hfNDkEi9iXUpCEO6nzywBf3/4c4Yk1wBOBZ7YWyWXMf4v
2g1evxELO5z1UlAwna6HSl7G0omIBqzz1Er5IS7C9WEZM8ZggwcuswCrbxfz4+fN
t7cCL5QyOvuxez+vrn+VIgLQzKm+LV4Wc+OFbHIys+0saQUhItKO0/CsXGc8R314
jdN5UsZk/MUdPPAs+6OCr8d3PpJvR6IST76TtN8aDjSS9T6em7dwdGFEwCGww3Jc
xrAkvvUmSlscz+rnvHA5DYQGK6NXLenB40sVQVfch1r1VqwvlzA0u7OovjwM8+7u
+DaBQ0YejbdnC7yfeE91LmZkG6jRKfvTJkv18tjNsgZsVmM13xzP67fCFIB9M+lN
t9zEldGKHVwm+06FHIWJsBDRgrquNb9xd1vgHHeIbJvKf+LqZhVrbKVEneG34Km+
ndtb+mvcGc0fOoMU9lYrFaxAWl8oU9BchC9IyjcPZB445R+AhfTuoHSUViSCo6IO
TG0hQsJuNoKmDAU8l5sTsiFXuXBOo1wK8gTkRnhZHduZrZIjJXvT7efz1knLQ6eG
prZHf4CtbgHyAe2XZabetWtCsFcPbOjC7ezNK57UvVH98h2GkckxOM00BESMCTee
kYy7uG0v0rrajzHY1wARAQABiQIlBBgBCgAPBQJW4HonAhsMBQkHKygAAAoJECO1
2++U1NgdyAsQAKZUVA6pY225BASkeNiW31L7K4VeRYpAdFkiRex2zQFtj9Vovfi1
JeTs0fRm35dUsQraf1bkhsjEdPVZ3gD324/baauFO04KX+soyQvK/tUq8KO+5ALt
Ul5aAljuSwxfJWFpApv+Mbf7gOjm+77jirs7pgG/gCow/mkRlmKTwAmn2DXjkckC
2EH0mqmh5pdoNWKO7WeTFFbUmESsPcnB2FwTpEjHFvgHll+rmKpXZTgFYN4dDhhm
HsL/SCf/Nw+YIsuvErQ9TJVdJDLG8ZYatruk7dZZMPtFxvxM1Q36gDIpPEOKPkvm
dMXg6jHaIdYIaoMpzXFaXsQMdRuMtzbcA+CdwXVY55qGLtfmM/QuEiIJdDeeh7iB
+VAMyEFOOpi8IFhixaeMoZAmrKDqOkzPcMJVklLYq8N+b9p5JszYNwZEbpyWCACM
6K+iJzlWzW/OPZttGLJBgYuSYIJIuG80Cx5m5m1e5RAgQ1iT8nbfrS+gYttwP48J
V7SXQg7QugxG9l1vlK4VjnXiOFulJ7V0e/VyUBpJp3qHcCxFq3RnxVwlIqKZh+jm
Q1bk0H0Xodd27nQITfDP5ullByGW2Jrjs6SsXeR3jl9+t0XQfInU1L9d/wSOkMjL
9IMUt06lV4vB/WP2xioqLZiZ4eAi0E+lWkFxjZsgNs2xbOAYRThMB8a5
=W1Ri
-----END PGP PUBLIC KEY BLOCK-----
```
</details>
PGP key fingerprint: `3647 9903 B23A E0A5 9359  9A3E 23B5 DBEF 94D4 D81D` ([public key](https://gist.github.com/cryptobot/864300b6b44ae2d2a15abedfe14bd040))
## Expectations
When reporting a vulnerability, please provide us with a detailed report that includes:
- A description of the vulnerability
- Steps to reproduce the vulnerability
- Possible impact of the vulnerability
- Any additional information that may be helpful
We ask that you do not publicly disclose the vulnerability until we have had a chance to address it.
## Thank You
We appreciate your help in keeping Cryptomator secure. Thank you for your contributions to the security of our project.
-13
View File
@@ -1,13 +0,0 @@
# Configuration for probot-no-response - https://github.com/probot/no-response
# Number of days of inactivity before an Issue is closed for lack of response
daysUntilClose: 14
# Label requiring a response
responseRequiredLabel: state:awaiting-response
# Comment to post when closing an Issue for lack of response. Set to `false` to disable
closeComment: >
This issue has been automatically closed because there has been no response
to our request for more information from the original author. With only the
information that is currently in the issue, we don't have enough information
to take action. Please reach out if you have or find the answers we need so
that we can investigate further.
+29
View File
@@ -0,0 +1,29 @@
# .github/release.yml
# see https://docs.github.com/en/repositories/releasing-projects-on-github/automatically-generated-release-notes#configuring-automatically-generated-release-notes
changelog:
exclude:
authors:
- cryptobot
- dependabot
- github-actions
categories:
- title: What's New 🎉
labels:
- type:feature-request
- type:enhancement
- title: Bugfixes 🐛
labels:
- type:security-issue
- type:bug
- type:minor-bug
- title: Other Changes 📎
labels:
- "*"
exclude:
labels:
- type:feature-request
- type:enhancement
- type:security-issue
- type:bug
- type:minor-bug
-24
View File
@@ -1,24 +0,0 @@
# Number of days of inactivity before an issue becomes stale
daysUntilStale: 365
# Number of days of inactivity before a stale issue is closed
daysUntilClose: 90
# Issues with these labels will never be considered stale
exemptLabels:
- type:security-issue # never close automatically
- type:feature-request # never close automatically
- type:enhancement # never close automatically
- type:upstream-bug # never close automatically
- state:awaiting-response # handled by different bot
- state:blocked
- state:confirmed
# Set to true to ignore issues in a milestone (defaults to false)
exemptMilestones: true
# Label to use when marking an issue as stale
staleLabel: state:stale
# Comment to post when marking an issue as stale. Set to `false` to disable
markComment: >
This issue has been automatically marked as stale because it has not had
recent activity. It will be closed if no further activity occurs. Thank you
for your contributions.
# Comment to post when closing a stale issue. Set to `false` to disable
closeComment: false
+11 -17
View File
@@ -10,13 +10,13 @@ on:
required: false
env:
JAVA_VERSION: 19
JAVA_VERSION: 20
jobs:
get-version:
uses: ./.github/workflows/get-version.yml
with:
version: ${{ github.event.inputs.version }}
version: ${{ inputs.version }}
build:
name: Build AppImage
@@ -47,7 +47,6 @@ jobs:
- name: Patch target dir
run: |
cp LICENSE.txt target
cp dist/linux/launcher.sh target
cp target/cryptomator-*.jar target/mods
- name: Run jlink
run: >
@@ -55,7 +54,7 @@ jobs:
--verbose
--output runtime
--module-path "${JAVA_HOME}/jmods"
--add-modules java.base,java.desktop,java.instrument,java.logging,java.naming,java.net.http,java.scripting,java.sql,java.xml,javafx.base,javafx.graphics,javafx.controls,javafx.fxml,jdk.unsupported,jdk.crypto.ec,jdk.accessibility,jdk.management.jfr
--add-modules java.base,java.desktop,java.instrument,java.logging,java.naming,java.net.http,java.scripting,java.sql,java.xml,javafx.base,javafx.graphics,javafx.controls,javafx.fxml,jdk.unsupported,jdk.crypto.ec,jdk.security.auth,jdk.accessibility,jdk.management.jfr
--strip-native-commands
--no-header-files
--no-man-pages
@@ -78,7 +77,7 @@ jobs:
--dest appdir
--name Cryptomator
--vendor "Skymatic GmbH"
--copyright "(C) 2016 - 2022 Skymatic GmbH"
--copyright "(C) 2016 - 2023 Skymatic GmbH"
--app-version "${{ needs.get-version.outputs.semVerNum }}.${{ needs.get-version.outputs.revNum }}"
--java-options "--enable-preview"
--java-options "--enable-native-access=org.cryptomator.jfuse.linux.amd64,org.cryptomator.jfuse.linux.aarch64"
@@ -86,12 +85,13 @@ jobs:
--java-options "-Xmx256m"
--java-options "-Dcryptomator.appVersion=\"${{ needs.get-version.outputs.semVerStr }}\""
--java-options "-Dfile.encoding=\"utf-8\""
--java-options "-Dcryptomator.logDir=\"~/.local/share/Cryptomator/logs\""
--java-options "-Dcryptomator.pluginDir=\"~/.local/share/Cryptomator/plugins\""
--java-options "-Dcryptomator.settingsPath=\"~/.config/Cryptomator/settings.json:~/.Cryptomator/settings.json\""
--java-options "-Dcryptomator.p12Path=\"~/.config/Cryptomator/key.p12\""
--java-options "-Dcryptomator.ipcSocketPath=\"~/.config/Cryptomator/ipc.socket\""
--java-options "-Dcryptomator.mountPointsDir=\"~/.local/share/Cryptomator/mnt\""
--java-options "-Djava.net.useSystemProxies=true"
--java-options "-Dcryptomator.logDir=\"@{userhome}/.local/share/Cryptomator/logs\""
--java-options "-Dcryptomator.pluginDir=\"@{userhome}/.local/share/Cryptomator/plugins\""
--java-options "-Dcryptomator.settingsPath=\"@{userhome}/.config/Cryptomator/settings.json:@{userhome}/.Cryptomator/settings.json\""
--java-options "-Dcryptomator.p12Path=\"@{userhome}/.config/Cryptomator/key.p12\""
--java-options "-Dcryptomator.ipcSocketPath=\"@{userhome}/.config/Cryptomator/ipc.socket\""
--java-options "-Dcryptomator.mountPointsDir=\"@{userhome}/.local/share/Cryptomator/mnt\""
--java-options "-Dcryptomator.showTrayIcon=false"
--java-options "-Dcryptomator.buildNumber=\"appimage-${{ needs.get-version.outputs.revNum }}\""
--add-launcher Cryptomator-gtk2=launcher-gtk2.properties
@@ -111,12 +111,6 @@ jobs:
ln -s usr/share/icons/hicolor/scalable/apps/org.cryptomator.Cryptomator.svg Cryptomator.AppDir/.DirIcon
ln -s usr/share/applications/org.cryptomator.Cryptomator.desktop Cryptomator.AppDir/Cryptomator.desktop
ln -s bin/cryptomator.sh Cryptomator.AppDir/AppRun
- name: Extract libjffi.so # workaround for https://github.com/cryptomator/cryptomator-linux/issues/27
run: |
JFFI_NATIVE_JAR=`ls lib/app/ | grep -e 'jffi-[1-9]\.[0-9]\{1,2\}.[0-9]\{1,2\}-native.jar'`
${JAVA_HOME}/bin/jar -xf lib/app/${JFFI_NATIVE_JAR} /jni/x86_64-Linux/
mv jni/x86_64-Linux/* lib/app/libjffi.so
working-directory: Cryptomator.AppDir
- name: Download AppImageKit
run: |
curl -L https://github.com/AppImage/AppImageKit/releases/download/13/appimagetool-x86_64.AppImage -o appimagetool.AppImage
+6 -1
View File
@@ -6,7 +6,7 @@ on:
types: [labeled]
env:
JAVA_VERSION: 19
JAVA_VERSION: 20
defaults:
run:
@@ -53,4 +53,9 @@ jobs:
body: |-
:construction: Work in Progress
⏳ Please be patient, the builds are still [running](https://github.com/cryptomator/cryptomator/actions). New versions of Cryptomator can be found here in a few moments. ⏳
As usual, the GPG signatures can be checked using [our public key `5811 7AFA 1F85 B3EE C154 677D 615D 449F E6E6 A235`](https://gist.github.com/cryptobot/211111cf092037490275f39d408f461a).
---
<!-- Don't forget to include the 💾 SHA-256 checksums of release artifacts: -->
+12 -26
View File
@@ -3,9 +3,6 @@ name: Build Debian Package
on:
workflow_dispatch:
inputs:
ref:
description: 'GitHub Ref (e.g. refs/tags/1.6.16)'
required: true
semver:
description: 'SemVer String (e.g. 1.7.0-beta1)'
required: true
@@ -19,9 +16,9 @@ on:
type: boolean
env:
JAVA_VERSION: 19
OPENJFX_JMODS_AMD64: 'https://download2.gluonhq.com/openjfx/19/openjfx-19_linux-x64_bin-jmods.zip'
OPENJFX_JMODS_AARCH64: 'https://download2.gluonhq.com/openjfx/19/openjfx-19_linux-aarch64_bin-jmods.zip'
JAVA_VERSION: 20
OPENJFX_JMODS_AMD64: 'https://download2.gluonhq.com/openjfx/20.0.1/openjfx-20.0.1_linux-x64_bin-jmods.zip'
OPENJFX_JMODS_AARCH64: 'https://download2.gluonhq.com/openjfx/20.0.1/openjfx-20.0.1_linux-aarch64_bin-jmods.zip'
jobs:
build:
@@ -29,9 +26,6 @@ jobs:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v3
with:
ref: ${{ inputs.ref }}
fetch-depth: 0
- id: versions
name: Get version information
run: |
@@ -45,7 +39,7 @@ jobs:
run: |
sudo add-apt-repository ppa:coffeelibs/openjdk
sudo apt-get update
sudo apt-get install debhelper devscripts dput coffeelibs-jdk-19 libgtk2.0-0
sudo apt-get install debhelper devscripts dput coffeelibs-jdk-${{ env.JAVA_VERSION }} libgtk2.0-0
- name: Setup Java
uses: actions/setup-java@v3
with:
@@ -65,10 +59,10 @@ jobs:
unzip -j openjfx-aarch64.zip \*/javafx.base.jmod \*/javafx.controls.jmod \*/javafx.fxml.jmod \*/javafx.graphics.jmod -d jmods/aarch64
- name: Ensure major jfx version in pom and in jmods is the same
run: |
JMOD_VERSION_AMD64=$(jmod describe ${JAVA_HOME}/jmods/amd64/javafx.base.jmod | head -1)
JMOD_VERSION_AMD64=$(jmod describe jmods/amd64/javafx.base.jmod | head -1)
JMOD_VERSION_AMD64=${JMOD_VERSION_AMD64#*@}
JMOD_VERSION_AMD64=${JMOD_VERSION_AMD64%%.*}
JMOD_VERSION_AARCH64=$(jmod describe ${JAVA_HOME}/jmods/aarch64/javafx.base.jmod | head -1)
JMOD_VERSION_AARCH64=$(jmod describe jmods/aarch64/javafx.base.jmod | head -1)
JMOD_VERSION_AARCH64=${JMOD_VERSION_AARCH64#*@}
JMOD_VERSION_AARCH64=${JMOD_VERSION_AARCH64%%.*}
POM_JFX_VERSION=$(mvn help:evaluate "-Dexpression=javafx.version" -q -DforceStdout)
@@ -141,18 +135,10 @@ jobs:
run: dput ppa:sebastian-stenzel/cryptomator-beta cryptomator_*_source.changes
# If ref is a tag, also upload to GitHub Releases:
- name: Determine tag name
if: startsWith(inputs.ref, 'refs/tags/')
run: |
REF=${{ inputs.ref }}
echo "TAG_NAME=${REF##*/}" >> $GITHUB_ENV
- name: Publish Debian package on GitHub Releases
if: startsWith(inputs.ref, 'refs/tags/')
uses: softprops/action-gh-release@v1
with:
fail_on_unmatched_files: true
tag_name: ${{ github.env.TAG_NAME }}
token: ${{ secrets.CRYPTOBOT_RELEASE_TOKEN }}
files: |
cryptomator_*_amd64.deb
cryptomator_*.asc
if: startsWith(github.ref, 'refs/tags/')
env:
GITHUB_TOKEN: ${{ secrets.CRYPTOBOT_RELEASE_TOKEN }}
run: |
artifacts=$(ls | grep cryptomator*.deb)
gh release upload ${{ github.ref_name }} $artifacts
+1 -1
View File
@@ -22,7 +22,7 @@ on:
value: ${{ jobs.determine-version.outputs.type }}
env:
JAVA_VERSION: 19
JAVA_VERSION: 20
JAVA_DIST: 'temurin'
JAVA_CACHE: 'maven'
+16 -13
View File
@@ -10,13 +10,13 @@ on:
required: false
env:
JAVA_VERSION: 19
JAVA_VERSION: 20
jobs:
get-version:
uses: ./.github/workflows/get-version.yml
with:
version: ${{ github.event.inputs.version }}
version: ${{ inputs.version }}
build:
name: Build Cryptomator.app for ${{ matrix.output-suffix }}
@@ -30,10 +30,12 @@ jobs:
architecture: x64
output-suffix: x64
xcode-path: '/Applications/Xcode_13.2.1.app'
fuse-lib: macFUSE
- os: [self-hosted, macOS, ARM64]
architecture: aarch64
output-suffix: arm64
xcode-path: '/Applications/Xcode_13.2.1.app'
fuse-lib: FUSE-T
steps:
- uses: actions/checkout@v3
- name: Setup Java
@@ -61,7 +63,6 @@ jobs:
- name: Patch target dir
run: |
cp LICENSE.txt target
cp dist/mac/launcher.sh target
cp target/cryptomator-*.jar target/mods
- name: Run jlink
run: >
@@ -87,22 +88,24 @@ jobs:
--dest appdir
--name Cryptomator
--vendor "Skymatic GmbH"
--copyright "(C) 2016 - 2022 Skymatic GmbH"
--copyright "(C) 2016 - 2023 Skymatic GmbH"
--app-version "${{ needs.get-version.outputs.semVerNum }}"
--java-options "--enable-preview"
--java-options "--enable-native-access=org.cryptomator.jfuse.mac"
--java-options "-Xss5m"
--java-options "-Xmx256m"
--java-options "-Dfile.encoding=\"utf-8\""
--java-options "-Djava.net.useSystemProxies=true"
--java-options "-Dapple.awt.enableTemplateImages=true"
--java-options "-Dsun.java2d.metal=true"
--java-options "-Dcryptomator.appVersion=\"${{ needs.get-version.outputs.semVerStr }}\""
--java-options "-Dcryptomator.logDir=\"~/Library/Logs/Cryptomator\""
--java-options "-Dcryptomator.pluginDir=\"~/Library/Application Support/Cryptomator/Plugins\""
--java-options "-Dcryptomator.settingsPath=\"~/Library/Application Support/Cryptomator/settings.json\""
--java-options "-Dcryptomator.p12Path=\"~/Library/Application Support/Cryptomator/key.p12\""
--java-options "-Dcryptomator.ipcSocketPath=\"~/Library/Application Support/Cryptomator/ipc.socket\""
--java-options "-Dcryptomator.logDir=\"@{userhome}/Library/Logs/Cryptomator\""
--java-options "-Dcryptomator.pluginDir=\"@{userhome}/Library/Application Support/Cryptomator/Plugins\""
--java-options "-Dcryptomator.settingsPath=\"@{userhome}/Library/Application Support/Cryptomator/settings.json\""
--java-options "-Dcryptomator.p12Path=\"@{userhome}/Library/Application Support/Cryptomator/key.p12\""
--java-options "-Dcryptomator.ipcSocketPath=\"@{userhome}/Library/Application Support/Cryptomator/ipc.socket\""
--java-options "-Dcryptomator.integrationsMac.keychainServiceName=\"Cryptomator\""
--java-options "-Dcryptomator.mountPointsDir=\"@{userhome}/Library/Application Support/Cryptomator/mnt\""
--java-options "-Dcryptomator.showTrayIcon=true"
--java-options "-Dcryptomator.buildNumber=\"dmg-${{ needs.get-version.outputs.revNum }}\""
--mac-package-identifier org.cryptomator
@@ -177,7 +180,7 @@ jobs:
run: |
mkdir dmg
mv Cryptomator.app dmg
cp dist/mac/dmg/resources/macFUSE.webloc dmg
cp dist/mac/dmg/resources/${{ matrix.fuse-lib }}.webloc dmg
ls -l dmg
- name: Install create-dmg
run: |
@@ -188,14 +191,14 @@ jobs:
create-dmg
--volname Cryptomator
--volicon "dist/mac/dmg/resources/Cryptomator-Volume.icns"
--background "dist/mac/dmg/resources/Cryptomator-background.tiff"
--background "dist/mac/dmg/resources/Cryptomator-${{ matrix.fuse-lib }}-background.tiff"
--window-pos 400 100
--window-size 640 694
--icon-size 128
--icon "Cryptomator.app" 128 245
--hide-extension "Cryptomator.app"
--icon "macFUSE.webloc" 320 501
--hide-extension "macFUSE.webloc"
--icon "${{ matrix.fuse-lib }}.webloc" 320 501
--hide-extension "${{ matrix.fuse-lib }}.webloc"
--app-drop-link 512 245
--eula "dist/mac/dmg/resources/license.rtf"
--icon ".background" 128 758
+22
View File
@@ -0,0 +1,22 @@
# Configuration for close-stale-issues - https://github.com/marketplace/actions/close-stale-issues
name: 'Close awaiting response issues'
on:
schedule:
- cron: '00 09 * * *'
jobs:
no-response:
runs-on: ubuntu-latest
permissions:
issues: write
pull-requests: write
steps:
- uses: actions/stale@v8
with:
days-before-stale: 14
days-before-close: 0
days-before-pr-close: -1
stale-issue-label: 'state:stale'
close-issue-message: "This issue has been automatically closed because there has been no response to our request for more information from the original author. With only the information that is currently in the issue, we don't have enough information to take action. Please reach out if you have or find the answers we need so that we can investigate further."
only-labels: 'state:awaiting-response'
+1 -1
View File
@@ -10,7 +10,7 @@ jobs:
steps:
- name: Download source tarball
run: |
curl -L -H "Accept: application/vnd.github+json" ${{ github.event.release.tarball_url }} --output cryptomator-${{ github.event.release.tag_name }}.tar.gz
curl -L -H "Accept: application/vnd.github+json" https://github.com/cryptomator/cryptomator/archive/refs/tags/${{ github.event.release.tag_name }}.tar.gz --output cryptomator-${{ github.event.release.tag_name }}.tar.gz
- name: Sign source tarball with key 615D449FE6E6A235
run: |
echo "${GPG_PRIVATE_KEY}" | gpg --batch --quiet --import
+1 -1
View File
@@ -4,7 +4,7 @@ on:
pull_request:
env:
JAVA_VERSION: 19
JAVA_VERSION: 20
defaults:
run:
+1 -1
View File
@@ -7,7 +7,7 @@ on:
- 'hotfix/**'
env:
JAVA_VERSION: 19
JAVA_VERSION: 20
defaults:
run:
+24
View File
@@ -0,0 +1,24 @@
# Configuration for close-stale-issues - https://github.com/marketplace/actions/close-stale-issues
name: 'Close stale issues'
on:
schedule:
- cron: '00 09 * * *'
jobs:
stale:
runs-on: ubuntu-latest
permissions:
issues: write
pull-requests: write
steps:
- uses: actions/stale@v8
with:
days-before-stale: 365
days-before-close: 90
exempt-issue-labels: 'type:security-issue,type:feature-request,type:enhancement,type:upstream-bug,state:awaiting-response,state:blocked,state:confirmed'
exempt-all-milestones: true
stale-issue-label: 'state:stale'
stale-pr-label: 'state:stale'
stale-issue-message: 'This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.'
stale-pr-message: 'This PR has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.'
+60 -34
View File
@@ -8,11 +8,17 @@ on:
version:
description: 'Version'
required: false
isDebug:
description: 'Build debug version with console output'
type: boolean
env:
JAVA_VERSION: 19
JAVA_DIST: 'zulu'
JAVA_VERSION: 20
JAVA_DIST: 'temurin'
JAVA_CACHE: 'maven'
JFX_JMODS_URL: 'https://download2.gluonhq.com/openjfx/20.0.1/openjfx-20.0.1_windows-x64_bin-jmods.zip'
JFX_JMODS_HASH: 'D00767334C43B8832B5CF10267D34CA8F563D187C4655B73EB6020DD79C054B5'
defaults:
run:
@@ -22,7 +28,7 @@ jobs:
get-version:
uses: ./.github/workflows/get-version.yml
with:
version: ${{ github.event.inputs.version }}
version: ${{ inputs.version }}
build-msi:
name: Build .msi Installer
@@ -30,6 +36,7 @@ jobs:
needs: [get-version]
env:
LOOPBACK_ALIAS: 'cryptomator-vault'
WIN_CONSOLE_FLAG: ''
steps:
- uses: actions/checkout@v3
- name: Setup Java
@@ -37,17 +44,31 @@ jobs:
with:
distribution: ${{ env.JAVA_DIST }}
java-version: ${{ env.JAVA_VERSION }}
java-package: 'jdk+fx'
java-package: 'jdk'
cache: ${{ env.JAVA_CACHE }}
- name: Ensure major jfx version in pom equals in jdk
shell: pwsh
- name: Download and extract JavaFX jmods from Gluon
#In the last step we move all jmods files a dir level up because jmods are placed inside a directory in the zip
run: |
$jfxPomVersion = (&mvn help:evaluate "-Dexpression=javafx.version" -q -DforceStdout) -split "\."
$jfxJdkVersion = ((Get-Content -path "${env:JAVA_HOME}/lib/javafx.properties" | Where-Object {$_ -like 'javafx.version=*' }) -replace '.*=','') -split "\."
if ($jfxPomVersion[0] -ne $jfxJdkVersion[0]) {
Write-Error "Major part of JavaFX version in pom($($jfxPomVersion[0])) does not match the version in JDK($($jfxJdkVersion[0])) "
exit 1
curl --output jfxjmods.zip -L "${{ env.JFX_JMODS_URL }}"
if(!(Get-FileHash -Path jfxjmods.zip -Algorithm SHA256).Hash.equals("${{ env.JFX_JMODS_HASH }}")) {
throw "Wrong checksum of JMOD archive downloaded from ${{ env.JFX_JMODS_URL }}.";
}
Expand-Archive -Path jfxjmods.zip -DestinationPath jfxjmods
Get-ChildItem -Path jfxjmods -Recurse -Filter "*.jmod" | ForEach-Object { Move-Item -Path $_ -Destination $_.Directory.Parent}
shell: pwsh
- name: Ensure major jfx version in pom and in jmods is the same
run: |
JMOD_VERSION_AMD64=$(jmod describe jfxjmods/javafx.base.jmod | head -1)
JMOD_VERSION_AMD64=${JMOD_VERSION_AMD64#*@}
JMOD_VERSION_AMD64=${JMOD_VERSION_AMD64%%.*}
POM_JFX_VERSION=$(mvn help:evaluate "-Dexpression=javafx.version" -q -DforceStdout)
POM_JFX_VERSION=${POM_JFX_VERSION#*@}
POM_JFX_VERSION=${POM_JFX_VERSION%%.*}
if [ $POM_JFX_VERSION -ne $JMOD_VERSION_AMD64 ]; then
>&2 echo "Major JavaFX version in pom.xml (${POM_JFX_VERSION}) != amd64 jmod version (${JMOD_VERSION_AMD64})"
exit 1
fi
- name: Set version
run : mvn versions:set -DnewVersion=${{ needs.get-version.outputs.semVerStr }}
- name: Run maven
@@ -55,20 +76,22 @@ jobs:
- name: Patch target dir
run: |
cp LICENSE.txt target
cp dist/linux/launcher.sh target
cp target/cryptomator-*.jar target/mods
- name: Run jlink
run: >
${JAVA_HOME}/bin/jlink
--verbose
--output runtime
--module-path "${JAVA_HOME}/jmods"
--module-path "jfxjmods;${JAVA_HOME}/jmods"
--add-modules java.base,java.desktop,java.instrument,java.logging,java.naming,java.net.http,java.scripting,java.sql,java.xml,javafx.base,javafx.graphics,javafx.controls,javafx.fxml,jdk.unsupported,jdk.crypto.ec,jdk.accessibility,jdk.management.jfr
--strip-native-commands
--no-header-files
--no-man-pages
--strip-debug
--compress=1
- name: Change win-console flag if debug is active
if: ${{ inputs.isDebug }}
run: echo "WIN_CONSOLE_FLAG=--win-console" >> $GITHUB_ENV
- name: Run jpackage
run: >
${JAVA_HOME}/bin/jpackage
@@ -81,7 +104,7 @@ jobs:
--dest appdir
--name Cryptomator
--vendor "Skymatic GmbH"
--copyright "(C) 2016 - 2022 Skymatic GmbH"
--copyright "(C) 2016 - 2023 Skymatic GmbH"
--app-version "${{ needs.get-version.outputs.semVerNum }}.${{ needs.get-version.outputs.revNum }}"
--java-options "--enable-preview"
--java-options "--enable-native-access=org.cryptomator.jfuse.win"
@@ -89,19 +112,22 @@ jobs:
--java-options "-Xmx256m"
--java-options "-Dcryptomator.appVersion=\"${{ needs.get-version.outputs.semVerStr }}\""
--java-options "-Dfile.encoding=\"utf-8\""
--java-options "-Dcryptomator.logDir=\"~/AppData/Roaming/Cryptomator\""
--java-options "-Dcryptomator.pluginDir=\"~/AppData/Roaming/Cryptomator/Plugins\""
--java-options "-Dcryptomator.settingsPath=\"~/AppData/Roaming/Cryptomator/settings.json\""
--java-options "-Dcryptomator.p12Path=\"~/AppData/Roaming/Cryptomator/key.p12\""
--java-options "-Dcryptomator.ipcSocketPath=\"~/AppData/Roaming/Cryptomator/ipc.socket\""
--java-options "-Dcryptomator.mountPointsDir=\"~/Cryptomator\""
--java-options "-Djava.net.useSystemProxies=true"
--java-options "-Dcryptomator.logDir=\"@{localappdata}/Cryptomator\""
--java-options "-Dcryptomator.pluginDir=\"@{appdata}/Cryptomator/Plugins\""
--java-options "-Dcryptomator.settingsPath=\"@{appdata}/Cryptomator/settings.json;@{userhome}/AppData/Roaming/Cryptomator/settings.json\""
--java-options "-Dcryptomator.p12Path=\"@{appdata}/Cryptomator/key.p12;@{userhome}/AppData/Roaming/Cryptomator/key.p12\""
--java-options "-Dcryptomator.ipcSocketPath=\"@{localappdata}/Cryptomator/ipc.socket\""
--java-options "-Dcryptomator.mountPointsDir=\"@{userhome}/Cryptomator\""
--java-options "-Dcryptomator.loopbackAlias=\"${{ env.LOOPBACK_ALIAS }}\""
--java-options "-Dcryptomator.showTrayIcon=true"
--java-options "-Dcryptomator.buildNumber=\"msi-${{ needs.get-version.outputs.revNum }}\""
--java-options "-Dcryptomator.integrationsWin.autoStartShellLinkName=\"Cryptomator\""
--java-options "-Dcryptomator.integrationsWin.keychainPaths=\"~/AppData/Roaming/Cryptomator/keychain.json\""
--java-options "-Dcryptomator.integrationsWin.keychainPaths=\"@{appdata}/Cryptomator/keychain.json;@{userhome}/AppData/Roaming/Cryptomator/keychain.json\""
--java-options "-Djavafx.verbose=${{ inputs.isDebug }}"
--resource-dir dist/win/resources
--icon dist/win/resources/Cryptomator.ico
${WIN_CONSOLE_FLAG}
- name: Patch Application Directory
run: |
cp dist/win/contrib/* appdir/Cryptomator
@@ -118,6 +144,9 @@ jobs:
- name: Fix permissions
run: attrib -r appdir/Cryptomator/Cryptomator.exe
shell: pwsh
- name: Extract integrations DLL for code signing
shell: pwsh
run: gci ./appdir/Cryptomator/app/mods/ -File integrations-win-*.jar | ForEach-Object {Set-Location -Path $_.Directory; jar --file=$($_.FullName) --extract integrations.dll }
- name: Codesign
uses: skymatic/code-sign-action@v2
with:
@@ -128,6 +157,10 @@ jobs:
timestampUrl: 'http://timestamp.digicert.com'
folder: appdir/Cryptomator
recursive: true
- name: Repack signed DLL into jar
shell: pwsh
run: |
gci ./appdir/Cryptomator/app/mods/ -File integrations-win-*.jar | ForEach-Object {Set-Location -Path $_.Directory; jar --file=$($_.FullName) --update integrations.dll; Remove-Item integrations.dll}
- name: Generate license for MSI
run: >
mvn -B license:add-third-party
@@ -149,8 +182,8 @@ jobs:
--dest installer
--name Cryptomator
--vendor "Skymatic GmbH"
--copyright "(C) 2016 - 2022 Skymatic GmbH"
--app-version "${{ needs.get-version.outputs.semVerNum }}"
--copyright "(C) 2016 - 2023 Skymatic GmbH"
--app-version "${{ needs.get-version.outputs.semVerNum }}.${{ needs.get-version.outputs.revNum}}"
--win-menu
--win-dir-chooser
--win-shortcut-prompt
@@ -197,15 +230,6 @@ jobs:
*.msi
*.asc
call-winget-flow:
needs: [get-version, build-msi]
if: github.event.action == 'published' && needs.get-version.outputs.versionType == 'stable'
uses: ./.github/workflows/winget.yml
with:
releaseTag: ${{ github.event.release.tag_name }}
secrets: inherit
build-exe:
name: Build .exe installer
runs-on: windows-latest
@@ -237,17 +261,18 @@ jobs:
shell: pwsh
- name: Download WinFsp
run: |
$winfspUrl= (Select-String -Path ".\dist\win\bundle\resources\winfsp-download.url" -Pattern 'https:.*').Matches.Value
$winfspUrl = (Select-String -Path ".\dist\win\bundle\resources\winFspMetaData.wxi" -Pattern '<\?define BundledWinFspDownloadLink="(.+)".*?>').Matches.Groups[1].Value
curl --output dist/win/bundle/resources/winfsp.msi -L $winfspUrl
shell: pwsh
- name: Compile to wixObj file
run: >
"${WIX}/bin/candle.exe" dist/win/bundle/bundleWithWinfsp.wxs
-ext WixBalExtension
-ext WixUtilExtension
-out dist/win/bundle/
-dBundleVersion="${{ needs.get-version.outputs.semVerNum }}.${{ needs.get-version.outputs.revNum }}"
-dBundleVendor="Skymatic GmbH"
-dBundleCopyright="(C) 2016 - 2022 Skymatic GmbH"
-dBundleCopyright="(C) 2016 - 2023 Skymatic GmbH"
-dAboutUrl="https://cryptomator.org"
-dHelpUrl="https://cryptomator.org/contact"
-dUpdateUrl="https://cryptomator.org/downloads/"
@@ -255,6 +280,7 @@ jobs:
run: >
"${WIX}/bin/light.exe" -b dist/win/ dist/win/bundle/bundleWithWinfsp.wixobj
-ext WixBalExtension
-ext WixUtilExtension
-out installer/unsigned/Cryptomator-Installer.exe
- name: Detach burn engine in preparation to sign
run: >
-49
View File
@@ -1,49 +0,0 @@
name: Release to Winget
on:
workflow_call:
inputs:
releaseTag:
required: true
type: string
workflow_dispatch:
inputs:
releaseTag:
description: 'Release tag name'
required: true
type: string
jobs:
publish-winget:
name: Publish on winget repo
runs-on: windows-latest
steps:
- name: Get download url for release assets
id: get-release-assets
uses: actions/github-script@v6
with:
script: |
const query =`query($tag:String!) {
repository(owner:"cryptomator", name:"cryptomator"){
release(tagName: $tag) {
releaseAssets(first:20) {
nodes {
name
downloadUrl
}
}
}
}
}`;
const variables = {
tag: "${{ inputs.releaseTag }}"
}
return await github.graphql(query, variables)
- name: Submit package to Windows Package Manager Community Repository
id: submit-winget
run: |
iwr https://aka.ms/wingetcreate/latest -OutFile wingetcreate.exe
$releaseAssets = (ConvertFrom-Json '${{ steps.get-release-assets.outputs.result }}').repository.release.releaseAssets.nodes
$installerUrl = $releaseAssets | Where-Object -Property name -match '^Cryptomator-.*\.msi$' | Select -ExpandProperty downloadUrl -First 1
.\wingetcreate.exe update Cryptomator.Cryptomator -s -v "${{ inputs.releaseTag }}" -u "$installerUrl" -t ${{ secrets.CRYPTOBOT_WINGET_TOKEN }}
shell: pwsh
+2 -1
View File
@@ -53,9 +53,10 @@
<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="KEEP_SIMPLE_CLASSES_IN_ONE_LINE" value="true" />
<option name="IF_BRACE_FORCE" value="3" />
<option name="ENUM_CONSTANTS_WRAP" value="2" />
<indentOptions>
<option name="USE_TAB_CHARACTER" value="true" />
+6 -4
View File
@@ -14,10 +14,10 @@
<option name="dagger.fastInit" value="enabled" />
<option name="dagger.formatGeneratedSource" value="enabled" />
<processorPath useClasspath="false">
<entry name="$MAVEN_REPOSITORY$/com/google/dagger/dagger-compiler/2.44/dagger-compiler-2.44.jar" />
<entry name="$MAVEN_REPOSITORY$/com/google/dagger/dagger/2.44/dagger-2.44.jar" />
<entry name="$MAVEN_REPOSITORY$/com/google/dagger/dagger-compiler/2.45/dagger-compiler-2.45.jar" />
<entry name="$MAVEN_REPOSITORY$/com/google/dagger/dagger/2.45/dagger-2.45.jar" />
<entry name="$MAVEN_REPOSITORY$/javax/inject/javax.inject/1/javax.inject-1.jar" />
<entry name="$MAVEN_REPOSITORY$/com/google/dagger/dagger-producers/2.44/dagger-producers-2.44.jar" />
<entry name="$MAVEN_REPOSITORY$/com/google/dagger/dagger-producers/2.45/dagger-producers-2.45.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/31.0.1-jre/guava-31.0.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" />
@@ -26,14 +26,16 @@
<entry name="$MAVEN_REPOSITORY$/com/google/errorprone/error_prone_annotations/2.7.1/error_prone_annotations-2.7.1.jar" />
<entry name="$MAVEN_REPOSITORY$/com/google/j2objc/j2objc-annotations/1.3/j2objc-annotations-1.3.jar" />
<entry name="$MAVEN_REPOSITORY$/org/checkerframework/checker-compat-qual/2.5.5/checker-compat-qual-2.5.5.jar" />
<entry name="$MAVEN_REPOSITORY$/com/google/dagger/dagger-spi/2.44/dagger-spi-2.44.jar" />
<entry name="$MAVEN_REPOSITORY$/com/google/dagger/dagger-spi/2.45/dagger-spi-2.45.jar" />
<entry name="$MAVEN_REPOSITORY$/com/google/devtools/ksp/symbol-processing-api/1.7.0-1.0.6/symbol-processing-api-1.7.0-1.0.6.jar" />
<entry name="$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib/1.7.0/kotlin-stdlib-1.7.0.jar" />
<entry name="$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib-common/1.7.0/kotlin-stdlib-common-1.7.0.jar" />
<entry name="$MAVEN_REPOSITORY$/org/jetbrains/annotations/13.0/annotations-13.0.jar" />
<entry name="$MAVEN_REPOSITORY$/com/squareup/javapoet/1.13.0/javapoet-1.13.0.jar" />
<entry name="$MAVEN_REPOSITORY$/com/squareup/kotlinpoet/1.11.0/kotlinpoet-1.11.0.jar" />
<entry name="$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib-jdk8/1.7.0/kotlin-stdlib-jdk8-1.7.0.jar" />
<entry name="$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib-jdk7/1.7.0/kotlin-stdlib-jdk7-1.7.0.jar" />
<entry name="$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-reflect/1.6.10/kotlin-reflect-1.6.10.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$/net/ltgt/gradle/incap/incap/0.2/incap-0.2.jar" />
+1 -1
View File
@@ -8,7 +8,7 @@
</list>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_19" default="true" project-jdk-name="19" project-jdk-type="JavaSDK">
<component name="ProjectRootManager" version="2" languageLevel="JDK_20_PREVIEW" project-jdk-name="20" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>
+1 -1
View File
@@ -2,7 +2,7 @@
<configuration default="false" name="Cryptomator Linux" type="Application" factoryName="Application">
<option name="MAIN_CLASS_NAME" value="org.cryptomator.launcher.Cryptomator" />
<module name="cryptomator" />
<option name="VM_PARAMETERS" value="-Dcryptomator.settingsPath=&quot;~/.config/Cryptomator/settings.json&quot; -Dcryptomator.p12Path=&quot;~/.config/Cryptomator/key.p12&quot; -Dcryptomator.ipcSocketPath=&quot;~/.config/Cryptomator/ipc.socket&quot; -Dcryptomator.logDir=&quot;~/.local/share/Cryptomator/logs&quot; -Dcryptomator.pluginDir=&quot;~/.local/share/Cryptomator/plugins&quot; -Dcryptomator.mountPointsDir=&quot;~/.local/share/Cryptomator/mnt&quot; -Dcryptomator.showTrayIcon=true -Xss20m -Xmx512m --enable-preview --enable-native-access=org.cryptomator.jfuse.linux.amd64,org.cryptomator.jfuse.linux.aarch64" />
<option name="VM_PARAMETERS" value="-Dcryptomator.settingsPath=&quot;@{userhome}/.config/Cryptomator/settings.json&quot; -Dcryptomator.p12Path=&quot;@{userhome}/.config/Cryptomator/key.p12&quot; -Dcryptomator.ipcSocketPath=&quot;@{userhome}/.config/Cryptomator/ipc.socket&quot; -Dcryptomator.logDir=&quot;@{userhome}/.local/share/Cryptomator/logs&quot; -Dcryptomator.pluginDir=&quot;@{userhome}/.local/share/Cryptomator/plugins&quot; -Dcryptomator.mountPointsDir=&quot;@{userhome}/.local/share/Cryptomator/mnt&quot; -Dcryptomator.showTrayIcon=true -Xss20m -Xmx512m --enable-preview --enable-native-access=org.cryptomator.jfuse.linux.amd64,org.cryptomator.jfuse.linux.aarch64" />
<method v="2">
<option name="Make" enabled="true" />
</method>
+1 -1
View File
@@ -2,7 +2,7 @@
<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="-Dcryptomator.settingsPath=&quot;~/.config/Cryptomator-Dev/settings.json&quot; -Dcryptomator.p12Path=&quot;~/.config/Cryptomator-Dev/key.p12&quot; -Dcryptomator.ipcSocketPath=&quot;~/.config/Cryptomator-Dev/ipc.socket&quot; -Dcryptomator.logDir=&quot;~/.local/share/Cryptomator-Dev/logs&quot; -Dcryptomator.pluginDir=&quot;~/.local/share/Cryptomator-Dev/plugins&quot; -Dcryptomator.mountPointsDir=&quot;~/.local/share/Cryptomator-Dev/mnt&quot; -Dcryptomator.showTrayIcon=true -Dfuse.experimental=&quot;true&quot; -Xss20m -Xmx512m --enable-preview --enable-native-access=org.cryptomator.jfuse.linux.amd64,org.cryptomator.jfuse.linux.aarch64" />
<option name="VM_PARAMETERS" value="-Dcryptomator.settingsPath=&quot;@{userhome}/.config/Cryptomator-Dev/settings.json&quot; -Dcryptomator.p12Path=&quot;@{userhome}/.config/Cryptomator-Dev/key.p12&quot; -Dcryptomator.ipcSocketPath=&quot;@{userhome}/.config/Cryptomator-Dev/ipc.socket&quot; -Dcryptomator.logDir=&quot;@{userhome}/.local/share/Cryptomator-Dev/logs&quot; -Dcryptomator.pluginDir=&quot;@{userhome}/.local/share/Cryptomator-Dev/plugins&quot; -Dcryptomator.mountPointsDir=&quot;@{userhome}/.local/share/Cryptomator-Dev/mnt&quot; -Dcryptomator.showTrayIcon=true -Dfuse.experimental=&quot;true&quot; -Xss20m -Xmx512m --enable-preview --enable-native-access=org.cryptomator.jfuse.linux.amd64,org.cryptomator.jfuse.linux.aarch64" />
<method v="2">
<option name="Make" enabled="true" />
</method>
+1 -1
View File
@@ -2,7 +2,7 @@
<configuration default="false" name="Cryptomator Windows" type="Application" factoryName="Application">
<option name="MAIN_CLASS_NAME" value="org.cryptomator.launcher.Cryptomator" />
<module name="cryptomator" />
<option name="VM_PARAMETERS" value="-Dcryptomator.settingsPath=&quot;~/AppData/Roaming/Cryptomator/settings.json&quot; -Dcryptomator.ipcSocketPath=&quot;~/AppData/Roaming/Cryptomator/ipc.socket&quot; -Dcryptomator.logDir=&quot;~/AppData/Roaming/Cryptomator&quot; -Dcryptomator.pluginDir=&quot;~/AppData/Roaming/Cryptomator/Plugins&quot; -Dcryptomator.integrationsWin.keychainPaths=&quot;~/AppData/Roaming/Cryptomator/keychain.json&quot; -Dcryptomator.p12Path=&quot;~/AppData/Roaming/Cryptomator/key.p12&quot; -Dcryptomator.mountPointsDir=&quot;~/Cryptomator&quot; -Dcryptomator.showTrayIcon=true -Xss2m -Xmx512m --enable-preview --enable-native-access=org.cryptomator.jfuse.win" />
<option name="VM_PARAMETERS" value="-Dcryptomator.settingsPath=&quot;@{appdata}/Cryptomator/settings.json;@{userhome}/AppData/Roaming/Cryptomator/settings.json&quot; -Dcryptomator.ipcSocketPath=&quot;@{localappdata}/Cryptomator/ipc.socket&quot; -Dcryptomator.logDir=&quot;@{localappdata}/Cryptomator&quot; -Dcryptomator.pluginDir=&quot;@{appdata}/Cryptomator/Plugins&quot; -Dcryptomator.integrationsWin.keychainPaths=&quot;@{appdata}/Cryptomator/keychain.json;@{userhome}/AppData/Roaming/Cryptomator/keychain.json&quot; -Dcryptomator.p12Path=&quot;@{appdata}/Cryptomator/key.p12;@{userhome}/AppData/Roaming/Cryptomator/key.p12&quot; -Dcryptomator.mountPointsDir=&quot;@{userhome}/Cryptomator&quot; -Dcryptomator.showTrayIcon=true -Xss2m -Xmx512m --enable-preview --enable-native-access=org.cryptomator.jfuse.win" />
<method v="2">
<option name="Make" enabled="true" />
</method>
+1 -1
View File
@@ -2,7 +2,7 @@
<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="-Dcryptomator.settingsPath=&quot;~/AppData/Roaming/Cryptomator-Dev/settings.json&quot; -Dcryptomator.ipcSocketPath=&quot;~/AppData/Roaming/Cryptomator-Dev/ipc.socket&quot; -Dcryptomator.logDir=&quot;~/AppData/Roaming/Cryptomator-Dev&quot; -Dcryptomator.pluginDir=&quot;~/AppData/Roaming/Cryptomator-Dev/Plugins&quot; -Dcryptomator.integrationsWin.keychainPaths=&quot;~/AppData/Roaming/Cryptomator-Dev/keychain.json&quot; -Dcryptomator.p12Path=&quot;~/AppData/Roaming/Cryptomator-Dev/key.p12&quot; -Dcryptomator.mountPointsDir=&quot;~/Cryptomator-Dev&quot; -Dcryptomator.showTrayIcon=true -Xss2m -Xmx512m --enable-preview --enable-native-access=org.cryptomator.jfuse.win" />
<option name="VM_PARAMETERS" value="-Dcryptomator.settingsPath=&quot;@{appdata}/Cryptomator-Dev/settings.json;@{userhome}/AppData/Roaming/Cryptomator-Dev/settings.json&quot; -Dcryptomator.ipcSocketPath=&quot;@{localappdata}/Cryptomator-Dev/ipc.socket&quot; -Dcryptomator.logDir=&quot;@{localappdata}/Cryptomator-Dev&quot; -Dcryptomator.pluginDir=&quot;@{appdata}/Cryptomator-Dev/Plugins&quot; -Dcryptomator.integrationsWin.keychainPaths=&quot;@{appdata}/Cryptomator-Dev/keychain.json;@{userhome}/AppData/Roaming/Cryptomator-Dev/keychain.json&quot; -Dcryptomator.p12Path=&quot;@{appdata}/Cryptomator-Dev/key.p12;@{userhome}/AppData/Roaming/Cryptomator-Dev/key.p12&quot; -Dcryptomator.mountPointsDir=&quot;@{userhome}/Cryptomator-Dev&quot; -Dcryptomator.showTrayIcon=true -Xss2m -Xmx512m --enable-preview --enable-native-access=org.cryptomator.jfuse.win" />
<method v="2">
<option name="Make" enabled="true" />
</method>
+1 -1
View File
@@ -5,7 +5,7 @@
</envs>
<option name="MAIN_CLASS_NAME" value="org.cryptomator.launcher.Cryptomator" />
<module name="cryptomator" />
<option name="VM_PARAMETERS" value="-Dapple.awt.enableTemplateImages=true -Dcryptomator.settingsPath=&quot;~/Library/Application Support/Cryptomator/settings.json&quot; -Dcryptomator.p12Path=&quot;~/Library/Application Support/Cryptomator/key.p12&quot; -Dcryptomator.ipcSocketPath=&quot;~/Library/Application Support/Cryptomator/ipc.socket&quot; -Dcryptomator.logDir=&quot;~/Library/Logs/Cryptomator&quot; -Dcryptomator.pluginDir=&quot;~/Library/Application Support/Cryptomator/Plugins&quot; -Dcryptomator.mountPointsDir=&quot;~/Cryptomator&quot; -Dcryptomator.showTrayIcon=true -Dcryptomator.integrationsMac.keychainServiceName=Cryptomator -Xss2m -Xmx512m -ea --enable-preview --enable-native-access=org.cryptomator.jfuse.mac" />
<option name="VM_PARAMETERS" value="-Dapple.awt.enableTemplateImages=true -Dcryptomator.settingsPath=&quot;@{userhome}/Library/Application Support/Cryptomator/settings.json&quot; -Dcryptomator.p12Path=&quot;@{userhome}/Library/Application Support/Cryptomator/key.p12&quot; -Dcryptomator.ipcSocketPath=&quot;@{userhome}/Library/Application Support/Cryptomator/ipc.socket&quot; -Dcryptomator.logDir=&quot;@{userhome}/Library/Logs/Cryptomator&quot; -Dcryptomator.pluginDir=&quot;@{userhome}/Library/Application Support/Cryptomator/Plugins&quot; -Dcryptomator.mountPointsDir=&quot;@{userhome}/Cryptomator&quot; -Dcryptomator.showTrayIcon=true -Dcryptomator.integrationsMac.keychainServiceName=Cryptomator -Xss2m -Xmx512m -ea --enable-preview --enable-native-access=org.cryptomator.jfuse.mac" />
<method v="2">
<option name="Make" enabled="true" />
</method>
+1 -1
View File
@@ -5,7 +5,7 @@
</envs>
<option name="MAIN_CLASS_NAME" value="org.cryptomator.launcher.Cryptomator" />
<module name="cryptomator" />
<option name="VM_PARAMETERS" value="-Dapple.awt.enableTemplateImages=true -Dcryptomator.settingsPath=&quot;~/Library/Application Support/Cryptomator-Dev/settings.json&quot; -Dcryptomator.p12Path=&quot;~/Library/Application Support/Cryptomator-Dev/key.p12&quot; -Dcryptomator.ipcSocketPath=&quot;~/Library/Application Support/Cryptomator-Dev/ipc.socket&quot; -Dcryptomator.logDir=&quot;~/Library/Logs/Cryptomator-Dev&quot; -Dcryptomator.pluginDir=&quot;~/Library/Application Support/Cryptomator-Dev/Plugins&quot; -Dcryptomator.mountPointsDir=&quot;~/Cryptomator&quot; -Dcryptomator.showTrayIcon=true -Dcryptomator.integrationsMac.keychainServiceName=Cryptomator -Xss2m -Xmx512m -ea --enable-preview --enable-native-access=org.cryptomator.jfuse.mac" />
<option name="VM_PARAMETERS" value="-Dapple.awt.enableTemplateImages=true -Dcryptomator.settingsPath=&quot;@{userhome}/Library/Application Support/Cryptomator-Dev/settings.json&quot; -Dcryptomator.p12Path=&quot;@{userhome}/Library/Application Support/Cryptomator-Dev/key.p12&quot; -Dcryptomator.ipcSocketPath=&quot;@{userhome}/Library/Application Support/Cryptomator-Dev/ipc.socket&quot; -Dcryptomator.logDir=&quot;@{userhome}/Library/Logs/Cryptomator-Dev&quot; -Dcryptomator.pluginDir=&quot;@{userhome}/Library/Application Support/Cryptomator-Dev/Plugins&quot; -Dcryptomator.mountPointsDir=&quot;@{userhome}/Cryptomator&quot; -Dcryptomator.showTrayIcon=true -Dcryptomator.integrationsMac.keychainServiceName=Cryptomator -Xss2m -Xmx512m -ea --enable-preview --enable-native-access=org.cryptomator.jfuse.mac" />
<method v="2">
<option name="Make" enabled="true" />
</method>
+2 -2
View File
@@ -21,7 +21,6 @@ Cryptomator is provided free of charge as an open-source project despite the hig
<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>
@@ -33,6 +32,7 @@ Cryptomator is provided free of charge as an open-source project despite the hig
<tr>
<td><a href="https://mowcapital.com/"><img src="https://cryptomator.org/img/sponsors/mowcapital.svg" alt="Mow Capital" height="40"></a></td>
<td><a href="https://www.easeus.com/"><img src="https://cryptomator.org/img/sponsors/easeus.png" alt="EaseUS" height="40"></a></td>
<td><a href="https://www.hassmann-it-forensik.de/"><img src="https://cryptomator.org/img/sponsors/hassmannitforensik.png" alt="Hassmann IT-Forensik" height="40"></a></td>
</tr>
</tbody>
</table>
@@ -73,7 +73,7 @@ Download native binaries of Cryptomator on [cryptomator.org](https://cryptomator
### Consistency
- HMAC over file contents to recognize changed ciphertext before decryption
- Authenticated encryption is used for file content to recognize changed ciphertext before decryption
- I/O operations are transactional and atomic, if the filesystems support it
- Each file contains all information needed for decryption (except for the key of course), no common metadata means no [SPOF](http://en.wikipedia.org/wiki/Single_point_of_failure)
+25 -19
View File
@@ -11,15 +11,20 @@ command -v curl >/dev/null 2>&1 || { echo >&2 "curl not found."; exit 1; }
VERSION=$(mvn -f ../../../pom.xml help:evaluate -Dexpression=project.version -q -DforceStdout)
SEMVER_STR=${VERSION}
mvn -f ../../../pom.xml versions:set -DnewVersion=${SEMVER_STR}
# compile
mvn -B -f ../../../pom.xml clean package -DskipTests -Plinux
mvn -B -f ../../../pom.xml clean package -Plinux -DskipTests
cp ../../../LICENSE.txt ../../../target
cp ../launcher.sh ../../../target
cp ../../../target/cryptomator-*.jar ../../../target/mods
# add runtime
${JAVA_HOME}/bin/jlink \
--verbose \
--output runtime \
--module-path "${JAVA_HOME}/jmods" \
--add-modules java.base,java.desktop,java.instrument,java.logging,java.naming,java.net.http,java.scripting,java.sql,java.xml,jdk.unsupported,jdk.crypto.ec,jdk.accessibility,jdk.management.jfr \
--add-modules java.base,java.desktop,java.instrument,java.logging,java.naming,java.net.http,java.scripting,java.sql,java.xml,javafx.base,javafx.graphics,javafx.controls,javafx.fxml,jdk.unsupported,jdk.crypto.ec,jdk.security.auth,jdk.accessibility,jdk.management.jfr \
--strip-native-commands \
--no-header-files \
--no-man-pages \
@@ -27,7 +32,7 @@ ${JAVA_HOME}/bin/jlink \
--compress=1
# create app dir
envsubst '${SEMVER_STR} ${REVISION_NUM}' < dist/linux/launcher-gtk2.properties > launcher-gtk2.properties
envsubst '${SEMVER_STR} ${REVISION_NUM}' < ../launcher-gtk2.properties > launcher-gtk2.properties
${JAVA_HOME}/bin/jpackage \
--verbose \
--type app-image \
@@ -35,30 +40,31 @@ ${JAVA_HOME}/bin/jpackage \
--input ../../../target/libs \
--module-path ../../../target/mods \
--module org.cryptomator.desktop/org.cryptomator.launcher.Cryptomator \
--dest . \
--dest appdir \
--name Cryptomator \
--vendor "Skymatic GmbH" \
--copyright "(C) 2016 - 2022 Skymatic GmbH" \
--java-options "--enable-preview" \
--java-options "--enable-native-access=org.cryptomator.jfuse.linux.amd64,org.cryptomator.jfuse.linux.aarch64" \
--copyright "(C) 2016 - 2023 Skymatic GmbH" \
--java-options "-Xss5m" \
--java-options "-Xmx256m" \
--app-version "${VERSION}.${REVISION_NO}" \
--java-options "-Dfile.encoding=\"utf-8\"" \
--java-options "-Dcryptomator.logDir=\"~/.local/share/Cryptomator/logs\"" \
--java-options "-Dcryptomator.pluginDir=\"~/.local/share/Cryptomator/plugins\"" \
--java-options "-Dcryptomator.settingsPath=\"~/.config/Cryptomator/settings.json:~/.Cryptomator/settings.json\"" \
--java-options "-Dcryptomator.ipcSocketPath=\"~/.config/Cryptomator/ipc.socket\"" \
--java-options "-Dcryptomator.mountPointsDir=\"~/.local/share/Cryptomator/mnt\"" \
--java-options "-Djava.net.useSystemProxies=true" \
--java-options "-Dcryptomator.logDir=\"@{userhome}/.local/share/Cryptomator/logs\"" \
--java-options "-Dcryptomator.pluginDir=\"@{userhome}/.local/share/Cryptomator/plugins\"" \
--java-options "-Dcryptomator.settingsPath=\"@{userhome}/.config/Cryptomator/settings.json:@{userhome}/.Cryptomator/settings.json\"" \
--java-options "-Dcryptomator.p12Path=\"@{userhome}/.config/Cryptomator/key.p12\"" \
--java-options "-Dcryptomator.ipcSocketPath=\"@{userhome}/.config/Cryptomator/ipc.socket\"" \
--java-options "-Dcryptomator.mountPointsDir=\"@{userhome}/.local/share/Cryptomator/mnt\"" \
--java-options "-Dcryptomator.showTrayIcon=false" \
--java-options "-Dcryptomator.buildNumber=\"appimage-${REVISION_NO}\"" \
--add-launcher cryptomator-gtk2=launcher-gtk2.properties \
--resource-dir ../resources
# transform AppDir
mv Cryptomator Cryptomator.AppDir
mv appdir/Cryptomator Cryptomator.AppDir
cp -r resources/AppDir/* Cryptomator.AppDir/
chmod +x Cryptomator.AppDir/lib/runtime/bin/java
envsubst '${REVISION_NO}' < resources/AppDir/bin/cryptomator.sh > Cryptomator.AppDir/bin/cryptomator.sh
cp ../common/org.cryptomator.Cryptomator256.png Cryptomator.AppDir/usr/share/icons/hicolor/256x256/apps/org.cryptomator.Cryptomator.png
cp ../common/org.cryptomator.Cryptomator512.png Cryptomator.AppDir/usr/share/icons/hicolor/512x512/apps/org.cryptomator.Cryptomator.png
@@ -72,12 +78,6 @@ ln -s usr/share/icons/hicolor/scalable/apps/org.cryptomator.Cryptomator.svg Cryp
ln -s usr/share/applications/org.cryptomator.Cryptomator.desktop Cryptomator.AppDir/Cryptomator.desktop
ln -s bin/cryptomator.sh Cryptomator.AppDir/AppRun
# extract jffi
JFFI_NATIVE_JAR=`ls Cryptomator.AppDir/lib/app | grep -e 'jffi-[1-9]\.[0-9]\{1,2\}.[0-9]\{1,2\}-native.jar'`
${JAVA_HOME}/bin/jar -xf Cryptomator.AppDir/lib/app/${JFFI_NATIVE_JAR} /jni/x86_64-Linux/
mv jni/x86_64-Linux/* Cryptomator.AppDir/lib/app/libjffi.so
rm -r jni/x86_64-Linux
# load AppImageTool
curl -L https://github.com/AppImage/AppImageKit/releases/download/13/appimagetool-x86_64.AppImage -o /tmp/appimagetool.AppImage
chmod +x /tmp/appimagetool.AppImage
@@ -85,5 +85,11 @@ chmod +x /tmp/appimagetool.AppImage
# create AppImage
/tmp/appimagetool.AppImage \
Cryptomator.AppDir \
cryptomator-SNAPSHOT-x86_64.AppImage \
cryptomator-${SEMVER_STR}-x86_64.AppImage \
-u 'gh-releases-zsync|cryptomator|cryptomator|latest|cryptomator-*-x86_64.AppImage.zsync'
echo ""
echo "Done. AppImage successfully created: cryptomator-${SEMVER_STR}-x86_64.AppImage"
echo ""
echo >&2 "To clean up, run: rm -rf Cryptomator.AppDir appdir jni runtime squashfs-root; rm launcher-gtk2.properties /tmp/appimagetool.AppImage"
echo ""
@@ -15,9 +15,6 @@ elif command -v pacman &> /dev/null; then # don't forget arch
GTK3_PRESENT=`pacman -Qi gtk3 &> /dev/null; echo $?`
fi
# workaround for https://github.com/cryptomator/cryptomator-linux/issues/27
export LD_PRELOAD=lib/app/libjffi.so
if [ "$GTK2_PRESENT" -eq 0 ] && [ "$GTK3_PRESENT" -ne 0 ]; then
bin/Cryptomator-gtk2 $@
else
@@ -66,6 +66,16 @@
</content_rating>
<releases>
<release date="2023-06-07" version="1.9.1"/>
<release date="2023-05-30" version="1.9.0"/>
<release date="2023-04-25" version="1.8.0"/>
<release date="2023-04-07" version="1.7.5"/>
<release date="2023-04-05" version="1.7.4"/>
<release date="2023-03-15" version="1.7.3"/>
<release date="2023-03-07" version="1.7.2"/>
<release date="2023-03-03" version="1.7.1"/>
<release date="2023-03-01" version="1.7.0"/>
<release date="2022-12-14" version="1.6.17"/>
<release date="2022-12-06" version="1.6.16"/>
<release date="2022-10-06" version="1.6.15"/>
<release date="2022-08-31" version="1.6.14"/>
+2 -2
View File
@@ -2,7 +2,7 @@ Source: cryptomator
Maintainer: Cryptobot <releases@cryptomator.org>
Section: utils
Priority: optional
Build-Depends: debhelper (>=10), coffeelibs-jdk-19, libgtk2.0-0, libgtk-3-0, libxxf86vm1, libgl1
Build-Depends: debhelper (>=10), coffeelibs-jdk-20, libgtk2.0-0, libgtk-3-0, libxxf86vm1, libgl1
Standards-Version: 4.5.0
Homepage: https://cryptomator.org
Vcs-Git: https://github.com/cryptomator/cryptomator.git
@@ -12,7 +12,7 @@ Package: cryptomator
Architecture: any
Section: utils
Priority: optional
Depends: ${shlibs:Depends}, ${misc:Depends}, libfuse2, xdg-utils, libjffi-jni
Depends: ${shlibs:Depends}, ${misc:Depends}, fuse3
Recommends: gvfs-backends, gvfs-fuse, gnome-keyring
XB-AppName: Cryptomator
XB-Category: Utility;Security;FileTools;
+2 -2
View File
@@ -4,11 +4,11 @@ Upstream-Contact: Cryptomator <info@cryptomator.org>
Source: https://cryptomator.org
Files: *
Copyright: 2016-2022 Skymatic GmbH
Copyright: 2016-2023 Skymatic GmbH
License: GPL-3+
Files: debian/org.cryptomator.Cryptomator.appdata.xml
Copyright: 2016-2022 Skymatic GmbH
Copyright: 2016-2023 Skymatic GmbH
License: FSFAP
License: GPL-3+
-1
View File
@@ -1,5 +1,4 @@
cryptomator usr/lib
debian/cryptomator.sh usr/lib/cryptomator/bin
common/org.cryptomator.Cryptomator.desktop usr/share/applications
common/org.cryptomator.Cryptomator.svg usr/share/icons/hicolor/scalable/apps
common/org.cryptomator.Cryptomator256.png usr/share/icons/hicolor/256x256/apps
+1 -1
View File
@@ -1 +1 @@
usr/lib/cryptomator/bin/cryptomator.sh usr/bin/cryptomator
usr/lib/cryptomator/bin/cryptomator usr/bin/cryptomator
-6
View File
@@ -1,6 +0,0 @@
#!/bin/sh
# fix for https://github.com/cryptomator/cryptomator/issues/1370
export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/jni/libjffi-1.2.so
/usr/lib/cryptomator/bin/cryptomator $@
+10 -16
View File
@@ -4,7 +4,7 @@
# Uncomment this to turn on verbose mode.
#export DH_VERBOSE=1
JAVA_HOME = /usr/lib/jvm/java-19-coffeelibs
JAVA_HOME = /usr/lib/jvm/java-20-coffeelibs
DEB_BUILD_ARCH ?= $(shell dpkg-architecture -qDEB_BUILD_ARCH)
ifeq ($(DEB_BUILD_ARCH),amd64)
JMODS_PATH = jmods/amd64:${JAVA_HOME}/jmods
@@ -27,7 +27,7 @@ override_dh_auto_build:
$(JAVA_HOME)/bin/jlink \
--output runtime \
--module-path "${JMODS_PATH}" \
--add-modules java.base,java.desktop,java.instrument,java.logging,java.naming,java.net.http,java.scripting,java.sql,java.xml,javafx.base,javafx.graphics,javafx.controls,javafx.fxml,jdk.unsupported,jdk.crypto.ec,jdk.accessibility,jdk.management.jfr \
--add-modules java.base,java.desktop,java.instrument,java.logging,java.naming,java.net.http,java.scripting,java.sql,java.xml,javafx.base,javafx.graphics,javafx.controls,javafx.fxml,jdk.unsupported,jdk.crypto.ec,jdk.security.auth,jdk.accessibility,jdk.management.jfr \
--strip-native-commands \
--no-header-files \
--no-man-pages \
@@ -42,28 +42,22 @@ override_dh_auto_build:
--dest . \
--name cryptomator \
--vendor "Skymatic GmbH" \
--copyright "(C) 2016 - 2022 Skymatic GmbH" \
--java-options "--enable-preview" \
--java-options "--enable-native-access=org.cryptomator.jfuse.linux.amd64,org.cryptomator.jfuse.linux.aarch64" \
--copyright "(C) 2016 - 2023 Skymatic GmbH" \
--java-options "-Xss5m" \
--java-options "-Xmx256m" \
--java-options "-Dfile.encoding=\"utf-8\"" \
--java-options "-Dcryptomator.logDir=\"~/.local/share/Cryptomator/logs\"" \
--java-options "-Dcryptomator.pluginDir=\"~/.local/share/Cryptomator/plugins\"" \
--java-options "-Dcryptomator.settingsPath=\"~/.config/Cryptomator/settings.json:~/.Cryptomator/settings.json\"" \
--java-options "-Dcryptomator.p12Path=\"~/.config/Cryptomator/key.p12\"" \
--java-options "-Dcryptomator.ipcSocketPath=\"~/.config/Cryptomator/ipc.socket\"" \
--java-options "-Dcryptomator.mountPointsDir=\"~/.local/share/Cryptomator/mnt\"" \
--java-options "-Djava.net.useSystemProxies=true" \
--java-options "-Dcryptomator.logDir=\"@{userhome}/.local/share/Cryptomator/logs\"" \
--java-options "-Dcryptomator.pluginDir=\"@{userhome}/.local/share/Cryptomator/plugins\"" \
--java-options "-Dcryptomator.settingsPath=\"@{userhome}/.config/Cryptomator/settings.json:@{userhome}/.Cryptomator/settings.json\"" \
--java-options "-Dcryptomator.p12Path=\"@{userhome}/.config/Cryptomator/key.p12\"" \
--java-options "-Dcryptomator.ipcSocketPath=\"@{userhome}/.config/Cryptomator/ipc.socket\"" \
--java-options "-Dcryptomator.mountPointsDir=\"@{userhome}/.local/share/Cryptomator/mnt\"" \
--java-options "-Dcryptomator.showTrayIcon=false" \
--java-options "-Dcryptomator.buildNumber=\"deb-${REVISION_NUM}\"" \
--java-options "-Dcryptomator.appVersion=\"${SEMVER_STR}\"" \
--app-version "${VERSION_NUM}.${REVISION_NUM}" \
--resource-dir resources \
--verbose
override_dh_fixperms:
dh_fixperms
chmod +x debian/cryptomator/usr/lib/cryptomator/bin/cryptomator.sh
# override_dh_strip:
# no-op
-15
View File
@@ -1,15 +0,0 @@
#!/bin/sh
cd $(dirname $0)
java \
-p "mods" \
-cp "libs/*" \
-Dcryptomator.settingsPath="~/.config/Cryptomator/settings.json" \
-Dcryptomator.ipcSocketPath="~/.config/Cryptomator/ipc.socket" \
-Dcryptomator.logDir="~/.local/share/Cryptomator/logs" \
-Dcryptomator.mountPointsDir="~/.local/share/Cryptomator/mnt" \
-Djdk.gtk.version=2 \
-Xss2m \
-Xmx512m \
--enable-preview \
--enable-native-access=org.cryptomator.jfuse.linux.amd64,org.cryptomator.jfuse.linux.aarch64 \
-m org.cryptomator.desktop/org.cryptomator.launcher.Cryptomator
+13 -10
View File
@@ -21,12 +21,13 @@ rm -rf runtime dmg *.app *.dmg
# set variables
APP_NAME="Cryptomator"
VENDOR="Skymatic GmbH"
COPYRIGHT_YEARS="2016 - 2022"
COPYRIGHT_YEARS="2016 - 2023"
PACKAGE_IDENTIFIER="org.cryptomator"
MAIN_JAR_GLOB="cryptomator-*.jar"
MODULE_AND_MAIN_CLASS="org.cryptomator.desktop/org.cryptomator.launcher.Cryptomator"
REVISION_NO=`git rev-list --count HEAD`
VERSION_NO=`mvn -f../../../pom.xml help:evaluate -Dexpression=project.version -q -DforceStdout | sed -rn 's/.*([0-9]+\.[0-9]+\.[0-9]+).*/\1/p'`
FUSE_LIB="FUSE-T"
# check preconditions
if [ -z "${JAVA_HOME}" ]; then echo "JAVA_HOME not set. Run using JAVA_HOME=/path/to/jdk ./build.sh"; exit 1; fi
@@ -70,15 +71,17 @@ ${JAVA_HOME}/bin/jpackage \
--java-options "-Xss5m" \
--java-options "-Xmx256m" \
--java-options "-Dfile.encoding=\"utf-8\"" \
--java-options "-Djava.net.useSystemProxies=true" \
--java-options "-Dapple.awt.enableTemplateImages=true" \
--java-options "-Dsun.java2d.metal=true" \
--java-options "-Dcryptomator.appVersion=\"${VERSION_NO}\"" \
--java-options "-Dcryptomator.logDir=\"~/Library/Logs/${APP_NAME}\"" \
--java-options "-Dcryptomator.pluginDir=\"~/Library/Application Support/${APP_NAME}/Plugins\"" \
--java-options "-Dcryptomator.settingsPath=\"~/Library/Application Support/${APP_NAME}/settings.json\"" \
--java-options "-Dcryptomator.ipcSocketPath=\"~/Library/Application Support/${APP_NAME}/ipc.socket\"" \
--java-options "-Dcryptomator.p12Path=\"~/Library/Application Support/${APP_NAME}/key.p12\"" \
--java-options "-Dcryptomator.logDir=\"@{userhome}/Library/Logs/${APP_NAME}\"" \
--java-options "-Dcryptomator.pluginDir=\"@{userhome}/Library/Application Support/${APP_NAME}/Plugins\"" \
--java-options "-Dcryptomator.settingsPath=\"@{userhome}/Library/Application Support/${APP_NAME}/settings.json\"" \
--java-options "-Dcryptomator.ipcSocketPath=\"@{userhome}/Library/Application Support/${APP_NAME}/ipc.socket\"" \
--java-options "-Dcryptomator.p12Path=\"@{userhome}/Library/Application Support/${APP_NAME}/key.p12\"" \
--java-options "-Dcryptomator.integrationsMac.keychainServiceName=\"${APP_NAME}\"" \
--java-options "-Dcryptomator.mountPointsDir=\"@{userhome}/Library/Application Support${APP_NAME}/mnt\"" \
--java-options "-Dcryptomator.showTrayIcon=true" \
--java-options "-Dcryptomator.buildNumber=\"dmg-${REVISION_NO}\"" \
--mac-package-identifier ${PACKAGE_IDENTIFIER} \
@@ -124,20 +127,20 @@ fi
# prepare dmg contents
mkdir dmg
mv ${APP_NAME}.app dmg
cp resources/macFUSE.webloc dmg
cp resources/${FUSE_LIB}.webloc dmg
# create dmg
create-dmg \
--volname ${APP_NAME} \
--volicon "resources/${APP_NAME}-Volume.icns" \
--background "resources/${APP_NAME}-background.tiff" \
--background "resources/${APP_NAME}-${FUSE_LIB}-background.tiff" \
--window-pos 400 100 \
--window-size 640 694 \
--icon-size 128 \
--icon "${APP_NAME}.app" 128 245 \
--hide-extension "${APP_NAME}.app" \
--icon "macFUSE.webloc" 320 501 \
--hide-extension "macFUSE.webloc" \
--icon "${FUSE_LIB}.webloc" 320 501 \
--hide-extension "${FUSE_LIB}.webloc" \
--app-drop-link 512 245 \
--eula "resources/license.rtf" \
--icon ".background" 128 758 \
Binary file not shown.
Binary file not shown.
Binary file not shown.
+8
View File
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>URL</key>
<string>https://www.fuse-t.org/</string>
</dict>
</plist>
+1 -1
View File
@@ -17,7 +17,7 @@
\f1\b0 \
\
\f0\b \'a9 2016 \'96 2022 Skymatic GmbH
\f0\b \'a9 2016 \'96 2023 Skymatic GmbH
\f1\b0 \
\
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.\
-14
View File
@@ -1,14 +0,0 @@
#!/bin/sh
cd $(dirname $0)
java \
-p "mods" \
-cp "libs/*" \
-Dcryptomator.settingsPath="~/Library/Application Support/Cryptomator/settings.json" \
-Dcryptomator.ipcSocketPath="~/Library/Application Support/Cryptomator/ipc.socket" \
-Dcryptomator.logDir="~/Library/Logs/Cryptomator" \
-Dcryptomator.mountPointsDir="/Volumes" \
-Xss20m \
-Xmx512m \
--enable-preview \
--enable-native-access=org.cryptomator.jfuse.mac \
-m org.cryptomator.desktop/org.cryptomator.launcher.Cryptomator
+35 -16
View File
@@ -12,6 +12,9 @@ Param(
[bool] $clean
)
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
$ProgressPreference = 'SilentlyContinue' # disables Invoke-WebRequest's progress bar, which slows down downloads to a few bytes/s
# check preconditions
if ((Get-Command "git" -ErrorAction SilentlyContinue) -eq $null)
{
@@ -26,7 +29,7 @@ if ((Get-Command "mvn" -ErrorAction SilentlyContinue) -eq $null)
$buildDir = Split-Path -Parent $PSCommandPath
$version = $(mvn -f $buildDir/../../pom.xml help:evaluate -Dexpression="project.version" -q -DforceStdout)
$semVerNo = $version -replace '(\d\.\d\.\d).*','$1'
$semVerNo = $version -replace '(\d+\.\d+\.\d+).*','$1'
$revisionNo = $(git rev-list --count HEAD)
Write-Output "`$version=$version"
@@ -47,11 +50,28 @@ if ($clean -and (Test-Path -Path $runtimeImagePath)) {
Remove-Item -Path $runtimeImagePath -Force -Recurse
}
## download jfx jmods
$jfxJmodsChecksum = 'd00767334c43b8832b5cf10267d34ca8f563d187c4655b73eb6020dd79c054b5'
$jfxJmodsZip = '.\resources\jfxJmods.zip'
if( !(Test-Path -Path $jfxJmodsZip) ) {
$jmodsUrl = "https://download2.gluonhq.com/openjfx/20.0.1/openjfx-20.0.1_windows-x64_bin-jmods.zip"
Write-Output "Downloading ${jmodsUrl}..."
Invoke-WebRequest $jmodsUrl -OutFile $jfxJmodsZip # redirects are followed by default
}
$jmodsChecksumActual = $(Get-FileHash -Path $jfxJmodsZip -Algorithm SHA256).Hash
if( $jmodsChecksumActual -ne $jfxJmodsChecksum ) {
Write-Error "Checksum mismatch for jfxJmods.zip. Expected: $jfxJmodsChecksum, actual: $jmodsChecksumActual"
exit 1;
}
Expand-Archive -Force -Path $jfxJmodsZip -DestinationPath ".\resources\"
& "$Env:JAVA_HOME\bin\jlink" `
--verbose `
--output runtime `
--module-path "$Env:JAVA_HOME/jmods" `
--add-modules java.base,java.desktop,java.instrument,java.logging,java.naming,java.net.http,java.scripting,java.sql,java.xml,jdk.unsupported,jdk.crypto.ec,jdk.accessibility,jdk.management.jfr `
--module-path "$Env:JAVA_HOME/jmods;$buildDir/resources/javafx-jmods-20.0.1" `
--add-modules java.base,java.desktop,java.instrument,java.logging,java.naming,java.net.http,java.scripting,java.sql,java.xml,jdk.unsupported,jdk.crypto.ec,jdk.accessibility,jdk.management.jfr,javafx.base,javafx.graphics,javafx.controls,javafx.fxml `
--strip-native-commands `
--no-header-files `
--no-man-pages `
@@ -82,15 +102,16 @@ if ($clean -and (Test-Path -Path $appPath)) {
--java-options "-Dcryptomator.appVersion=`"$semVerNo`"" `
--app-version "$semVerNo.$revisionNo" `
--java-options "-Dfile.encoding=`"utf-8`"" `
--java-options "-Dcryptomator.logDir=`"~/AppData/Roaming/$AppName`"" `
--java-options "-Dcryptomator.pluginDir=`"~/AppData/Roaming/$AppName/Plugins`"" `
--java-options "-Dcryptomator.settingsPath=`"~/AppData/Roaming/$AppName/settings.json`"" `
--java-options "-Dcryptomator.ipcSocketPath=`"~/AppData/Roaming/$AppName/ipc.socket`"" `
--java-options "-Dcryptomator.p12Path=`"~/AppData/Roaming/$AppName/key.p12`"" `
--java-options "-Dcryptomator.mountPointsDir=`"~/$AppName`"" `
--java-options "-Djava.net.useSystemProxies=true" `
--java-options "-Dcryptomator.logDir=`"@{localappdata}/$AppName`"" `
--java-options "-Dcryptomator.pluginDir=`"@{appdata}/$AppName/Plugins`"" `
--java-options "-Dcryptomator.settingsPath=`"@{appdata}/$AppName/settings.json;@{userhome}/AppData/Roaming/$AppName/settings.json`"" `
--java-options "-Dcryptomator.ipcSocketPath=`"@{localappdata}/$AppName/ipc.socket`"" `
--java-options "-Dcryptomator.p12Path=`"@{appdata}/$AppName/key.p12;@{userhome}/AppData/Roaming/$AppName/key.p12`"" `
--java-options "-Dcryptomator.mountPointsDir=`"@{userhome}/$AppName`"" `
--java-options "-Dcryptomator.loopbackAlias=`"$LoopbackAlias`"" `
--java-options "-Dcryptomator.integrationsWin.autoStartShellLinkName=`"$AppName`"" `
--java-options "-Dcryptomator.integrationsWin.keychainPaths=`"~/AppData/Roaming/$AppName/keychain.json`"" `
--java-options "-Dcryptomator.integrationsWin.keychainPaths=`"@{appdata}/$AppName/keychain.json;@{userhome}/AppData/Roaming/$AppName/keychain.json`"" `
--java-options "-Dcryptomator.showTrayIcon=true" `
--java-options "-Dcryptomator.buildNumber=`"msi-$revisionNo`"" `
--resource-dir resources `
@@ -129,7 +150,7 @@ $Env:JP_WIXWIZARD_RESOURCES = "$buildDir\resources"
--name $AppName `
--vendor $Vendor `
--copyright $copyright `
--app-version "$semVerNo" `
--app-version "$semVerNo.$revisionNo" `
--win-menu `
--win-dir-chooser `
--win-shortcut-prompt `
@@ -151,9 +172,7 @@ $Env:JP_WIXWIZARD_RESOURCES = "$buildDir\resources"
"-Dlicense.licenseMergesUrl=file:///$buildDir/../../license/merges"
# download Winfsp
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
$ProgressPreference = 'SilentlyContinue' # disables Invoke-WebRequest's progress bar, which slows down downloads to a few bytes/s
$winfspMsiUrl= (Select-String -Path ".\bundle\resources\winfsp-download.url" -Pattern 'https:.*').Matches.Value
$winfspMsiUrl= (Select-String -Path ".\bundle\resources\winFspMetaData.wxi" -Pattern '<\?define BundledWinFspDownloadLink="(.+)".*?>').Matches.Groups[1].Value
Write-Output "Downloading ${winfspMsiUrl}..."
Invoke-WebRequest $winfspMsiUrl -OutFile ".\bundle\resources\winfsp.msi" # redirects are followed by default
@@ -161,11 +180,11 @@ Invoke-WebRequest $winfspMsiUrl -OutFile ".\bundle\resources\winfsp.msi" # redir
Copy-Item ".\installer\$AppName-*.msi" -Destination ".\bundle\resources\$AppName.msi"
# create bundle including winfsp
& "$env:WIX\bin\candle.exe" .\bundle\bundleWithWinfsp.wxs -ext WixBalExtension -out bundle\ `
& "$env:WIX\bin\candle.exe" .\bundle\bundleWithWinfsp.wxs -ext WixBalExtension -ext WixUtilextension -out bundle\ `
-dBundleVersion="$semVerNo.$revisionNo" `
-dBundleVendor="$Vendor" `
-dBundleCopyright="$copyright" `
-dAboutUrl="$AboutUrl" `
-dHelpUrl="$HelpUrl" `
-dUpdateUrl="$UpdateUrl"
& "$env:WIX\bin\light.exe" -b . .\bundle\BundlewithWinfsp.wixobj -ext WixBalExtension -out installer\$AppName-Installer.exe
& "$env:WIX\bin\light.exe" -b . .\bundle\BundlewithWinfsp.wixobj -ext WixBalExtension -ext WixUtilextension -out installer\$AppName-Installer.exe
+19 -1
View File
@@ -1,13 +1,31 @@
<?xml version="1.0"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:bal="http://schemas.microsoft.com/wix/BalExtension">
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:bal="http://schemas.microsoft.com/wix/BalExtension" xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
<!-- see https://wixtoolset.org/documentation/manual/v3/xsd/wix/bundle.html-->
<!-- Attributes explicitly not used:
Condition - the single msi files have their own install conditions, no need to copy them here
-->
<Bundle Name="Cryptomator" UpgradeCode="29eea626-2e5b-4449-b5f8-4602925ddf7b" Version="$(var.BundleVersion)" Manufacturer="$(var.BundleVendor)"
AboutUrl="$(var.AboutUrl)" HelpUrl="$(var.HelpUrl)" UpdateUrl="$(var.UpdateUrl)" Copyright="$(var.BundleCopyright)" IconSourceFile="bundle\resources\Cryptomator.ico">
<!-- detect outdated WinFsp installations -->
<?include "resources\winFspMetaData.wxi" ?>
<util:ProductSearch
Variable="InstalledWinFspVersion"
Result="version"
UpgradeCode="82F812D9-4083-4EF1-8BC8-0F1EDA05B46B"
/>
<!-- Note: The bundle engine takes the Message format literaly -->
<bal:Condition Message=
"The WinFsp driver used by Cryptomator is outdated and must be removed before the installation.
1. Open the view of installed apps
2. Search for &quot;WinFsp&quot;
3. Uninstall the listed application
4. Reboot your device
5. Restart this installer">(InstalledWinFspVersion = v0.0.0.0) OR ($(var.BundledWinFspVersion) &lt;= InstalledWinFspVersion)</bal:Condition>
<!-- for definition of the standard themes, see https://github.com/wixtoolset/wix3/blob/master/src/ext/BalExtension/wixstdba/Resources/-->
<BootstrapperApplicationRef Id="WixStandardBootstrapperApplication.RtfLargeLicense">
<!-- see https://wixtoolset.org/documentation/manual/v3/xsd/bal/wixstandardbootstrapperapplication.html -->
+2 -1
View File
@@ -10,6 +10,7 @@
<Font Id="2" Height="-22" Weight="500" Foreground="666666">Segoe UI</Font>
<Font Id="3" Height="-12" Weight="500" Foreground="000000" Background="FFFFFF">Segoe UI</Font>
<Font Id="4" Height="-12" Weight="500" Foreground="ff0000" Background="FFFFFF" Underline="yes">Segoe UI</Font>
<Font Id="5" Height="-12" Weight="700" Foreground="000000" Background="FFFFFF">Segoe UI</Font>
<Image X="11" Y="11" Width="64" Height="64" ImageFile="logo.png" />
<Text X="80" Y="11" Width="-11" Height="64" FontId="1" DisablePrefix="yes">#(loc.Title)</Text>
@@ -82,7 +83,7 @@
<Text Name="FailureUninstallHeader" X="185" Y="50" Width="-11" Height="30" FontId="2" HideWhenDisabled="yes" DisablePrefix="yes">#(loc.FailureUninstallHeader)</Text>
<Text Name="FailureRepairHeader" X="185" Y="50" Width="-11" Height="30" FontId="2" HideWhenDisabled="yes" DisablePrefix="yes">#(loc.FailureRepairHeader)</Text>
<Hypertext Name="FailureLogFileLink" X="185" Y="121" Width="-11" Height="68" FontId="3" TabStop="yes" HideWhenDisabled="yes">#(loc.FailureHyperlinkLogText)</Hypertext>
<Hypertext Name="FailureMessageText" X="185" Y="-115" Width="-11" Height="80" FontId="3" TabStop="yes" HideWhenDisabled="yes" />
<Hypertext Name="FailureMessageText" X="185" Y="-80" Width="-11" Height="140" FontId="5" TabStop="yes" HideWhenDisabled="yes" />
<Text Name="FailureRestartText" X="185" Y="-57" Width="-11" Height="80" FontId="3" HideWhenDisabled="yes" DisablePrefix="yes">#(loc.FailureRestartText)</Text>
<Button Name="FailureRestartButton" X="-91" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0" HideWhenDisabled="yes">#(loc.FailureRestartButton)</Button>
<Button Name="FailureCloseButton" X="-11" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">#(loc.FailureCloseButton)</Button>
+1 -1
View File
@@ -10,7 +10,7 @@
\vieww12000\viewh15840\viewkind0
\pard\tx283\tx567\tx850\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\b\fs16\lang7 Cryptomator is distributed under the GPLv3 License, found below. Please see the bottom of this document for any other license applicable to code used within Cryptomator.\b0\par
\par
\b\'a9 2016 \'96 2022 Skymatic GmbH \b0\par
\b\'a9 2016 \'96 2023 Skymatic GmbH \b0\par
\par
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.\par
\par
+7
View File
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Include xmlns="http://schemas.microsoft.com/wix/2006/wi">
<!-- A version number MUST be prefixed with letter "v", otherwise it is considered a normal string -->
<?define BundledWinFspVersion="v1.12.22339" ?>
<?define BundledWinFspDownloadLink="https://github.com/winfsp/winfsp/releases/download/v1.12.22339/winfsp-1.12.22339.msi" ?> <!-- Only used by external build scripts -->
</Include>
-2
View File
@@ -1,2 +0,0 @@
[InternetShortcut]
URL=https://github.com/winfsp/winfsp/releases/download/v1.12/winfsp-1.12.22301.msi
-12
View File
@@ -1,12 +0,0 @@
@echo off
java ^
-p "app/mods" ^
-cp "app/*" ^
-Dcryptomator.settingsPath="~/AppData/Roaming/Cryptomator/settings.json" ^
-Dcryptomator.ipcSocketPath="~/AppData/Roaming/Cryptomator/ipc.socket" ^
-Dcryptomator.logDir="~/AppData/Roaming/Cryptomator" ^
-Dcryptomator.mountPointsDir="~/Cryptomator" ^
-Dcryptomator.keychainPath="~/AppData/Roaming/Cryptomator/keychain.json" ^
-Xss20m ^
-Xmx512m ^
-m org.cryptomator.desktop/org.cryptomator.launcher.Cryptomator
+5
View File
@@ -0,0 +1,5 @@
@echo off
:: see comments in file ./version170-migrate-settings.ps1
cd %~dp0
powershell -NoLogo -NonInteractive -ExecutionPolicy Unrestricted -Command .\version170-migrate-settings.ps1
+35
View File
@@ -0,0 +1,35 @@
# This script migrates Cryptomator settings for all local users on Windows in case the users uses custom directories as mountpoint
# See also https://github.com/cryptomator/cryptomator/pull/2654.
#
# TODO: This script should be evaluated in a yearly interval if it is still needed and if not, should be removed
#
#Requires -RunAsAdministrator
#Get all active, local user profiles
$profileList = 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList'
Get-ChildItem $profileList | ForEach-Object {
$profilePath = $_.GetValue("ProfileImagePath")
$settingsPath = "$profilePath\AppData\Roaming\Cryptomator\settings.json"
if(!(Test-Path -Path $settingsPath -PathType Leaf)) {
#No settings file, nothing to do.
return;
}
$settings = Get-Content -Path $settingsPath | ConvertFrom-Json
if($settings.preferredVolumeImpl -ne "FUSE") {
#Fuse not used, nothing to do
return;
}
#check if customMountPoints are used
$atLeastOneCustomPath = $false;
foreach ($vault in $settings.directories){
$atLeastOneCustomPath = $atLeastOneCustomPath -or ($vault.useCustomMountPath -eq "True")
}
#if so, use WinFsp Local Drive
if( $atLeastOneCustomPath ) {
Add-Member -Force -InputObject $settings -Name "mountService" -Value "org.cryptomator.frontend.fuse.mount.WinFspMountProvider" -MemberType NoteProperty
$newSettings = $settings | Select-Object * -ExcludeProperty "preferredVolumeImpl"
ConvertTo-Json $newSettings | Set-Content -Path $settingsPath
}
}
+2 -5
View File
@@ -65,13 +65,10 @@
<Control Id="Title" Type="Text" X="135" Y="20" Width="220" Height="60" Transparent="yes" NoPrefix="yes" Text="!(loc.ExitDialogTitle)" />
<!-- TODO: localize? -->
<Control Id="Suggestion" Type="Text" X="135" Y="100" Width="220" Height="60" Transparent="yes" NoPrefix="yes">
<Text>We recommend for the best user experience to download and install one of the following third party Windows drivers:</Text>
<Text>We recommend for the best user experience to download and install the following third party Windows driver:</Text>
</Control>
<Control Id="WinFsp" Type="Hyperlink" X="140" Y="125" Width="220" Height="60" Transparent="yes">
<Text><![CDATA[WinFsp (<a href="http://www.secfs.net/winfsp/rel/">Homepage</a>)]]></Text>
</Control>
<Control Id="Dokany" Type="Hyperlink" X="140" Y="137" Width="220" Height="60" Transparent="yes">
<Text><![CDATA[• Dokany (<a href="https://dokan-dev.github.io/">Homepage</a>)]]></Text>
<Text><![CDATA[WinFsp (<a href="https://winfsp.dev/">Homepage</a>)]]></Text>
</Control>
</Dialog>
+1 -1
View File
@@ -10,7 +10,7 @@
\vieww12000\viewh15840\viewkind0
\pard\tx283\tx567\tx850\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\b\fs16\lang7 Cryptomator is distributed under the GPLv3 License, found below. Please see the bottom of this document for any other license applicable to code used within Cryptomator.\b0\par
\par
\b\'a9 2016 \'96 2022 Skymatic GmbH \b0\par
\b\'a9 2016 \'96 2023 Skymatic GmbH \b0\par
\par
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.\par
\par
+18 -6
View File
@@ -54,7 +54,7 @@
Property="JP_UPGRADABLE_FOUND"
Maximum="$(var.JpAppVersion)"
MigrateFeatures="yes"
IncludeMaximum="$(var.JpUpgradeVersionOnlyDetectUpgrade)" />
IncludeMaximum="yes" /> <!-- TODO: check if this needs to be set to yes-->
<UpgradeVersion
OnlyDetect="$(var.JpUpgradeVersionOnlyDetectDowngrade)"
Property="JP_DOWNGRADABLE_FOUND"
@@ -70,6 +70,9 @@
<CustomAction Id="JpDisallowDowngrade" Error="!(loc.DowngradeErrorMessage)" />
<?endif?>
<Binary Id="JpCaDll" SourceFile="wixhelper.dll"/>
<CustomAction Id="JpFindRelatedProducts" BinaryKey="JpCaDll" DllEntry="FindRelatedProductsEx" />
<?ifndef SkipCryptomatorLegacyCheck ?>
<!-- Block installation if innosetup entry of Cryptomator is found -->
<Property Id="OLDEXEINSTALLER">
@@ -132,6 +135,9 @@
<!-- WebDAV patches -->
<CustomAction Id="PatchWebDAV" Impersonate="no" ExeCommand="[INSTALLDIR]patchWebDAV.bat" Directory="INSTALLDIR" Execute="deferred" Return="asyncWait" />
<!-- Special Settings migration for 1.7.0,. Should be removed eventually, for more info, see ../contrib/version170-migrate-settings.ps1-->
<CustomAction Id="V170MigrateSettings" Impersonate="no" ExeCommand="[INSTALLDIR]version170-migrate-settings.bat" Directory="INSTALLDIR" Execute="deferred" Return="asyncWait" />
<!-- Running App detection and exit -->
<Property Id="FOUNDRUNNINGAPP" Admin="yes"/>
<util:CloseApplication
@@ -140,11 +146,11 @@
CloseMessage="no"
RebootPrompt="no"
PromptToContinue="yes"
Description="A running instance of $(var.JpAppName) is found. Please close it to continue."
Description="A running instance of $(var.JpAppName) is found, using files marked for update. Please close it to continue."
Property="FOUNDRUNNINGAPP"
>
</util:CloseApplication>
<CustomAction Id="FailOnRunningApp" Impersonate="no" ExeCommand="[SystemFolder]\cmd.exe /c &quot;exit 1&quot;" Directory="INSTALLDIR" Execute="immediate" Return="check" />
<CustomAction Id="FailOnRunningApp" Error="Installation aborted, because files marked for update are used by a running instance of $(var.JpAppName)."/>
<?ifdef JpIcon ?>
<Property Id="ARPPRODUCTICON" Value="JpARPPRODUCTICON"/>
@@ -169,21 +175,27 @@
<?endif?>
<?ifndef JpAllowUpgrades ?>
<Custom Action="JpDisallowUpgrade" After="FindRelatedProducts">JP_UPGRADABLE_FOUND</Custom>
<Custom Action="JpDisallowUpgrade" After="JpFindRelatedProducts">JP_UPGRADABLE_FOUND</Custom>
<?endif?>
<?ifndef JpAllowDowngrades ?>
<Custom Action="JpDisallowDowngrade" After="FindRelatedProducts">JP_DOWNGRADABLE_FOUND</Custom>
<Custom Action="JpDisallowDowngrade" After="JpFindRelatedProducts">JP_DOWNGRADABLE_FOUND</Custom>
<?endif?>
<Custom Action="JpFindRelatedProducts" After="FindRelatedProducts"/>
<!-- Check and fail if Cryptomator is running -->
<Custom Action="WixCloseApplications" Before="InstallValidate"></Custom>
<Custom Action="FailOnRunningApp" After="WixCloseApplications" >FOUNDRUNNINGAPP</Custom>
<RemoveExistingProducts After="InstallValidate"/>
<RemoveExistingProducts After="InstallValidate"/> <!-- Moved from CostInitialize, due to WixCloseApplications -->
<Custom Action="PatchWebDAV" After="InstallFiles">NOT Installed OR REINSTALL</Custom>
<Custom Action="V170MigrateSettings" After="InstallFiles">NOT Installed OR REINSTALL</Custom>
</InstallExecuteSequence>
<InstallUISequence>
<Custom Action="JpFindRelatedProducts" After="FindRelatedProducts"/>
</InstallUISequence>
<WixVariable Id="WixUIBannerBmp" Value="$(env.JP_WIXWIZARD_RESOURCES)\banner.bmp" />
<WixVariable Id="WixUIDialogBmp" Value="$(env.JP_WIXWIZARD_RESOURCES)\background.bmp" />
</Product>
+37 -64
View File
@@ -3,7 +3,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>org.cryptomator</groupId>
<artifactId>cryptomator</artifactId>
<version>1.7.0</version>
<version>1.10.0-SNAPSHOT</version>
<name>Cryptomator Desktop App</name>
<organization>
@@ -17,49 +17,54 @@
<email>sebastian.stenzel@gmail.com</email>
<timezone>+1</timezone>
</developer>
<developer>
<name>Armin Schrenk</name>
<email>armin.schrenk+dev@mailbox.org</email>
<timezone>+1</timezone>
</developer>
</developers>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.jdk.version>19</project.jdk.version>
<project.jdk.version>20</project.jdk.version>
<!-- Group IDs of jars that need to stay on the class path for now -->
<!-- Check progress on https://github.com/swiesend/secret-service/issues/31 to remove hypfvieh, swiesend and jnr -->
<nonModularGroupIds>com.github.jnr,org.ow2.asm,org.apache.jackrabbit,org.apache.httpcomponents,de.swiesend,org.purejava,com.github.hypfvieh</nonModularGroupIds>
<!-- Once hypfvieh, swiesend, purejava and integrations-linux have module-info, remove them-->
<nonModularGroupIds>org.ow2.asm,org.apache.jackrabbit,org.apache.httpcomponents,de.swiesend,org.purejava,com.github.hypfvieh</nonModularGroupIds>
<!-- cryptomator dependencies -->
<cryptomator.cryptofs.version>2.5.3</cryptomator.cryptofs.version>
<cryptomator.integrations.version>1.2.0-beta2</cryptomator.integrations.version>
<cryptomator.integrations.win.version>1.1.2</cryptomator.integrations.win.version>
<cryptomator.integrations.mac.version>1.1.2</cryptomator.integrations.mac.version>
<cryptomator.integrations.linux.version>1.1.0</cryptomator.integrations.linux.version>
<cryptomator.fuse.version>2.0.0-beta2</cryptomator.fuse.version>
<cryptomator.dokany.version>2.0.0-beta1</cryptomator.dokany.version>
<cryptomator.webdav.version>2.0.0-beta1</cryptomator.webdav.version>
<cryptomator.cryptofs.version>2.6.6</cryptomator.cryptofs.version>
<cryptomator.integrations.version>1.2.0</cryptomator.integrations.version>
<cryptomator.integrations.win.version>1.2.0</cryptomator.integrations.win.version>
<cryptomator.integrations.mac.version>1.2.0</cryptomator.integrations.mac.version>
<cryptomator.integrations.linux.version>1.2.1</cryptomator.integrations.linux.version>
<cryptomator.fuse.version>3.0.0</cryptomator.fuse.version>
<cryptomator.dokany.version>2.0.0</cryptomator.dokany.version>
<cryptomator.webdav.version>2.0.3</cryptomator.webdav.version>
<!-- 3rd party dependencies -->
<commons-lang3.version>3.12.0</commons-lang3.version>
<dagger.version>2.44</dagger.version>
<dagger.version>2.45</dagger.version>
<easybind.version>2.2</easybind.version>
<guava.version>31.1-jre</guava.version>
<gson.version>2.9.1</gson.version>
<javafx.version>19</javafx.version>
<jwt.version>4.2.1</jwt.version>
<nimbus-jose.version>9.25.4</nimbus-jose.version>
<logback.version>1.4.4</logback.version>
<slf4j.version>2.0.3</slf4j.version>
<guava.version>32.0.1-jre</guava.version>
<jackson.version>2.15.2</jackson.version>
<javafx.version>20.0.1</javafx.version>
<jwt.version>4.4.0</jwt.version>
<nimbus-jose.version>9.31</nimbus-jose.version>
<logback.version>1.4.7</logback.version>
<slf4j.version>2.0.7</slf4j.version>
<tinyoauth2.version>0.5.1</tinyoauth2.version>
<zxcvbn.version>1.7.0</zxcvbn.version>
<!-- test dependencies -->
<junit.jupiter.version>5.9.1</junit.jupiter.version>
<mockito.version>4.8.0</mockito.version>
<junit.jupiter.version>5.9.3</junit.jupiter.version>
<mockito.version>5.3.1</mockito.version>
<hamcrest.version>2.2</hamcrest.version>
<!-- build-time dependencies -->
<jetbrains.annotations.version>23.0.0</jetbrains.annotations.version>
<dependency-check.version>7.4.0</dependency-check.version>
<jacoco.version>0.8.8</jacoco.version>
<dependency-check.version>8.1.2</dependency-check.version>
<jacoco.version>0.8.9</jacoco.version>
</properties>
<dependencies>
@@ -152,6 +157,11 @@
<artifactId>nimbus-jose-jwt</artifactId>
<version>${nimbus-jose.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
<!-- EasyBind -->
<dependency>
@@ -201,11 +211,6 @@
<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>
@@ -312,41 +317,6 @@
</compilerArgs>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<id>compile-light-theme</id>
<phase>compile</phase>
<goals>
<goal>java</goal>
</goals>
<configuration>
<mainClass>javafx.graphics/com.sun.javafx.css.parser.Css2Bin</mainClass>
<arguments>
<arg>${project.basedir}/src/main/resources/css/light_theme.css</arg>
<arg>${project.build.outputDirectory}/css/light_theme.bss</arg>
</arguments>
</configuration>
</execution>
<execution>
<id>compile-dark-theme</id>
<phase>compile</phase>
<goals>
<goal>java</goal>
</goals>
<configuration>
<mainClass>javafx.graphics/com.sun.javafx.css.parser.Css2Bin</mainClass>
<arguments>
<arg>${project.basedir}/src/main/resources/css/dark_theme.css</arg>
<arg>${project.build.outputDirectory}/css/dark_theme.bss</arg>
</arguments>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
@@ -362,6 +332,9 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<argLine>--enable-preview</argLine>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
+24 -1
View File
@@ -1,4 +1,17 @@
import ch.qos.logback.classic.spi.Configurator;
import org.cryptomator.common.locationpresets.DropboxLinuxLocationPresetsProvider;
import org.cryptomator.common.locationpresets.DropboxMacLocationPresetsProvider;
import org.cryptomator.common.locationpresets.DropboxWindowsLocationPresetsProvider;
import org.cryptomator.common.locationpresets.GoogleDriveLocationPresetsProvider;
import org.cryptomator.common.locationpresets.ICloudMacLocationPresetsProvider;
import org.cryptomator.common.locationpresets.ICloudWindowsLocationPresetsProvider;
import org.cryptomator.common.locationpresets.LeitzcloudLocationPresetsProvider;
import org.cryptomator.common.locationpresets.LocationPresetsProvider;
import org.cryptomator.common.locationpresets.MegaLocationPresetsProvider;
import org.cryptomator.common.locationpresets.OneDriveLinuxLocationPresetsProvider;
import org.cryptomator.common.locationpresets.OneDriveMacLocationPresetsProvider;
import org.cryptomator.common.locationpresets.OneDriveWindowsLocationPresetsProvider;
import org.cryptomator.common.locationpresets.PCloudLocationPresetsProvider;
import org.cryptomator.integrations.tray.TrayMenuController;
import org.cryptomator.logging.LogbackConfiguratorFactory;
import org.cryptomator.ui.traymenu.AwtTrayMenuController;
@@ -25,7 +38,7 @@ open module org.cryptomator.desktop {
requires ch.qos.logback.core;
requires com.auth0.jwt;
requires com.google.common;
requires com.google.gson;
requires com.fasterxml.jackson.databind;
requires com.nimbusds.jose.jwt;
requires com.nulabinc.zxcvbn;
requires com.tobiasdiez.easybind;
@@ -37,6 +50,16 @@ open module org.cryptomator.desktop {
/* TODO: filename-based modules: */
requires static javax.inject; /* ugly dagger/guava crap */
uses org.cryptomator.common.locationpresets.LocationPresetsProvider;
provides TrayMenuController with AwtTrayMenuController;
provides Configurator with LogbackConfiguratorFactory;
provides LocationPresetsProvider with //
DropboxWindowsLocationPresetsProvider, DropboxMacLocationPresetsProvider, DropboxLinuxLocationPresetsProvider, //
GoogleDriveLocationPresetsProvider, //
ICloudWindowsLocationPresetsProvider, ICloudMacLocationPresetsProvider, //
LeitzcloudLocationPresetsProvider, //
MegaLocationPresetsProvider, //
OneDriveWindowsLocationPresetsProvider, OneDriveMacLocationPresetsProvider, OneDriveLinuxLocationPresetsProvider, //
PCloudLocationPresetsProvider;
}
@@ -16,6 +16,7 @@ import org.cryptomator.common.settings.SettingsProvider;
import org.cryptomator.common.vaults.VaultComponent;
import org.cryptomator.common.vaults.VaultListModule;
import org.cryptomator.cryptolib.common.MasterkeyFileAccess;
import org.cryptomator.integrations.revealpath.RevealPathService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -26,6 +27,7 @@ import java.net.InetSocketAddress;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Comparator;
import java.util.Optional;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.SynchronousQueue;
@@ -83,6 +85,13 @@ public abstract class CommonsModule {
return new SemVerComparator();
}
@Provides
@Singleton
static Optional<RevealPathService> provideRevealPathService() {
return RevealPathService.get().findFirst();
}
@Provides
@Singleton
static Settings provideSettings(SettingsProvider settingsProvider) {
@@ -130,9 +139,9 @@ public abstract class CommonsModule {
@Provides
@Singleton
static ObservableValue<InetSocketAddress> provideServerSocketAddressBinding(Settings settings) {
return settings.port().map(port -> {
return settings.port.map(port -> {
String host = SystemUtils.IS_OS_WINDOWS ? "127.0.0.1" : "localhost";
return InetSocketAddress.createUnresolved(host, settings.port().intValue());
return InetSocketAddress.createUnresolved(host, settings.port.intValue());
});
}
@@ -1,5 +1,9 @@
package org.cryptomator.common;
import org.cryptomator.ui.keyloading.masterkeyfile.MasterkeyFileLoadingStrategy;
import java.net.URI;
public interface Constants {
String MASTERKEY_FILENAME = "masterkey.cryptomator";
@@ -7,6 +11,7 @@ public interface Constants {
String VAULTCONFIG_FILENAME = "vault.cryptomator";
String CRYPTOMATOR_FILENAME_EXT = ".cryptomator";
String CRYPTOMATOR_FILENAME_GLOB = "*.cryptomator";
URI DEFAULT_KEY_ID = URI.create(MasterkeyFileLoadingStrategy.SCHEME + ":" + MASTERKEY_FILENAME);
byte[] PEPPER = new byte[0];
}
@@ -18,8 +18,6 @@ import java.util.stream.StreamSupport;
public class Environment {
private static final Logger LOG = LoggerFactory.getLogger(Environment.class);
private static final Path RELATIVE_HOME_DIR = Paths.get("~");
private static final char PATH_LIST_SEP = ':';
private static final int DEFAULT_MIN_PW_LENGTH = 8;
private static final String SETTINGS_PATH_PROP_NAME = "cryptomator.settingsPath";
private static final String IPC_SOCKET_PATH_PROP_NAME = "cryptomator.ipcSocketPath";
@@ -80,7 +78,7 @@ public class Environment {
return getPaths(P12_PATH_PROP_NAME);
}
public Stream<Path> ipcSocketPath() {
public Stream<Path> getIpcSocketPath() {
return getPaths(IPC_SOCKET_PATH_PROP_NAME);
}
@@ -89,7 +87,7 @@ public class Environment {
}
public Optional<Path> getLogDir() {
return getPath(LOG_DIR_PROP_NAME).map(this::replaceHomeDir);
return getPath(LOG_DIR_PROP_NAME);
}
public Optional<String> getLoopbackAlias() {
@@ -97,11 +95,11 @@ public class Environment {
}
public Optional<Path> getPluginDir() {
return getPath(PLUGIN_DIR_PROP_NAME).map(this::replaceHomeDir);
return getPath(PLUGIN_DIR_PROP_NAME);
}
public Optional<Path> getMountPointsDir() {
return getPath(MOUNTPOINT_DIR_PROP_NAME).map(this::replaceHomeDir);
return getPath(MOUNTPOINT_DIR_PROP_NAME);
}
/**
@@ -131,22 +129,9 @@ public class Environment {
}
// 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 getHomeDir().resolve(RELATIVE_HOME_DIR.relativize(path));
} else {
return path;
}
Stream<Path> getPaths(String propertyName) {
Stream<String> rawSettingsPaths = getRawList(propertyName, System.getProperty("path.separator").charAt(0));
return rawSettingsPaths.filter(Predicate.not(Strings::isNullOrEmpty)).map(Path::of);
}
private Stream<String> getRawList(String propertyName, char separator) {
@@ -32,18 +32,15 @@ public class ErrorCode {
this.rootCauseSpecificFrames = rootCauseSpecificFrames;
}
// visible for testing
String methodCode() {
public String methodCode() {
return format(traceCode(rootCause, LATEST_FRAME));
}
// visible for testing
String rootCauseCode() {
public String rootCauseCode() {
return format(traceCode(rootCause, rootCauseSpecificFrames));
}
// visible for testing
String throwableCode() {
public String throwableCode() {
return format(traceCode(throwable, ALL_FRAMES));
}
@@ -30,7 +30,7 @@ public class LicenseHolder {
this.licenseSubject = validJwtClaims.map(DecodedJWT::getSubject);
this.validLicenseProperty = validJwtClaims.isNotNull();
Optional<DecodedJWT> claims = licenseChecker.check(settings.licenseKey().get());
Optional<DecodedJWT> claims = licenseChecker.check(settings.licenseKey.get());
validJwtClaims.set(claims.orElse(null));
}
@@ -38,7 +38,7 @@ public class LicenseHolder {
Optional<DecodedJWT> claims = licenseChecker.check(licenseKey);
validJwtClaims.set(claims.orElse(null));
if (claims.isPresent()) {
settings.licenseKey().set(licenseKey);
settings.licenseKey.set(licenseKey);
return true;
} else {
return false;
@@ -1,64 +0,0 @@
package org.cryptomator.common;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.List;
/**
* Enum of common cloud providers and their default local storage location path.
*/
public enum LocationPreset {
DROPBOX("Dropbox", "~/Dropbox"),
ICLOUDDRIVE("iCloud Drive", "~/Library/Mobile Documents/com~apple~CloudDocs", "~/iCloudDrive"),
GDRIVE("Google Drive", "~/Google Drive/My Drive", "~/Google Drive"),
MEGA("MEGA", "~/MEGA"),
ONEDRIVE("OneDrive", "~/OneDrive"),
PCLOUD("pCloud", "~/pCloudDrive"),
LOCAL("local");
private final String name;
private final List<Path> candidates;
LocationPreset(String name, String... candidates) {
this.name = name;
this.candidates = Arrays.stream(candidates).map(UserHome::resolve).map(Path::of).toList();
}
/**
* Checks for this LocationPreset if any of the associated paths exist.
*
* @return the first existing path or null, if none exists.
*/
public Path existingPath() {
return candidates.stream().filter(Files::isDirectory).findFirst().orElse(null);
}
public String getDisplayName() {
return name;
}
@Override
public String toString() {
return getDisplayName();
}
//this contruct is needed, since static members are initialized after every enum member is initialized
//TODO: refactor this to normal class and use this also in different parts of the project
private static class UserHome {
private static final String USER_HOME = System.getProperty("user.home");
private static String resolve(String path) {
if (path.startsWith("~/")) {
return UserHome.USER_HOME + path.substring(1);
} else {
return path;
}
}
}
}
@@ -0,0 +1,30 @@
package org.cryptomator.common;
import javafx.beans.binding.Bindings;
import javafx.beans.value.ObservableValue;
import java.util.Objects;
import java.util.function.Function;
import java.util.function.Supplier;
public class ObservableUtil {
public static <T, U> ObservableValue<U> mapWithDefault(ObservableValue<T> observable, Function<? super T, ? extends U> mapper, U defaultValue) {
return Bindings.createObjectBinding(() -> {
if (observable.getValue() == null) {
return defaultValue;
} else {
return mapper.apply(observable.getValue());
}
}, observable);
}
public static <T, U> ObservableValue<U> mapWithDefault(ObservableValue<T> observable, Function<? super T, ? extends U> mapper, Supplier<U> defaultValue) {
return Bindings.createObjectBinding(() -> {
if (observable.getValue() == null) {
return defaultValue.get();
} else {
return mapper.apply(observable.getValue());
}
}, observable);
}
}
@@ -0,0 +1,171 @@
package org.cryptomator.common;
import org.jetbrains.annotations.Nullable;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.io.Reader;
import java.io.Writer;
import java.nio.charset.Charset;
import java.util.Collection;
import java.util.Enumeration;
import java.util.InvalidPropertiesFormatException;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Function;
class PropertiesDecorator extends Properties {
protected final Properties delegate;
PropertiesDecorator(Properties delegate) {
this.delegate = delegate;
}
@Override
public String getProperty(String key) {return delegate.getProperty(key);}
@Override
public String getProperty(String key, String defaultValue) {return delegate.getProperty(key, defaultValue);}
@Override
public synchronized Object setProperty(String key, String value) {
return delegate.setProperty(key, value);
}
@Override
public synchronized void load(Reader reader) throws IOException {delegate.load(reader);}
@Override
public synchronized void load(InputStream inStream) throws IOException {delegate.load(inStream);}
@Override
public void store(Writer writer, String comments) throws IOException {delegate.store(writer, comments);}
@Override
public void store(OutputStream out, @Nullable String comments) throws IOException {delegate.store(out, comments);}
@Override
public synchronized void loadFromXML(InputStream in) throws IOException, InvalidPropertiesFormatException {delegate.loadFromXML(in);}
@Override
public void storeToXML(OutputStream os, String comment) throws IOException {delegate.storeToXML(os, comment);}
@Override
public void storeToXML(OutputStream os, String comment, String encoding) throws IOException {delegate.storeToXML(os, comment, encoding);}
@Override
public void storeToXML(OutputStream os, String comment, Charset charset) throws IOException {delegate.storeToXML(os, comment, charset);}
@Override
public Enumeration<?> propertyNames() {return delegate.propertyNames();}
@Override
public Set<String> stringPropertyNames() {return delegate.stringPropertyNames();}
@Override
public void list(PrintStream out) {delegate.list(out);}
@Override
public void list(PrintWriter out) {delegate.list(out);}
@Override
public int size() {return delegate.size();}
@Override
public boolean isEmpty() {return delegate.isEmpty();}
@Override
public Enumeration<Object> keys() {return delegate.keys();}
@Override
public Enumeration<Object> elements() {return delegate.elements();}
@Override
public boolean contains(Object value) {return delegate.contains(value);}
@Override
public boolean containsValue(Object value) {return delegate.containsValue(value);}
@Override
public boolean containsKey(Object key) {return delegate.containsKey(key);}
@Override
public Object get(Object key) {return delegate.get(key);}
@Override
public synchronized Object put(Object key, Object value) {return delegate.put(key, value);}
@Override
public synchronized Object remove(Object key) {return delegate.remove(key);}
@Override
public synchronized void putAll(Map<?, ?> t) {delegate.putAll(t);}
@Override
public synchronized void clear() {delegate.clear();}
@Override
public synchronized String toString() {return delegate.toString();}
@Override
public Set<Object> keySet() {return delegate.keySet();}
@Override
public Collection<Object> values() {return delegate.values();}
@Override
public Set<Map.Entry<Object, Object>> entrySet() {return delegate.entrySet();}
@Override
public synchronized boolean equals(Object o) {return delegate.equals(o);}
@Override
public synchronized int hashCode() {return delegate.hashCode();}
@Override
public Object getOrDefault(Object key, Object defaultValue) {return delegate.getOrDefault(key, defaultValue);}
@Override
public synchronized void forEach(BiConsumer<? super Object, ? super Object> action) {delegate.forEach(action);}
@Override
public synchronized void replaceAll(BiFunction<? super Object, ? super Object, ?> function) {delegate.replaceAll(function);}
@Override
public synchronized Object putIfAbsent(Object key, Object value) {return delegate.putIfAbsent(key, value);}
@Override
public synchronized boolean remove(Object key, Object value) {return delegate.remove(key, value);}
@Override
public synchronized boolean replace(Object key, Object oldValue, Object newValue) {return delegate.replace(key, oldValue, newValue);}
@Override
public synchronized Object replace(Object key, Object value) {return delegate.replace(key, value);}
@Override
public synchronized Object computeIfAbsent(Object key, Function<? super Object, ?> mappingFunction) {return delegate.computeIfAbsent(key, mappingFunction);}
@Override
public synchronized Object computeIfPresent(Object key, BiFunction<? super Object, ? super Object, ?> remappingFunction) {return delegate.computeIfPresent(key, remappingFunction);}
@Override
public synchronized Object compute(Object key, BiFunction<? super Object, ? super Object, ?> remappingFunction) {return delegate.compute(key, remappingFunction);}
@Override
public synchronized Object merge(Object key, Object value, BiFunction<? super Object, ? super Object, ?> remappingFunction) {return delegate.merge(key, value, remappingFunction);}
@Override
public synchronized Object clone() {
var delegateClone = (Properties) delegate.clone();
return new PropertiesDecorator(delegateClone);
}
}
@@ -0,0 +1,70 @@
package org.cryptomator.common;
import org.jetbrains.annotations.VisibleForTesting;
import org.slf4j.LoggerFactory;
import java.util.Map;
import java.util.Properties;
import java.util.regex.Pattern;
public class SubstitutingProperties extends PropertiesDecorator {
private static final Pattern TEMPLATE = Pattern.compile("@\\{(\\w+)}");
private final Map<String, String> env;
public SubstitutingProperties(Properties props, Map<String, String> systemEnvironment) {
super(props);
this.env = systemEnvironment;
}
@Override
public String getProperty(String key) {
var value = delegate.getProperty(key);
if (key.startsWith("cryptomator.") && value != null) {
return process(value);
} else {
return value;
}
}
@Override
public String getProperty(String key, String defaultValue) {
var result = getProperty(key);
return result != null ? result : defaultValue;
}
@VisibleForTesting
String process(String value) {
return TEMPLATE.matcher(value).replaceAll(match -> //
switch (match.group(1)) {
case "appdir" -> resolveFrom("APPDIR", Source.ENV);
case "appdata" -> resolveFrom("APPDATA", Source.ENV);
case "localappdata" -> resolveFrom("LOCALAPPDATA", Source.ENV);
case "userhome" -> resolveFrom("user.home", Source.PROPS);
default -> {
LoggerFactory.getLogger(SubstitutingProperties.class).warn("Unknown variable {} in property value {}.", match.group(), value);
yield match.group();
}
});
}
private String resolveFrom(String key, Source src) {
var val = switch (src) {
case ENV -> env.get(key);
case PROPS -> delegate.getProperty(key);
};
if (val == null) {
LoggerFactory.getLogger(SubstitutingProperties.class).warn("Variable {} used for substitution not found in {}. Replaced with empty string.", key, src);
return "";
} else {
return val.replace("\\", "\\\\");
}
}
private enum Source {
ENV,
PROPS;
}
}
@@ -23,14 +23,14 @@ public class KeychainModule {
@Singleton
static ObjectExpression<KeychainAccessProvider> provideKeychainAccessProvider(Settings settings, List<KeychainAccessProvider> providers) {
return Bindings.createObjectBinding(() -> {
if (!settings.useKeychain().get()) {
if (!settings.useKeychain.get()) {
return null;
}
var selectedProviderClass = settings.keychainProvider().get();
var selectedProviderClass = settings.keychainProvider.get();
var selectedProvider = providers.stream().filter(provider -> provider.getClass().getName().equals(selectedProviderClass)).findAny();
var fallbackProvider = providers.stream().findFirst().orElse(null);
return selectedProvider.orElse(fallbackProvider);
}, settings.keychainProvider(), settings.useKeychain());
}, settings.keychainProvider, settings.useKeychain);
}
}
@@ -0,0 +1,32 @@
package org.cryptomator.common.locationpresets;
import org.cryptomator.integrations.common.OperatingSystem;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.function.Predicate;
import java.util.regex.Pattern;
import java.util.stream.Stream;
import static org.cryptomator.integrations.common.OperatingSystem.Value.LINUX;
@OperatingSystem(LINUX)
public final class DropboxLinuxLocationPresetsProvider implements LocationPresetsProvider {
private static final Path USER_HOME = LocationPresetsProvider.resolveLocation("~/.").toAbsolutePath();
private static final Predicate<String> PATTERN = Pattern.compile("Dropbox \\(.+\\)").asMatchPredicate();
@Override
public Stream<LocationPreset> getLocations() {
try (var dirStream = Files.list(USER_HOME)) {
var presets = dirStream.filter(p -> Files.isDirectory(p) && PATTERN.test(p.getFileName().toString())) //
.map(p -> new LocationPreset(p.getFileName().toString(), p)) //
.toList();
return presets.stream(); //workaround to ensure that the directory stream is always closed
} catch (IOException | UncheckedIOException e) { //UncheckedIOException thrown by the stream of Files.list()
return Stream.of();
}
}
}
@@ -0,0 +1,35 @@
package org.cryptomator.common.locationpresets;
import org.cryptomator.integrations.common.CheckAvailability;
import org.cryptomator.integrations.common.OperatingSystem;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.stream.Stream;
import static org.cryptomator.integrations.common.OperatingSystem.Value.MAC;
@OperatingSystem(MAC)
@CheckAvailability
public final class DropboxMacLocationPresetsProvider implements LocationPresetsProvider {
private static final Path LOCATION = LocationPresetsProvider.resolveLocation("~/Library/CloudStorage/Dropbox");
private static final Path FALLBACK_LOCATION = LocationPresetsProvider.resolveLocation("~/Dropbox");
@CheckAvailability
public static boolean isPresent() {
return Files.isDirectory(LOCATION) || Files.isDirectory(FALLBACK_LOCATION);
}
@Override
public Stream<LocationPreset> getLocations() {
if(Files.isDirectory(LOCATION)) {
return Stream.of(new LocationPreset("Dropbox", LOCATION));
} else if(Files.isDirectory(FALLBACK_LOCATION)) {
return Stream.of(new LocationPreset("Dropbox", FALLBACK_LOCATION));
} else {
return Stream.of();
}
}
}
@@ -0,0 +1,28 @@
package org.cryptomator.common.locationpresets;
import org.cryptomator.integrations.common.CheckAvailability;
import org.cryptomator.integrations.common.OperatingSystem;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.stream.Stream;
import static org.cryptomator.integrations.common.OperatingSystem.Value.WINDOWS;
@OperatingSystem(WINDOWS)
@CheckAvailability
public final class DropboxWindowsLocationPresetsProvider implements LocationPresetsProvider {
private static final Path LOCATION = LocationPresetsProvider.resolveLocation("~/Dropbox");
@CheckAvailability
public static boolean isPresent() {
return Files.isDirectory(LOCATION);
}
@Override
public Stream<LocationPreset> getLocations() {
return Stream.of(new LocationPreset("Dropbox", LOCATION));
}
}
@@ -0,0 +1,41 @@
package org.cryptomator.common.locationpresets;
import org.cryptomator.integrations.common.CheckAvailability;
import org.cryptomator.integrations.common.OperatingSystem;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
import static org.cryptomator.integrations.common.OperatingSystem.Value.MAC;
import static org.cryptomator.integrations.common.OperatingSystem.Value.WINDOWS;
@OperatingSystem(WINDOWS)
@OperatingSystem(MAC)
@CheckAvailability
public final class GoogleDriveLocationPresetsProvider implements LocationPresetsProvider {
private static final List<Path> LOCATIONS = Arrays.asList( //
LocationPresetsProvider.resolveLocation("~/GoogleDrive/My Drive"), //
LocationPresetsProvider.resolveLocation("~/Google Drive/My Drive"), //
LocationPresetsProvider.resolveLocation("~/GoogleDrive"), //
LocationPresetsProvider.resolveLocation("~/Google Drive") //
);
@CheckAvailability
public static boolean isPresent() {
return LOCATIONS.stream().anyMatch(Files::isDirectory);
}
@Override
public Stream<LocationPreset> getLocations() {
return LOCATIONS.stream() //
.filter(Files::isDirectory) //
.map(location -> new LocationPreset("Google Drive", location)) //
.findFirst() //
.stream();
}
}
@@ -0,0 +1,27 @@
package org.cryptomator.common.locationpresets;
import org.cryptomator.integrations.common.CheckAvailability;
import org.cryptomator.integrations.common.OperatingSystem;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.stream.Stream;
import static org.cryptomator.integrations.common.OperatingSystem.Value.MAC;
@OperatingSystem(MAC)
@CheckAvailability
public final class ICloudMacLocationPresetsProvider implements LocationPresetsProvider {
private static final Path LOCATION = LocationPresetsProvider.resolveLocation("~/Library/Mobile Documents/com~apple~CloudDocs");
@CheckAvailability
public static boolean isPresent() {
return Files.isDirectory(LOCATION);
}
@Override
public Stream<LocationPreset> getLocations() {
return Stream.of(new LocationPreset("iCloud Drive", LOCATION));
}
}
@@ -0,0 +1,27 @@
package org.cryptomator.common.locationpresets;
import org.cryptomator.integrations.common.CheckAvailability;
import org.cryptomator.integrations.common.OperatingSystem;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.stream.Stream;
import static org.cryptomator.integrations.common.OperatingSystem.Value.WINDOWS;
@OperatingSystem(WINDOWS)
@CheckAvailability
public final class ICloudWindowsLocationPresetsProvider implements LocationPresetsProvider {
private static final Path LOCATION = LocationPresetsProvider.resolveLocation("~/iCloudDrive");
@CheckAvailability
public static boolean isPresent() {
return Files.isDirectory(LOCATION);
}
@Override
public Stream<LocationPreset> getLocations() {
return Stream.of(new LocationPreset("iCloud Drive", LOCATION));
}
}
@@ -0,0 +1,30 @@
package org.cryptomator.common.locationpresets;
import org.cryptomator.integrations.common.CheckAvailability;
import org.cryptomator.integrations.common.OperatingSystem;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.stream.Stream;
import static org.cryptomator.integrations.common.OperatingSystem.Value.MAC;
import static org.cryptomator.integrations.common.OperatingSystem.Value.WINDOWS;
@OperatingSystem(WINDOWS)
@OperatingSystem(MAC)
@CheckAvailability
public final class LeitzcloudLocationPresetsProvider implements LocationPresetsProvider {
private static final Path LOCATION = LocationPresetsProvider.resolveLocation("~/leitzcloud");
@CheckAvailability
public static boolean isPresent() {
return Files.isDirectory(LOCATION);
}
@Override
public Stream<LocationPreset> getLocations() {
return Stream.of(new LocationPreset("leitzcloud", LOCATION));
}
}
@@ -0,0 +1,9 @@
package org.cryptomator.common.locationpresets;
import java.nio.file.Path;
public record LocationPreset(String name, Path path) {
}
@@ -0,0 +1,97 @@
package org.cryptomator.common.locationpresets;
import org.cryptomator.integrations.common.CheckAvailability;
import org.cryptomator.integrations.common.IntegrationsLoader;
import org.cryptomator.integrations.common.OperatingSystem;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.ServiceLoader;
import java.util.stream.Stream;
public interface LocationPresetsProvider {
Logger LOG = LoggerFactory.getLogger(LocationPresetsProvider.class);
String USER_HOME = System.getProperty("user.home");
/**
* Streams account-separated location presets found by this provider
* @return Stream of LocationPresets
*/
Stream<LocationPreset> getLocations();
static Path resolveLocation(String p) {
if (p.startsWith("~/")) {
return Path.of(USER_HOME, p.substring(2));
} else {
return Path.of(p);
}
}
//copied from org.cryptomator.integrations.common.IntegrationsLoader
//TODO: delete, once migrated to integrations-api
static <T> Stream<T> loadAll(Class<T> clazz) {
return ServiceLoader.load(clazz)
.stream()
.filter(LocationPresetsProvider::isSupportedOperatingSystem)
.filter(LocationPresetsProvider::passesStaticAvailabilityCheck)
.map(ServiceLoader.Provider::get)
.peek(impl -> logServiceIsAvailable(clazz, impl.getClass()));
}
private static boolean isSupportedOperatingSystem(ServiceLoader.Provider<?> provider) {
var annotations = provider.type().getAnnotationsByType(OperatingSystem.class);
return annotations.length == 0 || Arrays.stream(annotations).anyMatch(OperatingSystem.Value::isCurrent);
}
private static boolean passesStaticAvailabilityCheck(ServiceLoader.Provider<?> provider) {
return passesStaticAvailabilityCheck(provider.type());
}
static boolean passesStaticAvailabilityCheck(Class<?> type) {
return passesAvailabilityCheck(type, null);
}
private static void logServiceIsAvailable(Class<?> apiType, Class<?> implType) {
if (LOG.isDebugEnabled()) {
LOG.debug("{}: Implementation is available: {}", apiType.getSimpleName(), implType.getName());
}
}
private static <T> boolean passesAvailabilityCheck(Class<? extends T> type, @Nullable T instance) {
if (!type.isAnnotationPresent(CheckAvailability.class)) {
return true; // if type is not annotated, skip tests
}
if (!type.getModule().isExported(type.getPackageName(), IntegrationsLoader.class.getModule())) {
LOG.error("Can't run @CheckAvailability tests for class {}. Make sure to export {} to {}!", type.getName(), type.getPackageName(), IntegrationsLoader.class.getPackageName());
return false;
}
return Arrays.stream(type.getMethods())
.filter(m -> isAvailabilityCheck(m, instance == null))
.allMatch(m -> passesAvailabilityCheck(m, instance));
}
private static boolean passesAvailabilityCheck(Method m, @Nullable Object instance) {
assert Boolean.TYPE.equals(m.getReturnType());
try {
return (boolean) m.invoke(instance);
} catch (ReflectiveOperationException e) {
LOG.warn("Failed to invoke @CheckAvailability test {}#{}", m.getDeclaringClass(), m.getName(), e);
return false;
}
}
private static boolean isAvailabilityCheck(Method m, boolean isStatic) {
return m.isAnnotationPresent(CheckAvailability.class)
&& Boolean.TYPE.equals(m.getReturnType())
&& m.getParameterCount() == 0
&& Modifier.isStatic(m.getModifiers()) == isStatic;
}
}
@@ -0,0 +1,29 @@
package org.cryptomator.common.locationpresets;
import org.cryptomator.integrations.common.CheckAvailability;
import org.cryptomator.integrations.common.OperatingSystem;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.stream.Stream;
import static org.cryptomator.integrations.common.OperatingSystem.Value.MAC;
import static org.cryptomator.integrations.common.OperatingSystem.Value.WINDOWS;
@OperatingSystem(WINDOWS)
@OperatingSystem(MAC)
@CheckAvailability
public final class MegaLocationPresetsProvider implements LocationPresetsProvider {
private static final Path LOCATION = LocationPresetsProvider.resolveLocation("~/MEGA");
@CheckAvailability
public static boolean isPresent() {
return Files.isDirectory(LOCATION);
}
@Override
public Stream<LocationPreset> getLocations() {
return Stream.of(new LocationPreset("MEGA", LOCATION));
}
}
@@ -0,0 +1,28 @@
package org.cryptomator.common.locationpresets;
import org.cryptomator.integrations.common.CheckAvailability;
import org.cryptomator.integrations.common.OperatingSystem;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.stream.Stream;
import static org.cryptomator.integrations.common.OperatingSystem.Value.LINUX;
@OperatingSystem(LINUX)
@CheckAvailability
public final class OneDriveLinuxLocationPresetsProvider implements LocationPresetsProvider {
private static final Path LOCATION = LocationPresetsProvider.resolveLocation("~/OneDrive");
@CheckAvailability
public static boolean isPresent() {
return Files.isDirectory(LOCATION);
}
@Override
public Stream<LocationPreset> getLocations() {
return Stream.of(new LocationPreset("OneDrive", LOCATION));
}
}
@@ -0,0 +1,44 @@
package org.cryptomator.common.locationpresets;
import org.cryptomator.integrations.common.OperatingSystem;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
import static org.cryptomator.integrations.common.OperatingSystem.Value.MAC;
@OperatingSystem(MAC)
public final class OneDriveMacLocationPresetsProvider implements LocationPresetsProvider {
private static final Path FALLBACK_LOCATION = LocationPresetsProvider.resolveLocation("~/OneDrive");
private static final Path PARENT_LOCATION = LocationPresetsProvider.resolveLocation("~/Library/CloudStorage");
@Override
public Stream<LocationPreset> getLocations() {
var newLocations = getNewLocations().toList();
if (newLocations.size() >= 1) {
return newLocations.stream();
} else {
return getOldLocation();
}
}
private Stream<LocationPreset> getNewLocations() {
try (var dirStream = Files.newDirectoryStream(PARENT_LOCATION, "OneDrive*")) {
return StreamSupport.stream(dirStream.spliterator(), false) //
.filter(Files::isDirectory) //
.map(p -> new LocationPreset(String.join(" - ", p.getFileName().toString().split("-")), p));
} catch (IOException e) {
return Stream.of();
}
}
private Stream<LocationPreset> getOldLocation() {
return Stream.of(new LocationPreset("OneDrive", FALLBACK_LOCATION)).filter(preset -> Files.isDirectory(preset.path()));
}
}
@@ -0,0 +1,108 @@
package org.cryptomator.common.locationpresets;
import org.cryptomator.integrations.common.OperatingSystem;
import org.jetbrains.annotations.Blocking;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static org.cryptomator.integrations.common.OperatingSystem.Value.WINDOWS;
@OperatingSystem(WINDOWS)
public final class OneDriveWindowsLocationPresetsProvider implements LocationPresetsProvider {
private static final Logger LOG = LoggerFactory.getLogger(OneDriveWindowsLocationPresetsProvider.class);
private static final String REGSTR_TOKEN = "REG_SZ";
private static final String REG_ONEDRIVE_ACCOUNTS = "HKEY_CURRENT_USER\\Software\\Microsoft\\OneDrive\\Accounts\\";
@Override
public Stream<LocationPreset> getLocations() {
try {
var accountRegKeys = queryRegistry(REG_ONEDRIVE_ACCOUNTS, List.of(), l -> l.startsWith(REG_ONEDRIVE_ACCOUNTS)).toList();
var cloudLocations = new ArrayList<LocationPreset>();
for (var accountRegKey : accountRegKeys) {
var path = queryRegistry(accountRegKey, List.of("/v", "UserFolder"), l -> l.contains("UserFolder")).map(result -> result.substring(result.indexOf(REGSTR_TOKEN) + REGSTR_TOKEN.length()).trim()) //
.map(Path::of) //
.findFirst().orElseThrow();
var name = "OneDrive"; //we assume personal oneDrive account by default
if (!accountRegKey.endsWith("Personal")) {
name = queryRegistry(accountRegKey, List.of("/v", "DisplayName"), l -> l.contains("DisplayName")).map(result -> result.substring(result.indexOf(REGSTR_TOKEN) + REGSTR_TOKEN.length()).trim()) //
.map("OneDrive - "::concat) //
.findFirst().orElseThrow();
}
cloudLocations.add(new LocationPreset(name, path));
}
return cloudLocations.stream();
} catch (IOException | CommandFailedException | TimeoutException e) {
LOG.error("Unable to determine OneDrive location", e);
return Stream.of();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
LOG.error("Determination of OneDrive location interrupted", e);
return Stream.of();
}
}
private Stream<String> queryRegistry(String keyname, List<String> moreArgs, Predicate<String> outputFilter) throws InterruptedException, CommandFailedException, TimeoutException, IOException {
var args = new ArrayList<String>();
args.add("reg");
args.add("query");
args.add(keyname);
args.addAll(moreArgs);
ProcessBuilder command = new ProcessBuilder(args);
Process p = command.start();
waitForSuccess(p, 3, "`reg query`");
return p.inputReader(StandardCharsets.UTF_8).lines().filter(outputFilter);
}
/**
* Waits {@code timeoutSeconds} seconds for {@code process} to finish with exit code {@code 0}.
*
* @param process The process to wait for
* @param timeoutSeconds How long to wait (in seconds)
* @param cmdDescription A short description of the process used to generate log and exception messages
* @throws TimeoutException Thrown when the process doesn't finish in time
* @throws InterruptedException Thrown when the thread is interrupted while waiting for the process to finish
* @throws CommandFailedException Thrown when the process exit code is non-zero
*/
@Blocking
private static void waitForSuccess(Process process, int timeoutSeconds, String cmdDescription) throws TimeoutException, InterruptedException, CommandFailedException {
boolean exited = process.waitFor(timeoutSeconds, TimeUnit.SECONDS);
if (!exited) {
throw new TimeoutException(cmdDescription + " timed out after " + timeoutSeconds + "s");
}
if (process.exitValue() != 0) {
@SuppressWarnings("resource") var stdout = process.inputReader(StandardCharsets.UTF_8).lines().collect(Collectors.joining("\n"));
@SuppressWarnings("resource") var stderr = process.errorReader(StandardCharsets.UTF_8).lines().collect(Collectors.joining("\n"));
throw new CommandFailedException(cmdDescription, process.exitValue(), stdout, stderr);
}
}
private static class CommandFailedException extends Exception {
int exitCode;
String stdout;
String stderr;
private CommandFailedException(String cmdDescription, int exitCode, String stdout, String stderr) {
super(cmdDescription + " returned with non-zero exit code " + exitCode);
this.exitCode = exitCode;
this.stdout = stdout;
this.stderr = stderr;
}
}
}
@@ -0,0 +1,39 @@
package org.cryptomator.common.locationpresets;
import org.cryptomator.integrations.common.CheckAvailability;
import org.cryptomator.integrations.common.OperatingSystem;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
import static org.cryptomator.integrations.common.OperatingSystem.Value.MAC;
import static org.cryptomator.integrations.common.OperatingSystem.Value.WINDOWS;
@OperatingSystem(WINDOWS)
@OperatingSystem(MAC)
@CheckAvailability
public final class PCloudLocationPresetsProvider implements LocationPresetsProvider {
private static final List<Path> LOCATIONS = Arrays.asList( //
LocationPresetsProvider.resolveLocation("~/pCloudDrive"), //
LocationPresetsProvider.resolveLocation("~/pCloud Drive") //
);
@CheckAvailability
public static boolean isPresent() {
return LOCATIONS.stream().anyMatch(Files::isDirectory);
}
@Override
public Stream<LocationPreset> getLocations() {
return LOCATIONS.stream() //
.filter(Files::isDirectory) //
.map(location -> new LocationPreset("pCloud", location)) //
.findFirst() //
.stream();
}
}
@@ -0,0 +1,6 @@
package org.cryptomator.common.mount;
import org.cryptomator.integrations.mount.MountService;
public record ActualMountService(MountService service, boolean isDesired) {
}
@@ -0,0 +1,9 @@
package org.cryptomator.common.mount;
public class IllegalMountPointException extends IllegalArgumentException {
public IllegalMountPointException(String msg) {
super(msg);
}
}
@@ -2,16 +2,23 @@ package org.cryptomator.common.mount;
import dagger.Module;
import dagger.Provides;
import org.cryptomator.common.ObservableUtil;
import org.cryptomator.common.settings.Settings;
import org.cryptomator.integrations.mount.Mount;
import org.cryptomator.integrations.mount.MountService;
import javax.inject.Named;
import javax.inject.Singleton;
import javafx.beans.value.ObservableValue;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
@Module
public class MountModule {
private static final AtomicReference<MountService> formerSelectedMountService = new AtomicReference<>(null);
private static final List<String> problematicFuseMountServices = List.of("org.cryptomator.frontend.fuse.mount.MacFuseMountProvider", "org.cryptomator.frontend.fuse.mount.FuseTMountProvider");
@Provides
@Singleton
static List<MountService> provideSupportedMountServices() {
@@ -20,11 +27,46 @@ public class MountModule {
@Provides
@Singleton
static ObservableValue<MountService> provideMountService(Settings settings, List<MountService> serviceImpls) {
return settings.mountService().map(desiredServiceImpl -> {
var fallbackProvider = serviceImpls.stream().findFirst().orElse(null);
return serviceImpls.stream().filter(serviceImpl -> serviceImpl.getClass().getName().equals(desiredServiceImpl)).findAny().orElse(fallbackProvider);
});
@Named("FUPFMS")
static AtomicReference<MountService> provideFirstUsedProblematicFuseMountService() {
return new AtomicReference<>(null);
}
@Provides
@Singleton
static ObservableValue<ActualMountService> provideMountService(Settings settings, List<MountService> serviceImpls, @Named("FUPFMS") AtomicReference<MountService> fupfms) {
var fallbackProvider = serviceImpls.stream().findFirst().orElse(null);
var observableMountService = ObservableUtil.mapWithDefault(settings.mountService, //
desiredServiceImpl -> { //
var serviceFromSettings = serviceImpls.stream().filter(serviceImpl -> serviceImpl.getClass().getName().equals(desiredServiceImpl)).findAny(); //
var targetedService = serviceFromSettings.orElse(fallbackProvider);
return applyWorkaroundForProblematicFuse(targetedService, serviceFromSettings.isPresent(), fupfms);
}, //
() -> { //
return applyWorkaroundForProblematicFuse(fallbackProvider, true, fupfms);
});
return observableMountService;
}
//see https://github.com/cryptomator/cryptomator/issues/2786
private synchronized static ActualMountService applyWorkaroundForProblematicFuse(MountService targetedService, boolean isDesired, AtomicReference<MountService> firstUsedProblematicFuseMountService) {
//set the first used problematic fuse service if applicable
var targetIsProblematicFuse = isProblematicFuseService(targetedService);
if (targetIsProblematicFuse && firstUsedProblematicFuseMountService.get() == null) {
firstUsedProblematicFuseMountService.set(targetedService);
}
//do not use the targeted mount service and fallback to former one, if the service is problematic _and_ not the first problematic one used.
if (targetIsProblematicFuse && !firstUsedProblematicFuseMountService.get().equals(targetedService)) {
return new ActualMountService(formerSelectedMountService.get(), false);
} else {
formerSelectedMountService.set(targetedService);
return new ActualMountService(targetedService, isDesired);
}
}
public static boolean isProblematicFuseService(MountService service) {
return problematicFuseMountServices.contains(service.getClass().getName());
}
}
@@ -0,0 +1,8 @@
package org.cryptomator.common.mount;
public class MountPointInUseException extends IllegalMountPointException {
public MountPointInUseException(String msg) {
super(msg);
}
}
@@ -0,0 +1,8 @@
package org.cryptomator.common.mount;
public class MountPointNotExistsException extends IllegalMountPointException {
public MountPointNotExistsException(String msg) {
super(msg);
}
}
@@ -0,0 +1,8 @@
package org.cryptomator.common.mount;
public class MountPointNotSupportedException extends IllegalMountPointException {
public MountPointNotSupportedException(String msg) {
super(msg);
}
}
@@ -0,0 +1,12 @@
package org.cryptomator.common.mount;
public class MountPointPreparationException extends RuntimeException {
public MountPointPreparationException(String msg) {
super(msg);
}
public MountPointPreparationException(Throwable cause) {
super(cause);
}
}
@@ -0,0 +1,121 @@
package org.cryptomator.common.mount;
import org.apache.commons.lang3.SystemUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.nio.file.DirectoryNotEmptyException;
import java.nio.file.FileAlreadyExistsException;
import java.nio.file.Files;
import java.nio.file.LinkOption;
import java.nio.file.NoSuchFileException;
import java.nio.file.NotDirectoryException;
import java.nio.file.Path;
public final class MountWithinParentUtil {
private static final Logger LOG = LoggerFactory.getLogger(Mounter.class);
private static final String HIDEAWAY_PREFIX = ".~$";
private static final String HIDEAWAY_SUFFIX = ".tmp";
private static final String WIN_HIDDEN_ATTR = "dos:hidden";
private MountWithinParentUtil() {}
static void prepareParentNoMountPoint(Path mountPoint) throws MountPointPreparationException {
Path hideaway = getHideaway(mountPoint);
var mpExists = Files.exists(mountPoint, LinkOption.NOFOLLOW_LINKS);
var hideExists = Files.exists(hideaway, LinkOption.NOFOLLOW_LINKS);
//TODO: possible improvement by just deleting an _empty_ hideaway
if (mpExists && hideExists) { //both resources exist (whatever type)
throw new MountPointPreparationException(new FileAlreadyExistsException(hideaway.toString()));
} else if (!mpExists && !hideExists) { //neither mountpoint nor hideaway exist
throw new MountPointPreparationException(new NoSuchFileException(mountPoint.toString()));
} else if (!mpExists) { //only hideaway exists
checkIsDirectory(hideaway);
LOG.info("Mountpoint {} seems to be not properly cleaned up. Will be fixed on unmount.", mountPoint);
try {
if (SystemUtils.IS_OS_WINDOWS) {
Files.setAttribute(hideaway, WIN_HIDDEN_ATTR, true, LinkOption.NOFOLLOW_LINKS);
}
} catch (IOException e) {
throw new MountPointPreparationException(e);
}
} else { //only mountpoint exists
try {
checkIsDirectory(mountPoint);
checkIsEmpty(mountPoint);
Files.move(mountPoint, hideaway);
if (SystemUtils.IS_OS_WINDOWS) {
Files.setAttribute(hideaway, WIN_HIDDEN_ATTR, true, LinkOption.NOFOLLOW_LINKS);
}
int attempts = 0;
while (!Files.notExists(mountPoint)) {
if (attempts >= 10) {
throw new MountPointPreparationException("Path " + mountPoint + " could not be cleared");
}
Thread.sleep(1000);
attempts++;
}
} catch (IOException e) {
throw new MountPointPreparationException(e);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new MountPointPreparationException(e);
}
}
}
static void cleanup(Path mountPoint) {
Path hideaway = getHideaway(mountPoint);
try {
waitForMountpointRestoration(mountPoint);
Files.move(hideaway, mountPoint);
if (SystemUtils.IS_OS_WINDOWS) {
Files.setAttribute(mountPoint, WIN_HIDDEN_ATTR, false);
}
} catch (IOException e) {
LOG.error("Unable to restore hidden directory to mountpoint {}.", mountPoint, e);
}
}
//on Windows removing the mountpoint takes some time, so we poll for at most 3 seconds
private static void waitForMountpointRestoration(Path mountPoint) throws FileAlreadyExistsException {
int attempts = 0;
while (!Files.notExists(mountPoint, LinkOption.NOFOLLOW_LINKS)) {
attempts++;
if (attempts >= 5) {
throw new FileAlreadyExistsException("Timeout waiting for mountpoint cleanup for " + mountPoint + " .");
}
try {
Thread.sleep(300);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new FileAlreadyExistsException("Interrupted before mountpoint " + mountPoint + " was cleared");
}
}
}
private static void checkIsDirectory(Path toCheck) throws MountPointPreparationException {
if (!Files.isDirectory(toCheck, LinkOption.NOFOLLOW_LINKS)) {
throw new MountPointPreparationException(new NotDirectoryException(toCheck.toString()));
}
}
private static void checkIsEmpty(Path toCheck) throws MountPointPreparationException, IOException {
try (var dirStream = Files.list(toCheck)) {
if (dirStream.findFirst().isPresent()) {
throw new MountPointPreparationException(new DirectoryNotEmptyException(toCheck.toString()));
}
}
}
//visible for testing
static Path getHideaway(Path mountPoint) {
return mountPoint.resolveSibling(HIDEAWAY_PREFIX + mountPoint.getFileName().toString() + HIDEAWAY_SUFFIX);
}
}
@@ -0,0 +1,145 @@
package org.cryptomator.common.mount;
import org.cryptomator.common.Environment;
import org.cryptomator.common.settings.Settings;
import org.cryptomator.common.settings.VaultSettings;
import org.cryptomator.integrations.mount.Mount;
import org.cryptomator.integrations.mount.MountBuilder;
import org.cryptomator.integrations.mount.MountFailedException;
import org.cryptomator.integrations.mount.MountService;
import javax.inject.Inject;
import javax.inject.Singleton;
import javafx.beans.value.ObservableValue;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import static org.cryptomator.integrations.mount.MountCapability.MOUNT_AS_DRIVE_LETTER;
import static org.cryptomator.integrations.mount.MountCapability.MOUNT_TO_EXISTING_DIR;
import static org.cryptomator.integrations.mount.MountCapability.MOUNT_TO_SYSTEM_CHOSEN_PATH;
import static org.cryptomator.integrations.mount.MountCapability.MOUNT_WITHIN_EXISTING_PARENT;
import static org.cryptomator.integrations.mount.MountCapability.UNMOUNT_FORCED;
@Singleton
public class Mounter {
private final Settings settings;
private final Environment env;
private final WindowsDriveLetters driveLetters;
private final ObservableValue<ActualMountService> mountServiceObservable;
@Inject
public Mounter(Settings settings, Environment env, WindowsDriveLetters driveLetters, ObservableValue<ActualMountService> mountServiceObservable) {
this.settings = settings;
this.env = env;
this.driveLetters = driveLetters;
this.mountServiceObservable = mountServiceObservable;
}
private class SettledMounter {
private MountService service;
private MountBuilder builder;
private VaultSettings vaultSettings;
public SettledMounter(MountService service, MountBuilder builder, VaultSettings vaultSettings) {
this.service = service;
this.builder = builder;
this.vaultSettings = vaultSettings;
}
Runnable prepare() throws IOException {
for (var capability : service.capabilities()) {
switch (capability) {
case FILE_SYSTEM_NAME -> builder.setFileSystemName("cryptoFs");
case LOOPBACK_PORT ->
builder.setLoopbackPort(settings.port.get()); //TODO: move port from settings to vaultsettings (see https://github.com/cryptomator/cryptomator/tree/feature/mount-setting-per-vault)
case LOOPBACK_HOST_NAME -> env.getLoopbackAlias().ifPresent(builder::setLoopbackHostName);
case READ_ONLY -> builder.setReadOnly(vaultSettings.usesReadOnlyMode.get());
case MOUNT_FLAGS -> {
var mountFlags = vaultSettings.mountFlags.get();
if (mountFlags == null || mountFlags.isBlank()) {
builder.setMountFlags(service.getDefaultMountFlags());
} else {
builder.setMountFlags(mountFlags);
}
}
case VOLUME_ID -> builder.setVolumeId(vaultSettings.id);
case VOLUME_NAME -> builder.setVolumeName(vaultSettings.mountName.get());
}
}
return prepareMountPoint();
}
private Runnable prepareMountPoint() throws IOException {
Runnable cleanup = () -> {};
var userChosenMountPoint = vaultSettings.mountPoint.get();
var defaultMountPointBase = env.getMountPointsDir().orElseThrow();
var canMountToDriveLetter = service.hasCapability(MOUNT_AS_DRIVE_LETTER);
var canMountToParent = service.hasCapability(MOUNT_WITHIN_EXISTING_PARENT);
var canMountToDir = service.hasCapability(MOUNT_TO_EXISTING_DIR);
var canMountToSystem = service.hasCapability(MOUNT_TO_SYSTEM_CHOSEN_PATH);
if (userChosenMountPoint == null) {
if (canMountToSystem) {
// no need to set a mount point
} else if (canMountToDriveLetter) {
builder.setMountpoint(driveLetters.getFirstDesiredAvailable().orElseThrow()); //TODO: catch exception and translate
} else if (canMountToParent) {
Files.createDirectories(defaultMountPointBase);
builder.setMountpoint(defaultMountPointBase);
} else if (canMountToDir) {
var mountPoint = defaultMountPointBase.resolve(vaultSettings.mountName.get());
Files.createDirectories(mountPoint);
builder.setMountpoint(mountPoint);
}
} else {
var mpIsDriveLetter = userChosenMountPoint.toString().matches("[A-Z]:\\\\");
if (mpIsDriveLetter) {
if (driveLetters.getOccupied().contains(userChosenMountPoint)) {
throw new MountPointInUseException(userChosenMountPoint.toString());
}
} else if (canMountToParent && !canMountToDir) {
MountWithinParentUtil.prepareParentNoMountPoint(userChosenMountPoint);
cleanup = () -> {
MountWithinParentUtil.cleanup(userChosenMountPoint);
};
}
try {
builder.setMountpoint(userChosenMountPoint);
} catch (IllegalArgumentException | UnsupportedOperationException e) {
var configNotSupported = (!canMountToDriveLetter && mpIsDriveLetter) //mounting as driveletter, albeit not supported
|| (!canMountToDir && !mpIsDriveLetter) //mounting to directory, albeit not supported
|| (!canMountToParent && !mpIsDriveLetter) //
|| (!canMountToDir && !canMountToParent && !canMountToSystem && !canMountToDriveLetter);
if (configNotSupported) {
throw new MountPointNotSupportedException(e.getMessage());
} else if (canMountToDir && !canMountToParent && !Files.exists(userChosenMountPoint)) {
//mountpoint must exist
throw new MountPointNotExistsException(e.getMessage());
} else {
//TODO: add specific exception for !canMountToDir && canMountToParent && !Files.notExists(userChosenMountPoint)
throw new IllegalMountPointException(e.getMessage());
}
}
}
return cleanup;
}
}
public MountHandle mount(VaultSettings vaultSettings, Path cryptoFsRoot) throws IOException, MountFailedException {
var mountService = this.mountServiceObservable.getValue().service();
var builder = mountService.forFileSystem(cryptoFsRoot);
var internal = new SettledMounter(mountService, builder, vaultSettings);
var cleanup = internal.prepare();
return new MountHandle(builder.mount(), mountService.hasCapability(UNMOUNT_FORCED), cleanup);
}
public record MountHandle(Mount mountObj, boolean supportsUnmountForced, Runnable specialCleanup) {
}
}
@@ -76,6 +76,11 @@ public class DeviceKey {
private P384KeyPair createAndStoreNewKeyPair(char[] passphrase, Path p12File) throws IOException {
var keyPair = P384KeyPair.generate();
var tmpFile = p12File.resolveSibling(p12File.getFileName().toString() + ".tmp");
if(Files.exists(tmpFile)) {
LOG.debug("Leftover from devicekey creation detected. Deleting {}", tmpFile);
Files.delete(tmpFile);
}
LOG.debug("Store new device key to {}", p12File);
keyPair.store(p12File, passphrase);
return keyPair;
@@ -10,6 +10,8 @@ package org.cryptomator.common.settings;
import org.apache.commons.lang3.SystemUtils;
import org.cryptomator.common.Environment;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javafx.beans.Observable;
import javafx.beans.property.BooleanProperty;
@@ -27,59 +29,88 @@ import java.util.function.Consumer;
public class Settings {
public static final int MIN_PORT = 1024;
public static final int MAX_PORT = 65535;
public static final boolean DEFAULT_ASKED_FOR_UPDATE_CHECK = false;
public static final boolean DEFAULT_CHECK_FOR_UPDATES = false;
public static final boolean DEFAULT_START_HIDDEN = false;
public static final boolean DEFAULT_AUTO_CLOSE_VAULTS = false;
public static final boolean DEFAULT_USE_KEYCHAIN = true;
public static final int DEFAULT_PORT = 42427;
public static final int DEFAULT_NUM_TRAY_NOTIFICATIONS = 3;
public static final boolean DEFAULT_DEBUG_MODE = false;
public static final UiTheme DEFAULT_THEME = UiTheme.LIGHT;
private static final Logger LOG = LoggerFactory.getLogger(Settings.class);
static final boolean DEFAULT_ASKED_FOR_UPDATE_CHECK = false;
static final boolean DEFAULT_CHECK_FOR_UPDATES = false;
static final boolean DEFAULT_START_HIDDEN = false;
static final boolean DEFAULT_AUTO_CLOSE_VAULTS = false;
static final boolean DEFAULT_USE_KEYCHAIN = true;
static final int DEFAULT_PORT = 42427;
static final int DEFAULT_NUM_TRAY_NOTIFICATIONS = 3;
static final boolean DEFAULT_DEBUG_MODE = false;
static final UiTheme DEFAULT_THEME = UiTheme.LIGHT;
@Deprecated // to be changed to "whatever is available" eventually
public static final String DEFAULT_KEYCHAIN_PROVIDER = SystemUtils.IS_OS_WINDOWS ? "org.cryptomator.windows.keychain.WindowsProtectedKeychainAccess" : SystemUtils.IS_OS_MAC ? "org.cryptomator.macos.keychain.MacSystemKeychainAccess" : "org.cryptomator.linux.keychain.SecretServiceKeychainAccess";
public static final NodeOrientation DEFAULT_USER_INTERFACE_ORIENTATION = NodeOrientation.LEFT_TO_RIGHT;
public static final String DEFAULT_LICENSE_KEY = "";
public static final boolean DEFAULT_SHOW_MINIMIZE_BUTTON = false;
public static final String DEFAULT_DISPLAY_CONFIGURATION = "";
public static final String DEFAULT_LANGUAGE = null;
private final ObservableList<VaultSettings> directories = FXCollections.observableArrayList(VaultSettings::observables);
private final BooleanProperty askedForUpdateCheck = new SimpleBooleanProperty(DEFAULT_ASKED_FOR_UPDATE_CHECK);
private final BooleanProperty checkForUpdates = new SimpleBooleanProperty(DEFAULT_CHECK_FOR_UPDATES);
private final BooleanProperty startHidden = new SimpleBooleanProperty(DEFAULT_START_HIDDEN);
private final BooleanProperty autoCloseVaults = new SimpleBooleanProperty(DEFAULT_AUTO_CLOSE_VAULTS);
private final BooleanProperty useKeychain = new SimpleBooleanProperty(DEFAULT_USE_KEYCHAIN);
private final IntegerProperty port = new SimpleIntegerProperty(DEFAULT_PORT);
private final IntegerProperty numTrayNotifications = new SimpleIntegerProperty(DEFAULT_NUM_TRAY_NOTIFICATIONS);
private final BooleanProperty debugMode = new SimpleBooleanProperty(DEFAULT_DEBUG_MODE);
private final ObjectProperty<UiTheme> theme = new SimpleObjectProperty<>(DEFAULT_THEME);
private final ObjectProperty<String> keychainProvider = new SimpleObjectProperty<>(DEFAULT_KEYCHAIN_PROVIDER);
private final ObjectProperty<NodeOrientation> userInterfaceOrientation = new SimpleObjectProperty<>(DEFAULT_USER_INTERFACE_ORIENTATION);
private final StringProperty licenseKey = new SimpleStringProperty(DEFAULT_LICENSE_KEY);
private final BooleanProperty showMinimizeButton = new SimpleBooleanProperty(DEFAULT_SHOW_MINIMIZE_BUTTON);
private final BooleanProperty showTrayIcon;
private final IntegerProperty windowXPosition = new SimpleIntegerProperty();
private final IntegerProperty windowYPosition = new SimpleIntegerProperty();
private final IntegerProperty windowWidth = new SimpleIntegerProperty();
private final IntegerProperty windowHeight = new SimpleIntegerProperty();
private final ObjectProperty<String> displayConfiguration = new SimpleObjectProperty<>(DEFAULT_DISPLAY_CONFIGURATION);
private final StringProperty language = new SimpleStringProperty(DEFAULT_LANGUAGE);
private final StringProperty mountService = new SimpleStringProperty();
static final String DEFAULT_KEYCHAIN_PROVIDER = SystemUtils.IS_OS_WINDOWS ? "org.cryptomator.windows.keychain.WindowsProtectedKeychainAccess" : SystemUtils.IS_OS_MAC ? "org.cryptomator.macos.keychain.MacSystemKeychainAccess" : "org.cryptomator.linux.keychain.SecretServiceKeychainAccess";
static final String DEFAULT_USER_INTERFACE_ORIENTATION = NodeOrientation.LEFT_TO_RIGHT.name();
static final boolean DEFAULT_SHOW_MINIMIZE_BUTTON = false;
static final String DEFAULT_LAST_UPDATE_CHECK = "2000-01-01";
public final ObservableList<VaultSettings> directories;
public final BooleanProperty askedForUpdateCheck;
public final BooleanProperty checkForUpdates;
public final BooleanProperty startHidden;
public final BooleanProperty autoCloseVaults;
public final BooleanProperty useKeychain;
public final IntegerProperty port;
public final IntegerProperty numTrayNotifications;
public final BooleanProperty debugMode;
public final ObjectProperty<UiTheme> theme;
public final StringProperty keychainProvider;
public final ObjectProperty<NodeOrientation> userInterfaceOrientation;
public final StringProperty licenseKey;
public final BooleanProperty showMinimizeButton;
public final BooleanProperty showTrayIcon;
public final IntegerProperty windowXPosition;
public final IntegerProperty windowYPosition;
public final IntegerProperty windowWidth;
public final IntegerProperty windowHeight;
public final StringProperty displayConfiguration;
public final StringProperty language;
public final StringProperty mountService;
public final StringProperty lastUpdateCheck;
private Consumer<Settings> saveCmd;
public static Settings create(Environment env) {
var defaults = new SettingsJson();
defaults.showTrayIcon = env.showTrayIcon();
return new Settings(defaults);
}
/**
* Package-private constructor; use {@link SettingsProvider}.
* Recreate settings from json
*
* @param json The parsed settings.json
*/
Settings(Environment env) {
this.showTrayIcon = new SimpleBooleanProperty(env.showTrayIcon());
Settings(SettingsJson json) {
this.directories = FXCollections.observableArrayList(VaultSettings::observables);
this.askedForUpdateCheck = new SimpleBooleanProperty(this, "askedForUpdateCheck", json.askedForUpdateCheck);
this.checkForUpdates = new SimpleBooleanProperty(this, "checkForUpdates", json.checkForUpdatesEnabled);
this.startHidden = new SimpleBooleanProperty(this, "startHidden", json.startHidden);
this.autoCloseVaults = new SimpleBooleanProperty(this, "autoCloseVaults", json.autoCloseVaults);
this.useKeychain = new SimpleBooleanProperty(this, "useKeychain", json.useKeychain);
this.port = new SimpleIntegerProperty(this, "webDavPort", json.port);
this.numTrayNotifications = new SimpleIntegerProperty(this, "numTrayNotifications", json.numTrayNotifications);
this.debugMode = new SimpleBooleanProperty(this, "debugMode", json.debugMode);
this.theme = new SimpleObjectProperty<>(this, "theme", json.theme);
this.keychainProvider = new SimpleStringProperty(this, "keychainProvider", json.keychainProvider);
this.userInterfaceOrientation = new SimpleObjectProperty<>(this, "userInterfaceOrientation", parseEnum(json.uiOrientation, NodeOrientation.class, NodeOrientation.LEFT_TO_RIGHT));
this.licenseKey = new SimpleStringProperty(this, "licenseKey", json.licenseKey);
this.showMinimizeButton = new SimpleBooleanProperty(this, "showMinimizeButton", json.showMinimizeButton);
this.showTrayIcon = new SimpleBooleanProperty(this, "showTrayIcon", json.showTrayIcon);
this.windowXPosition = new SimpleIntegerProperty(this, "windowXPosition", json.windowXPosition);
this.windowYPosition = new SimpleIntegerProperty(this, "windowYPosition", json.windowYPosition);
this.windowWidth = new SimpleIntegerProperty(this, "windowWidth", json.windowWidth);
this.windowHeight = new SimpleIntegerProperty(this, "windowHeight", json.windowHeight);
this.displayConfiguration = new SimpleStringProperty(this, "displayConfiguration", json.displayConfiguration);
this.language = new SimpleStringProperty(this, "language", json.language);
this.mountService = new SimpleStringProperty(this, "mountService", json.mountService);
this.lastUpdateCheck = new SimpleStringProperty(this, "lastUpdateCheck", json.lastUpdateCheck);
this.directories.addAll(json.directories.stream().map(VaultSettings::new).toList());
migrateLegacySettings(json);
directories.addListener(this::somethingChanged);
askedForUpdateCheck.addListener(this::somethingChanged);
@@ -103,8 +134,76 @@ public class Settings {
displayConfiguration.addListener(this::somethingChanged);
language.addListener(this::somethingChanged);
mountService.addListener(this::somethingChanged);
lastUpdateCheck.addListener(this::somethingChanged);
}
@SuppressWarnings("deprecation")
private void migrateLegacySettings(SettingsJson json) {
// implicit migration of 1.6.x legacy setting "preferredVolumeImpl":
if (this.mountService.get() == null && json.preferredVolumeImpl != null) {
this.mountService.set(switch (json.preferredVolumeImpl) {
case "Dokany" -> "org.cryptomator.frontend.dokany.mount.DokanyMountProvider";
case "FUSE" -> {
if (SystemUtils.IS_OS_WINDOWS) {
yield "org.cryptomator.frontend.fuse.mount.WinFspNetworkMountProvider";
} else if (SystemUtils.IS_OS_MAC) {
yield "org.cryptomator.frontend.fuse.mount.MacFuseMountProvider";
} else {
yield "org.cryptomator.frontend.fuse.mount.LinuxFuseMountProvider";
}
}
default -> {
if (SystemUtils.IS_OS_WINDOWS) {
yield "org.cryptomator.frontend.webdav.mount.WindowsMounter";
} else if (SystemUtils.IS_OS_MAC) {
yield "org.cryptomator.frontend.webdav.mount.MacAppleScriptMounter";
} else {
yield "org.cryptomator.frontend.webdav.mount.LinuxGioMounter";
}
}
});
}
}
SettingsJson serialized() {
var json = new SettingsJson();
json.directories = directories.stream().map(VaultSettings::serialized).toList();
json.askedForUpdateCheck = askedForUpdateCheck.get();
json.checkForUpdatesEnabled = checkForUpdates.get();
json.startHidden = startHidden.get();
json.autoCloseVaults = autoCloseVaults.get();
json.useKeychain = useKeychain.get();
json.port = port.get();
json.numTrayNotifications = numTrayNotifications.get();
json.debugMode = debugMode.get();
json.theme = theme.get();
json.keychainProvider = keychainProvider.get();
json.uiOrientation = userInterfaceOrientation.get().name();
json.licenseKey = licenseKey.get();
json.showMinimizeButton = showMinimizeButton.get();
json.showTrayIcon = showTrayIcon.get();
json.windowXPosition = windowXPosition.get();
json.windowYPosition = windowYPosition.get();
json.windowWidth = windowWidth.get();
json.windowHeight = windowHeight.get();
json.displayConfiguration = displayConfiguration.get();
json.language = language.get();
json.mountService = mountService.get();
json.lastUpdateCheck = lastUpdateCheck.get();
return json;
}
private <E extends Enum<E>> E parseEnum(String value, Class<E> clazz, E defaultValue) {
try {
return Enum.valueOf(clazz, value.toUpperCase());
} catch (IllegalArgumentException e) {
LOG.warn("No value {}.{}. Defaulting to {}.", clazz.getSimpleName(), value, defaultValue);
return defaultValue;
}
}
// TODO rename to setChangeListener
void setSaveCmd(Consumer<Settings> saveCmd) {
this.saveCmd = saveCmd;
}
@@ -119,90 +218,4 @@ public class Settings {
}
}
/* Getter/Setter */
public ObservableList<VaultSettings> getDirectories() {
return directories;
}
public BooleanProperty askedForUpdateCheck() {
return askedForUpdateCheck;
}
public BooleanProperty checkForUpdates() {
return checkForUpdates;
}
public BooleanProperty startHidden() {
return startHidden;
}
public BooleanProperty autoCloseVaults() {
return autoCloseVaults;
}
public BooleanProperty useKeychain() { return useKeychain; }
public IntegerProperty port() {
return port;
}
public IntegerProperty numTrayNotifications() {
return numTrayNotifications;
}
public BooleanProperty debugMode() {
return debugMode;
}
public StringProperty mountService() {
return mountService;
}
public ObjectProperty<UiTheme> theme() {
return theme;
}
public ObjectProperty<String> keychainProvider() {return keychainProvider;}
public ObjectProperty<NodeOrientation> userInterfaceOrientation() {
return userInterfaceOrientation;
}
public StringProperty licenseKey() {
return licenseKey;
}
public BooleanProperty showMinimizeButton() {
return showMinimizeButton;
}
public BooleanProperty showTrayIcon() {
return showTrayIcon;
}
public IntegerProperty windowXPositionProperty() {
return windowXPosition;
}
public IntegerProperty windowYPositionProperty() {
return windowYPosition;
}
public IntegerProperty windowWidthProperty() {
return windowWidth;
}
public IntegerProperty windowHeightProperty() {
return windowHeight;
}
public ObjectProperty<String> displayConfigurationProperty() {
return displayConfiguration;
}
public StringProperty languageProperty() {
return language;
}
}
@@ -0,0 +1,89 @@
package org.cryptomator.common.settings;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.List;
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
class SettingsJson {
@JsonProperty("directories")
List<VaultSettingsJson> directories = List.of();
@JsonProperty("writtenByVersion")
String writtenByVersion;
@JsonProperty("askedForUpdateCheck")
boolean askedForUpdateCheck = Settings.DEFAULT_ASKED_FOR_UPDATE_CHECK;
@JsonProperty("autoCloseVaults")
boolean autoCloseVaults = Settings.DEFAULT_AUTO_CLOSE_VAULTS;
@JsonProperty("checkForUpdatesEnabled")
boolean checkForUpdatesEnabled = Settings.DEFAULT_CHECK_FOR_UPDATES;
@JsonProperty("debugMode")
boolean debugMode = Settings.DEFAULT_DEBUG_MODE;
@JsonProperty("theme")
UiTheme theme = Settings.DEFAULT_THEME;
@JsonProperty("displayConfiguration")
String displayConfiguration;
@JsonProperty("keychainProvider")
String keychainProvider = Settings.DEFAULT_KEYCHAIN_PROVIDER;
@JsonProperty("language")
String language;
@JsonProperty("licenseKey")
String licenseKey;
@JsonProperty("mountService")
String mountService;
@JsonProperty("numTrayNotifications")
int numTrayNotifications = Settings.DEFAULT_NUM_TRAY_NOTIFICATIONS;
@JsonProperty("port")
int port = Settings.DEFAULT_PORT;
@JsonProperty("showMinimizeButton")
boolean showMinimizeButton = Settings.DEFAULT_SHOW_MINIMIZE_BUTTON;
@JsonProperty("showTrayIcon")
boolean showTrayIcon;
@JsonProperty("startHidden")
boolean startHidden = Settings.DEFAULT_START_HIDDEN;
@JsonProperty("uiOrientation")
String uiOrientation = Settings.DEFAULT_USER_INTERFACE_ORIENTATION;
@JsonProperty("useKeychain")
boolean useKeychain = Settings.DEFAULT_USE_KEYCHAIN;
@JsonProperty("windowHeight")
int windowHeight;
@JsonProperty("windowWidth")
int windowWidth;
@JsonProperty("windowXPosition")
int windowXPosition;
@JsonProperty("windowYPosition")
int windowYPosition;
@Deprecated(since = "1.7.0")
@JsonProperty(value = "preferredVolumeImpl", access = JsonProperty.Access.WRITE_ONLY) // WRITE_ONLY means value is "written" into the java object during deserialization. Upvote this: https://github.com/FasterXML/jackson-annotations/issues/233
String preferredVolumeImpl;
@JsonProperty("lastUpdateCheck")
String lastUpdateCheck = Settings.DEFAULT_LAST_UPDATE_CHECK;
}
@@ -1,147 +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.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;
import org.cryptomator.common.Environment;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.inject.Inject;
import javax.inject.Singleton;
import javafx.geometry.NodeOrientation;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@Singleton
public class SettingsJsonAdapter extends TypeAdapter<Settings> {
private static final Logger LOG = LoggerFactory.getLogger(SettingsJsonAdapter.class);
private final VaultSettingsJsonAdapter vaultSettingsJsonAdapter = new VaultSettingsJsonAdapter();
private final Environment env;
@Inject
public SettingsJsonAdapter(Environment env) {
this.env = env;
}
@Override
public void write(JsonWriter out, Settings value) throws IOException {
out.beginObject();
out.name("directories");
writeVaultSettingsArray(out, value.getDirectories());
out.name("askedForUpdateCheck").value(value.askedForUpdateCheck().get());
out.name("checkForUpdatesEnabled").value(value.checkForUpdates().get());
out.name("startHidden").value(value.startHidden().get());
out.name("autoCloseVaults").value(value.autoCloseVaults().get());
out.name("port").value(value.port().get());
out.name("numTrayNotifications").value(value.numTrayNotifications().get());
out.name("debugMode").value(value.debugMode().get());
out.name("theme").value(value.theme().get().name());
out.name("uiOrientation").value(value.userInterfaceOrientation().get().name());
out.name("keychainProvider").value(value.keychainProvider().get());
out.name("useKeychain").value(value.useKeychain().get());
out.name("licenseKey").value(value.licenseKey().get());
out.name("showMinimizeButton").value(value.showMinimizeButton().get());
out.name("showTrayIcon").value(value.showTrayIcon().get());
out.name("windowXPosition").value((value.windowXPositionProperty().get()));
out.name("windowYPosition").value((value.windowYPositionProperty().get()));
out.name("windowWidth").value((value.windowWidthProperty().get()));
out.name("windowHeight").value((value.windowHeightProperty().get()));
out.name("displayConfiguration").value((value.displayConfigurationProperty().get()));
out.name("language").value((value.languageProperty().get()));
out.name("mountService").value(value.mountService().get());
out.endObject();
}
private void writeVaultSettingsArray(JsonWriter out, Iterable<VaultSettings> vaultSettings) throws IOException {
out.beginArray();
for (VaultSettings value : vaultSettings) {
vaultSettingsJsonAdapter.write(out, value);
}
out.endArray();
}
@Override
public Settings read(JsonReader in) throws IOException {
Settings settings = new Settings(env);
in.beginObject();
while (in.hasNext()) {
String name = in.nextName();
switch (name) {
case "directories" -> settings.getDirectories().addAll(readVaultSettingsArray(in));
case "askedForUpdateCheck" -> settings.askedForUpdateCheck().set(in.nextBoolean());
case "checkForUpdatesEnabled" -> settings.checkForUpdates().set(in.nextBoolean());
case "startHidden" -> settings.startHidden().set(in.nextBoolean());
case "autoCloseVaults" -> settings.autoCloseVaults().set(in.nextBoolean());
case "port" -> settings.port().set(in.nextInt());
case "numTrayNotifications" -> settings.numTrayNotifications().set(in.nextInt());
case "debugMode" -> settings.debugMode().set(in.nextBoolean());
case "theme" -> settings.theme().set(parseUiTheme(in.nextString()));
case "uiOrientation" -> settings.userInterfaceOrientation().set(parseUiOrientation(in.nextString()));
case "keychainProvider" -> settings.keychainProvider().set(in.nextString());
case "useKeychain" -> settings.useKeychain().set(in.nextBoolean());
case "licenseKey" -> settings.licenseKey().set(in.nextString());
case "showMinimizeButton" -> settings.showMinimizeButton().set(in.nextBoolean());
case "showTrayIcon" -> settings.showTrayIcon().set(in.nextBoolean());
case "windowXPosition" -> settings.windowXPositionProperty().set(in.nextInt());
case "windowYPosition" -> settings.windowYPositionProperty().set(in.nextInt());
case "windowWidth" -> settings.windowWidthProperty().set(in.nextInt());
case "windowHeight" -> settings.windowHeightProperty().set(in.nextInt());
case "displayConfiguration" -> settings.displayConfigurationProperty().set(in.nextString());
case "language" -> settings.languageProperty().set(in.nextString());
case "mountService" -> {
var token = in.peek();
if (JsonToken.STRING == token) {
settings.mountService().set(in.nextString());
}
}
default -> {
LOG.warn("Unsupported vault setting found in JSON: {}", name);
in.skipValue();
}
}
}
in.endObject();
return settings;
}
private UiTheme parseUiTheme(String uiThemeName) {
try {
return UiTheme.valueOf(uiThemeName.toUpperCase());
} catch (IllegalArgumentException e) {
LOG.warn("Invalid ui theme {}. Defaulting to {}.", uiThemeName, Settings.DEFAULT_THEME);
return Settings.DEFAULT_THEME;
}
}
private NodeOrientation parseUiOrientation(String uiOrientationName) {
try {
return NodeOrientation.valueOf(uiOrientationName.toUpperCase());
} catch (IllegalArgumentException e) {
LOG.warn("Invalid ui orientation {}. Defaulting to {}.", uiOrientationName, Settings.DEFAULT_USER_INTERFACE_ORIENTATION);
return Settings.DEFAULT_USER_INTERFACE_ORIENTATION;
}
}
private List<VaultSettings> readVaultSettingsArray(JsonReader in) throws IOException {
List<VaultSettings> result = new ArrayList<>();
in.beginArray();
while (!JsonToken.END_ARRAY.equals(in.peek())) {
result.add(vaultSettingsJsonAdapter.read(in));
}
in.endArray();
return result;
}
}
@@ -8,12 +8,9 @@
*******************************************************************************/
package org.cryptomator.common.settings;
import com.fasterxml.jackson.core.JacksonException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.base.Suppliers;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;
import com.google.gson.JsonParser;
import org.cryptomator.common.Environment;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -22,12 +19,7 @@ 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.Writer;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
@@ -44,6 +36,7 @@ import java.util.stream.Stream;
@Singleton
public class SettingsProvider implements Supplier<Settings> {
private static final ObjectMapper JSON = new ObjectMapper().setDefaultLeniency(true);
private static final Logger LOG = LoggerFactory.getLogger(SettingsProvider.class);
private static final long SAVE_DELAY_MS = 1000;
@@ -51,16 +44,11 @@ public class SettingsProvider implements Supplier<Settings> {
private final Supplier<Settings> settings = Suppliers.memoize(this::load);
private final Environment env;
private final ScheduledExecutorService scheduler;
private final Gson gson;
@Inject
public SettingsProvider(SettingsJsonAdapter settingsJsonAdapter, Environment env, ScheduledExecutorService scheduler) {
public SettingsProvider(Environment env, ScheduledExecutorService scheduler) {
this.env = env;
this.scheduler = scheduler;
this.gson = new GsonBuilder() //
.setPrettyPrinting().setLenient().disableHtmlEscaping() //
.registerTypeAdapter(Settings.class, settingsJsonAdapter) //
.create();
}
@Override
@@ -69,28 +57,25 @@ public class SettingsProvider implements Supplier<Settings> {
}
private Settings load() {
Settings settings = env.getSettingsPath().flatMap(this::tryLoad).findFirst().orElse(new Settings(env));
Settings settings = env.getSettingsPath().flatMap(this::tryLoad).findFirst().orElseGet(() -> Settings.create(env));
settings.setSaveCmd(this::scheduleSave);
return settings;
}
private Stream<Settings> tryLoad(Path path) {
LOG.debug("Attempting to load settings from {}", path);
try (InputStream in = Files.newInputStream(path, StandardOpenOption.READ); //
Reader reader = new InputStreamReader(in, StandardCharsets.UTF_8)) {
JsonElement json = JsonParser.parseReader(reader);
if (json.isJsonObject()) {
Settings settings = gson.fromJson(json, Settings.class);
LOG.info("Settings loaded from {}", path);
return Stream.of(settings);
} else {
LOG.warn("Invalid json file {}", path);
return Stream.empty();
}
try (InputStream in = Files.newInputStream(path, StandardOpenOption.READ)) {
var json = JSON.reader().readValue(in, SettingsJson.class);
LOG.info("Settings loaded from {}", path);
var settings = new Settings(json);
return Stream.of(settings);
} catch (JacksonException e) {
LOG.warn("Failed to parse json file {}", path, e);
return Stream.empty();
} catch (NoSuchFileException e) {
return Stream.empty();
} catch (IOException | JsonParseException e) {
LOG.warn("Exception while loading settings from " + path, e);
} catch (IOException e) {
LOG.warn("Failed to load json file {}", path, e);
return Stream.empty();
}
}
@@ -116,13 +101,14 @@ public class SettingsProvider implements Supplier<Settings> {
try {
Files.createDirectories(settingsPath.getParent());
Path tmpPath = settingsPath.resolveSibling(settingsPath.getFileName().toString() + ".tmp");
try (OutputStream out = Files.newOutputStream(tmpPath, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.WRITE); //
Writer writer = new OutputStreamWriter(out, StandardCharsets.UTF_8)) {
gson.toJson(settings, writer);
try (OutputStream out = Files.newOutputStream(tmpPath, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.WRITE)) {
var jsonObj = settings.serialized();
jsonObj.writtenByVersion = env.getAppVersion() + env.getBuildNumber().map("-"::concat).orElse("");
JSON.writerWithDefaultPrettyPrinter().writeValue(out, jsonObj);
}
Files.move(tmpPath, settingsPath, StandardCopyOption.REPLACE_EXISTING);
LOG.info("Settings saved to {}", settingsPath);
} catch (IOException | JsonParseException e) {
} catch (IOException e) {
LOG.error("Failed to save settings.", e);
}
}
@@ -1,9 +1,12 @@
package org.cryptomator.common.settings;
import com.fasterxml.jackson.annotation.JsonEnumDefaultValue;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.apache.commons.lang3.SystemUtils;
@JsonFormat(shape = JsonFormat.Shape.STRING)
public enum UiTheme {
LIGHT("preferences.interface.theme.light"), //
@JsonEnumDefaultValue LIGHT("preferences.interface.theme.light"), //
DARK("preferences.interface.theme.dark"), //
AUTOMATIC("preferences.interface.theme.automatic");
@@ -6,7 +6,9 @@
package org.cryptomator.common.settings;
import com.google.common.base.CharMatcher;
import com.google.common.base.Strings;
import com.google.common.io.BaseEncoding;
import org.apache.commons.lang3.SystemUtils;
import javafx.beans.Observable;
import javafx.beans.binding.Bindings;
@@ -20,6 +22,7 @@ import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Objects;
import java.util.Random;
@@ -28,33 +31,45 @@ import java.util.Random;
*/
public class VaultSettings {
public static final boolean DEFAULT_UNLOCK_AFTER_STARTUP = false;
public static final boolean DEFAULT_REVEAL_AFTER_MOUNT = true;
public static final boolean DEFAULT_USES_READONLY_MODE = false;
public static final String DEFAULT_MOUNT_FLAGS = "";
public static final int DEFAULT_MAX_CLEARTEXT_FILENAME_LENGTH = -1;
public static final WhenUnlocked DEFAULT_ACTION_AFTER_UNLOCK = WhenUnlocked.ASK;
public static final boolean DEFAULT_AUTOLOCK_WHEN_IDLE = false;
public static final int DEFAULT_AUTOLOCK_IDLE_SECONDS = 30 * 60;
static final boolean DEFAULT_UNLOCK_AFTER_STARTUP = false;
static final boolean DEFAULT_REVEAL_AFTER_MOUNT = true;
static final boolean DEFAULT_USES_READONLY_MODE = false;
static final String DEFAULT_MOUNT_FLAGS = ""; // TODO: remove empty default mount flags and let this property be null if not used
static final int DEFAULT_MAX_CLEARTEXT_FILENAME_LENGTH = -1;
static final WhenUnlocked DEFAULT_ACTION_AFTER_UNLOCK = WhenUnlocked.ASK;
static final boolean DEFAULT_AUTOLOCK_WHEN_IDLE = false;
static final int DEFAULT_AUTOLOCK_IDLE_SECONDS = 30 * 60;
private static final Random RNG = new Random();
private final String id;
private final ObjectProperty<Path> path = new SimpleObjectProperty<>();
private final StringProperty displayName = new SimpleStringProperty();
private final BooleanProperty unlockAfterStartup = new SimpleBooleanProperty(DEFAULT_UNLOCK_AFTER_STARTUP);
private final BooleanProperty revealAfterMount = new SimpleBooleanProperty(DEFAULT_REVEAL_AFTER_MOUNT);
private final BooleanProperty usesReadOnlyMode = new SimpleBooleanProperty(DEFAULT_USES_READONLY_MODE);
private final StringProperty mountFlags = new SimpleStringProperty(DEFAULT_MOUNT_FLAGS);
private final IntegerProperty maxCleartextFilenameLength = new SimpleIntegerProperty(DEFAULT_MAX_CLEARTEXT_FILENAME_LENGTH);
private final ObjectProperty<WhenUnlocked> actionAfterUnlock = new SimpleObjectProperty<>(DEFAULT_ACTION_AFTER_UNLOCK);
private final BooleanProperty autoLockWhenIdle = new SimpleBooleanProperty(DEFAULT_AUTOLOCK_WHEN_IDLE);
private final IntegerProperty autoLockIdleSeconds = new SimpleIntegerProperty(DEFAULT_AUTOLOCK_IDLE_SECONDS);
private final StringExpression mountName;
private final ObjectProperty<Path> mountPoint = new SimpleObjectProperty<>();
public final String id;
public final ObjectProperty<Path> path;
public final StringProperty displayName;
public final BooleanProperty unlockAfterStartup;
public final BooleanProperty revealAfterMount;
public final BooleanProperty usesReadOnlyMode;
public final StringProperty mountFlags;
public final IntegerProperty maxCleartextFilenameLength;
public final ObjectProperty<WhenUnlocked> actionAfterUnlock;
public final BooleanProperty autoLockWhenIdle;
public final IntegerProperty autoLockIdleSeconds;
public final ObjectProperty<Path> mountPoint;
public final StringExpression mountName;
public VaultSettings(String id) {
this.id = Objects.requireNonNull(id);
VaultSettings(VaultSettingsJson json) {
this.id = json.id;
this.path = new SimpleObjectProperty<>(this, "path", json.path == null ? null : Paths.get(json.path));
this.displayName = new SimpleStringProperty(this, "displayName", json.displayName);
this.unlockAfterStartup = new SimpleBooleanProperty(this, "unlockAfterStartup", json.unlockAfterStartup);
this.revealAfterMount = new SimpleBooleanProperty(this, "revealAfterMount", json.revealAfterMount);
this.usesReadOnlyMode = new SimpleBooleanProperty(this, "usesReadOnlyMode", json.usesReadOnlyMode);
this.mountFlags = new SimpleStringProperty(this, "mountFlags", json.mountFlags);
this.maxCleartextFilenameLength = new SimpleIntegerProperty(this, "maxCleartextFilenameLength", json.maxCleartextFilenameLength);
this.actionAfterUnlock = new SimpleObjectProperty<>(this, "actionAfterUnlock", json.actionAfterUnlock);
this.autoLockWhenIdle = new SimpleBooleanProperty(this, "autoLockWhenIdle", json.autoLockWhenIdle);
this.autoLockIdleSeconds = new SimpleIntegerProperty(this, "autoLockIdleSeconds", json.autoLockIdleSeconds);
this.mountPoint = new SimpleObjectProperty<>(this, "mountPoint", json.mountPoint == null ? null : Path.of(json.mountPoint));
// mount name is no longer an explicit setting, see https://github.com/cryptomator/cryptomator/pull/1318
this.mountName = StringExpression.stringExpression(Bindings.createStringBinding(() -> {
final String name;
if (displayName.isEmpty().get()) {
@@ -64,6 +79,18 @@ public class VaultSettings {
}
return normalizeDisplayName(name);
}, displayName, path));
migrateLegacySettings(json);
}
@SuppressWarnings("deprecation")
private void migrateLegacySettings(VaultSettingsJson json) {
// implicit migration of 1.6.x legacy setting "customMountPath" / "winDriveLetter":
if (json.useCustomMountPath && !Strings.isNullOrEmpty(json.customMountPath)) {
this.mountPoint.set(Path.of(json.customMountPath));
} else if (!Strings.isNullOrEmpty(json.winDriveLetter)) {
this.mountPoint.set(Path.of(json.winDriveLetter + ":\\"));
}
}
Observable[] observables() {
@@ -71,7 +98,9 @@ public class VaultSettings {
}
public static VaultSettings withRandomId() {
return new VaultSettings(generateId());
var defaults = new VaultSettingsJson();
defaults.id = generateId();
return new VaultSettings(defaults);
}
private static String generateId() {
@@ -80,6 +109,23 @@ public class VaultSettings {
return BaseEncoding.base64Url().encode(randomBytes);
}
VaultSettingsJson serialized() {
var json = new VaultSettingsJson();
json.id = id;
json.path = path.map(Path::toString).getValue();
json.displayName = displayName.get();
json.unlockAfterStartup = unlockAfterStartup.get();
json.revealAfterMount = revealAfterMount.get();
json.usesReadOnlyMode = usesReadOnlyMode.get();
json.mountFlags = mountFlags.get();
json.maxCleartextFilenameLength = maxCleartextFilenameLength.get();
json.actionAfterUnlock = actionAfterUnlock.get();
json.autoLockWhenIdle = autoLockWhenIdle.get();
json.autoLockIdleSeconds = autoLockIdleSeconds.get();
json.mountPoint = mountPoint.map(Path::toString).getValue();
return json;
}
//visible for testing
static String normalizeDisplayName(String original) {
if (original.isBlank() || ".".equals(original) || "..".equals(original)) {
@@ -93,68 +139,6 @@ public class VaultSettings {
return CharMatcher.anyOf("<>:\"/\\|?*").or(CharMatcher.javaIsoControl()).collapseFrom(withoutFancyWhitespaces, '_');
}
/* Getter/Setter */
public String getId() {
return id;
}
public ObjectProperty<Path> path() {
return path;
}
public StringProperty displayName() {
return displayName;
}
public StringExpression mountName() {
return mountName;
}
public BooleanProperty unlockAfterStartup() {
return unlockAfterStartup;
}
public BooleanProperty revealAfterMount() {
return revealAfterMount;
}
public Path getMountPoint() {
return mountPoint.get();
}
public ObjectProperty<Path> mountPoint() {
return mountPoint;
}
public BooleanProperty usesReadOnlyMode() {
return usesReadOnlyMode;
}
public StringProperty mountFlags() {
return mountFlags;
}
public IntegerProperty maxCleartextFilenameLength() {
return maxCleartextFilenameLength;
}
public ObjectProperty<WhenUnlocked> actionAfterUnlock() {
return actionAfterUnlock;
}
public WhenUnlocked getActionAfterUnlock() {
return actionAfterUnlock.get();
}
public BooleanProperty autoLockWhenIdle() {
return autoLockWhenIdle;
}
public IntegerProperty autoLockIdleSeconds() {
return autoLockIdleSeconds;
}
/* Hashcode/Equals */
@Override
@@ -0,0 +1,62 @@
package org.cryptomator.common.settings;
import com.fasterxml.jackson.annotation.JsonAlias;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
class VaultSettingsJson {
@JsonProperty(value = "id", required = true)
String id;
@JsonProperty(value = "path")
String path;
@JsonProperty("displayName")
String displayName;
@JsonProperty("unlockAfterStartup")
boolean unlockAfterStartup = VaultSettings.DEFAULT_UNLOCK_AFTER_STARTUP;
@JsonProperty("revealAfterMount")
boolean revealAfterMount = VaultSettings.DEFAULT_REVEAL_AFTER_MOUNT;
@JsonProperty("mountPoint")
String mountPoint;
@JsonProperty("usesReadOnlyMode")
boolean usesReadOnlyMode = VaultSettings.DEFAULT_USES_READONLY_MODE;
@JsonProperty("mountFlags")
String mountFlags = VaultSettings.DEFAULT_MOUNT_FLAGS;
@JsonProperty("maxCleartextFilenameLength")
int maxCleartextFilenameLength = VaultSettings.DEFAULT_MAX_CLEARTEXT_FILENAME_LENGTH;
@JsonProperty("actionAfterUnlock")
WhenUnlocked actionAfterUnlock = VaultSettings.DEFAULT_ACTION_AFTER_UNLOCK;
@JsonProperty("autoLockWhenIdle")
boolean autoLockWhenIdle = VaultSettings.DEFAULT_AUTOLOCK_WHEN_IDLE;
@JsonProperty("autoLockIdleSeconds")
int autoLockIdleSeconds = VaultSettings.DEFAULT_AUTOLOCK_IDLE_SECONDS;
@Deprecated(since = "1.7.0")
@JsonProperty(value = "winDriveLetter", access = JsonProperty.Access.WRITE_ONLY) // WRITE_ONLY means value is "written" into the java object during deserialization. Upvote this: https://github.com/FasterXML/jackson-annotations/issues/233
String winDriveLetter;
@Deprecated(since = "1.7.0")
@JsonProperty(value = "useCustomMountPath", access = JsonProperty.Access.WRITE_ONLY) // WRITE_ONLY means value is "written" into the java object during deserialization. Upvote this: https://github.com/FasterXML/jackson-annotations/issues/233
@JsonAlias("usesIndividualMountPath")
boolean useCustomMountPath;
@Deprecated(since = "1.7.0")
@JsonProperty(value = "customMountPath", access = JsonProperty.Access.WRITE_ONLY) // WRITE_ONLY means value is "written" into the java object during deserialization. Upvote this: https://github.com/FasterXML/jackson-annotations/issues/233
@JsonAlias("individualMountPath")
String customMountPath;
}
@@ -1,126 +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.JsonToken;
import com.google.gson.stream.JsonWriter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.nio.file.InvalidPathException;
import java.nio.file.Path;
import java.nio.file.Paths;
class VaultSettingsJsonAdapter {
private static final Logger LOG = LoggerFactory.getLogger(VaultSettingsJsonAdapter.class);
public void write(JsonWriter out, VaultSettings value) throws IOException {
out.beginObject();
out.name("id").value(value.getId());
out.name("path").value(value.path().get().toString());
out.name("displayName").value(value.displayName().get());
out.name("unlockAfterStartup").value(value.unlockAfterStartup().get());
out.name("revealAfterMount").value(value.revealAfterMount().get());
var mountPoint = value.mountPoint().get();
out.name("mountPoint").value(mountPoint != null ? mountPoint.toAbsolutePath().toString() : null);
out.name("usesReadOnlyMode").value(value.usesReadOnlyMode().get());
out.name("mountFlags").value(value.mountFlags().get());
out.name("maxCleartextFilenameLength").value(value.maxCleartextFilenameLength().get());
out.name("actionAfterUnlock").value(value.actionAfterUnlock().get().name());
out.name("autoLockWhenIdle").value(value.autoLockWhenIdle().get());
out.name("autoLockIdleSeconds").value(value.autoLockIdleSeconds().get());
out.endObject();
}
//TODO: usesCustomMountPath, customMountPath and winDriveLetter removed
// -> migration required
public VaultSettings read(JsonReader in) throws IOException {
String id = null;
String path = null;
String mountName = null; //see https://github.com/cryptomator/cryptomator/pull/1318
String displayName = null;
boolean unlockAfterStartup = VaultSettings.DEFAULT_UNLOCK_AFTER_STARTUP;
boolean revealAfterMount = VaultSettings.DEFAULT_REVEAL_AFTER_MOUNT;
boolean usesReadOnlyMode = VaultSettings.DEFAULT_USES_READONLY_MODE;
String mountFlags = VaultSettings.DEFAULT_MOUNT_FLAGS;
Path mountPoint = null;
int maxCleartextFilenameLength = VaultSettings.DEFAULT_MAX_CLEARTEXT_FILENAME_LENGTH;
WhenUnlocked actionAfterUnlock = VaultSettings.DEFAULT_ACTION_AFTER_UNLOCK;
boolean autoLockWhenIdle = VaultSettings.DEFAULT_AUTOLOCK_WHEN_IDLE;
int autoLockIdleSeconds = VaultSettings.DEFAULT_AUTOLOCK_IDLE_SECONDS;
in.beginObject();
while (in.hasNext()) {
String name = in.nextName();
switch (name) {
case "id" -> id = in.nextString();
case "path" -> path = in.nextString();
case "mountName" -> mountName = in.nextString(); //see https://github.com/cryptomator/cryptomator/pull/1318
case "displayName" -> displayName = in.nextString();
case "unlockAfterStartup" -> unlockAfterStartup = in.nextBoolean();
case "revealAfterMount" -> revealAfterMount = in.nextBoolean();
case "usesReadOnlyMode" -> usesReadOnlyMode = in.nextBoolean();
case "mountFlags" -> mountFlags = in.nextString();
case "mountPoint" -> {
if (JsonToken.NULL == in.peek()) {
in.nextNull();
} else {
mountPoint = parseMountPoint(in.nextString());
}
}
case "maxCleartextFilenameLength" -> maxCleartextFilenameLength = in.nextInt();
case "actionAfterUnlock" -> actionAfterUnlock = parseActionAfterUnlock(in.nextString());
case "autoLockWhenIdle" -> autoLockWhenIdle = in.nextBoolean();
case "autoLockIdleSeconds" -> autoLockIdleSeconds = in.nextInt();
default -> {
LOG.warn("Unsupported vault setting found in JSON: {}", name);
in.skipValue();
}
}
}
in.endObject();
VaultSettings vaultSettings = (id == null) ? VaultSettings.withRandomId() : new VaultSettings(id);
if (displayName != null) { //see https://github.com/cryptomator/cryptomator/pull/1318
vaultSettings.displayName().set(displayName);
} else {
vaultSettings.displayName().set(mountName);
}
vaultSettings.path().set(Paths.get(path));
vaultSettings.unlockAfterStartup().set(unlockAfterStartup);
vaultSettings.revealAfterMount().set(revealAfterMount);
vaultSettings.usesReadOnlyMode().set(usesReadOnlyMode);
vaultSettings.mountFlags().set(mountFlags);
vaultSettings.maxCleartextFilenameLength().set(maxCleartextFilenameLength);
vaultSettings.actionAfterUnlock().set(actionAfterUnlock);
vaultSettings.autoLockWhenIdle().set(autoLockWhenIdle);
vaultSettings.autoLockIdleSeconds().set(autoLockIdleSeconds);
vaultSettings.mountPoint().set(mountPoint);
return vaultSettings;
}
private Path parseMountPoint(String mountPoint) {
try {
return Path.of(mountPoint);
} catch (InvalidPathException e) {
LOG.warn("Invalid string as mount point. Defaulting to null.");
return null;
}
}
private WhenUnlocked parseActionAfterUnlock(String actionAfterUnlockName) {
try {
return WhenUnlocked.valueOf(actionAfterUnlockName.toUpperCase());
} catch (IllegalArgumentException e) {
LOG.warn("Invalid action after unlock {}. Defaulting to {}.", actionAfterUnlockName, VaultSettings.DEFAULT_ACTION_AFTER_UNLOCK);
return VaultSettings.DEFAULT_ACTION_AFTER_UNLOCK;
}
}
}

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