Compare commits

...
769 Commits
Author SHA1 Message Date
Armin Schrenk 1fb987607c use single method to initialize JavaFX 2025-01-21 17:03:42 +01:00
Armin Schrenk 5d4066d29a fix test 2025-01-21 16:01:49 +01:00
Armin Schrenk d3909134d5 actually use authentication 2025-01-21 15:55:47 +01:00
Armin Schrenk fd9d1bf0cf fix unit test 2025-01-16 10:49:57 +01:00
Armin Schrenk 2f812377c3 bump integrations-win to 1.4.1 to fix jvm crashes 2025-01-16 10:31:38 +01:00
Armin Schrenk ebce90eb74 weakValues are too agressive 2025-01-15 10:02:42 +01:00
Armin Schrenk c888b52ebb rely on the cache directly after unlock and inject in the cache on keychain changes 2025-01-15 10:02:21 +01:00
Armin Schrenk e422c7ce4b use caffeine for building a cache
(cherry picked from commit fc709eb700)
2025-01-15 09:38:50 +01:00
Armin Schrenk 41ad8d5dcc response in th ui to keychain impl change 2025-01-14 18:42:08 +01:00
Armin Schrenk 526c3973d6 bump dependencies to add biometric auth providers
* integrations-win to 1.4.0
* integrations-mac to 1.3.0
2025-01-14 15:42:10 +01:00
Armin Schrenk dc16c961af only store password, if it is not already stored 2025-01-14 15:41:17 +01:00
Ralph Plawetzki c54a603078 Merge branch 'develop' into 2ndfactor 2025-01-11 17:59:54 +01:00
mindmonkandGitHub de3b2715c7 Merge pull request #3618 from cryptomator/feature/dialog-builder
Feature: SimpleDialogBuilder
2025-01-10 15:17:24 +01:00
Jan-Peter Klein f3d8bd359d Merge branch 'develop' into feature/dialog-builder 2025-01-10 15:05:07 +01:00
Armin SchrenkandGitHub d7d6e46b2a Ensure JDK 23 is used in building mac dmg x64 2025-01-10 14:33:34 +01:00
Jan-Peter Klein 501f682d68 annotate Dialogs with @Singleton
removed redundant providers
2025-01-10 11:58:19 +01:00
Jan-Peter Klein 7cbf1e10e5 refactor dialogs with injected resourceBundle for builder creation 2025-01-09 17:39:02 +01:00
Jan-Peter Klein fb00972bc1 improve naming 2025-01-09 15:31:07 +01:00
Jan-Peter Klein 387fb28c65 remove unused LOGs and improved var naming 2025-01-09 15:22:25 +01:00
Jan-Peter Klein 40fbfd10d1 moved all simple dialogs to Dialogs 2025-01-08 19:17:20 +01:00
Jan-Peter Klein e5e4695cd6 replaced setters and extended the constructor of SimpleDialogController 2025-01-08 17:50:54 +01:00
Armin Schrenk 4a0c8ae80e fix check-jdk-update workflow [ci skip] 2025-01-08 17:09:53 +01:00
Armin Schrenk 384ca8eb2a for testing 2025-01-08 16:02:00 +01:00
Jan-Peter Klein 59f360bde7 improve formatting, rename and simplify vars 2025-01-08 15:07:04 +01:00
Jan-Peter Klein 8830e0f5fb Move repeated 'remove vault' dialog to Dialogs class 2025-01-07 15:19:06 +01:00
Jan-Peter Klein 7a391a2825 reformat code 2025-01-07 14:47:20 +01:00
Jan-Peter Klein a1941911ef renamed to simple Dialog 2025-01-07 14:45:09 +01:00
Jan-Peter Klein a0667ff361 add validation for required parameters and changed exception message 2025-01-07 14:39:22 +01:00
Ralph Plawetzki be59097a53 Merge branch 'develop' into 2ndfactor 2024-12-14 07:37:30 +01:00
Armin SchrenkandGitHub cbc41d535d Merge pull request #3641 from cryptomator/feature/jdk23
Feature: JDK 23
2024-12-11 15:42:09 +01:00
Armin Schrenk f51780dcb5 also update deb rules file [ci skip] 2024-12-10 18:03:07 +01:00
Armin Schrenk c055488df7 update github workflows 2024-12-10 17:47:48 +01:00
Armin Schrenk b15c376e59 fix and update JDK check workflow 2024-12-10 17:42:55 +01:00
Armin Schrenk fdf03d2fdc enable JDK23 for IDE 2024-12-10 17:15:34 +01:00
Armin Schrenk 437350af9f reduce api diff 2024-12-10 17:14:09 +01:00
Julian RaufelderandGitHub 5114e2ad22 Merge pull request #3640 from lamtrinhdev/develop
Correct the link of issues list for both iOS and Android.
2024-12-09 14:09:03 +01:00
LamTrinh.DevandGitHub b3b4f61c42 Correct the link of issues list for both iOS and Android. 2024-12-09 19:13:44 +07:00
Armin Schrenk fa16556af1 do not allow empty display name for vault
Fixes #3633
2024-12-02 11:02:11 +01:00
Armin SchrenkandGitHub de766c2653 Update suppression.xml 2024-12-02 09:40:40 +01:00
Ralph Plawetzki ccc4842839 Use widened integrations-api 2024-12-02 08:16:28 +01:00
Ralph Plawetzki d95625faa1 Revert "Add CheckBox to enable Touch ID per vault"
This reverts commit cfa3093dd0.
2024-12-02 08:12:03 +01:00
Ralph Plawetzki c5bfdf32a9 Revert "Save Touch ID setting per vault"
This reverts commit 10bce1fb06.
2024-12-02 08:12:03 +01:00
Ralph Plawetzki 0598681a23 Revert "Decide on Touch ID setting whether user needs"
This reverts commit 2194360c8a.
2024-12-02 08:12:03 +01:00
Ralph Plawetzki 3b8bff0d47 Revert "loadPassphraseForAuthenticatedUser is not needed to"
This reverts commit 2378227756.
2024-12-02 08:12:02 +01:00
Ralph Plawetzki 55051072cb Revert "Actually save preference on checkbox change"
This reverts commit 62827b69cc.
2024-12-02 08:12:02 +01:00
Ralph Plawetzki 6cb409eeaf Revert "Grab new API"
This reverts commit 9516928529.
2024-12-02 08:12:02 +01:00
Ralph Plawetzki b38a350c48 Revert "Remove log statement used for testing"
This reverts commit 14ba852351.
2024-12-02 08:12:02 +01:00
Ralph Plawetzki 0e5857015a Revert "Change existing keychain entry"
This reverts commit 9cc863ae79.
2024-12-02 08:12:02 +01:00
Ralph Plawetzki 9e9aa20692 Revert "Disable feature for other platforms than Mac"
This reverts commit d8b798ff0f.
2024-12-02 08:12:01 +01:00
Ralph Plawetzki ad49ca2cb4 Revert "Generalize naming"
This reverts commit 953aee560f.
2024-12-02 08:12:01 +01:00
Ralph Plawetzki ba84da71f3 Revert "Code cleanups following coderabbitai recommendations"
This reverts commit af3779ba2e.
2024-12-02 08:12:01 +01:00
Ralph Plawetzki 5c34f59d09 Revert "Don't use SNAPSHOTS"
This reverts commit 175ed500a2.
2024-12-02 08:12:01 +01:00
Ralph Plawetzki 7499867665 Revert "Use overloaded method storePassword instead of a new one"
This reverts commit aa34ad52e6.
2024-12-02 08:12:00 +01:00
Ralph Plawetzki 7b293b8082 Revert "New, widened integrations-api"
This reverts commit 2f1b5109d6.
2024-12-02 08:12:00 +01:00
Ralph Plawetzki 46e8a13555 Revert "Improve thread handling"
This reverts commit c8075dbc19.
2024-12-02 08:11:01 +01:00
Ralph Plawetzki 63a3150ec3 Revert "Remove unneeded saving a keychain entry right after"
This reverts commit e8126e68ce.
2024-12-02 08:11:01 +01:00
Ralph Plawetzki 0a78987d30 Revert "Fix typo"
This reverts commit 78675c9638.
2024-12-02 08:11:00 +01:00
Ralph Plawetzki 929782c318 Revert "Fix doubled method due to merge error"
This reverts commit b5dbfd3209.
2024-12-02 08:11:00 +01:00
Ralph Plawetzki 97a0f9c435 Migrate keychain entries on Mac on provider change 2024-12-02 07:56:23 +01:00
Ralph Plawetzki f7e65f4eec Add cryptomator.integrationsWin.windowsHelloKeychainPaths to Environment 2024-11-30 14:39:56 +01:00
Ralph Plawetzki b3c56f3aab Add Windows Hello provider 2024-11-30 12:25:36 +01:00
Armin Schrenk dcc27efe5c remove unused option in app-image creation [skip ci]
references 84732337ca
2024-11-28 17:26:10 +01:00
Armin Schrenk 78ceb604f9 only use macos intel runner on releases 2024-11-27 16:47:42 +01:00
Armin SchrenkandGitHub 7bdcdcba3d Update suppression.xml 2024-11-26 15:49:43 +01:00
Jan-Peter Klein e929d41d67 reordered and renamed to org.ui.dialogs.SimpleDialog... 2024-11-25 19:23:48 +01:00
Jan-Peter Klein 600aca083c refactor CustomDialog.Builder provisioning to use Dagger's Provider 2024-11-25 15:09:29 +01:00
Ralph Plawetzki b5dbfd3209 Fix doubled method due to merge error 2024-11-24 18:14:26 +01:00
Ralph Plawetzki 78675c9638 Fix typo 2024-11-24 15:02:06 +01:00
Ralph Plawetzki e8126e68ce Remove unneeded saving a keychain entry right after
it was loaded
2024-11-24 15:02:06 +01:00
Ralph Plawetzki c8075dbc19 Improve thread handling 2024-11-24 15:02:05 +01:00
Ralph Plawetzki 2f1b5109d6 New, widened integrations-api 2024-11-24 15:01:44 +01:00
Ralph Plawetzki aa34ad52e6 Use overloaded method storePassword instead of a new one 2024-11-24 15:00:54 +01:00
Ralph Plawetzki 175ed500a2 Don't use SNAPSHOTS 2024-11-24 14:57:16 +01:00
Ralph Plawetzki af3779ba2e Code cleanups following coderabbitai recommendations 2024-11-24 14:56:38 +01:00
Ralph Plawetzki 953aee560f Generalize naming 2024-11-24 14:56:38 +01:00
Ralph Plawetzki d8b798ff0f Disable feature for other platforms than Mac 2024-11-24 14:56:38 +01:00
Ralph Plawetzki 9cc863ae79 Change existing keychain entry 2024-11-24 14:56:38 +01:00
Ralph Plawetzki 14ba852351 Remove log statement used for testing 2024-11-24 14:56:37 +01:00
Ralph Plawetzki 9516928529 Grab new API 2024-11-24 14:56:30 +01:00
Ralph Plawetzki 62827b69cc Actually save preference on checkbox change 2024-11-24 14:48:32 +01:00
Ralph Plawetzki 2378227756 loadPassphraseForAuthenticatedUser is not needed to
load as an authenticated user; loadPassphrase is
sufficient
2024-11-24 14:48:32 +01:00
Ralph Plawetzki 2194360c8a Decide on Touch ID setting whether user needs
to authenticate on loading and storing a passphrase
2024-11-24 14:48:32 +01:00
Ralph Plawetzki 10bce1fb06 Save Touch ID setting per vault 2024-11-24 14:48:32 +01:00
Ralph Plawetzki cfa3093dd0 Add CheckBox to enable Touch ID per vault 2024-11-24 14:48:31 +01:00
Jan-Peter Klein 02c20c01ee improve exception handling 2024-11-21 16:55:03 +01:00
mindmonkandGitHub 50cfdbbc0b Merge pull request #3617 from cryptomator/feature/ui-cleanup
Enhance UI Components, Fix Issues, and Improve Visual Consistency
2024-11-20 12:21:31 +01:00
Gutyina Gergő 38c556af0b Update jdk version to 23 2024-11-19 23:31:24 +01:00
Gutyina Gergő 0b9d777109 Remove string templates 2024-11-19 23:31:24 +01:00
Armin Schrenk eb3c1f3c7a Merge branch 'main' into develop
# Conflicts:
#	pom.xml
2024-11-19 10:01:00 +01:00
Armin Schrenk 311c490377 Merge branch 'hotfix/1.14.2' 2024-11-19 09:59:27 +01:00
Armin Schrenk 39ed00ff6f Use correct version 2024-11-19 09:57:56 +01:00
Armin Schrenk 28338d2dcf use stable version 2024-11-19 09:50:46 +01:00
Jan-Peter Klein bba5d11bdc small fixes 2024-11-18 18:07:36 +01:00
mindmonkandGitHub 36ef191874 Merge branch 'develop' into feature/dialog-builder 2024-11-18 17:58:59 +01:00
Jan-Peter Klein 3e4c6c1b61 del old logo file 2024-11-18 16:59:13 +01:00
Jan-Peter Klein c9d0224814 fix logo scaling 2024-11-18 16:48:41 +01:00
Armin SchrenkandGitHub 8aed6045a0 Feature: Show update reminder every 14 days (#3597)
fixes #3596

only show update reminder every 14 days
2024-11-15 18:14:57 +01:00
Jan-Peter Klein 8440705436 set resizable false 2024-11-15 15:49:11 +01:00
Jan-Peter Klein af667b10cf code cleanup 2024-11-14 18:09:23 +01:00
Jan-Peter Klein 1b522fe9a0 undo add uiDesigner 2024-11-14 17:20:08 +01:00
Jan-Peter Klein cb3c46744e removed replaced files 2024-11-14 16:38:44 +01:00
Jan-Peter Klein c471289fb5 changed resolveText() to throw Exceptions
removed fxApplication scope
2024-11-14 16:19:50 +01:00
Jan-Peter Klein 18ca563865 custom dialog init 2024-11-14 11:35:23 +01:00
Jan-Peter Klein 2430526ee7 changed to class Builder
used FxmlLoaderFactory.forController
set title and other string values by key
2024-11-06 16:35:19 +01:00
Armin Schrenk c9bb0235e2 use macos 15 for building [ci skip] 2024-11-05 16:18:32 +01:00
Armin Schrenk 2f8236e9db Update release template [ci skip] 2024-11-05 12:10:57 +01:00
Armin Schrenk e4e757606d update dependencies for patch release
Fixes #3574 and #3499. Closes #3569
2024-11-05 11:11:32 +01:00
CryptobotandArmin Schrenk 6fcb796177 New Crowdin updates (#3559)
New translations strings.properties

Afrikaans; Arabic; Bashkir; Belarusian; Bengali; Bosnian; Bulgarian; Catalan; Chinese Simplified; Chinese Traditional; Chinese Traditional, Hong Kong; Croatian; Czech; Danish; Dutch; English; Filipino; Finnish; French; Galician; German; Greek; Hebrew; Hindi; Hungarian; Indonesian; Italian; Japanese; Korean; Latvian; Macedonian; Marathi; Norwegian; 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; Urdu (Pakistan); Uyghur; Vietnamese;

[ci skip]

(cherry picked from commit 0fb0bc8e1d)
2024-11-04 17:59:02 +01:00
CryptobotandArmin Schrenk 4d6b035c29 New Crowdin updates (#3553)
New translations strings.properties

Afrikaans; English; Norwegian; Thai; Uyghur;

[ci skip]

(cherry picked from commit 2939702842)
2024-11-04 17:57:43 +01:00
dependabot[bot]andGitHub 68c206a4fa Bump the java-test-dependencies group across 1 directory with 2 updates (#3591) 2024-11-04 15:49:48 +00:00
dependabot[bot]andGitHub d258171131 Bump the maven-build-plugins group across 1 directory with 3 updates (#3598) 2024-11-04 15:47:08 +00:00
dependabot[bot]andGitHub adaf9ef5ce Bump the java-production-dependencies group across 1 directory with 8 updates (#3603) 2024-11-04 15:43:21 +00:00
Tobias HagemannandGitHub 22f299f67c Update README.md
[ci skip]
2024-11-04 15:13:40 +01:00
CryptobotandGitHub 0fb0bc8e1d New Crowdin updates (#3559)
New translations strings.properties

Afrikaans; Arabic; Bashkir; Belarusian; Bengali; Bosnian; Bulgarian; Catalan; Chinese Simplified; Chinese Traditional; Chinese Traditional, Hong Kong; Croatian; Czech; Danish; Dutch; English; Filipino; Finnish; French; Galician; German; Greek; Hebrew; Hindi; Hungarian; Indonesian; Italian; Japanese; Korean; Latvian; Macedonian; Marathi; Norwegian; 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; Urdu (Pakistan); Uyghur; Vietnamese; 

[ci skip]
2024-11-04 15:05:37 +01:00
Armin Schrenk da666410fc update dependabot config 2024-11-04 14:56:02 +01:00
Armin Schrenk ea007f3cfe fix IDE issues 2024-10-29 09:46:56 +01:00
Armin Schrenk 1c868a644f remove unused/obsolete static variable 2024-10-29 09:44:50 +01:00
Jan-Peter Klein 5ff6a8c258 used dialogBuilder for dokankySupportEndDialog 2024-10-23 19:48:55 +02:00
Jan-Peter Klein 62d7b7a0c0 replaced RemoveVaultComponent.Builder with CustomDialogBuilder in all places 2024-10-22 18:53:06 +02:00
Jan-Peter Klein 7fcbb57ab1 used builder pattern 2024-10-22 17:07:42 +02:00
Jan-Peter Klein 8e25dcd396 implement CustomDialogBuilder 2024-10-22 14:56:56 +02:00
mindmonkandGitHub a9f1e5b761 Merge pull request #3550 from cryptomator/feature/gdrive-presets
Feature: Refined GoogleDrive Presets - List Only "My Drive" Root Folders
2024-10-18 13:05:50 +02:00
Jan-Peter Klein f642149723 used List.of() for FALLBACK_LOCATIONS 2024-10-16 18:00:47 +02:00
Jan-Peter Klein 4b359d98cb removed unnecessary stream support 2024-10-10 17:39:53 +02:00
Jan-Peter Klein 764fccf0b5 pr mentioned changes 2024-10-10 17:34:23 +02:00
Jan-Peter Klein 81d1059489 added generic 'Remove' string property 2024-10-09 17:35:33 +02:00
Jan-Peter Klein a2574a5883 unified spacing 2024-10-09 16:59:13 +02:00
Jan-Peter Klein 118a1411d8 fixed empty vaultList contextMenu 2024-10-09 16:55:56 +02:00
Jan-Peter Klein 44310cbd0e set missing min width and height 2024-10-09 16:50:26 +02:00
Jan-Peter Klein 2dce7b6f71 removed drivePath param 2024-10-09 14:50:05 +02:00
Jan-Peter Klein 98db82d137 contains instead of stream 2024-10-09 14:48:40 +02:00
Jan-Peter Klein fd55656261 filtered by 'My Drive' and translations 2024-10-08 20:08:37 +02:00
mindmonkandGitHub 978dec64ee Merge pull request #3549 from cryptomator/feature/improve-preferences-contribute-tab
Feature: Optimize 'Support us' Tab in Preferences - Add Supporter Certificate Removal & Improved Layout
2024-10-04 12:27:13 +02:00
mindmonkandGitHub 8d7bf3a370 Merge pull request #3467 from cryptomator/feature/redesign-mainwindow
Feature: Redesigned MainWindow
2024-10-04 12:13:09 +02:00
Jan-Peter Klein 1cea7bcffc set bigger minHeight 2024-10-02 17:03:52 +02:00
Jan-Peter Klein 16e77d4b9b add clear to setStyleClass 2024-10-02 16:56:39 +02:00
Jan-Peter Klein f22111e36f revert unrelated changes 2024-10-02 16:46:41 +02:00
Jan-Peter Klein c5d4c9a9c1 removed duplicate code 2024-10-02 14:20:09 +02:00
mindmonkandGitHub 4bc9b1d60c Merge pull request #3474 from cryptomator/feature/notificationbar
Feature: Introduce NotificationBars for Update is available, Support Cryptomator, and DEBUG MODE
2024-10-02 11:05:58 +02:00
mindmonkandGitHub 7a40a3cb0c Merge branch 'feature/redesign-mainwindow' into feature/notificationbar 2024-10-02 11:05:39 +02:00
mindmonkandGitHub ad555ece8e Merge pull request #3554 from cryptomator/feature/condensed-vault-list
Feature: Add Option to Enable Compact Vault List View
2024-10-02 10:55:51 +02:00
Jan-Peter Klein 2d96d2e5c6 optimised cellSize binding and removed unused imports 2024-10-01 18:56:21 +02:00
Armin SchrenkandGitHub 0a968b60aa Remove Guava dependency and update Dagger 2024-10-01 17:19:31 +02:00
Jan-Peter Klein 3b4f82092d undo string removal 2024-10-01 13:31:43 +02:00
Jan-Peter Klein de16647d00 reformat code 2024-09-26 11:24:57 +02:00
AhmatjanandGitHub 03403e53bc translation: Add Uyghur Language Translation (#3557) 2024-09-26 11:12:26 +02:00
CryptobotandGitHub 2939702842 New Crowdin updates (#3553)
New translations strings.properties

Afrikaans; English; Norwegian; Thai; Uyghur;

[ci skip]
2024-09-26 11:10:21 +02:00
Jan-Peter Klein b3d09a4cae changed apostroph 2024-09-26 10:41:17 +02:00
Jan-Peter Klein 73c0af9749 changed wording and removed unnecessary method calls 2024-09-25 16:20:19 +02:00
Jan-Peter Klein 53c7e031a3 changes mentioned by infeo 2024-09-24 16:14:52 +02:00
Jan-Peter Klein 1e280f2c97 removed FXML loader, elements created programmatically in NotificationBar 2024-09-24 16:05:31 +02:00
Jan-Peter Klein ce82593fc6 simplified bindings 2024-09-24 15:48:15 +02:00
Jan-Peter Klein c2c3d778d1 added @CheckAvailability
changed exception handling
2024-09-24 15:29:13 +02:00
Jan-Peter Klein 7771181e15 changed wording to compact 2024-09-23 14:21:55 +02:00
Jan-Peter Klein 1a39333b4c cr mentioned changes 2024-09-23 14:02:42 +02:00
Armin Schrenk 85472db00a Merge branch 'main' into develop 2024-09-18 13:25:15 +02:00
Armin Schrenk d6a020994e Merge branch 'hotfix/1.14.1' 2024-09-18 13:17:25 +02:00
Armin Schrenk 518f75be32 fixes #3538 2024-09-18 13:16:45 +02:00
Armin Schrenk 28c7dbad69 prepare 1.14.1 2024-09-18 13:16:16 +02:00
Jan-Peter Klein 31e9f3a025 Merge branch 'feature/redesign-mainwindow' into feature/condensed-vault-list 2024-09-17 18:06:14 +02:00
Jan-Peter Klein a03d5af144 add tilter to display only folders with write permissions 2024-09-17 16:49:31 +02:00
Armin Schrenk 50a654d5af [ci skip] use recommended winget-releaser version 2024-09-17 11:37:27 +02:00
Armin Schrenk 1954f31910 [ci skip] Merge branch 'main' into develop 2024-09-17 10:04:32 +02:00
Armin Schrenk 68bf441fdd Merge branch 'release/1.14.0' 2024-09-17 10:03:02 +02:00
Armin Schrenk a606bcb81e finalize 1.14.0 2024-09-17 09:59:22 +02:00
Armin Schrenk fe93e51ffa Merge branch 'develop' into release/1.14.0 2024-09-17 09:51:23 +02:00
CryptobotandGitHub f2949aae63 New Crowdin updates (#3520)
New translations strings.properties

Chinese Simplified; Chinese Traditional; Filipino; German; Punjabi; Romanian; Russian; Slovenian; Turkish; Ukrainian; 

[ci skip]
2024-09-17 09:49:55 +02:00
Armin Schrenk 80e101456b adjust keychainManager to new API 2024-09-16 17:40:49 +02:00
Armin Schrenk 2f311c1dfe use final releases 2024-09-16 17:29:24 +02:00
Jan-Peter Klein c5cfe4d1b3 removed unnecessary properties 2024-09-16 15:40:52 +02:00
Jan-Peter Klein a09b55c81b triggered updatechecker in constructor 2024-09-16 15:39:14 +02:00
Jan-Peter Klein 32f266c721 removed unused vbox in controller 2024-09-16 15:26:45 +02:00
Jan-Peter Klein 3adffad087 removed ALT+F4 shortcut, it is already registered by default 2024-09-16 14:55:51 +02:00
Jan-Peter Klein 84e3cf0762 removed green border and fixed margin for windows 2024-09-16 14:48:06 +02:00
Jan-Peter Klein 1292936904 clean up 2024-09-13 11:49:05 +02:00
Jan-Peter Klein 7a913c89c9 condensed vault list implemented 2024-09-12 11:36:14 +02:00
Jan-Peter Klein 4c4816bdab fixed missing import 2024-09-11 15:10:23 +02:00
Jan-Peter Klein f9bfd5d1b1 set stage owner 2024-09-11 15:06:27 +02:00
Jan-Peter Klein 00e1e3654e implemented remove cert dialog 2024-09-10 18:01:09 +02:00
Tobias HagemannandGitHub 8aaee3710a Update README.md 2024-09-10 11:57:03 +02:00
Jan-Peter Klein 1946fc6c0e filter hidden directories 2024-09-04 15:05:24 +02:00
Jan-Peter Klein 8fb95b67d9 changes mentioned in pull #3270 2024-09-04 14:28:42 +02:00
Jan-Peter Klein e6890e8fa5 Merge branch 'develop' of https://github.com/siard-y/cryptomator into feature/gdrive-presets 2024-09-04 13:56:47 +02:00
Jan-Peter Klein 7cdb2025dc improved supporter cert ui with cert stemp, donate/sponsors link buttons and remove button with dialog 2024-09-04 13:23:36 +02:00
Armin SchrenkandGitHub 414d81dc06 Update mac-dmg.yml
Switch to macOS-12 due to errors
2024-08-20 18:17:08 +02:00
Armin SchrenkandGitHub b450ab028d Update mac-dmg.yml
macos-11 is no more
2024-08-20 17:42:32 +02:00
Armin Schrenk 5a51e53603 Merge branch 'develop' into release/1.14.0 2024-08-20 11:18:22 +02:00
Armin Schrenk d65beb632d Fixes #3519 2024-08-20 11:10:26 +02:00
Armin Schrenk 2b03477d31 prepare 1.14.0 2024-08-19 16:36:31 +02:00
CryptobotandGitHub f25e23da82 New Crowdin updates (#3463)
New translations strings.properties

Arabic; Chinese Simplified; Chinese Traditional; Dutch; Filipino; French; German; Greek; Italian; Japanese; Korean; Persian; Polish; Portuguese; Portuguese, Brazilian; Punjabi; Russian; Slovak; Spanish; Swedish; Turkish; Urdu (Pakistan); 

[ci skip]
2024-08-19 16:33:41 +02:00
dependabot[bot]andGitHub 82368e2632 Bump the java-production-dependencies group across 1 directory with 9 updates (#3516) 2024-08-19 14:29:15 +00:00
dependabot[bot]andGitHub 9057090b56 Bump the maven-build-plugins group across 1 directory with 3 updates (#3513) 2024-08-19 14:18:32 +00:00
dependabot[bot]andGitHub 357937e0bf Bump the java-test-dependencies group across 1 directory with 2 updates (#3514) 2024-08-19 14:17:07 +00:00
Armin Schrenk f84a2396eb ignore integrations-api 2.0.0-alpha1 2024-08-19 10:42:58 +02:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>Armin Schrenk
193dcad6e8 Bump the javafx group with 5 updates (#3498)
* Bump javafx from 22.0.1 to 22.0.2
* update build scripts to updated jfx version

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Armin Schrenk <armin.schrenk@skymatic.de>
2024-08-19 10:34:14 +02:00
Armin Schrenk 257f4427b8 catch all methods of adding a vault for #2880 2024-08-19 10:27:13 +02:00
Armin Schrenk 4778ba0770 add autostart for deb artifact 2024-08-16 15:56:58 +02:00
Armin SchrenkandGitHub 77b908199e Mitigates #2880 (#3512) 2024-08-16 12:59:38 +02:00
Armin SchrenkandGitHub d448c42f87 Feature: JDK 22.0.2+9 for release artifacts (#3510)
* update jdks for release artifacts to jdk 22.02+9
2024-08-14 16:40:44 +02:00
Armin Schrenk b9403222ba add java.compiler module to build scripts
references 93d0fd41a6 and https://github.com/google/dagger/issues/4321
2024-08-13 16:28:09 +02:00
Armin Schrenk 93d0fd41a6 Update cryptofs to 2.7.0-beta1
Closes #2058
2024-08-13 11:59:23 +02:00
Armin Schrenk 067bd4752c prevent leaking of NVD API key into logs 2024-08-09 11:30:16 +02:00
Armin Schrenk fb4f9fc68f Update integrations-win and -linux for quickAccess service providers 2024-08-09 11:05:02 +02:00
Armin SchrenkandGitHub a20667a156 Merge pull request #3494 from cryptomator/feature/quick-access
Feature: Add unlocked vaults to an quick access area
2024-08-07 16:42:53 +02:00
Armin Schrenk 4d47544244 cleanup 2024-08-07 16:32:30 +02:00
Armin Schrenk d59f149f7c Load quick access service lazy 2024-08-06 15:17:18 +02:00
Armin Schrenk 028f6e7a02 clean up 2024-08-06 15:08:29 +02:00
Armin Schrenk 71e4f98665 hard code default quickaccess service 2024-08-06 12:26:26 +02:00
Tobias Hagemann d60ced52fe added codesigning jdk files in build.sh for local macos builds to match mac-dmg.yml ci build 2024-07-30 21:14:32 +02:00
Tobias Hagemann 45c7d2b071 added provisioning profile to mac build process with updated entitlements 2024-07-30 18:48:54 +02:00
Ralph PlawetzkiandGitHub 7a789d2eed Fixes #3501 (PR #3502) 2024-07-30 12:27:16 +02:00
Armin Schrenk cc1e542146 clean up 2024-07-23 16:50:27 +02:00
Armin Schrenk e4e84d46b6 hide option, if no quick access service is present 2024-07-23 16:50:15 +02:00
Armin Schrenk 61fc53bf9c rename internal method 2024-07-23 16:39:34 +02:00
Tobias HagemannandGitHub f8386a5a99 Update README.md 2024-07-18 15:09:05 +02:00
Armin Schrenk da7e89fc72 fix windows build script 2024-07-17 16:35:33 +02:00
Armin Schrenk 6b57a0ad9c add translation 2024-07-17 11:34:29 +02:00
Armin Schrenk f1eb997804 make quickAccessService togglable & selectable in UI 2024-07-16 17:25:47 +02:00
Armin Schrenk 2fe5180721 cleanup 2024-07-16 17:19:52 +02:00
Jan-Peter Klein 958c22bed8 Merge branch 'feature/redesign-mainwindow' in feature/notificationbar 2024-07-16 14:52:50 +02:00
Jan-Peter Klein 6ff640648f Merge branch 'develop' into feature/redesign-mainwindow 2024-07-16 14:48:50 +02:00
Jan-Peter Klein 7b132adfe2 adjust add vault button position for improved UI 2024-07-16 14:31:11 +02:00
Armin Schrenk 2fa88490bd update to integrations-api 1.4.0-beta2
* differ between using quick access and actual impl
* rename properties
2024-07-16 13:36:37 +02:00
Jan-Peter Klein 5f5b5a5426 set preferences window min width and height 2024-07-09 13:48:45 +02:00
Jan-Peter Klein cb054bb4f5 fix update available check in preference tab selection 2024-07-09 13:46:41 +02:00
Jan-Peter Klein 3497144034 introduced NotificationBar control 2024-07-08 16:42:49 +02:00
dependabot[bot]andGitHub b4f9bc62ca Bump the maven-build-plugins group across 1 directory with 3 updates (#3484) 2024-07-08 07:52:56 +00:00
Tobias HagemannandGitHub 34bface2d7 Merge pull request #3481 from purejava/fix-#3480 2024-07-07 16:40:40 +02:00
Ralph Plawetzki 70e52b1a31 Fix typo
Closes #3480
2024-07-07 15:41:28 +02:00
Tobias HagemannandGitHub 59a2398c4c Update README.md 2024-07-04 11:49:37 +02:00
Jan-Peter Klein edbeea5502 fixed update check on start and bindings 2024-07-02 15:31:28 +02:00
Jan-Peter Klein a88e08147d changed background color of pref button 2024-07-02 15:08:07 +02:00
Jan-Peter Klein 8ff06a3efd implement hideable notification bars 2024-07-02 12:43:27 +02:00
Jan-Peter Klein 902c66cf1e removed vbox id and renamed style 2024-07-01 18:19:30 +02:00
Jan-Peter Klein d58307d1d6 optimize vaultList height update to avoid repeated bindings 2024-07-01 13:09:53 +02:00
Jan-Peter Klein 3e6204a657 remove showMinimizeButton setting 2024-07-01 12:32:50 +02:00
Jan-Peter Klein e677a0beaa removed MainWindowTitleController and ResizeController and the corresponding fxml 2024-07-01 12:25:48 +02:00
Armin Schrenk e5003c1783 use quick access service in unlock/lock 2024-06-27 17:47:05 +02:00
Jan-Peter Klein d379ada100 addded debug, update and support notification bar 2024-06-26 15:13:28 +02:00
Jan-Peter Klein cb7d0ade47 fixed some SonarCloud mentioned issues 2024-06-26 13:43:21 +02:00
Armin Schrenk d6fd012f71 fix av whitelisting step in win-exe workflow 2024-06-26 13:28:37 +02:00
Armin Schrenk d9d8c84230 adjust formatting of metainfo file 2024-06-26 13:23:38 +02:00
Jan-Peter Klein 4d9dc4312d Merge branch 'develop' into feature/redesign-mainwindow 2024-06-26 13:07:53 +02:00
Julian Raufelder 1ad2cc3ee5 Update to JDK 22 2024-06-26 11:57:17 +02:00
Armin Schrenk 2eac09f6be [ci skip] Merge branch 'main' into develop 2024-06-26 10:29:47 +02:00
Armin Schrenk 4114ea6163 Merge branch 'release/1.13.0' 2024-06-26 10:29:15 +02:00
Armin Schrenk 82da9f7a88 finalize release 2024-06-26 10:27:29 +02:00
Armin Schrenk aa08046c4d Merge branch 'develop' into release/1.13.0 2024-06-21 15:18:39 +02:00
Armin Schrenk b6d7f63470 [ci skip] also sign binaries from CraC project (dammn zulu jdk) 2024-06-21 15:10:47 +02:00
Armin Schrenk 624d18238c Merge branch 'develop' into release/1.13.0 2024-06-21 14:38:38 +02:00
Armin Schrenk 3bfe2b7a9e fix Windows build 2024-06-21 14:38:17 +02:00
Armin Schrenk ba79cd0f8c prepare 1.13.0 2024-06-21 11:55:54 +02:00
Armin Schrenk be63ea1104 Closes #3439 2024-06-21 11:51:49 +02:00
CryptobotandGitHub a3ad2a5677 New Crowdin updates (#3355)
New translations strings.properties

Arabic; Bashkir; Belarusian; Bengali; Bosnian; Bulgarian; Catalan; Chinese Simplified; Chinese Traditional; Chinese Traditional, Hong Kong; Croatian; Czech; Danish; Dutch; Filipino; Finnish; French; Galician; German; Greek; Hebrew; Hindi; Hungarian; Indonesian; Italian; Japanese; Korean; Latvian; Macedonian; Marathi; 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]
2024-06-21 11:29:09 +02:00
dependabot[bot]andGitHub 26e5ceea01 Bump the maven-build-plugins group with 2 updates (#3459) 2024-06-21 08:20:05 +00:00
dependabot[bot]andGitHub 83f1c4ea41 Bump org.mockito:mockito-core in the java-test-dependencies group (#3427) 2024-06-21 08:19:43 +00:00
Armin SchrenkandGitHub 8d78e1432a Merge pull request #3454 from cryptomator/feature/jfx22
Feature: Update to jfx22
2024-06-20 14:43:15 +02:00
mindmonkandGitHub d2ec5a5646 Merge pull request #3457 from cryptomator/feature/dokany-info-dialog
Feature: Migrate volume type Dokany to Default one and Display Info Dialog
2024-06-17 12:20:39 +02:00
Jan-Peter Klein 6bb0328799 removed dialog in naming 2024-06-14 14:20:18 +02:00
Jan-Peter Klein 8a8617b480 renamed method and code refactored 2024-06-14 11:07:21 +02:00
Jan-Peter Klein 92fad41b96 Merge branch 'develop' into feature/redesign-mainwindow 2024-06-13 12:49:59 +02:00
Jan-Peter Klein 7484744038 minor text change 2024-06-13 12:06:38 +02:00
Jan-Peter Klein 0bbc4ecae5 refactored code and new method handleDokanySupportEndAndShowDialog 2024-06-13 12:06:18 +02:00
Jan-Peter Klein 9fcb166047 close dialog by click on 'Open Preferences' 2024-06-13 12:04:34 +02:00
Jan-Peter Klein 1ac017e3ab changed dialog prefix 2024-06-13 11:51:01 +02:00
Jan-Peter Klein 1ba401b8e6 changed wording of button and description
primary color for icon
2024-06-12 12:02:40 +02:00
Armin Schrenk 07303b58f7 Merge branch 'develop' into feature/jfx22 2024-06-12 11:16:41 +02:00
Armin SchrenkandGitHub 32a463768c Merge pull request #3456 from purejava/fix-#3453
Workaround for malformed javafx POM. Closes #3453.
2024-06-12 11:14:52 +02:00
Armin Schrenk 2307950e3b add javafx.platform property workaround to other build/ci scripts 2024-06-12 10:58:49 +02:00
Ralph Plawetzki 8108128c22 Temporary work around for JavaFX upstream bug
Occurs with Maven 3.9.7, fixed with Gluon JavaFX 23-ea+20, that contains a fixed parent POM
See https://mail.openjdk.org/pipermail/openjfx-dev/2024-May/047279.html
2024-06-11 19:59:18 +02:00
Jan-Peter Klein 58fe6da7a8 Merge branch 'develop' into feature/dokany-info-dialog 2024-06-11 15:25:23 +02:00
Jan-Peter Klein 92bf73297a add dokany info dialog 2024-06-11 14:43:56 +02:00
Armin Schrenk 0bf8fb39dd Update to javafx 22.0.1 2024-06-07 15:39:42 +02:00
Armin Schrenk 0dc9a3a834 align local build scripts 2024-06-07 14:56:54 +02:00
Armin Schrenk 91d6264b9f ignore downloaded artifact 2024-06-06 12:10:03 +02:00
Armin Schrenk d2599ea525 closes #2656 2024-06-06 12:07:18 +02:00
dependabot[bot]andGitHub 7180af9bc7 Bump the java-production-dependencies group across 1 directory with 9 updates (#3446) 2024-06-03 10:30:50 +00:00
Armin SchrenkandGitHub dc993dc57c fixes #3440 (PR in #3447) 2024-06-03 12:29:54 +02:00
dependabot[bot]andGitHub 464c74ab6c Bump the maven-build-plugins group across 1 directory with 2 updates (#3431) 2024-06-03 09:39:36 +00:00
Jan-Peter Klein e038348dca changed mainWindow StageStyle to UNDECORATED
removed main_window_title area
moved main_window_resize functions to MainWindowController
put add vault button under the vault list and wrapped both in a ScrollPane
bound vault list height properties to amount of entries and width to scroll pane width
add listener to scroll down after adding a vault
moved preferences button under vault list
new style classes for new elements
changed wording
2024-05-28 21:56:03 +02:00
Armin SchrenkandGitHub 8c7dd8c74f Merge pull request #3435 from cryptomator/feature/jdk22
Feature: JDK22
2024-05-21 16:58:57 +02:00
Armin Schrenk 69bcf6fac6 do not forget to update debian files
(dammn you unflexible launchpad!)
2024-05-21 12:51:01 +02:00
Armin Schrenk 7c243dd434 pin cryptolib version due removed jdk.crypto.ec package 2024-05-16 17:51:04 +02:00
Armin Schrenk 357a0b9c31 closes #3376 2024-05-14 17:58:21 +02:00
Armin Schrenk d69d11b82f update dependencies requiring JDK 22 2024-05-14 17:25:56 +02:00
mindmonkandGitHub 863e9bbcb3 Merge pull request #3362 from cryptomator/feature/update-checker-refactoring
Feature: Expansion of Preferences Update Tab with UI Elements and Refactoring of UpdateChecker
2024-05-10 16:31:26 +02:00
Jan-Peter Klein 1c47012033 undo getter changes 2024-05-10 15:57:04 +02:00
Jan-Peter Klein cd99eaa323 updateAvailable ObservableValue to BooleanBinding 2024-05-10 15:51:41 +02:00
Jan-Peter Klein dda2afda92 refactored ObservableValues to BooleanBindings and code cleanup 2024-05-10 15:45:17 +02:00
Jan-Peter Klein 5519eefcfa cr related changes 2024-05-10 14:55:50 +02:00
Jan-Peter Klein a81352800d removed twoWeeksAgo var 2024-05-08 11:38:23 +02:00
Jan-Peter Klein 6fec16e498 removed unused ui function 2024-05-08 10:57:42 +02:00
Jan-Peter Klein 42f31204a3 removed lastUpdateReminder setting 2024-05-08 09:41:58 +02:00
Jan-Peter Klein 7ab64cfe46 removed lastUpdateReminder setting 2024-05-08 09:05:26 +02:00
Jan-Peter Klein 1581a10c04 removed unused label id 2024-05-08 08:30:06 +02:00
Jan-Peter Klein 249becc25d removed unused instance var 2024-05-08 08:28:53 +02:00
Jan-Peter Klein da8e84f39d removed unnecessary HBox 2024-05-07 13:27:52 +02:00
Jan-Peter Klein 9ad2d223c3 changed BooleanBinding updateAvailable to ObservableValue<Boolean> 2024-05-07 13:23:53 +02:00
Jan-Peter Klein 3bf1e659ef changed checkFailed text wording 2024-05-07 12:41:39 +02:00
Jan-Peter Klein e79257e5ea changed checkFailed property to ObservableValue 2024-05-06 13:46:49 +02:00
Armin Schrenk dac517a6fb update project ot jdk 22
Note: dependency bumps regarding jdk22 compatiblilty are missing!
2024-05-02 16:59:45 +02:00
mindmonkandGitHub 1ab808f1b0 Merge pull request #3414 from MSevenR/feature/double-click-unlocked-vault
Double-click on an Unlocked Vault
2024-05-02 09:31:56 +02:00
Jan-Peter Klein 08f81b7df4 registered module in SettingsJsonTest 2024-04-29 11:12:14 +02:00
Jan-Peter Klein b16f32ca83 introduced new dependency
removed latestVersion from Settings
changed SettingsJson from Date to Instant
new UpdateChecker Property checkFailed
optimized naming
changed wordning
refactoring
2024-04-29 10:34:17 +02:00
MSevenR d6ed88b544 Double-click on an Unlocked Vault
Double-click on an Unlocked Vault in the List to Reveal It
2024-04-26 01:44:45 -05:00
Jan-Peter Klein ae697d7b73 refactor isUpdateSuccessfulAndCurrent to instance variable 2024-04-25 10:54:00 +02:00
Jan-Peter Klein ff3306cc17 removed blank line, unused instance variable, import and Logger
refactored DateTimeFormatter into an instance variable
2024-04-24 15:03:49 +02:00
Armin Schrenk 9ae2f4e0f6 add timezone id to timestamp in settings 2024-04-23 16:12:59 +02:00
Armin Schrenk 4230afcbac refactored timeDiff-message-method to updatePref controller 2024-04-23 16:12:36 +02:00
Armin Schrenk 7fc6ab05a4 use Instant also in UpdateChecker 2024-04-23 15:19:45 +02:00
Armin Schrenk 060f6bfc97 change storage of timestamps in model to Instant 2024-04-23 15:18:37 +02:00
Jan-Peter Klein 919dac6caa refactoring 2024-04-22 16:35:20 +02:00
Jan-Peter Klein 98bcf63b2c remove lastUpdateCheck from Settings; add lastUpdateReminder and lastSuccessfulUpdateCheck
implement updateTimeDifferenceMessage
reorder UI elements
refactor code for clarity and maintainability
2024-04-17 11:40:58 +02:00
Tobias HagemannandGitHub 0585262952 Merge pull request #3395 from purejava/flathub-colour-banners
Add coloured banners for app in Flathub store
2024-04-13 16:33:31 +02:00
Ralph PlawetzkiandGitHub a33dc3980e Use colours from Cryptomator CD manual 2024-04-13 15:36:52 +02:00
Ralph PlawetzkiandGitHub caa5e77386 Swap the light and dark colors, it's calmer for the eye 2024-04-13 08:48:20 +02:00
Ralph Plawetzki c037920e79 Add coloured banners for app in Flathub store 2024-04-12 17:45:38 +02:00
Armin SchrenkandGitHub 3cdd352d39 Update check-jdk-updates.yml
Use latest jdk version for jdk check
2024-04-10 12:27:05 +02:00
dependabot[bot]andGitHub 8ae80e2932 Bump the maven-build-plugins group with 2 updates (#3391) 2024-04-09 08:34:03 +00:00
dependabot[bot]andGitHub 2ffa1ee236 Bump the github-actions group with 2 updates (#3387) 2024-04-09 08:16:34 +00:00
Tobias HagemannandGitHub 2bf5b57823 Update README.md
[ci skip]
2024-04-05 12:33:38 +02:00
Jan-Peter Klein 853ea69180 updated log error message as suggested by coderabbit 2024-04-04 13:30:47 +02:00
Jan-Peter Klein 43d0dd99ec adjusted code as per PR suggestions 2024-04-04 12:37:56 +02:00
Armin Schrenk b40e6db701 Merge branch 'main' into develop 2024-03-27 13:02:32 +01:00
Armin Schrenk 387eb420eb Merge branch 'hotfix/1.12.4' 2024-03-27 12:58:36 +01:00
Armin Schrenk 7785bb8820 finalize 1.12.4 2024-03-27 12:57:55 +01:00
Armin Schrenk de4fa8c7b0 use latest WiX version
fixes CVE-2024-29187 and CVE-2024-29188
2024-03-27 12:55:13 +01:00
Armin Schrenk 17f519e01c prepare 1.12.4 2024-03-27 12:53:49 +01:00
dependabot[bot]andGitHub 6c50023074 Bump the maven-build-plugins group with 2 updates (#3380) 2024-03-25 09:09:23 +00:00
Sebastian Stenzel 0009940e1e adjusted after dependency update 2024-03-14 12:09:10 +01:00
Armin Schrenk f2a50b59b5 well, that should be the last reference to dokany 2024-03-12 09:56:30 +01:00
Armin SchrenkandGitHub ed03606981 One should also remove the actual dependency 2024-03-12 09:51:11 +01:00
Armin Schrenk 4a1eaf25c7 Closes #3361, Fixes #3351 2024-03-12 09:46:37 +01:00
dependabot[bot]andGitHub f5e445a610 Bump the java-production-dependencies group with 3 updates (#3365) 2024-03-12 07:57:00 +00:00
Jan-Peter Klein 6a3a256c0b Merge branch 'develop' into feature/update-checker-refactoring 2024-03-08 10:28:16 +01:00
Jan-Peter Klein 1ed77ebcc0 code cleanup 2024-03-08 10:27:35 +01:00
Jan-Peter Klein db224e9e5c added latestVersion and lastUpdateCheck to settings and integrated with update checker 2024-03-08 09:58:59 +01:00
dependabot[bot]andGitHub c719982ef3 Bump the github-actions group with 1 update (#3354) 2024-03-05 17:24:28 +00:00
dependabot[bot]andGitHub f783f5d5ec Bump the java-test-dependencies group with 1 update (#3358) 2024-03-05 17:21:45 +00:00
dependabot[bot]andGitHub dd4f87b54c Bump the java-production-dependencies group with 4 updates (#3359) 2024-03-05 17:21:09 +00:00
Jan-Peter Klein b3789700e1 add upToDateLabel and fix update indicator issue 2024-03-05 12:56:38 +01:00
Jan-Peter Klein b39834f4eb Merge branch 'develop' into feature/update-checker-refactoring 2024-03-05 10:18:32 +01:00
Jan-Peter Klein 8064d75102 removed state label and reorganized ui elements 2024-03-05 10:15:11 +01:00
Jan-Peter Klein 4064b61cd7 refactored updateChecker by incorporating state management and date tracking 2024-02-29 09:29:26 +01:00
Armin Schrenk ef3affece3 [ci skip] fix wrong PR description in flathub workflow 2024-02-28 13:42:37 +01:00
Armin Schrenk 414465371b [ci skip] refactor win-exe workflow
* only publish, if msi and exe succeed
* make stable release jobs dependent of publish
2024-02-28 13:19:54 +01:00
Armin Schrenk feed72a729 [ci skip] fix flathub workflow 2024-02-27 22:52:56 +01:00
Armin Schrenk bca20a7a66 [ci skip] seperate av whitelisting into own workflow to be able to upload assets on failure 2024-02-27 18:55:14 +01:00
Armin Schrenk a38377baaa [ci skip] Merge branch 'main' into develop 2024-02-27 12:53:30 +01:00
Armin Schrenk 61a45fc738 Merge branch 'release/1.12.3' 2024-02-27 12:52:00 +01:00
Armin Schrenk 3a65b5551f adjust release check to changed metainfo file
references fcb940e29c
2024-02-27 12:48:36 +01:00
Armin Schrenk 94ed5c18b8 damnn merge from develop to release 2024-02-27 12:41:06 +01:00
Armin Schrenk a559483d86 finalize 1.12.3 2024-02-27 12:38:52 +01:00
Armin Schrenk 3acdef1dd0 Merge branch 'develop' into release/1.12.3 2024-02-27 12:37:13 +01:00
Armin Schrenk def6f8ab95 [ci skip] clean up 2024-02-27 12:35:55 +01:00
Armin Schrenk 11ba1f3ddc revert 1ab73be1f4 and 2d968eac8c 2024-02-27 12:32:37 +01:00
CryptobotandGitHub 3228f2cf5f New Crowdin updates (#3343)
New translations strings.properties

Chinese Simplified; Dutch; French; Japanese; Portuguese; Russian; Slovak; Swedish; 

[ci skip]
2024-02-27 10:23:56 +01:00
Armin Schrenk 9c4f7ad79d [ci skip] remove unknown env/style combination from appstream metadata 2024-02-26 17:41:18 +01:00
Armin Schrenk 3bd57d162b [ci skip] update appstream metadata 2024-02-26 17:37:04 +01:00
dependabot[bot]andGitHub 5ea73a5a8d Bump the java-production-dependencies group with 1 update (#3347) 2024-02-26 09:50:42 +00:00
Armin Schrenk 38670838c7 [ci skip] Drop yq usage 2024-02-26 10:15:25 +01:00
Armin Schrenk 3e0b84dbce [ci skip] fix pr body description & reduce log noise 2024-02-23 17:39:38 +01:00
Armin Schrenk 2302db6206 [ci skip] fix create pr command in flathub job 2024-02-23 17:27:48 +01:00
Armin Schrenk a94bf99660 [ci skip] automatically set up tracking branch on push 2024-02-23 17:13:11 +01:00
Armin Schrenk 0c5ce353b1 [ci skip] use github.actor 2024-02-23 17:05:26 +01:00
Armin Schrenk b3ce777a42 [ci skip] configure git in flathub job 2024-02-23 16:29:18 +01:00
Armin Schrenk 3085df3397 [ci skip] further fixes:
* remove yq after update
* set token for git
2024-02-23 16:14:21 +01:00
Armin Schrenk fb740b605f add missing quote char [ci skip] 2024-02-23 15:57:06 +01:00
Armin Schrenk 6a74d9f3b2 use same varaible in get-version job 2024-02-23 15:53:22 +01:00
Armin Schrenk 1c7dffb63f Add ci job to create flathub PR on release [ci skip] 2024-02-23 15:44:48 +01:00
Jan-Peter Klein a213f073b1 enhance screen selection by adding primary fallback 2024-02-23 10:51:23 +01:00
Armin Schrenk 1ab73be1f4 fixes #3344 2024-02-22 16:11:54 +01:00
Armin Schrenk 8412871090 apply proper formatting and state to error dialog 2024-02-22 12:23:43 +01:00
Armin Schrenk fa63f3ca67 Reset develop to SNAPSHOT version 2024-02-22 12:21:00 +01:00
Armin Schrenk dbc0f52481 fix not-uploading artifacts on release 2024-02-21 22:04:35 +01:00
Armin Schrenk b8cd1caeac also upload asc file as artifact for mac build 2024-02-21 13:09:14 +01:00
Armin Schrenk 43c25b6d97 fix ci
references 84732337ca
2024-02-21 12:53:01 +01:00
Armin Schrenk e44bc09074 Merge branch 'develop' into release/1.12.3 2024-02-21 12:20:36 +01:00
CryptobotandGitHub 7b02f78ef5 New Crowdin updates (#3342)
New translations strings.properties

Arabic; Bashkir; Belarusian; Bengali; Bosnian; Bulgarian; Catalan; Chinese Simplified; Chinese Traditional; Chinese Traditional, Hong Kong; Croatian; Czech; Danish; Dutch; Filipino; Finnish; French; Galician; German; Greek; Hebrew; Hindi; Hungarian; Indonesian; Italian; Japanese; Korean; Latvian; Macedonian; Marathi; 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]
2024-02-21 12:13:24 +01:00
Armin Schrenk f7e8a4d1e6 prepare 1.12.3 2024-02-20 18:13:01 +01:00
Armin Schrenk 664375d692 fix wrong method name 2024-02-20 18:06:55 +01:00
Armin SchrenkandGitHub 2d968eac8c Merge pull request #3336 from cryptomator/feature/3272-vaultid-as-mountpoint
Feature: For FUSE-Ts default mountpoint use vault id as mountpoint
2024-02-20 17:34:09 +01:00
Armin Schrenk 542d2fcfe1 only create winget PR for stable versions [ci skip] 2024-02-19 16:42:42 +01:00
mindmonkandGitHub 144e929896 Merge pull request #3335 from cryptomator/feature/center-unlock-dialog-on-mainstage
Center Unlock Success Dialog on Main Application Window
2024-02-19 15:05:28 +01:00
Armin Schrenk 803748f78d update code-sign-action [ci skip] 2024-02-19 14:46:58 +01:00
Armin Schrenk 3410e7243a Update minimal required macOS version for dmg
due to javafx update in 7d281e2878
2024-02-19 13:02:05 +01:00
Armin Schrenk 84732337ca removed GTK-2 support
due to javafx update in 7d281e2878
2024-02-19 12:17:11 +01:00
dependabot[bot]andGitHub c527808710 Bump the java-production-dependencies group with 4 updates (#3340) 2024-02-19 09:35:25 +00:00
Armin Schrenk 99c89dbf39 fix possible null comparsion 2024-02-19 10:22:22 +01:00
Jan-Peter Klein 829b64cd3d dialog centers on main app screen if mainWindow is hidden 2024-02-19 08:55:16 +01:00
Jan-Peter Klein f4007267fb simplified the code and removed the function 2024-02-16 17:31:20 +01:00
Armin Schrenk c82a0bfaf3 cleanup 2024-02-16 17:09:05 +01:00
Armin SchrenkandGitHub 251ad65344 Merge pull request #3327 from cryptomator/feature/3233-load-presets-background
Feature: Load LocationPresets in background and show indicator in UI
2024-02-16 16:21:01 +01:00
Jan-Peter Klein 155ba4607b introduced functionality to center the unlock screen within the main application window 2024-02-16 15:24:52 +01:00
Armin Schrenk 62f6865d3e cleanup created directories after mount
fails silently
2024-02-14 10:30:51 +01:00
Armin Schrenk ffb3290248 Merge branch 'develop' into feature/3272-vaultid-as-mountpoint 2024-02-14 10:29:30 +01:00
Armin Schrenk a013ae3d91 [ci skip] change mountPointDir for macOS-Dev-run profile
aligns production build
2024-02-14 10:29:14 +01:00
Armin Schrenk 19a954e677 use correct mountProvider 2024-02-14 10:05:56 +01:00
Armin Schrenk f262980acc closes #3272 2024-02-13 16:37:46 +01:00
Armin Schrenk 3b3aa18c92 fixes #3233
this time with gc prevention of a binding
2024-02-13 00:55:07 +01:00
Armin Schrenk c7b8bc89c2 also don't bother upload to av scan, if not published 2024-02-12 13:18:17 +01:00
Armin Schrenk 5fc981abd3 prevent automatic overwrite of already released files 2024-02-12 13:16:45 +01:00
Armin Schrenk 36ec1a5ebc update windows update url [ci skip] 2024-02-09 18:37:19 +01:00
Armin Schrenk be4aad4168 set default value for Windows debug flag 2024-02-09 17:03:22 +01:00
Armin Schrenk fcb940e29c update release section of appstream metainfo file [ci skip] 2024-02-09 14:52:10 +01:00
Armin Schrenk 4f3ca2a6c4 fix appimage build script [ci skip] 2024-02-09 12:56:33 +01:00
Armin Schrenk 27cd34bee0 Merge branch 'main' into develop [ci skip] 2024-02-09 12:53:16 +01:00
Armin Schrenk c07e51be51 Merge branch 'release/1.12.2' 2024-02-09 12:51:57 +01:00
Armin Schrenk 0421879b39 finalize 1.12.2 2024-02-09 12:51:19 +01:00
Armin Schrenk 2d627717a0 prepare 1.12.2 2024-02-09 10:59:33 +01:00
Armin Schrenk dc0e88a694 fixes #3319 2024-02-09 10:55:27 +01:00
Armin Schrenk a5e3630375 also specify version for winget release [ci skip] 2024-02-08 17:47:50 +01:00
Armin Schrenk 17335e8f70 shorten workflow name [ci skip] 2024-02-08 17:39:38 +01:00
Armin Schrenk 42dd2fba48 github cli needs special token in CI env [ci skip] 2024-02-08 17:37:50 +01:00
Armin Schrenk e1cca6427c Add ci job for releasing to winget 2024-02-08 17:34:02 +01:00
Armin Schrenk 42d3dbaa23 always use latest version of winfsp-uninstaller 2024-02-08 17:10:40 +01:00
Armin Schrenk 185d67c492 Merge branch 'main' into develop [ci skip] 2024-02-07 11:43:59 +01:00
Armin Schrenk a8af3c8b40 Merge branch 'release/1.12.1' 2024-02-07 11:42:58 +01:00
Armin Schrenk 038a7fac62 finalize 1.12.1 2024-02-07 11:42:37 +01:00
Armin Schrenk 48408fa40d prepare 1.12.1 2024-02-07 11:37:44 +01:00
Armin Schrenk 18a417667e Fixes #3315 2024-02-07 11:33:45 +01:00
JaniruTEC aab07b13e3 Changed version specifier for dependency-check
See: https://github.com/cryptomator/cryptofs/pull/202#discussion_r1453615249
2024-02-06 22:28:16 +01:00
Armin Schrenk 869e40e351 use latest coffeelibs-jdk release 2024-02-06 15:34:09 +01:00
Armin Schrenk bf91e3f15c Merge branch 'main' into develop [ci skip] 2024-02-06 14:29:19 +01:00
Armin Schrenk 17544828e4 Merge branch 'release/1.12.0' 2024-02-06 14:28:08 +01:00
Armin Schrenk cfef3139b1 finalize 1.12.0 2024-02-06 14:20:50 +01:00
Armin Schrenk b01ba27b06 Partially reverting 24293b316f 2024-02-06 14:16:03 +01:00
Armin Schrenk 5a33e66a7d prepare 1.12.0 2024-02-06 11:31:42 +01:00
Armin Schrenk 3c4e35406e Bump dependencies 2024-02-06 11:27:02 +01:00
CryptobotandGitHub d3275fa4e7 New Crowdin updates (#3256)
New translations strings.properties

Arabic; Bashkir; Belarusian; Bulgarian; Catalan; Chinese Simplified; Chinese Traditional; Chinese Traditional, Hong Kong; Czech; Danish; Dutch; Filipino; French; German; Greek; Hebrew; Hungarian; Italian; Japanese; Korean; Latvian; Norwegian Bokmal; Polish; Portuguese; Portuguese, Brazilian; Punjabi; Romanian; Russian; Slovak; Spanish; Swahili, Tanzania; Swedish; Turkish; Vietnamese;

[ci skip]
2024-02-06 11:21:07 +01:00
dependabot[bot]andGitHub a30db34c19 Bump the java-production-dependencies group with 6 updates (#3295) 2024-02-06 10:18:33 +00:00
dependabot[bot]andGitHub 509100e7ae Bump the java-test-dependencies group with 2 updates (#3312) 2024-02-06 10:17:11 +00:00
dependabot[bot]andGitHub 024c34172b Bump the github-actions group with 5 updates (#3308) 2024-02-06 10:16:24 +00:00
dependabot[bot]andGitHub 638570562b Bump the maven-build-plugins group with 3 updates (#3300) 2024-02-06 10:15:06 +00:00
Sebastian StenzelandGitHub ee5a5c6563 Merge pull request #3291 from cryptomator/feature/legacy-device-migration
Hub 1.2.x → Hub 1.3.x Legacy Device Migration
2024-02-02 14:59:30 +01:00
Armin Schrenk 85c52c60c5 Revert "update javafx to 21.0.2"
This reverts commit 93184abd3c.
2024-02-02 10:45:34 +01:00
Armin Schrenk 93184abd3c update javafx to 21.0.2 2024-01-30 12:55:33 +01:00
Armin Schrenk 8062392ccd update jdk to 21.0.2+13 2024-01-30 12:17:45 +01:00
Jan-Peter Klein d49c02c7de optimize share vault fxml 2024-01-29 17:37:55 +01:00
Sebastian Stenzel d66cfe0e7c adjust to new migration API 2024-01-26 16:48:08 +01:00
mindmonkandGitHub fa26fa9dee Merge pull request #3289 from cryptomator/feature/share-vault
Feature: Introduce 'Share Vault' Functionality
2024-01-26 16:08:06 +01:00
Jan-Peter Klein 52fc94ca01 fixed a spelling error 2024-01-26 16:03:51 +01:00
Jan-Peter Klein e9a412ae16 improved layout and added styleClass for add-box 2024-01-26 15:42:25 +01:00
Jan-Peter Klein 8104c35d76 more specific translation keys and consistent spacing 2024-01-23 19:09:49 +01:00
Jan-Peter Klein baa2e05e69 improved wording and layout 2024-01-23 14:00:20 +01:00
Armin SchrenkandGitHub f50b204cef Merge pull request #3288 from cryptomator/feature/3246-split-device-registration
Feature: Split device registration into "normal" and "legacy" flow
2024-01-22 14:56:45 +01:00
lectricalandJaniruTEC ed902bc59f Hello 2024 2024-01-20 16:22:27 +01:00
Sebastian Stenzel 693299a5d7 first draft of legacy device migration
actual migration still missing due to API discussion
2024-01-20 13:28:56 +01:00
Sebastian Stenzel def64aa2ac added tests 2024-01-20 13:25:57 +01:00
Sebastian Stenzel c5bb8a131d dedup 2024-01-20 13:15:33 +01:00
Sebastian Stenzel 2e443c72a9 add new API encryptVaultKey(vaultKey, userKey)
and `decodeECPublicKey(byte[])`
2024-01-20 13:12:59 +01:00
Sebastian Stenzel e9ee17493b refactor API, expose decodeECPrivateKey(byte[]) 2024-01-20 13:01:48 +01:00
Sebastian Stenzel 35eb548d8e replaced Guava's BaseEncoding with Base64 2024-01-20 12:58:44 +01:00
Sebastian Stenzel dc5d6e734e deduplicate code 2024-01-19 17:55:36 +01:00
Sebastian Stenzel 729f38866f use string templates for URI construction 2024-01-19 17:40:39 +01:00
Jan-Peter Klein 4de8434f1b Merge branch 'develop' into feature/share-vault 2024-01-19 12:31:37 +01:00
Jan-Peter Klein cd40731b5f implemented open hub feature
optimized fxml files and img
2024-01-19 12:30:56 +01:00
Armin SchrenkandGitHub 24293b316f Merge pull request #3236 from cryptomator/feature/3233-locationpresets-background
Feature: Load LocationPresets in background and show indicator in UI
2024-01-19 10:51:46 +01:00
Armin Schrenk 062c674ef1 Always hide spinner, as soon as locationPresetLoading is finished 2024-01-19 10:44:06 +01:00
Armin SchrenkandGitHub 830bb5776f Use naming convention for comparator 2024-01-19 10:04:15 +01:00
Armin Schrenk bfdb23785e Merge branch 'develop' into feature/3233-locationpresets-background 2024-01-18 15:57:45 +01:00
Armin Schrenk 248d655afb ditch custom in-place sorting and rely on javafx methods 2024-01-18 15:45:45 +01:00
Armin Schrenk 995c0a4b92 remove unnecessary TODO 2024-01-17 23:30:41 +01:00
Armin Schrenk 42425afe56 closes #3246
splitting registerSuccess into two scenes, one for hub 1.3.x and one for legacy
2024-01-17 16:52:35 +01:00
Sebastian Stenzel a1b712495f switch back to UI thread later
see https://github.com/cryptomator/cryptomator/pull/3287#discussion_r1453196792
2024-01-17 13:35:23 +01:00
Sebastian Stenzel 2225476bf8 reordered methods
[ci skip]
2024-01-17 13:33:38 +01:00
Sebastian StenzelandGitHub 325057c548 Merge pull request #3287 from cryptomator/feature/refactored-hub-unlock
Refactored Hub Unlock
2024-01-17 13:32:09 +01:00
JaniruTECandGitHub b1a5eed2aa Merge pull request #3286 from cryptomator/refactoring/centralize-dependency-check
Externalize dependency-check
2024-01-16 19:54:32 +01:00
Jan-Peter Klein 4ca190cfb9 implemented a 'Share Vault' button in vault_detail_locked and added a new window for vault sharing options 2024-01-16 17:21:07 +01:00
GiwrgosTsifoutisandGitHub 828fd321cc Fixed "Locked Vault Options after unlocking vault #3249" (#3267)
Fixes #3249 

Bound the UIs disabled state to the vault's lock state without the need of a map
2024-01-16 12:32:36 +01:00
Armin Schrenk 2e32f39986 [ci skip] fix missing translation key
(cherry picked from commit daa026b285)
2024-01-16 11:38:54 +01:00
Armin Schrenk daa026b285 [ci skip] fix missing translation key 2024-01-16 11:38:33 +01:00
Sebastian Stenzel 87084e8c2a TODO now obsolete
as we will now re-attempt unlock when returning from device registration

[ci skip]
2024-01-16 04:14:06 +01:00
Sebastian Stenzel 8e52058373 re-attempt receiving key after registering device 2024-01-16 03:58:30 +01:00
Armin Schrenk 8bf0acf35f build release artifacts with javafx 21.0.1
references 7d281e2878
2024-01-15 16:35:34 +01:00
JaniruTECandGitHub e0d3a3d9c7 Externalized dependency-check 2024-01-15 16:12:27 +01:00
Sebastian Stenzel b59ce75ecd add step 0: check API level 2024-01-14 15:02:41 +01:00
Sebastian Stenzel 748f895b98 change unlock request order 2024-01-14 15:01:51 +01:00
Sebastian Stenzel 6d974c7fcf fix incorrect vaultId 2024-01-14 14:58:58 +01:00
Sebastian Stenzel 0ed73e8b41 use string templates for building /api/* URIs 2024-01-14 14:02:35 +01:00
Sebastian Stenzel 538b4ecd0b added javadoc 2024-01-14 13:59:23 +01:00
Armin Schrenk 8f32b46b30 set no jlink compression for build artifacts
references 00fc2a9837
2024-01-12 13:18:05 +01:00
Armin Schrenk 4de25afde0 wrap locations in scrollPane 2024-01-11 23:48:26 +01:00
Armin Schrenk 2e6c228f3f Merge branch 'develop' into feature/3233-locationpresets-background 2024-01-11 22:59:41 +01:00
Armin Schrenk 00fc2a9837 remove deprecate compress options and use default ones
see also https://bugs.openjdk.org/browse/JDK-8301124?jql=text%20~%20%22compress%22
2024-01-11 22:59:08 +01:00
Armin Schrenk 22e80e7dac update local appimage buildscript to download jmods 2024-01-11 22:56:41 +01:00
Armin Schrenk 517e05c378 use stable version of winfsp-uninstaller 2024-01-11 22:35:51 +01:00
Sebastian StenzelandGitHub 5759b7e596 Merge pull request #3210 from cryptomator/feature/3203-device-already-registered
Feature: Adjust Hub workflow, if device is already registerd
2024-01-11 12:05:25 +01:00
Sebastian Stenzel bfb26f6171 renamed field 2024-01-11 11:46:06 +01:00
Sebastian Stenzel f36e2bb4b7 reduced visibility 2024-01-11 11:45:57 +01:00
Sebastian Stenzel b85e455ff5 renamed field 2024-01-11 11:42:08 +01:00
Sebastian Stenzel a902400522 get rid of registerException
use separate views, no need to pass state between views
2024-01-11 11:23:54 +01:00
Sebastian Stenzel a6d6474294 Merge branch 'develop' into feature/3203-device-already-registered 2024-01-11 11:02:45 +01:00
Sebastian Stenzel 06859fe36b remove newline
[ci skip]
2024-01-11 10:27:42 +01:00
Sebastian StenzelandGitHub 7d7b7c1dc9 Merge pull request #3260 from cryptomator/feature/annihilate-FUPFMS
annihilate FUPFMS
2024-01-11 10:25:21 +01:00
Sebastian Stenzel 706d2b51be remove added newline
[ci skip]
2024-01-11 10:24:28 +01:00
Armin SchrenkandGitHub 92bf136a8b Merge pull request #3278 from mooons/issue-3277
Bump README's build dependency JDK version from 19 to 21
2024-01-09 12:03:21 +01:00
mooons f00f028d8b Bump README's build dependency JDK version from 19 to 21. Fix #3277 2024-01-09 01:57:59 -08:00
Siard d85c6c8f41 Create separate files for GoogleDrive presets providers. cryptomator/2921
- Change imports accordingly in module-info.java
2024-01-03 16:42:46 +01:00
Siard 17057e8f8d Add Google Drive presets improvement. cryptomator/2921
- The code now defaults to searching through '~/Library/CloudStorage/GoogleDrive-*/*' before using the fallback options.
2024-01-03 16:41:11 +01:00
dependabot[bot]andGitHub 325092efb0 Bump the java-test-dependencies group with 1 update (#3238) 2023-12-26 04:32:24 +00:00
dependabot[bot]andGitHub aaf8036713 Bump the maven-build-plugins group with 3 updates (#3264) 2023-12-25 19:40:21 +00:00
Sebastian Stenzel c86ee679a9 renamed fuse-specific exception to be more generic 2023-12-21 10:05:22 +01:00
Sebastian Stenzel a0fcb63a1a replaced FUPFMS
with more generic set of used mount services
2023-12-21 09:40:43 +01:00
Armin SchrenkandGitHub 55ba255651 Update dependency-check.yml
to not run into 403 due to rate limit
2023-12-18 10:49:47 +01:00
dependabot[bot]andGitHub 47df4213c3 Bump the java-production-dependencies group with 5 updates (#3255) 2023-12-18 09:40:34 +00:00
Armin Schrenk 6929760979 adjust dependency check plugin 2023-12-13 16:47:30 +01:00
Armin Schrenk 720fbd0e6b use separate cache for dependency-cache data 2023-12-13 16:47:08 +01:00
mindmonkandGitHub 923af4bc83 Merge pull request #3199 from cryptomator/feature/vault-volume-type
Feature: Customizable Volume Type Options for Each Vault
2023-12-13 16:16:08 +01:00
Jan-Peter Klein e9c464ba8f sonar cloud issues solved 2023-12-13 15:56:39 +01:00
Jan-Peter Klein 7b0f616747 Merge branch 'develop' into feature/vault-volume-type 2023-12-13 15:50:55 +01:00
Jan-Peter Klein 65788f3c1f pr mentioned changes 2023-12-13 15:50:37 +01:00
Jan-Peter Klein f55fbf0f64 code cleanup and optimized a description text 2023-12-13 09:25:50 +01:00
Armin Schrenk 851838e3a2 remove run of dependency-chec workflow for release branches (already done in check release workflow) 2023-12-12 14:58:48 +01:00
Armin Schrenk e194f9b205 update dependency check and refactor to own workflow 2023-12-12 14:56:48 +01:00
Jan-Peter Klein 2f8df88ad5 Merge branch 'develop' into feature/vault-volume-type
# Conflicts:
#	src/main/java/org/cryptomator/ui/unlock/UnlockWorkflow.java
2023-12-12 12:48:59 +01:00
Jan-Peter Klein 55247d9f8a moved provideDefaultMountService to MountModule and renamed problematicFuseMountServices to CONFLICTING_MOUNT_SERVICES 2023-12-12 12:38:33 +01:00
dependabot[bot]andGitHub 48f273b755 Bump ch.qos.logback:logback-core from 1.4.13 to 1.4.14 (#3251) 2023-12-12 08:48:54 +00:00
Jan-Peter Klein 4fc31cb13f refactored 'loopbackPortSupported' from 'BooleanExpression' to 'ObservableValue<Boolean>' in VolumePreferencesController and MountOptionsController 2023-12-11 15:16:41 +01:00
Jan-Peter Klein a795b82a42 vault options ui change 2023-12-11 14:49:54 +01:00
Jan-Peter Klein 1e28a04a7b renamed string properties 2023-12-11 10:16:26 +01:00
Jan-Peter Klein b88eef4591 renamed string property 2023-12-08 12:03:08 +01:00
Jan-Peter Klein eef5edf775 code cleanup 2023-12-08 11:14:54 +01:00
Armin Schrenk bdb1d605eb Add cloud vendor to example of involved software 2023-12-07 18:43:10 +01:00
Armin Schrenk dfe4b74f3d clean code:
* remove unused methods
* combine or move methods
2023-12-07 17:48:58 +01:00
Jan-Peter Klein 985a3c30de changed string properties for volume type labels 2023-12-07 13:56:04 +01:00
Jan-Peter Klein 1b5125dfed refactored code, global default volume type settings 2023-12-07 10:48:33 +01:00
Jan-Peter Klein da240ce8b9 optimized error message 2023-12-07 08:40:39 +01:00
Jan-Peter Klein 52affb891e refactored mount method 2023-12-06 16:41:36 +01:00
Jan-Peter Klein fac72ca24a undo remove settings port 2023-12-06 09:44:05 +01:00
Jan-Peter Klein 5cbed502ed undo VaultListManager changes 2023-12-06 08:49:21 +01:00
Jan-Peter Klein dce4c60881 removed pr unrelated changes and code cleanup 2023-12-06 08:40:43 +01:00
Jan-Peter Klein 63bf0315c7 created global mountService 2023-12-05 16:21:12 +01:00
Armin Schrenk 8b543c48ee [ci skip] Merge branch 'main' into develop 2023-12-05 11:11:31 +01:00
Armin Schrenk 087a5326df Merge branch 'release/1.11.1' 2023-12-05 11:09:36 +01:00
Armin Schrenk a4545352d8 finalize 1.11.1 2023-12-05 11:09:09 +01:00
dependabot[bot]andGitHub a07dea7ca8 Bump the github-actions group with 2 updates (#3235) 2023-12-05 08:39:49 +00:00
Jan-Peter Klein c369487e8e Merge branch 'develop' into feature/vault-volume-type 2023-12-01 09:13:38 +01:00
Jan-Peter Klein 98590ecec5 refactoring 2023-12-01 09:11:43 +01:00
Armin SchrenkandGitHub 316f3975ed add missing import 2023-11-30 18:24:52 +01:00
Armin SchrenkandGitHub 71bf7e0913 Simplify handling of window hiding events 2023-11-30 18:22:07 +01:00
dependabot[bot]andGitHub c7839e2c46 Bump the java-production-dependencies group with 2 updates (#3234) 2023-11-30 14:26:07 +00:00
Armin Schrenk 89b8bc4148 adjust ui and add localization 2023-11-30 11:44:41 +01:00
Armin Schrenk 43ad1c05c0 cancel background task, if window is closed 2023-11-30 11:18:33 +01:00
Armin Schrenk 1343099be6 [ci skip] correct dependabot config 2023-11-30 10:03:29 +01:00
Armin Schrenk b895ac69fb fixes #3233 2023-11-29 18:45:52 +01:00
dependabot[bot]andGitHub 7d281e2878 Bump the javafx group with 5 updates (#3229) 2023-11-29 15:08:31 +00:00
Armin Schrenk 688450bf5a prepare 1.11.1 2023-11-28 13:38:05 +01:00
CryptobotandGitHub e994133177 New Crowdin updates (#3191)
New translations strings.properties

Bulgarian; Chinese Simplified; Chinese Traditional; Dutch; Filipino; French; Greek; Hungarian; Norwegian Bokmal; Polish; Portuguese; Portuguese, Brazilian; Punjabi; Romanian; Spanish; Swedish; Turkish; 

[ci skip]
2023-11-28 13:32:08 +01:00
dependabot[bot]andGitHub 68713ef9a7 Merge pull request #3228 from cryptomator/dependabot/maven/maven-build-plugins-907533b1a4 2023-11-28 12:28:35 +00:00
Armin Schrenk dbacbc8874 do not exectue dependency-check on CI (due to missing NVD API key) 2023-11-28 13:25:47 +01:00
dependabot[bot]andGitHub 8382299a05 Bump the maven-build-plugins group with 4 updates
Bumps the maven-build-plugins group with 4 updates: [org.apache.maven.plugins:maven-dependency-plugin](https://github.com/apache/maven-dependency-plugin), [org.apache.maven.plugins:maven-surefire-plugin](https://github.com/apache/maven-surefire), [org.codehaus.mojo:license-maven-plugin](https://github.com/mojohaus/license-maven-plugin) and [org.owasp:dependency-check-maven](https://github.com/jeremylong/DependencyCheck).


Updates `org.apache.maven.plugins:maven-dependency-plugin` from 3.6.0 to 3.6.1
- [Commits](https://github.com/apache/maven-dependency-plugin/compare/maven-dependency-plugin-3.6.0...maven-dependency-plugin-3.6.1)

Updates `org.apache.maven.plugins:maven-surefire-plugin` from 3.1.2 to 3.2.2
- [Release notes](https://github.com/apache/maven-surefire/releases)
- [Commits](https://github.com/apache/maven-surefire/compare/surefire-3.1.2...surefire-3.2.2)

Updates `org.codehaus.mojo:license-maven-plugin` from 2.2.0 to 2.3.0
- [Release notes](https://github.com/mojohaus/license-maven-plugin/releases)
- [Commits](https://github.com/mojohaus/license-maven-plugin/compare/2.2.0...2.3.0)

Updates `org.owasp:dependency-check-maven` from 8.4.0 to 9.0.1
- [Release notes](https://github.com/jeremylong/DependencyCheck/releases)
- [Changelog](https://github.com/jeremylong/DependencyCheck/blob/main/CHANGELOG.md)
- [Commits](https://github.com/jeremylong/DependencyCheck/compare/v8.4.0...v9.0.1)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-dependency-plugin
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: maven-build-plugins
- dependency-name: org.apache.maven.plugins:maven-surefire-plugin
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: maven-build-plugins
- dependency-name: org.codehaus.mojo:license-maven-plugin
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: maven-build-plugins
- dependency-name: org.owasp:dependency-check-maven
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: maven-build-plugins
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-28 12:20:39 +00:00
dependabot[bot]andGitHub 93b09cf449 Bump the java-production-dependencies group with 6 updates (#3230) 2023-11-28 12:19:58 +00:00
dependabot[bot]andGitHub dac3311b81 Bump the java-test-dependencies group with 2 updates (#3227) 2023-11-28 12:05:42 +00:00
Armin Schrenk 5b1ca7a533 update dependabot config 2023-11-28 12:59:39 +01:00
Armin Schrenk e940c29110 Closes #3226 2023-11-28 12:44:42 +01:00
Jan-Peter Klein 6a704ca0ad Merge branch 'develop' into feature/vault-volume-type 2023-11-27 16:24:35 +01:00
Jan-Peter Klein 38c102a64b refactored code by removing unnecessary observables 2023-11-27 12:46:29 +01:00
Armin Schrenk b632c84bb6 more renaming 2023-11-24 11:23:22 +01:00
Armin Schrenk 6bb5ed1d73 fixes #3207 2023-11-24 11:19:44 +01:00
Jan-Peter Klein 1052e4c3d2 fix gui issues in vault mount settings 2023-11-23 10:55:17 +01:00
44f776050f Apply suggestions from code review
Co-authored-by: Tobias Hagemann <tobias.hagemann@skymatic.de>
2023-11-22 21:36:15 +01:00
Armin Schrenk baa29dbd73 remove unused translation key 2023-11-17 16:33:53 +01:00
Armin Schrenk 1caf391936 use correct word for button label 2023-11-17 16:24:23 +01:00
Armin Schrenk 82caf76e12 clean up 2023-11-17 15:51:20 +01:00
Armin Schrenk de27bbf96e always cancle unlock result when closing the unlock window 2023-11-17 15:50:39 +01:00
Armin Schrenk 1199ef40dd on 409 repsonse of registerDevice-request, show setupFailed with adjusted message 2023-11-17 15:47:08 +01:00
Jan-Peter Klein e7e88f13e3 improved code quality 2023-11-17 14:51:13 +01:00
Armin Schrenk 41c22b7840 Rename leftovers 2023-11-17 13:30:40 +01:00
Armin SchrenkandGitHub 19cc4e8a37 Merge pull request #3194 from AntoineJT/feature/3155-toggle-vault-status-on-double-click
Feature: Double click on a vault in the list to unlock it
2023-11-15 16:51:44 +01:00
Jan-Peter Klein 7bc1d52bf8 set deprecated since of settingsjson port to 1.12.0, changed button text and added tooltip to 'show vault options' button 2023-11-12 13:49:47 +01:00
Antoine James Tournepiche fd84ff09e1 No longer lock vault on double click
See https://github.com/cryptomator/cryptomator/pull/3194#issuecomment-1806106843
2023-11-10 22:05:58 +01:00
Antoine James Tournepiche 3dce175f94 Improve naming, avoid shadowing 2023-11-10 17:42:19 +01:00
Antoine James Tournepiche 0aaa3263cf Improve feature #3155 implementation 2023-11-09 23:50:34 +01:00
Antoine James Tournepiche c4dcbd8c44 Implement requested feature #3155
Toggle selected vault lock status on double click on a vault item
in the vault list on the main window
2023-11-09 23:42:22 +01:00
Jan-Peter Klein ef9cdd8e92 Merge branch 'develop' into feature/vault-volume-type
# Conflicts:
#	src/main/resources/i18n/strings.properties
2023-11-08 11:45:03 +01:00
Armin Schrenk 09ced50590 [ci skip] reset to snapshot version 2023-11-08 11:28:21 +01:00
Armin Schrenk b2ab1a30a5 Merge branch 'main' into develop 2023-11-08 11:26:49 +01:00
Armin Schrenk 9eff3916b3 Merge branch 'release/1.11.0' 2023-11-08 11:26:13 +01:00
Armin Schrenk 98472d1952 use correct release date 2023-11-08 11:25:45 +01:00
Armin Schrenk 1ceafb69a5 finalize 1.11.0 2023-11-08 11:22:27 +01:00
Armin Schrenk f3f4b6576c Merge branch 'develop' into release/1.11.0
# Conflicts:
#	src/main/resources/i18n/strings.properties
2023-11-08 10:52:30 +01:00
CryptobotandGitHub e699d7dafc New Crowdin updates (#3189)
* New translations strings.properties
German, Spanish, Turkish
[ci skip]
2023-11-08 10:51:07 +01:00
CryptobotandGitHub 5eb6d186c0 New Crowdin updates (#3188)
New translations strings.properties

Arabic; Belarusian; Bengali; Bosnian; Bulgarian; Catalan; Chinese Simplified; Chinese Traditional; Chinese Traditional, Hong Kong; Croatian; Czech; Danish; Dutch; Filipino; Finnish; 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-11-08 10:41:05 +01:00
Armin Schrenk edc9409e56 pin wording 2023-11-08 10:19:12 +01:00
JaniruTEC d015719fae Removed outdated translations 2023-11-07 18:52:48 +01:00
JaniruTEC afc69e447e Renamed "setup code" to "Account Key" in localization files 2023-11-07 18:20:10 +01:00
JaniruTEC 54fbbd734f Renamed "setup code" to "Account Key" in UI 2023-11-07 18:19:12 +01:00
Jan-Peter Klein 2f657c7c14 migrate port to vault settings 2023-11-07 12:42:07 +01:00
Sebastian StenzelandArmin Schrenk d29872e69e add "Action Required" prompt
when encountering http status 449 during vault unlock. fixes #3181

Co-authored-by: SailReal <julian.raufelder@skymatic.de>
(cherry picked from commit f2e7d0fae2)
2023-11-07 12:20:27 +01:00
Jan-Peter Klein ab9278a9fc Merge branch 'develop' into feature/vault-volume-type 2023-11-03 10:48:00 +01:00
Jan-Peter Klein 49769f986a remove port from settings 2023-11-03 10:47:43 +01:00
Jan-Peter Klein b68b895bba removed tcp port from volume preferences controller 2023-11-02 16:53:29 +01:00
Tobias Hagemann 99fb9972f9 updated sponsors
[ci skip]
2023-11-02 15:37:19 +01:00
Sebastian StenzelandSailReal f2e7d0fae2 add "Action Required" prompt
when encountering http status 449 during vault unlock. fixes #3181

Co-authored-by: SailReal <julian.raufelder@skymatic.de>
2023-11-02 14:41:58 +01:00
Jan-Peter Klein 77f9e6c411 some ui and wording changes 2023-11-02 13:47:58 +01:00
Jan-Peter Klein 31fcf294e9 fix misbehaivour 2023-11-01 14:59:25 +01:00
Jan-Peter Klein a03f00ee9a set up default mount service as pre fallbackProvider 2023-10-31 20:29:54 +01:00
Jan-Peter Klein 80af32bd82 introduced FuseRestartRequiredException and UnlockFuseRestartRequired window 2023-10-30 17:05:09 +01:00
Jan-Peter Klein b7e4c0fe31 set default mount service and port while adding a vault 2023-10-30 15:27:11 +01:00
Jan-Peter Klein 76d499596f Merge branch 'develop' into feature/vault-volume-type 2023-10-30 14:33:32 +01:00
Jan-Peter Klein 1818344c49 different labeling for volume type option in general volume preferences and vault options 2023-10-30 14:33:01 +01:00
Armin Schrenk 7ff2e22f17 Merge branch 'develop' into release/1.11.0 2023-10-30 10:41:11 +01:00
CryptobotandGitHub 4eee66b0ef New Crowdin updates (#3128)
New translations strings.properties

Arabic; Belarusian; Bulgarian; Catalan; Chinese Simplified; Chinese Traditional; Chinese Traditional, Hong Kong; Czech; Danish; Dutch; Filipino; Finnish; French; German; Greek; Hebrew; Hungarian; Italian; Japanese; Korean; Norwegian Bokmal; Polish; Portuguese; Portuguese, Brazilian; Romanian; Russian; Slovak; Spanish; Swahili, Tanzania; Swedish; Turkish; Ukrainian; Vietnamese; 

[ci skip]
2023-10-30 10:39:04 +01:00
Sebastian Stenzel 19fe7ba6bf updated to tiny-oauth2-client 0.8.0 2023-10-27 19:54:58 +02:00
Armin SchrenkandGitHub 7b522582fb Merge pull request #3163 from cryptomator/feature/3075-fix-ci-jdk-version
Feature: Use fixed JDK version for releases
2023-10-27 12:51:49 +02:00
Jan-Peter Klein e79c975d7b prevent mounting via MountFailedException when fuseRestartRequired 2023-10-27 12:39:25 +02:00
Armin SchrenkandGitHub 7594e51e2b Update debian.yml
Remove architecture in apt install dependency
2023-10-27 12:30:37 +02:00
Armin Schrenk b3f0ff3662 use coffeelibs JDK for release builds 2023-10-27 12:10:37 +02:00
Armin SchrenkandGitHub 8ce304a0c3 Add link to how-to-jdk-update in notification 2023-10-26 16:21:22 +02:00
Jan-Peter Klein c85823fe04 code cleanup 2023-10-26 12:18:40 +02:00
Jan-Peter Klein 8f46aec851 created MountServiceConverter class 2023-10-26 10:35:16 +02:00
Jan-Peter Klein cd6d1eeab3 moved fupfms to VaultModule 2023-10-26 10:25:11 +02:00
Jan-Peter Klein 52b74a74fe display specific mount options according to selected volume type in vault mounting options 2023-10-25 14:02:29 +02:00
Jan-Peter Klein 368f0630c1 some sonar cloud fixes 2023-10-25 12:44:22 +02:00
Jan-Peter Klein 040bc4c5df fix sonar cloud issues 2023-10-24 14:26:06 +02:00
Jan-Peter Klein 07906fbea5 modified mounter to utilize the mount service settings specified in the vault settings 2023-10-24 14:04:53 +02:00
Armin SchrenkandGitHub f893b2b5be Merge pull request #3026 from cryptomator/feature/uninstall-old-winfsp
Feature: Update to WinFsp 2.x and uninstall old winfsp in Windows EXE installer
2023-10-23 12:26:28 +02:00
Armin Schrenk db868c6df7 move worklfow to correct directory 2023-10-20 16:22:45 +02:00
Jan-Peter Klein 44f67b7c89 Merge branch 'develop' into feature/vault-volume-type 2023-10-20 15:58:52 +02:00
Sebastian Stenzel 6225d8d1f0 Merge branch 'develop' into release/1.11.0 2023-10-20 14:00:42 +02:00
Sebastian Stenzel ed975b459e bump dependencies 2023-10-20 14:00:08 +02:00
Armin Schrenk 652a6f5c4d use environment variables and update current jdk 2023-10-20 13:42:00 +02:00
Armin Schrenk a7a94099a8 Closes #3075 2023-10-20 13:35:03 +02:00
Armin Schrenk 71a3cbc334 add workflow to check for jdk updates 2023-10-20 13:29:43 +02:00
Armin SchrenkandGitHub 800b2440b3 Merge pull request #3157 from cryptomator/feature/3113-network-timeout
Time restrict network requests
2023-10-20 12:58:08 +02:00
Sebastian Stenzel f50a49e7a3 prepare 1.11.0 2023-10-20 12:11:06 +02:00
Sebastian Stenzel 92ece4dfb6 increased request timeout to 10s 2023-10-20 12:06:10 +02:00
Sebastian Stenzel 174225c60e add timeout to OAuth2 requests 2023-10-20 12:03:07 +02:00
Sebastian Stenzel 3071410a22 Merge branch 'develop' into feature/3113-network-timeout 2023-10-20 12:00:16 +02:00
Sebastian StenzelandGitHub 5c5777ffc5 Merge pull request #3091 from cryptomator/feature/simplify-out-of-bounds
simplify out-of-bounds check
2023-10-20 11:56:36 +02:00
Sebastian StenzelandGitHub 8dd8b93656 Merge pull request #3041 from cryptomator/feature/new-hub-keyloading
Adjusted to Hub 1.3.x API
2023-10-20 11:55:28 +02:00
Armin Schrenk 3b2d455b4a Update dependencies 2023-10-19 17:31:52 +02:00
Sebastian Stenzel b0dfa22903 removed unused class 2023-10-19 12:49:19 +02:00
Sebastian Stenzel 88b1c28d88 Merge branch 'develop' into feature/new-hub-keyloading 2023-10-19 11:33:13 +02:00
Sebastian Stenzel 5b85d7859a bump webdav-nio-adapter version 2023-10-19 11:28:54 +02:00
Sebastian Stenzel 468eed58d5 cleanup 2023-10-19 10:00:14 +02:00
Sebastian Stenzel 34c17be474 add request timeouts 2023-10-19 10:00:03 +02:00
Sebastian Stenzel 5dedd6b1c1 renamed class again 2023-10-18 11:30:22 +02:00
Sebastian Stenzel 25e8e81686 support apiBaseUrl in hub config 2023-10-18 11:08:42 +02:00
Sebastian Stenzel 1f7ab03bbb undo JEP 443 changes due to bug in javac
leads to invalid class files when built via Maven due to specific combination of javac arguments
2023-10-18 11:01:26 +02:00
Sebastian Stenzel 86f3cb7288 applied suggestions from code review 2023-10-18 09:40:34 +02:00
Sebastian Stenzel a1b8bf23b4 Merge branch 'develop' into feature/new-hub-keyloading 2023-10-18 09:40:03 +02:00
Sebastian StenzelandGitHub 1f21d5ea4c Merge pull request #3129 from cryptomator/feature/jdk21
JDK 21
2023-10-18 09:39:12 +02:00
Sebastian Stenzel f8ff7201d7 Merge branch 'develop' into feature/new-hub-keyloading 2023-10-18 08:50:34 +02:00
Armin Schrenk 3567c036c3 remove unused imports 2023-10-17 17:25:38 +02:00
Armin Schrenk 0cf1f087ad Closes #3113 2023-10-17 11:36:50 +02:00
Armin Schrenk 209f60727e fix f4ad7aa43d 2023-10-16 16:38:12 +02:00
Armin Schrenk 56624fc079 Replace URL files by hardcoded links in build scripts 2023-10-16 16:35:17 +02:00
Armin Schrenk 218c5243e3 Merge branch 'develop' into feature/uninstall-old-winfsp 2023-10-16 16:29:57 +02:00
Armin SchrenkandGitHub 560a979e0e Merge pull request #3131 from cryptomator/feature/sign-all-dlls
Feature: Sign all dlls to pass Microsoft Windows Smart App control
2023-10-16 16:21:08 +02:00
Sebastian Stenzel 1debe4c7c8 explicitly set Logback ConfiguratorRank 2023-10-16 16:20:03 +02:00
Sebastian Stenzel 2e2aa77727 update dependencies 2023-10-16 16:19:11 +02:00
Sebastian Stenzel 162ebf6545 Merge branch 'develop' into feature/jdk21 2023-10-16 16:12:10 +02:00
Armin Schrenk cf09eff640 Use new version of uninstaller:
* logging
* correct reboot
2023-10-13 17:49:48 +02:00
Armin SchrenkandGitHub 2d503a0edb Merge pull request #3148 from cryptomator/feature/propagate-deleted-discussions
Propagate deleted discussions to the error database
2023-10-13 17:01:45 +02:00
Julian Raufelder 7f7f0a099a Propagate deleted discussions to the error database 2023-10-12 14:11:54 +02:00
Julian Raufelder 109f5d1faa Update the error-db when a discussion is deleted 2023-10-12 10:56:14 +02:00
Armin Schrenk 38a5d40b64 Merge branch 'develop' into feature/uninstall-old-winfsp 2023-10-11 16:14:26 +02:00
Armin Schrenk 9b55f6fc56 Refactor extraction and singing in seperate steps 2023-10-11 12:55:05 +02:00
Sebastian Stenzel 83879f5cfe revert 8e9d54b & 6c5ee14 due to bug in JDK 21
see https://bugs.openjdk.org/browse/JDK-8313323
2023-10-09 16:19:56 +02:00
Armin SchrenkandGitHub 083ac5a7e0 Merge pull request #3133 from purejava/build-arch
Improve AppImage build script
2023-10-09 13:10:05 +02:00
dependabot[bot]andGitHub a7eba377ba Bump org.mockito:mockito-core from 5.5.0 to 5.6.0 (#3142) 2023-10-09 09:58:47 +00:00
dependabot[bot]andGitHub 4ee1e6d9f1 Bump the github-actions group with 1 update (#3135) 2023-10-04 20:24:43 +00:00
Ralph Plawetzki 24a63c10d0 Build for aarch64 too 2023-09-30 14:54:15 +02:00
Armin Schrenk 0d805b2d43 clean up 2023-09-28 18:34:38 +02:00
Armin Schrenk 7bc47fe6d7 Really fixes #3130 2023-09-28 18:33:26 +02:00
Armin Schrenk ae50846257 Revert ce466e7715 2023-09-28 18:33:01 +02:00
Armin Schrenk ce466e7715 fixes #3130 2023-09-28 13:47:51 +02:00
Armin Schrenk 15885545b5 supress some output 2023-09-27 11:13:52 +02:00
Armin Schrenk 29fedcd390 integrate code from test script into github workflow 2023-09-27 10:24:59 +02:00
Armin Schrenk fadd6b761f add cert import 2023-09-26 17:30:18 +02:00
Armin Schrenk d857335901 update test script:
* use variables
* use signtool
* find newest signtool version
2023-09-26 16:43:00 +02:00
Armin Schrenk 93b4cbfb2c add test script 2023-09-26 13:42:18 +02:00
Armin Schrenk 625334c6c8 fix windows build script 2023-09-25 16:02:31 +02:00
Sebastian Stenzel 943374856e build using JDK 21 GA 2023-09-25 12:18:01 +02:00
Sebastian Stenzel e1d7fd92ad Merge branch 'develop' into feature/jdk21
# Conflicts:
#	pom.xml
2023-09-25 12:15:14 +02:00
Sebastian Stenzel c10dc74818 update integrations-linux to 1.4.0-beta1 2023-09-25 12:12:28 +02:00
Tobias Hagemann 92d9f2c18d try to fix mac build script to be compatible with create-dmg 1.2.0 2023-09-20 15:27:17 +02:00
Armin SchrenkandGitHub d7488b6984 fix wrong pom version 2023-09-20 15:16:18 +02:00
Tobias Hagemann 88ad3cd724 Merge branch 'develop' into feature/new-hub-keyloading 2023-09-20 14:38:13 +02:00
Armin Schrenk ba9e0b0c12 Merge branch 'main' into develop 2023-09-20 11:34:37 +02:00
Armin Schrenk bbe7255901 Merge branch 'release/1.10.1' 2023-09-20 11:33:39 +02:00
Armin Schrenk 51e55d3e3b finalize 1.10.1 2023-09-20 11:09:37 +02:00
Armin Schrenk f704dc0de9 prepare 1.10.1 2023-09-20 11:07:50 +02:00
CryptobotandGitHub e858280f30 New Crowdin updates (#3110)
New Crowdin updates (#3110)

New translations strings.properties

Bulgarian; Chinese Traditional; 

[ci skip]
2023-09-20 11:05:33 +02:00
Armin SchrenkandGitHub f9b170204a Merge pull request #3118 from cryptomator/feature/3117-disable-update-check
Disable Update Check
2023-09-20 11:02:14 +02:00
Armin SchrenkandGitHub 0ed7415a0d Merge pull request #3109 from cryptomator/feature/error-dialog-request-with-errorcode
Enhance user agent string when downloading error code database
2023-09-20 11:02:01 +02:00
Armin Schrenk 7a0d50ecca removed unnecessary import 2023-09-20 10:48:26 +02:00
Armin SchrenkandGitHub 19e035aa33 Merge pull request #3123 from cryptomator/feature/context-menu-focus
Fix addVaultButton misbehavior
2023-09-19 20:56:56 +02:00
Jan-Peter Klein 830970cb75 improved format and naming 2023-09-19 16:29:12 +02:00
Jan-Peter Klein 9b2987d0a2 improved function naming 2023-09-19 16:26:55 +02:00
Armin Schrenk 76a4062f8b update org.cryptomator.integrations:integrations-win from 1.2.2 to 1.2.3 2023-09-19 15:12:45 +02:00
Jan-Peter Klein 113717f955 addVaultButton context menu event filter removed 2023-09-19 15:12:40 +02:00
Jan-Peter Klein c40ad58028 detached context menu from button to fix misbehavior 2023-09-19 15:03:22 +02:00
Jan-Peter Klein d6a7efcb7f added OS_NAME, OS_VERSION and OS_ARCH to user-agent 2023-09-19 14:00:45 +02:00
Jan-Peter Klein 910b89d6ce Merge branch 'develop' into feature/error-dialog-request-with-errorcode 2023-09-19 13:19:40 +02:00
Tobias Hagemann 5554dfdd89 fixes #3121 2023-09-19 12:22:24 +02:00
Tobias Hagemann 1657cd50fc fixes #3112 2023-09-19 12:12:27 +02:00
Sebastian Stenzel 57bf5e11b5 Merge branch 'develop' into feature/simplify-out-of-bounds 2023-09-18 19:33:25 +02:00
Sebastian Stenzel 594ca47c85 Merge branch 'develop' into feature/jdk21
# Conflicts:
#	.github/workflows/appimage.yml
#	.github/workflows/mac-dmg.yml
2023-09-18 19:33:06 +02:00
Sebastian Stenzel 6c5ee14c73 rename unused var 2023-09-18 19:29:35 +02:00
Sebastian Stenzel 8e9d54b44b rename unused var 2023-09-18 19:27:28 +02:00
Sebastian Stenzel 70805665bf use features of Java 21 with --enable-preview 2023-09-18 19:21:56 +02:00
Sebastian Stenzel ac243a706e improve readability 2023-09-18 19:13:03 +02:00
Sebastian Stenzel aa382ce80d update coffeelibs jdk to 21 2023-09-18 19:10:54 +02:00
b7da508ccc Update src/main/java/org/cryptomator/ui/mainwindow/ResizeController.java
Co-authored-by: Bas Ruigrok <Rexbas@proton.me>
2023-09-18 13:19:58 +02:00
Sebastian Stenzel 47bd0ca647 disable update check for PPA builds 2023-09-18 13:10:19 +02:00
Sebastian Stenzel c5d6c0ce98 add cryptomator.disableUpdateCheck property 2023-09-18 13:03:09 +02:00
Sebastian Stenzel 6017d6b7a9 bump webdav-nio-adapter
containing fixes for CVE-2023-40167, CVE-2023-2976, CVE-2023-37895
2023-09-18 12:34:49 +02:00
Sebastian Stenzel e31e06b288 added @VisibleForTesting 2023-09-18 10:13:51 +02:00
Sebastian Stenzel 84ac803a7d reordered properties
[ci skip]
2023-09-18 10:10:50 +02:00
Armin SchrenkandGitHub bcb970afb1 Update bug.yml
Add missing FUSE option in volume type selection
2023-09-13 13:59:50 +02:00
Jan-Peter Klein 9d640b57ce added build number to user-agent header 2023-09-13 12:31:53 +02:00
Jan-Peter Klein 4c83617847 fixed build error 2023-09-12 18:07:30 +02:00
Jan-Peter Klein 5d7906972b added user-agent header with <product> / <product-version> to HttpRequest 2023-09-12 17:59:08 +02:00
Jan-Peter Klein 666cd4a4f0 enhanced request URI with URLEncoder for errorCode 2023-09-12 17:14:45 +02:00
Jan-Peter Klein eb4d39e8b4 introduce 'errorCode' parameter in request 2023-09-12 13:34:55 +02:00
Jan-Peter Klein 44ec19122a added port and mountService to vaultSettings 2023-09-12 02:19:08 +02:00
Jan-Peter Klein 8ba2540b35 implemented volume type selection in 'vault options mount' 2023-09-11 14:23:31 +02:00
Armin Schrenk a1ad89a2e2 Merge branch 'main' into develop [ci skip] 2023-09-11 09:56:35 +02:00
Armin Schrenk 38108299fa Merge branch 'release/1.10.0' 2023-09-11 09:55:14 +02:00
Armin Schrenk 189e2679f1 finalize 1.10.0 2023-09-11 09:53:35 +02:00
Armin Schrenk 22ceb57052 Merge branch 'develop' into release/1.10.0 2023-09-11 09:51:13 +02:00
Armin Schrenk 0130c7cce6 fix local windows build script [ci skip] 2023-09-11 09:50:41 +02:00
CryptobotandGitHub 18b6484731 New Crowdin updates (#3095)
New translations strings.properties

Arabic; Chinese Simplified; Filipino; German; Japanese; Norwegian Bokmal; Polish; Portuguese, Brazilian; Spanish; Swedish; Ukrainian; 

[ci skip]
2023-09-11 09:46:49 +02:00
Sebastian Stenzel f19ff59005 add suffix to uploaded artifacts 2023-09-06 16:47:29 +02:00
Sebastian Stenzel 8786b5ee2a can't use env vars in matrix builds 2023-09-06 16:43:58 +02:00
Sebastian Stenzel c7e23f9646 build AppImage for aarch64 2023-09-06 16:40:00 +02:00
Sebastian Stenzel 4043e3f71f build using JDK 21 2023-09-06 16:22:41 +02:00
Tobias Hagemann 08887f1147 Merge branch 'develop' into feature/new-hub-keyloading 2023-09-06 14:18:11 +02:00
Sebastian Stenzel 13a0578ab7 fix checksum file format 2023-09-06 13:05:01 +02:00
Sebastian Stenzel 888bf04ec2 fix workflow files 2023-09-06 13:01:48 +02:00
Sebastian Stenzel d0822041ec renamed workflow file 2023-09-06 12:58:08 +02:00
Sebastian Stenzel e65a57bba9 harmonize workflow files
in regards to JDK distribution and OpenJFX downloads
2023-09-06 12:57:41 +02:00
Armin SchrenkandGitHub 2bb1b09789 Merge pull request #3097 from cryptomator/dependabot/maven/maven-dependencies-a3030d6477
Bump the maven-dependencies group with 3 updates
2023-09-04 14:00:36 +02:00
dependabot[bot]andGitHub b83dad4e24 Bump the maven-dependencies group with 3 updates
Bumps the maven-dependencies group with 3 updates: org.slf4j:slf4j-api, [com.google.dagger:dagger](https://github.com/google/dagger) and [com.google.dagger:dagger-compiler](https://github.com/google/dagger).


Updates `org.slf4j:slf4j-api` from 2.0.7 to 2.0.9

Updates `com.google.dagger:dagger` from 2.47 to 2.48
- [Release notes](https://github.com/google/dagger/releases)
- [Changelog](https://github.com/google/dagger/blob/master/CHANGELOG.md)
- [Commits](https://github.com/google/dagger/compare/dagger-2.47...dagger-2.48)

Updates `com.google.dagger:dagger-compiler` from 2.47 to 2.48
- [Release notes](https://github.com/google/dagger/releases)
- [Changelog](https://github.com/google/dagger/blob/master/CHANGELOG.md)
- [Commits](https://github.com/google/dagger/compare/dagger-2.47...dagger-2.48)

---
updated-dependencies:
- dependency-name: org.slf4j:slf4j-api
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: maven-dependencies
- dependency-name: com.google.dagger:dagger
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: maven-dependencies
- dependency-name: com.google.dagger:dagger-compiler
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: maven-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-04 06:48:51 +00:00
Armin Schrenk 06f288ef76 only execute winfsp-uninstaller on install or repair 2023-08-29 17:51:05 +02:00
Armin Schrenk ffcad9f1ec reformat 2023-08-29 17:32:49 +02:00
Armin Schrenk 031dc8a31a bump exe uninstaller to new version and skip uninstaller on bundle uninstall 2023-08-29 17:25:43 +02:00
Sebastian Stenzel cfd433b328 revert to simple of of bounds check
as suggested in https://github.com/cryptomator/cryptomator/pull/3017#discussion_r1264527894 with minor adjustments
2023-08-29 07:26:46 +02:00
Armin Schrenk 422efcc89f [ci skip] use new version of winfsp-uninstaller 2023-08-23 15:43:57 +02:00
Armin Schrenk c1c0c2e82f [ci skip] use new version of winfsp-uninstaller 2023-08-22 10:47:18 +02:00
Armin Schrenk c6790fec70 [ci skip] use new version of winfsp-uninstaller 2023-08-17 12:01:58 +02:00
Armin Schrenk e9ef122e7f Merge branch 'develop' into feature/uninstall-old-winfsp 2023-08-14 15:13:11 +02:00
Sebastian Stenzel f48963a6d0 Merge branch 'develop' into feature/new-hub-keyloading
# Conflicts:
#	src/main/java/org/cryptomator/ui/keyloading/hub/ReceiveKeyController.java
2023-08-09 15:26:03 +02:00
Armin Schrenk 40611b4ebe improve wording 2023-08-01 10:48:42 +02:00
Sebastian Stenzel 6ce34efb52 Merge branch 'develop' into feature/new-hub-keyloading 2023-07-28 15:23:00 +02:00
Armin Schrenk 0800c53aac update to uninstaller-beta4 2023-07-24 10:36:23 +02:00
Armin Schrenk c6ab05979c cleanup [ci skip] 2023-07-19 16:33:40 +02:00
Armin Schrenk 2c8d5d3d5d update ci script 2023-07-19 16:30:08 +02:00
Armin Schrenk b76a311ddc Replace winfsp-uninstaller by downloadlink 2023-07-19 16:24:44 +02:00
Armin Schrenk 315bf0d51f Format confirmation dialog 2023-07-14 16:00:49 +02:00
Armin Schrenk 4cdbe50eb6 adjust to new winfsp-uninstaller exe 2023-07-13 17:29:50 +02:00
Armin Schrenk ead0f0fae1 add exe for winfsp uninstallation and include in burn bundle 2023-07-11 09:41:54 +02:00
Sebastian Stenzel cd10d38990 adjusted to latest API-changes 2023-07-06 18:57:10 +02:00
Sebastian Stenzel 8cb21c97e3 add mark for future improvement 2023-07-04 16:58:37 +02:00
Sebastian Stenzel 0ad8ce77ef handle "invalid setup code" error properly 2023-07-04 16:55:42 +02:00
Sebastian Stenzel e358ffd666 added tests 2023-07-04 16:47:54 +02:00
Sebastian Stenzel 496f9a9cd5 docs
[ci skip]
2023-07-04 15:05:22 +02:00
Sebastian Stenzel 61025de0d6 renamed var
[ci skip]
2023-07-04 14:43:56 +02:00
Sebastian Stenzel f08049b960 fix "register device" on legacy hub instances 2023-07-04 14:34:36 +02:00
Sebastian Stenzel 746c8f54eb Merge branch 'develop' into feature/new-hub-keyloading
# Conflicts:
#	src/main/java/org/cryptomator/ui/keyloading/hub/CreateDeviceDto.java
#	src/main/java/org/cryptomator/ui/keyloading/hub/RegisterDeviceController.java
2023-06-30 16:20:59 +02:00
Sebastian Stenzel 9fc1efa005 adjust labels 2023-06-29 10:38:31 +02:00
Sebastian Stenzel 448eac8ff5 cleanup 2023-06-23 12:06:06 +02:00
Sebastian Stenzel 5a18d086e0 register device using a setup code 2023-06-22 17:16:00 +02:00
Sebastian Stenzel 918ace2eb6 Merge branch 'develop' into feature/new-hub-keyloading 2023-06-14 10:31:58 +02:00
Sebastian Stenzel fe733967dc send device type in device registration request 2023-06-01 15:06:21 +02:00
Sebastian Stenzel 59f5c0cb12 started new unlock workflow using user-specific private key 2023-05-09 17:09:49 +02:00
258 changed files with 11254 additions and 2990 deletions
+1 -1
View File
@@ -3,7 +3,7 @@
## Did you find a bug? ## Did you find a bug?
- Ensure you're running the latest version of Cryptomator. - Ensure you're running the latest version of Cryptomator.
- Ensure the bug is related to the desktop version of Cryptomator. Bugs concerning the Cryptomator iOS and Android app can be reported on the [Cryptomator for iOS issues list](https://github.com/cryptomator/cryptomator-ios/issues) and [Cryptomator for Android issues list](https://github.com/cryptomator/cryptomator-android/issues) respectively. - Ensure the bug is related to the desktop version of Cryptomator. Bugs concerning the Cryptomator iOS and Android app can be reported on the [Cryptomator for iOS issues list](https://github.com/cryptomator/ios/issues) and [Cryptomator for Android issues list](https://github.com/cryptomator/android/issues) respectively.
- Ensure the bug was not [already reported](https://github.com/cryptomator/cryptomator/issues). You can also check out our [FAQ](https://community.cryptomator.org/c/kb/faq). - Ensure the bug was not [already reported](https://github.com/cryptomator/cryptomator/issues). You can also check out our [FAQ](https://community.cryptomator.org/c/kb/faq).
- If you're unable to find an open issue addressing the problem, [submit a new one](https://github.com/cryptomator/cryptomator/issues/new/choose). - If you're unable to find an open issue addressing the problem, [submit a new one](https://github.com/cryptomator/cryptomator/issues/new/choose).
+3 -1
View File
@@ -26,6 +26,7 @@ body:
Examples: Examples:
- Operating System: Windows 10 - Operating System: Windows 10
- Cryptomator: 1.5.16 - Cryptomator: 1.5.16
- OneDrive: 23.226
- LibreOffice: 7.1.4 - LibreOffice: 7.1.4
value: | value: |
- Operating System: - Operating System:
@@ -43,6 +44,7 @@ body:
- WinFsp (Local Drive) - WinFsp (Local Drive)
- FUSE-T - FUSE-T
- macFUSE - macFUSE
- FUSE
- WebDAV (Windows Explorer) - WebDAV (Windows Explorer)
- WebDAV (AppleScript) - WebDAV (AppleScript)
- WebDAV (gio) - WebDAV (gio)
@@ -95,4 +97,4 @@ body:
id: further-info id: further-info
attributes: attributes:
label: Anything else? label: Anything else?
description: Links? References? Screenshots? Configurations? Any data that might be necessary to reproduce the issue? description: Links? References? Screenshots? Configurations? Any data that might be necessary to reproduce the issue?
+36 -2
View File
@@ -6,11 +6,45 @@ updates:
interval: "weekly" interval: "weekly"
day: "monday" day: "monday"
time: "06:00" time: "06:00"
timezone: "UTC" timezone: "Etc/UTC"
ignore:
- dependency-name: "org.cryptomator:integrations-api"
versions: ["2.0.0-alpha1"]
- dependency-name: "jakarta.inject:jakarta.inject-api"
versions: ["2.0.1.MR"]
- dependency-name: "org.openjfx:*"
update-types: ["version-update:semver-major"]
groups: groups:
maven-dependencies: java-test-dependencies:
patterns:
- "org.junit.jupiter:*"
- "org.mockito:*"
- "org.hamcrest:*"
- "com.google.jimfs:jimfs"
maven-build-plugins:
patterns:
- "org.apache.maven.plugins:*"
- "org.jacoco:jacoco-maven-plugin"
- "org.owasp:dependency-check-maven"
- "me.fabriciorby:maven-surefire-junit5-tree-reporter"
- "org.codehaus.mojo:license-maven-plugin"
javafx:
patterns:
- "org.openjfx:*"
java-production-dependencies:
patterns: patterns:
- "*" - "*"
exclude-patterns:
- "org.openjfx:*"
- "org.apache.maven.plugins:*"
- "org.jacoco:jacoco-maven-plugin"
- "org.owasp:dependency-check-maven"
- "me.fabriciorby:maven-surefire-junit5-tree-reporter"
- "org.codehaus.mojo:license-maven-plugin"
- "org.junit.jupiter:*"
- "org.mockito:*"
- "org.hamcrest:*"
- "com.google.jimfs:jimfs"
- package-ecosystem: "github-actions" - package-ecosystem: "github-actions"
directory: "/" # even for `.github/workflows` directory: "/" # even for `.github/workflows`
+50 -31
View File
@@ -10,7 +10,8 @@ on:
required: false required: false
env: env:
JAVA_VERSION: 20 JAVA_DIST: 'zulu'
JAVA_VERSION: '23.0.1+11'
jobs: jobs:
get-version: get-version:
@@ -20,52 +21,71 @@ jobs:
build: build:
name: Build AppImage name: Build AppImage
runs-on: ubuntu-latest runs-on: ${{ matrix.os }}
needs: [get-version] needs: [get-version]
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
appimage-suffix: x86_64
openjfx-url: 'https://download2.gluonhq.com/openjfx/22.0.2/openjfx-22.0.2_linux-x64_bin-jmods.zip'
openjfx-sha: 'd44bff3b94d5668fdee18a938d7b1269026d663d44765f02d29a9bdfd3fa1eb0'
- os: [self-hosted, Linux, ARM64]
appimage-suffix: aarch64
openjfx-url: 'https://download2.gluonhq.com/openjfx/22.0.2/openjfx-22.0.2_linux-aarch64_bin-jmods.zip'
openjfx-sha: '3d5457136690c4f5bb9522d38b45218e045bdac13c24aa4c808c7c8d17d039c7'
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- name: Setup Java - name: Setup Java
uses: actions/setup-java@v3 uses: actions/setup-java@v4
with: with:
distribution: 'zulu' distribution: ${{ env.JAVA_DIST }}
java-version: ${{ env.JAVA_VERSION }} java-version: ${{ env.JAVA_VERSION }}
java-package: 'jdk+fx'
check-latest: true check-latest: true
cache: 'maven' cache: 'maven'
- name: Ensure major jfx version in pom equals in jdk
shell: pwsh - name: Download OpenJFX jmods
id: download-jmods
run: | run: |
$jfxPomVersion = (&mvn help:evaluate "-Dexpression=javafx.version" -q -DforceStdout) -split "\." curl -L ${{ matrix.openjfx-url }} -o openjfx-jmods.zip
$jfxJdkVersion = ((Get-Content -path "${env:JAVA_HOME}/lib/javafx.properties" | Where-Object {$_ -like 'javafx.version=*' }) -replace '.*=','') -split "\." echo "${{ matrix.openjfx-sha }} openjfx-jmods.zip" | shasum -a256 --check
if ($jfxPomVersion[0] -ne $jfxJdkVersion[0]) { mkdir -p openjfx-jmods
Write-Error "Major part of JavaFX version in pom($($jfxPomVersion[0])) does not match the version in JDK($($jfxJdkVersion[0])) " unzip -j openjfx-jmods.zip \*/javafx.base.jmod \*/javafx.controls.jmod \*/javafx.fxml.jmod \*/javafx.graphics.jmod -d openjfx-jmods
- name: Ensure major jfx version in pom and in jmods is the same
run: |
JMOD_VERSION=$(jmod describe openjfx-jmods/javafx.base.jmod | head -1)
JMOD_VERSION=${JMOD_VERSION#*@}
JMOD_VERSION=${JMOD_VERSION%%.*}
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})"
exit 1 exit 1
} fi
- name: Set version - name: Set version
run : mvn versions:set -DnewVersion=${{ needs.get-version.outputs.semVerStr }} run : mvn versions:set -DnewVersion=${{ needs.get-version.outputs.semVerStr }}
- name: Run maven - name: Run maven
run: mvn -B clean package -Pdependency-check,linux -DskipTests run: mvn -B clean package -Plinux -DskipTests -Djavafx.platform=linux
- name: Patch target dir - name: Patch target dir
run: | run: |
cp LICENSE.txt target cp LICENSE.txt target
cp target/cryptomator-*.jar target/mods cp target/cryptomator-*.jar target/mods
- name: Run jlink - name: Run jlink
#Remark: no compression is applied for improved build compression later (here appimage)
run: > run: >
${JAVA_HOME}/bin/jlink ${JAVA_HOME}/bin/jlink
--verbose --verbose
--output runtime --output runtime
--module-path "${JAVA_HOME}/jmods" --module-path "${JAVA_HOME}/jmods:openjfx-jmods"
--add-modules java.base,java.desktop,java.instrument,java.logging,java.naming,java.net.http,java.scripting,java.sql,java.xml,javafx.base,javafx.graphics,javafx.controls,javafx.fxml,jdk.unsupported,jdk.crypto.ec,jdk.security.auth,jdk.accessibility,jdk.management.jfr,jdk.net --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.security.auth,jdk.accessibility,jdk.management.jfr,jdk.net,java.compiler
--strip-native-commands --strip-native-commands
--no-header-files --no-header-files
--no-man-pages --no-man-pages
--strip-debug --strip-debug
--compress=1 --compress zip-0
- name: Prepare additional launcher
run: envsubst '${SEMVER_STR} ${REVISION_NUM}' < dist/linux/launcher-gtk2.properties > launcher-gtk2.properties
env:
SEMVER_STR: ${{ needs.get-version.outputs.semVerStr }}
REVISION_NUM: ${{ needs.get-version.outputs.revNum }}
- name: Run jpackage - name: Run jpackage
run: > run: >
${JAVA_HOME}/bin/jpackage ${JAVA_HOME}/bin/jpackage
@@ -78,7 +98,7 @@ jobs:
--dest appdir --dest appdir
--name Cryptomator --name Cryptomator
--vendor "Skymatic GmbH" --vendor "Skymatic GmbH"
--copyright "(C) 2016 - 2023 Skymatic GmbH" --copyright "(C) 2016 - 2024 Skymatic GmbH"
--app-version "${{ needs.get-version.outputs.semVerNum }}.${{ needs.get-version.outputs.revNum }}" --app-version "${{ needs.get-version.outputs.semVerNum }}.${{ needs.get-version.outputs.revNum }}"
--java-options "--enable-preview" --java-options "--enable-preview"
--java-options "--enable-native-access=org.cryptomator.jfuse.linux.amd64,org.cryptomator.jfuse.linux.aarch64,org.purejava.appindicator" --java-options "--enable-native-access=org.cryptomator.jfuse.linux.amd64,org.cryptomator.jfuse.linux.aarch64,org.purejava.appindicator"
@@ -96,7 +116,6 @@ jobs:
--java-options "-Dcryptomator.showTrayIcon=true" --java-options "-Dcryptomator.showTrayIcon=true"
--java-options "-Dcryptomator.integrationsLinux.trayIconsDir=\"@{appdir}/usr/share/icons/hicolor/symbolic/apps\"" --java-options "-Dcryptomator.integrationsLinux.trayIconsDir=\"@{appdir}/usr/share/icons/hicolor/symbolic/apps\""
--java-options "-Dcryptomator.buildNumber=\"appimage-${{ needs.get-version.outputs.revNum }}\"" --java-options "-Dcryptomator.buildNumber=\"appimage-${{ needs.get-version.outputs.revNum }}\""
--add-launcher Cryptomator-gtk2=launcher-gtk2.properties
--resource-dir dist/linux/resources --resource-dir dist/linux/resources
- name: Patch Cryptomator.AppDir - name: Patch Cryptomator.AppDir
run: | run: |
@@ -119,7 +138,7 @@ jobs:
ln -s bin/cryptomator.sh Cryptomator.AppDir/AppRun ln -s bin/cryptomator.sh Cryptomator.AppDir/AppRun
- name: Download AppImageKit - name: Download AppImageKit
run: | run: |
curl -L https://github.com/AppImage/AppImageKit/releases/download/13/appimagetool-x86_64.AppImage -o appimagetool.AppImage curl -L https://github.com/AppImage/AppImageKit/releases/download/13/appimagetool-${{ matrix.appimage-suffix }}.AppImage -o appimagetool.AppImage
chmod +x appimagetool.AppImage chmod +x appimagetool.AppImage
./appimagetool.AppImage --appimage-extract ./appimagetool.AppImage --appimage-extract
- name: Prepare GPG-Agent for signing with key 615D449FE6E6A235 - name: Prepare GPG-Agent for signing with key 615D449FE6E6A235
@@ -131,25 +150,25 @@ jobs:
GPG_PASSPHRASE: ${{ secrets.RELEASES_GPG_PASSPHRASE }} GPG_PASSPHRASE: ${{ secrets.RELEASES_GPG_PASSPHRASE }}
- name: Build AppImage - name: Build AppImage
run: > run: >
./squashfs-root/AppRun Cryptomator.AppDir cryptomator-${{ needs.get-version.outputs.semVerStr }}-x86_64.AppImage ./squashfs-root/AppRun Cryptomator.AppDir cryptomator-${{ needs.get-version.outputs.semVerStr }}-${{ matrix.appimage-suffix }}.AppImage
-u 'gh-releases-zsync|cryptomator|cryptomator|latest|cryptomator-*-x86_64.AppImage.zsync' -u 'gh-releases-zsync|cryptomator|cryptomator|latest|cryptomator-*-${{ matrix.appimage-suffix }}.AppImage.zsync'
--sign --sign-key=615D449FE6E6A235 --sign-args="--batch --pinentry-mode loopback" --sign --sign-key=615D449FE6E6A235 --sign-args="--batch --pinentry-mode loopback"
- name: Create detached GPG signatures - name: Create detached GPG signatures
run: | run: |
gpg --batch --quiet --passphrase-fd 0 --pinentry-mode loopback -u 615D449FE6E6A235 --detach-sign -a cryptomator-*.AppImage gpg --batch --quiet --passphrase-fd 0 --pinentry-mode loopback -u 615D449FE6E6A235 --detach-sign -a cryptomator-*.AppImage
gpg --batch --quiet --passphrase-fd 0 --pinentry-mode loopback -u 615D449FE6E6A235 --detach-sign -a cryptomator-*.AppImage.zsync gpg --batch --quiet --passphrase-fd 0 --pinentry-mode loopback -u 615D449FE6E6A235 --detach-sign -a cryptomator-*.AppImage.zsync
- name: Upload artifacts - name: Upload artifacts
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
with: with:
name: appimage name: appimage-${{ matrix.appimage-suffix }}
path: | path: |
cryptomator-*.AppImage cryptomator-*.AppImage
cryptomator-*.AppImage.zsync cryptomator-*.AppImage.zsync
cryptomator-*.asc cryptomator-*.asc
if-no-files-found: error if-no-files-found: error
- name: Publish AppImage on GitHub Releases - name: Publish AppImage on GitHub Releases
if: startsWith(github.ref, 'refs/tags/') if: startsWith(github.ref, 'refs/tags/') && github.event.action == 'published'
uses: softprops/action-gh-release@v1 uses: softprops/action-gh-release@v2
with: with:
fail_on_unmatched_files: true fail_on_unmatched_files: true
token: ${{ secrets.CRYPTOBOT_RELEASE_TOKEN }} token: ${{ secrets.CRYPTOBOT_RELEASE_TOKEN }}
+40
View File
@@ -0,0 +1,40 @@
name: AntiVirus Whitelisting
on:
workflow_call:
inputs:
url:
description: "Url to the file to upload"
required: true
type: string
workflow_dispatch:
inputs:
url:
description: "Url to the file to upload"
required: true
type: string
jobs:
allowlist:
name: Anti Virus Allowlisting
runs-on: ubuntu-latest
steps:
- name: Download file
run: |
curl --remote-name ${{ inputs.url }} -L
- name: Upload to Kaspersky
uses: SamKirkland/FTP-Deploy-Action@v4.3.5
with:
protocol: ftps
server: allowlist.kaspersky-labs.com
port: 990
username: ${{ secrets.ALLOWLIST_KASPERSKY_USERNAME }}
password: ${{ secrets.ALLOWLIST_KASPERSKY_PASSWORD }}
- name: Upload to Avast
uses: SamKirkland/FTP-Deploy-Action@v4.3.5
with:
protocol: ftp
server: whitelisting.avast.com
port: 21
username: ${{ secrets.ALLOWLIST_AVAST_USERNAME }}
password: ${{ secrets.ALLOWLIST_AVAST_PASSWORD }}
+27 -11
View File
@@ -6,7 +6,8 @@ on:
types: [labeled] types: [labeled]
env: env:
JAVA_VERSION: 20 JAVA_DIST: 'zulu'
JAVA_VERSION: 23
defaults: defaults:
run: run:
@@ -17,14 +18,14 @@ jobs:
name: Compile and Test name: Compile and Test
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- uses: actions/setup-java@v3 - uses: actions/setup-java@v4
with: with:
distribution: 'zulu' distribution: ${{ env.JAVA_DIST }}
java-version: ${{ env.JAVA_VERSION }} java-version: ${{ env.JAVA_VERSION }}
cache: 'maven' cache: 'maven'
- name: Cache SonarCloud packages - name: Cache SonarCloud packages
uses: actions/cache@v3 uses: actions/cache@v4
with: with:
path: ~/.sonar/cache path: ~/.sonar/cache
key: ${{ runner.os }}-sonar key: ${{ runner.os }}-sonar
@@ -32,10 +33,10 @@ jobs:
- name: Build and Test - name: Build and Test
run: > run: >
xvfb-run xvfb-run
mvn -B verify mvn -B verify -Djavafx.platform=linux
jacoco:report jacoco:report
org.sonarsource.scanner.maven:sonar-maven-plugin:sonar org.sonarsource.scanner.maven:sonar-maven-plugin:sonar
-Pcoverage,dependency-check -Pcoverage
-Dsonar.projectKey=cryptomator_cryptomator -Dsonar.projectKey=cryptomator_cryptomator
-Dsonar.organization=cryptomator -Dsonar.organization=cryptomator
-Dsonar.host.url=https://sonarcloud.io -Dsonar.host.url=https://sonarcloud.io
@@ -44,7 +45,7 @@ jobs:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
- name: Draft a release - name: Draft a release
if: startsWith(github.ref, 'refs/tags/') if: startsWith(github.ref, 'refs/tags/')
uses: softprops/action-gh-release@v1 uses: softprops/action-gh-release@v2
with: with:
draft: true draft: true
discussion_category_name: releases discussion_category_name: releases
@@ -52,10 +53,25 @@ jobs:
generate_release_notes: true generate_release_notes: true
body: |- body: |-
:construction: Work in Progress :construction: Work in Progress
### What's New 🎉
⏳ 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. ⏳ ### Bugfixes 🐛
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). ### Other Changes 📎
--- ---
<!-- Don't forget to include the 💾 SHA-256 checksums of release artifacts: -->
TODO FULL CHANGELOG
📜 List of closed issues is available [here](TODO)
---
⏳ 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. ⏳
<!-- Don't forget to include the
💾 SHA-256 checksums of release artifacts:
```
```
-->
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).
+83
View File
@@ -0,0 +1,83 @@
name: Check JDK for non-major updates
on:
schedule:
- cron: '0 0 1 * *' # run once a month at the first day of month
workflow_dispatch:
env:
JDK_VERSION: '23.0.1+11'
JDK_VENDOR: zulu
RUNTIME_VERSION_HELPER: >
public class Test {
public static void main(String[] args) {
System.out.println(Runtime.version());
}
}
jobs:
check-version:
name: Checkout latest jdk version
runs-on: ubuntu-latest
env:
JDK_MAJOR_VERSION: 'toBeFilled'
steps:
- name: Determine current major version
run: echo 'JDK_MAJOR_VERSION=${{ env.JDK_VERSION }}'.substring(0,20) >> "$env:GITHUB_ENV"
shell: pwsh
- name: Checkout latest JDK ${{ env.JDK_MAJOR_VERSION }}
uses: actions/setup-java@v4
with:
java-version: ${{ env.JDK_MAJOR_VERSION}}
distribution: ${{ env.JDK_VENDOR }}
check-latest: true
- name: Determine if update is available
id: determine
shell: pwsh
run: |
$latestVersion = 0,0,0,0 #INTERIM, UPDATE, PATCH and BUILD
$currentVersion = 0,0,0,0
# Get the latest JDK runtime version
"${env:RUNTIME_VERSION_HELPER}" | Set-Content -Path "GetRuntimeVersion.java"
$latestVersionString = & java GetRuntimeVersion.java
$runtimeVersionAndBuild = $latestVersionString.Split('+')
if($runtimeVersionAndBuild.Length -eq 2) {
$latestVersion[3]=$runtimeVersionAndBuild[1];
}
$tmp=$runtimeVersionAndBuild[0].Split('.')
for($i=0;$i -lt $latestVersion.Length; $i++) {
$latestVersion[$i]=$tmp[$i+1];
}
# Get the current JDK version
$runtimeVersionAndBuild = '${{ env.JDK_VERSION}}'.Split('+')
if($runtimeVersionAndBuild.Length -eq 2) {
$currentVersion[3]=$runtimeVersionAndBuild[1];
}
$tmp=$runtimeVersionAndBuild[0].Split('.')
for($i=0;$i -lt $currentVersion.Length; $i++) {
$currentVersion[$i]=$tmp[$i+1];
}
# compare
for($i=0; $i -lt $currentVersion.Length ; $i++) {
if($latestVersion[$i] -gt $currentVersion[$i]){
echo 'UPDATE_AVAILABLE=true' >> "$env:GITHUB_OUTPUT"
echo "LATEST_JDK_VERSION='${latestVersionString}'" >> "$env:GITHUB_OUTPUT"
return 0;
}
}
- name: Notify
if: steps.determine.outputs.UPDATE_AVAILABLE == 'true'
uses: rtCamp/action-slack-notify@v2
env:
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }}
SLACK_USERNAME: 'Cryptobot'
SLACK_ICON: false
SLACK_ICON_EMOJI: ':bot:'
SLACK_CHANNEL: 'cryptomator-desktop'
SLACK_TITLE: "JDK update available"
SLACK_MESSAGE: "Cryptomator-CI JDK can be upgraded to ${{ steps.determine.outputs.LATEST_JDK_VERSION }}. Check the Nextcloud collective for instructions."
SLACK_FOOTER: false
MSG_MINIMAL: true
+20 -13
View File
@@ -16,16 +16,21 @@ on:
type: boolean type: boolean
env: env:
JAVA_VERSION: 20 JAVA_DIST: 'zulu'
OPENJFX_JMODS_AMD64: 'https://download2.gluonhq.com/openjfx/20.0.2/openjfx-20.0.2_linux-x64_bin-jmods.zip' JAVA_VERSION: '23.0.1+11'
OPENJFX_JMODS_AARCH64: 'https://download2.gluonhq.com/openjfx/20.0.2/openjfx-20.0.2_linux-aarch64_bin-jmods.zip' COFFEELIBS_JDK: 23
COFFEELIBS_JDK_VERSION: '23.0.1+11-0ppa1'
OPENJFX_JMODS_AMD64: 'https://download2.gluonhq.com/openjfx/22.0.2/openjfx-22.0.2_linux-x64_bin-jmods.zip'
OPENJFX_JMODS_AMD64_HASH: 'd44bff3b94d5668fdee18a938d7b1269026d663d44765f02d29a9bdfd3fa1eb0'
OPENJFX_JMODS_AARCH64: 'https://download2.gluonhq.com/openjfx/22.0.2/openjfx-22.0.2_linux-aarch64_bin-jmods.zip'
OPENJFX_JMODS_AARCH64_HASH: '3d5457136690c4f5bb9522d38b45218e045bdac13c24aa4c808c7c8d17d039c7'
jobs: jobs:
build: build:
name: Build Debian Package name: Build Debian Package
runs-on: ubuntu-20.04 runs-on: ubuntu-20.04
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- id: versions - id: versions
name: Get version information name: Get version information
run: | run: |
@@ -39,23 +44,25 @@ jobs:
run: | run: |
sudo add-apt-repository ppa:coffeelibs/openjdk sudo add-apt-repository ppa:coffeelibs/openjdk
sudo apt-get update sudo apt-get update
sudo apt-get install debhelper devscripts dput coffeelibs-jdk-${{ env.JAVA_VERSION }} libgtk2.0-0 sudo apt-get install debhelper devscripts dput coffeelibs-jdk-${{ env.COFFEELIBS_JDK }}=${{ env.COFFEELIBS_JDK_VERSION }}
- name: Setup Java - name: Setup Java
uses: actions/setup-java@v3 uses: actions/setup-java@v4
with: with:
distribution: 'zulu' distribution: ${{ env.JAVA_DIST }}
java-version: ${{ env.JAVA_VERSION }} java-version: ${{ env.JAVA_VERSION }}
check-latest: true check-latest: true
cache: 'maven' cache: 'maven'
- name: Run maven - name: Run maven
run: mvn -B clean package -Pdependency-check,linux -DskipTests run: mvn -B clean package -Plinux -Djavafx.platform=linux -DskipTests
- name: Download OpenJFX jmods - name: Download OpenJFX jmods
id: download-jmods id: download-jmods
run: | run: |
curl -L ${{ env.OPENJFX_JMODS_AMD64 }} -o openjfx-amd64.zip curl -L ${{ env.OPENJFX_JMODS_AMD64 }} -o openjfx-amd64.zip
echo "${{ env.OPENJFX_JMODS_AMD64_HASH }} openjfx-amd64.zip" | shasum -a256 --check
mkdir -p jmods/amd64 mkdir -p jmods/amd64
unzip -j openjfx-amd64.zip \*/javafx.base.jmod \*/javafx.controls.jmod \*/javafx.fxml.jmod \*/javafx.graphics.jmod -d jmods/amd64 unzip -j openjfx-amd64.zip \*/javafx.base.jmod \*/javafx.controls.jmod \*/javafx.fxml.jmod \*/javafx.graphics.jmod -d jmods/amd64
curl -L ${{ env.OPENJFX_JMODS_AARCH64 }} -o openjfx-aarch64.zip curl -L ${{ env.OPENJFX_JMODS_AARCH64 }} -o openjfx-aarch64.zip
echo "${{ env.OPENJFX_JMODS_AARCH64_HASH }} openjfx-aarch64.zip" | shasum -a256 --check
mkdir -p jmods/aarch64 mkdir -p jmods/aarch64
unzip -j openjfx-aarch64.zip \*/javafx.base.jmod \*/javafx.controls.jmod \*/javafx.fxml.jmod \*/javafx.graphics.jmod -d jmods/aarch64 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 - name: Ensure major jfx version in pom and in jmods is the same
@@ -92,7 +99,8 @@ jobs:
run: | run: |
cp -r dist/linux/debian/ pkgdir cp -r dist/linux/debian/ pkgdir
export RFC2822_TIMESTAMP=`date --rfc-2822` export RFC2822_TIMESTAMP=`date --rfc-2822`
envsubst '${SEMVER_STR} ${VERSION_NUM} ${REVISION_NUM}' < dist/linux/debian/rules > pkgdir/debian/rules export DISABLE_UPDATE_CHECK=${{ inputs.dput }}
envsubst '${SEMVER_STR} ${VERSION_NUM} ${REVISION_NUM} ${DISABLE_UPDATE_CHECK}' < dist/linux/debian/rules > pkgdir/debian/rules
envsubst '${PPA_VERSION} ${RFC2822_TIMESTAMP}' < dist/linux/debian/changelog > pkgdir/debian/changelog envsubst '${PPA_VERSION} ${RFC2822_TIMESTAMP}' < dist/linux/debian/changelog > pkgdir/debian/changelog
find . -name "*.jar" >> pkgdir/debian/source/include-binaries find . -name "*.jar" >> pkgdir/debian/source/include-binaries
mv pkgdir cryptomator_${{ inputs.ppaver }} mv pkgdir cryptomator_${{ inputs.ppaver }}
@@ -120,7 +128,7 @@ jobs:
run: | run: |
gpg --batch --quiet --passphrase-fd 0 --pinentry-mode loopback -u 615D449FE6E6A235 --detach-sign -a cryptomator_*_amd64.deb gpg --batch --quiet --passphrase-fd 0 --pinentry-mode loopback -u 615D449FE6E6A235 --detach-sign -a cryptomator_*_amd64.deb
- name: Upload artifacts - name: Upload artifacts
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
with: with:
name: linux-deb-package name: linux-deb-package
path: | path: |
@@ -134,12 +142,11 @@ jobs:
- name: Publish on PPA - name: Publish on PPA
if: inputs.dput if: inputs.dput
run: dput ppa:sebastian-stenzel/cryptomator-beta cryptomator_*_source.changes run: dput ppa:sebastian-stenzel/cryptomator-beta cryptomator_*_source.changes
# If ref is a tag, also upload to GitHub Releases: # If ref is a tag, also upload to GitHub Releases:
- name: Publish Debian package on GitHub Releases - name: Publish Debian package on GitHub Releases
if: startsWith(github.ref, 'refs/tags/') if: startsWith(github.ref, 'refs/tags/') && inputs.dput
env: env:
GITHUB_TOKEN: ${{ secrets.CRYPTOBOT_RELEASE_TOKEN }} GITHUB_TOKEN: ${{ secrets.CRYPTOBOT_RELEASE_TOKEN }}
run: | run: |
artifacts=$(ls | grep cryptomator*.deb) artifacts=$(ls | grep cryptomator*.deb)
gh release upload ${{ github.ref_name }} $artifacts gh release upload ${{ github.ref_name }} $artifacts
+18
View File
@@ -0,0 +1,18 @@
name: OWASP Maven Dependency Check
on:
schedule:
- cron: '0 8 * * 0'
workflow_dispatch:
jobs:
check-dependencies:
uses: skymatic/workflows/.github/workflows/run-dependency-check.yml@v1
with:
runner-os: 'ubuntu-latest'
java-distribution: 'temurin'
java-version: 23
check-command: 'mvn -B validate -Pdependency-check -Djavafx.platform=linux'
secrets:
nvd-api-key: ${{ secrets.NVD_API_KEY }}
slack-webhook-url: ${{ secrets.SLACK_WEBHOOK_URL }}
+1 -1
View File
@@ -10,7 +10,7 @@ jobs:
steps: steps:
- name: Get download count of latest releases - name: Get download count of latest releases
id: get-stats id: get-stats
uses: actions/github-script@v6 uses: actions/github-script@v7
with: with:
script: | script: |
const query = `query($owner:String!, $name:String!) { const query = `query($owner:String!, $name:String!) {
+10 -4
View File
@@ -2,7 +2,7 @@ name: Update Error Database
on: on:
discussion: discussion:
types: [created, edited, category_changed, answered, unanswered] types: [created, edited, deleted, category_changed, answered, unanswered]
discussion_comment: discussion_comment:
types: [created, edited, deleted] types: [created, edited, deleted]
@@ -12,8 +12,9 @@ jobs:
if: github.event.discussion.category.name == 'Errors' if: github.event.discussion.category.name == 'Errors'
steps: steps:
- name: Query Discussion Data - name: Query Discussion Data
if: github.event_name == 'discussion_comment' || github.event_name == 'discussion' && github.event.action != 'deleted'
id: query-data id: query-data
uses: actions/github-script@v6 uses: actions/github-script@v7
with: with:
script: | script: |
const query = `query ($owner: String!, $name: String!, $discussionNumber: Int!) { const query = `query ($owner: String!, $name: String!, $discussionNumber: Int!) {
@@ -47,8 +48,13 @@ jobs:
- name: Merge Error Code Data - name: Merge Error Code Data
run: | run: |
jq -c '.' ${{ steps.get-gist.outputs.file }} > original.json jq -c '.' ${{ steps.get-gist.outputs.file }} > original.json
echo $DISCUSSION | jq -c '.repository.discussion | .comments = .comments.totalCount | {(.id|tostring) : .}' > new.json if [ ! -z "$DISCUSSION" ]
jq -s '.[0] * .[1]' original.json new.json > merged.json then
echo $DISCUSSION | jq -c '.repository.discussion | .comments = .comments.totalCount | {(.id|tostring) : .}' > new.json
jq -s '.[0] * .[1]' original.json new.json > merged.json
else
cat original.json | jq 'del(.[] | select(.url=="https://github.com/cryptomator/cryptomator/discussions/${{ github.event.discussion.number }}"))' > merged.json
fi
env: env:
DISCUSSION: ${{ steps.query-data.outputs.result }} DISCUSSION: ${{ steps.query-data.outputs.result }}
- name: Patch Gist - name: Patch Gist
+88
View File
@@ -0,0 +1,88 @@
name: Create PR for flathub
on:
release:
types: [published]
workflow_dispatch:
inputs:
tag:
description: 'Release tag'
required: true
jobs:
get-version:
uses: ./.github/workflows/get-version.yml
with:
version: ${{ inputs.tag }}
tarball:
name: Determines tarball url and compute checksum
runs-on: ubuntu-latest
needs: [get-version]
if: github.event_name == 'workflow_dispatch' || needs.get-version.outputs.versionType == 'stable'
outputs:
url: ${{ steps.url.outputs.url}}
sha512: ${{ steps.sha512.outputs.sha512}}
steps:
- name: Determine tarball url
id: url
run: |
URL="";
if [[ -n "${{ inputs.tag }}" ]]; then
URL="https://github.com/cryptomator/cryptomator/archive/refs/tags/${{ inputs.tag }}.tar.gz"
else
URL="https://github.com/cryptomator/cryptomator/archive/refs/tags/${{ github.event.release.tag_name }}.tar.gz"
fi
echo "url=${URL}" >> "$GITHUB_OUTPUT"
- name: Download source tarball and compute checksum
id: sha512
run: |
curl --silent --fail-with-body -L -H "Accept: application/vnd.github+json" ${{ steps.url.outputs.url }} --output cryptomator.tar.gz
TARBALL_SHA512=$(sha512sum cryptomator.tar.gz | cut -d ' ' -f1)
echo "sha512=${TARBALL_SHA512}" >> "$GITHUB_OUTPUT"
flathub:
name: Create PR for flathub
runs-on: ubuntu-latest
needs: [tarball, get-version]
env:
FLATHUB_PR_URL: tbd
steps:
- uses: actions/checkout@v4
with:
repository: 'flathub/org.cryptomator.Cryptomator'
token: ${{ secrets.CRYPTOBOT_WINGET_TOKEN }}
- name: Checkout release branch
run: |
git checkout -b release/${{ needs.get-version.outputs.semVerStr }}
- name: Update build file
run: |
sed -i -e 's/VERSION: [0-9]\+\.[0-9]\+\.[0-9]\+.*/VERSION: ${{ needs.get-version.outputs.semVerStr }}/g' org.cryptomator.Cryptomator.yaml
sed -i -e 's/sha512: [0-9A-Za-z_\+-]\{128\} #CRYPTOMATOR/sha512: ${{ needs.tarball.outputs.sha512 }} #CRYPTOMATOR/g' org.cryptomator.Cryptomator.yaml
sed -i -e 's;url: https://github.com/cryptomator/cryptomator/archive/refs/tags/[^[:blank:]]\+;url: ${{ needs.tarball.outputs.url }};g' org.cryptomator.Cryptomator.yaml
- name: Commit and push
run: |
git config user.name "${{ github.actor }}"
git config user.email "${{ github.actor_id }}+${{ github.actor }}@users.noreply.github.com"
git config push.autoSetupRemote true
git stage .
git commit -m "Prepare release ${{needs.get-version.outputs.semVerStr}}"
git push
- name: Create pull request
run: |
printf "> [!IMPORTANT]\n> Todos:\n> - [ ] Update maven dependencies\n> - [ ] Check for JDK update\n> - [ ] Check for JFX update" > pr_body.md
PR_URL=$(gh pr create --title "Release ${{ needs.get-version.outputs.semVerStr }}" --body-file pr_body.md)
echo "FLATHUB_PR_URL=$PR_URL" >> "$GITHUB_ENV"
env:
GH_TOKEN: ${{ secrets.CRYPTOBOT_WINGET_TOKEN }}
- name: Slack Notification
uses: rtCamp/action-slack-notify@v2
if: github.event_name == 'release'
env:
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }}
SLACK_USERNAME: 'Cryptobot'
SLACK_ICON: false
SLACK_ICON_EMOJI: ':bot:'
SLACK_CHANNEL: 'cryptomator-desktop'
SLACK_TITLE: "Flathub release PR created for ${{ github.event.repository.name }} ${{ github.event.release.tag_name }} created."
SLACK_MESSAGE: "See <${{ env.FLATHUB_PR_URL }}|PR> on how to proceed.>."
SLACK_FOOTER: false
MSG_MINIMAL: true
+8 -9
View File
@@ -22,9 +22,8 @@ on:
value: ${{ jobs.determine-version.outputs.type }} value: ${{ jobs.determine-version.outputs.type }}
env: env:
JAVA_VERSION: 20 JAVA_DIST: 'zulu'
JAVA_DIST: 'temurin' JAVA_VERSION: 23
JAVA_CACHE: 'maven'
jobs: jobs:
determine-version: determine-version:
@@ -36,22 +35,22 @@ jobs:
revNum: ${{ steps.versions.outputs.revNum }} revNum: ${{ steps.versions.outputs.revNum }}
type: ${{ steps.versions.outputs.type}} type: ${{ steps.versions.outputs.type}}
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
with: with:
fetch-depth: 0 fetch-depth: 0
- name: Setup Java - name: Setup Java
uses: actions/setup-java@v3 uses: actions/setup-java@v4
with: with:
distribution: ${{ env.JAVA_DIST }} distribution: ${{ env.JAVA_DIST }}
java-version: ${{ env.JAVA_VERSION }} java-version: ${{ env.JAVA_VERSION }}
cache: ${{ env.JAVA_CACHE }} cache: 'maven'
- id: versions - id: versions
name: Get version information name: Get version information
run: | run: |
if [[ $GITHUB_REF =~ refs/tags/[0-9]+\.[0-9]+\.[0-9]+.* ]]; then if [[ $GITHUB_REF =~ refs/tags/[0-9]+\.[0-9]+\.[0-9]+.* ]]; then
SEM_VER_STR=${GITHUB_REF##*/} SEM_VER_STR=${GITHUB_REF##*/}
elif [[ "${{ inputs.version }}" =~ [0-9]+\.[0-9]+\.[0-9]+.* ]]; then elif [[ "${{ inputs.version }}" =~ [0-9]+\.[0-9]+\.[0-9]+.* ]]; then
SEM_VER_STR="${{ github.event.inputs.version }}" SEM_VER_STR="${{ inputs.version }}"
else else
SEM_VER_STR=`mvn help:evaluate -Dexpression=project.version -q -DforceStdout` SEM_VER_STR=`mvn help:evaluate -Dexpression=project.version -q -DforceStdout`
fi fi
@@ -72,6 +71,6 @@ jobs:
echo "revNum=${REVCOUNT}" >> $GITHUB_OUTPUT echo "revNum=${REVCOUNT}" >> $GITHUB_OUTPUT
echo "type=${TYPE}" >> $GITHUB_OUTPUT echo "type=${TYPE}" >> $GITHUB_OUTPUT
- name: Validate Version - name: Validate Version
uses: skymatic/semver-validation-action@v2 uses: skymatic/semver-validation-action@v3
with: with:
version: ${{ steps.versions.outputs.semVerStr }} version: ${{ steps.versions.outputs.semVerStr }}
+264
View File
@@ -0,0 +1,264 @@
name: Build macOS .dmg for x64
#######################################
# STOP! DO NOT EDIT THIS FILE!
#
# It is a copy of mac-dmg.yml with tiny adjustements (mainly lines 42 to 47)
# It was made necessary, since Github does not offer free macos intel runners for macos 15 and above.
# This workflow can only be triggered by a release.
#
#######################################
on:
release:
types: [published]
env:
JAVA_DIST: 'zulu'
JAVA_VERSION: '23.0.1+11'
jobs:
get-version:
uses: ./.github/workflows/get-version.yml
with:
version: ${{ inputs.version }}
build-arm:
name: Build Cryptomator.app for ${{ matrix.output-suffix }}
runs-on: ${{ matrix.os }}
needs: [get-version]
strategy:
fail-fast: false
matrix:
include:
- os: macos-15-large
architecture: x64
output-suffix: x64
fuse-lib: macFUSE
openjfx-url: 'https://download2.gluonhq.com/openjfx/22.0.2/openjfx-22.0.2_osx-x64_bin-jmods.zip'
openjfx-sha: '115cb08bb59d880cfff6e51e0bf0dcc45785ed9d456b8b8425597b04da6ab3d4'
steps:
- uses: actions/checkout@v4
- name: Setup Java
uses: actions/setup-java@v4
with:
distribution: ${{ env.JAVA_DIST }}
java-version: ${{ env.JAVA_VERSION }}
architecture: ${{ matrix.architecture }}
check-latest: true
cache: 'maven'
- name: Download OpenJFX jmods
id: download-jmods
run: |
curl -L ${{ matrix.openjfx-url }} -o openjfx-jmods.zip
echo "${{ matrix.openjfx-sha }} *openjfx-jmods.zip" | shasum -a256 --check
mkdir -p openjfx-jmods/
unzip -jo openjfx-jmods.zip \*/javafx.base.jmod \*/javafx.controls.jmod \*/javafx.fxml.jmod \*/javafx.graphics.jmod -d openjfx-jmods
- name: Ensure major jfx version in pom and in jmods is the same
run: |
JMOD_VERSION=$(jmod describe openjfx-jmods/javafx.base.jmod | head -1)
JMOD_VERSION=${JMOD_VERSION#*@}
JMOD_VERSION=${JMOD_VERSION%%.*}
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}" ]; then
>&2 echo "Major JavaFX version in pom.xml (${POM_JFX_VERSION}) != jmod version (${JMOD_VERSION})"
exit 1
fi
- name: Set version
run : mvn versions:set -DnewVersion=${{ needs.get-version.outputs.semVerStr }}
- name: Run maven
run: mvn -B -Djavafx.platform=mac clean package -Pmac -DskipTests
- name: Patch target dir
run: |
cp LICENSE.txt target
cp target/cryptomator-*.jar target/mods
- name: Run jlink
#Remark: no compression is applied for improved build compression later (here dmg)
run: >
${JAVA_HOME}/bin/jlink
--verbose
--output runtime
--module-path "${JAVA_HOME}/jmods:openjfx-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.accessibility,jdk.management.jfr,java.compiler
--strip-native-commands
--no-header-files
--no-man-pages
--strip-debug
--compress zip-0
- name: Run jpackage
run: >
${JAVA_HOME}/bin/jpackage
--verbose
--type app-image
--runtime-image runtime
--input target/libs
--module-path target/mods
--module org.cryptomator.desktop/org.cryptomator.launcher.Cryptomator
--dest appdir
--name Cryptomator
--vendor "Skymatic GmbH"
--copyright "(C) 2016 - 2024 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=\"@{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
--resource-dir dist/mac/resources
- name: Patch Cryptomator.app
run: |
mv appdir/Cryptomator.app Cryptomator.app
mv dist/mac/resources/Cryptomator-Vault.icns Cryptomator.app/Contents/Resources/
sed -i '' "s|###BUNDLE_SHORT_VERSION_STRING###|${VERSION_NO}|g" Cryptomator.app/Contents/Info.plist
sed -i '' "s|###BUNDLE_VERSION###|${REVISION_NO}|g" Cryptomator.app/Contents/Info.plist
echo -n "$PROVISIONING_PROFILE_BASE64" | base64 --decode --output Cryptomator.app/Contents/embedded.provisionprofile
env:
VERSION_NO: ${{ needs.get-version.outputs.semVerNum }}
REVISION_NO: ${{ needs.get-version.outputs.revNum }}
PROVISIONING_PROFILE_BASE64: ${{ secrets.MACOS_PROVISIONING_PROFILE_BASE64 }}
- name: Generate license for dmg
run: >
mvn -B -Djavafx.platform=mac license:add-third-party
-Dlicense.thirdPartyFilename=license.rtf
-Dlicense.outputDirectory=dist/mac/dmg/resources
-Dlicense.fileTemplate=dist/mac/dmg/resources/licenseTemplate.ftl
-Dlicense.includedScopes=compile
-Dlicense.excludedGroups=^org\.cryptomator
-Dlicense.failOnMissing=true
-Dlicense.licenseMergesUrl=file://${{ github.workspace }}/license/merges
- name: Install codesign certificate
run: |
# create variables
CERTIFICATE_PATH=$RUNNER_TEMP/codesign.p12
KEYCHAIN_PATH=$RUNNER_TEMP/codesign.keychain-db
# import certificate and provisioning profile from secrets
echo -n "$CODESIGN_P12_BASE64" | base64 --decode --output $CERTIFICATE_PATH
# create temporary keychain
security create-keychain -p "$CODESIGN_TMP_KEYCHAIN_PW" $KEYCHAIN_PATH
security set-keychain-settings -lut 900 $KEYCHAIN_PATH
security unlock-keychain -p "$CODESIGN_TMP_KEYCHAIN_PW" $KEYCHAIN_PATH
# import certificate to keychain
security import $CERTIFICATE_PATH -P "$CODESIGN_P12_PW" -A -t cert -f pkcs12 -k $KEYCHAIN_PATH
security list-keychain -d user -s $KEYCHAIN_PATH
env:
CODESIGN_P12_BASE64: ${{ secrets.MACOS_CODESIGN_P12_BASE64 }}
CODESIGN_P12_PW: ${{ secrets.MACOS_CODESIGN_P12_PW }}
CODESIGN_TMP_KEYCHAIN_PW: ${{ secrets.MACOS_CODESIGN_TMP_KEYCHAIN_PW }}
- name: Codesign
run: |
echo "Codesigning jdk files..."
find Cryptomator.app/Contents/runtime/Contents/Home/lib/ -name '*.dylib' -exec codesign --force -s ${CODESIGN_IDENTITY} {} \;
find Cryptomator.app/Contents/runtime/Contents/Home/lib/ \( -name 'jspawnhelper' -o -name 'pauseengine' -o -name 'simengine' \) -exec codesign --force -o runtime -s ${CODESIGN_IDENTITY} {} \;
echo "Codesigning jar contents..."
find Cryptomator.app/Contents/runtime/Contents/MacOS -name '*.dylib' -exec codesign --force -s ${CODESIGN_IDENTITY} {} \;
for JAR_PATH in `find Cryptomator.app -name "*.jar"`; do
if [[ `unzip -l ${JAR_PATH} | grep '.dylib\|.jnilib'` ]]; then
JAR_FILENAME=$(basename ${JAR_PATH})
OUTPUT_PATH=${JAR_PATH%.*}
echo "Codesigning libs in ${JAR_FILENAME}..."
unzip -q ${JAR_PATH} -d ${OUTPUT_PATH}
find ${OUTPUT_PATH} -name '*.dylib' -exec codesign --force -s ${CODESIGN_IDENTITY} {} \;
find ${OUTPUT_PATH} -name '*.jnilib' -exec codesign --force -s ${CODESIGN_IDENTITY} {} \;
rm ${JAR_PATH}
pushd ${OUTPUT_PATH} > /dev/null
zip -qr ../${JAR_FILENAME} *
popd > /dev/null
rm -r ${OUTPUT_PATH}
fi
done
echo "Codesigning Cryptomator.app..."
sed -i '' "s|###APP_IDENTIFIER_PREFIX###|${TEAM_IDENTIFIER}.|g" dist/mac/Cryptomator.entitlements
sed -i '' "s|###TEAM_IDENTIFIER###|${TEAM_IDENTIFIER}|g" dist/mac/Cryptomator.entitlements
codesign --force --deep --entitlements dist/mac/Cryptomator.entitlements -o runtime -s ${CODESIGN_IDENTITY} Cryptomator.app
env:
CODESIGN_IDENTITY: ${{ secrets.MACOS_CODESIGN_IDENTITY }}
TEAM_IDENTIFIER: ${{ secrets.MACOS_TEAM_IDENTIFIER }}
- name: Prepare .dmg contents
run: |
mkdir dmg
mv Cryptomator.app dmg
cp dist/mac/dmg/resources/${{ matrix.fuse-lib }}.webloc dmg
ls -l dmg
- name: Install create-dmg
run: |
brew install create-dmg
create-dmg --help
- name: Create .dmg
run: >
create-dmg
--volname Cryptomator
--volicon "dist/mac/dmg/resources/Cryptomator-Volume.icns"
--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 "${{ 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
--icon ".VolumeIcon.icns" 512 758
Cryptomator-${VERSION_NO}-${{ matrix.output-suffix }}.dmg dmg
env:
VERSION_NO: ${{ needs.get-version.outputs.semVerNum }}
- name: Notarize .dmg
if: startsWith(github.ref, 'refs/tags/') || inputs.notarize
uses: cocoalibs/xcode-notarization-action@v1
with:
app-path: 'Cryptomator-*.dmg'
apple-id: ${{ secrets.MACOS_NOTARIZATION_APPLE_ID }}
password: ${{ secrets.MACOS_NOTARIZATION_PW }}
team-id: ${{ secrets.MACOS_NOTARIZATION_TEAM_ID }}
xcode-path: '/Applications/Xcode_16.app'
- name: Add possible alpha/beta tags to installer name
run: mv Cryptomator-*.dmg Cryptomator-${{ needs.get-version.outputs.semVerStr }}-${{ matrix.output-suffix }}.dmg
- name: Create detached GPG signature with key 615D449FE6E6A235
run: |
echo "${GPG_PRIVATE_KEY}" | gpg --batch --quiet --import
echo "${GPG_PASSPHRASE}" | gpg --batch --quiet --passphrase-fd 0 --pinentry-mode loopback -u 615D449FE6E6A235 --detach-sign -a Cryptomator-*.dmg
env:
GPG_PRIVATE_KEY: ${{ secrets.RELEASES_GPG_PRIVATE_KEY }}
GPG_PASSPHRASE: ${{ secrets.RELEASES_GPG_PASSPHRASE }}
- name: Clean up codesign certificate
if: ${{ always() }}
run: security delete-keychain $RUNNER_TEMP/codesign.keychain-db
continue-on-error: true
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: dmg-${{ matrix.output-suffix }}
path: |
Cryptomator-*.dmg
Cryptomator-*.asc
if-no-files-found: error
- name: Publish dmg on GitHub Releases
if: startsWith(github.ref, 'refs/tags/') && github.event.action == 'published'
uses: softprops/action-gh-release@v2
with:
fail_on_unmatched_files: true
token: ${{ secrets.CRYPTOBOT_RELEASE_TOKEN }}
files: |
Cryptomator-*.dmg
Cryptomator-*.asc
+31 -32
View File
@@ -1,4 +1,4 @@
name: Build macOS .dmg name: Build macOS .dmg for arm64
on: on:
release: release:
@@ -15,7 +15,8 @@ on:
type: boolean type: boolean
env: env:
JAVA_VERSION: 20 JAVA_DIST: 'zulu'
JAVA_VERSION: '23.0.1+11'
jobs: jobs:
get-version: get-version:
@@ -31,28 +32,19 @@ jobs:
fail-fast: false fail-fast: false
matrix: matrix:
include: include:
- os: macos-11 - os: macos-15
architecture: x64
output-suffix: x64
xcode-path: '/Applications/Xcode_13.2.1.app'
fuse-lib: macFUSE
openjfx-url: https://download2.gluonhq.com/openjfx/20.0.2/openjfx-20.0.2_osx-x64_bin-jmods.zip
openjfx-sha: 55b8ff7453d59c89ae129f6c9c5ad7b09a5d359568811b376ac1766c14d6a17c
- os: [self-hosted, macOS, ARM64]
architecture: aarch64 architecture: aarch64
output-suffix: arm64 output-suffix: arm64
xcode-path: '/Applications/Xcode_13.2.1.app'
fuse-lib: FUSE-T fuse-lib: FUSE-T
openjfx-url: https://download2.gluonhq.com/openjfx/20.0.2/openjfx-20.0.2_osx-aarch64_bin-jmods.zip openjfx-url: 'https://download2.gluonhq.com/openjfx/22.0.2/openjfx-22.0.2_osx-aarch64_bin-jmods.zip'
openjfx-sha: c60f5f19aa847e0e620e0b011e5de68f2c6755641c2141cec27a0b89f612beaf openjfx-sha: '813c6748f7c99cb7a579d48b48a087b4682b1fad1fc1a4fe5f9b21cf872b15a7'
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- name: Setup Java - name: Setup Java
uses: actions/setup-java@v3 uses: actions/setup-java@v4
with: with:
distribution: 'temurin' distribution: ${{ env.JAVA_DIST }}
java-version: ${{ env.JAVA_VERSION }} java-version: ${{ env.JAVA_VERSION }}
java-package: 'jdk'
architecture: ${{ matrix.architecture }} architecture: ${{ matrix.architecture }}
check-latest: true check-latest: true
cache: 'maven' cache: 'maven'
@@ -62,7 +54,7 @@ jobs:
curl -L ${{ matrix.openjfx-url }} -o openjfx-jmods.zip curl -L ${{ matrix.openjfx-url }} -o openjfx-jmods.zip
echo "${{ matrix.openjfx-sha }} *openjfx-jmods.zip" | shasum -a256 --check echo "${{ matrix.openjfx-sha }} *openjfx-jmods.zip" | shasum -a256 --check
mkdir -p openjfx-jmods/ mkdir -p openjfx-jmods/
unzip -j openjfx-jmods.zip \*/javafx.base.jmod \*/javafx.controls.jmod \*/javafx.fxml.jmod \*/javafx.graphics.jmod -d openjfx-jmods unzip -jo openjfx-jmods.zip \*/javafx.base.jmod \*/javafx.controls.jmod \*/javafx.fxml.jmod \*/javafx.graphics.jmod -d openjfx-jmods
- name: Ensure major jfx version in pom and in jmods is the same - name: Ensure major jfx version in pom and in jmods is the same
run: | run: |
JMOD_VERSION=$(jmod describe openjfx-jmods/javafx.base.jmod | head -1) JMOD_VERSION=$(jmod describe openjfx-jmods/javafx.base.jmod | head -1)
@@ -72,30 +64,31 @@ jobs:
POM_JFX_VERSION=${POM_JFX_VERSION#*@} POM_JFX_VERSION=${POM_JFX_VERSION#*@}
POM_JFX_VERSION=${POM_JFX_VERSION%%.*} POM_JFX_VERSION=${POM_JFX_VERSION%%.*}
if [ $POM_JFX_VERSION -ne $JMOD_VERSION ]; then if [ "${POM_JFX_VERSION}" -ne "${JMOD_VERSION}" ]; then
>&2 echo "Major JavaFX version in pom.xml (${POM_JFX_VERSION}) != jmod version (${JMOD_VERSION_AMD64})" >&2 echo "Major JavaFX version in pom.xml (${POM_JFX_VERSION}) != jmod version (${JMOD_VERSION})"
exit 1 exit 1
fi fi
- name: Set version - name: Set version
run : mvn versions:set -DnewVersion=${{ needs.get-version.outputs.semVerStr }} run : mvn versions:set -DnewVersion=${{ needs.get-version.outputs.semVerStr }}
- name: Run maven - name: Run maven
run: mvn -B clean package -Pdependency-check,mac -DskipTests run: mvn -B -Djavafx.platform=mac clean package -Pmac -DskipTests
- name: Patch target dir - name: Patch target dir
run: | run: |
cp LICENSE.txt target cp LICENSE.txt target
cp target/cryptomator-*.jar target/mods cp target/cryptomator-*.jar target/mods
- name: Run jlink - name: Run jlink
#Remark: no compression is applied for improved build compression later (here dmg)
run: > run: >
${JAVA_HOME}/bin/jlink ${JAVA_HOME}/bin/jlink
--verbose --verbose
--output runtime --output runtime
--module-path "${JAVA_HOME}/jmods:openjfx-jmods" --module-path "${JAVA_HOME}/jmods:openjfx-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.accessibility,jdk.management.jfr,java.compiler
--strip-native-commands --strip-native-commands
--no-header-files --no-header-files
--no-man-pages --no-man-pages
--strip-debug --strip-debug
--compress=1 --compress zip-0
- name: Run jpackage - name: Run jpackage
run: > run: >
${JAVA_HOME}/bin/jpackage ${JAVA_HOME}/bin/jpackage
@@ -108,7 +101,7 @@ jobs:
--dest appdir --dest appdir
--name Cryptomator --name Cryptomator
--vendor "Skymatic GmbH" --vendor "Skymatic GmbH"
--copyright "(C) 2016 - 2023 Skymatic GmbH" --copyright "(C) 2016 - 2024 Skymatic GmbH"
--app-version "${{ needs.get-version.outputs.semVerNum }}" --app-version "${{ needs.get-version.outputs.semVerNum }}"
--java-options "--enable-preview" --java-options "--enable-preview"
--java-options "--enable-native-access=org.cryptomator.jfuse.mac" --java-options "--enable-native-access=org.cryptomator.jfuse.mac"
@@ -136,12 +129,14 @@ jobs:
mv dist/mac/resources/Cryptomator-Vault.icns Cryptomator.app/Contents/Resources/ mv dist/mac/resources/Cryptomator-Vault.icns Cryptomator.app/Contents/Resources/
sed -i '' "s|###BUNDLE_SHORT_VERSION_STRING###|${VERSION_NO}|g" Cryptomator.app/Contents/Info.plist sed -i '' "s|###BUNDLE_SHORT_VERSION_STRING###|${VERSION_NO}|g" Cryptomator.app/Contents/Info.plist
sed -i '' "s|###BUNDLE_VERSION###|${REVISION_NO}|g" Cryptomator.app/Contents/Info.plist sed -i '' "s|###BUNDLE_VERSION###|${REVISION_NO}|g" Cryptomator.app/Contents/Info.plist
echo -n "$PROVISIONING_PROFILE_BASE64" | base64 --decode --output Cryptomator.app/Contents/embedded.provisionprofile
env: env:
VERSION_NO: ${{ needs.get-version.outputs.semVerNum }} VERSION_NO: ${{ needs.get-version.outputs.semVerNum }}
REVISION_NO: ${{ needs.get-version.outputs.revNum }} REVISION_NO: ${{ needs.get-version.outputs.revNum }}
PROVISIONING_PROFILE_BASE64: ${{ secrets.MACOS_PROVISIONING_PROFILE_BASE64 }}
- name: Generate license for dmg - name: Generate license for dmg
run: > run: >
mvn -B license:add-third-party mvn -B -Djavafx.platform=mac license:add-third-party
-Dlicense.thirdPartyFilename=license.rtf -Dlicense.thirdPartyFilename=license.rtf
-Dlicense.outputDirectory=dist/mac/dmg/resources -Dlicense.outputDirectory=dist/mac/dmg/resources
-Dlicense.fileTemplate=dist/mac/dmg/resources/licenseTemplate.ftl -Dlicense.fileTemplate=dist/mac/dmg/resources/licenseTemplate.ftl
@@ -174,7 +169,7 @@ jobs:
run: | run: |
echo "Codesigning jdk files..." echo "Codesigning jdk files..."
find Cryptomator.app/Contents/runtime/Contents/Home/lib/ -name '*.dylib' -exec codesign --force -s ${CODESIGN_IDENTITY} {} \; find Cryptomator.app/Contents/runtime/Contents/Home/lib/ -name '*.dylib' -exec codesign --force -s ${CODESIGN_IDENTITY} {} \;
find Cryptomator.app/Contents/runtime/Contents/Home/lib/ -name 'jspawnhelper' -exec codesign --force -o runtime -s ${CODESIGN_IDENTITY} {} \; find Cryptomator.app/Contents/runtime/Contents/Home/lib/ \( -name 'jspawnhelper' -o -name 'pauseengine' -o -name 'simengine' \) -exec codesign --force -o runtime -s ${CODESIGN_IDENTITY} {} \;
echo "Codesigning jar contents..." echo "Codesigning jar contents..."
find Cryptomator.app/Contents/runtime/Contents/MacOS -name '*.dylib' -exec codesign --force -s ${CODESIGN_IDENTITY} {} \; find Cryptomator.app/Contents/runtime/Contents/MacOS -name '*.dylib' -exec codesign --force -s ${CODESIGN_IDENTITY} {} \;
for JAR_PATH in `find Cryptomator.app -name "*.jar"`; do for JAR_PATH in `find Cryptomator.app -name "*.jar"`; do
@@ -193,9 +188,12 @@ jobs:
fi fi
done done
echo "Codesigning Cryptomator.app..." echo "Codesigning Cryptomator.app..."
sed -i '' "s|###APP_IDENTIFIER_PREFIX###|${TEAM_IDENTIFIER}.|g" dist/mac/Cryptomator.entitlements
sed -i '' "s|###TEAM_IDENTIFIER###|${TEAM_IDENTIFIER}|g" dist/mac/Cryptomator.entitlements
codesign --force --deep --entitlements dist/mac/Cryptomator.entitlements -o runtime -s ${CODESIGN_IDENTITY} Cryptomator.app codesign --force --deep --entitlements dist/mac/Cryptomator.entitlements -o runtime -s ${CODESIGN_IDENTITY} Cryptomator.app
env: env:
CODESIGN_IDENTITY: ${{ secrets.MACOS_CODESIGN_IDENTITY }} CODESIGN_IDENTITY: ${{ secrets.MACOS_CODESIGN_IDENTITY }}
TEAM_IDENTIFIER: ${{ secrets.MACOS_TEAM_IDENTIFIER }}
- name: Prepare .dmg contents - name: Prepare .dmg contents
run: | run: |
mkdir dmg mkdir dmg
@@ -222,7 +220,6 @@ jobs:
--app-drop-link 512 245 --app-drop-link 512 245
--eula "dist/mac/dmg/resources/license.rtf" --eula "dist/mac/dmg/resources/license.rtf"
--icon ".background" 128 758 --icon ".background" 128 758
--icon ".fseventsd" 320 758
--icon ".VolumeIcon.icns" 512 758 --icon ".VolumeIcon.icns" 512 758
Cryptomator-${VERSION_NO}-${{ matrix.output-suffix }}.dmg dmg Cryptomator-${VERSION_NO}-${{ matrix.output-suffix }}.dmg dmg
env: env:
@@ -235,7 +232,7 @@ jobs:
apple-id: ${{ secrets.MACOS_NOTARIZATION_APPLE_ID }} apple-id: ${{ secrets.MACOS_NOTARIZATION_APPLE_ID }}
password: ${{ secrets.MACOS_NOTARIZATION_PW }} password: ${{ secrets.MACOS_NOTARIZATION_PW }}
team-id: ${{ secrets.MACOS_NOTARIZATION_TEAM_ID }} team-id: ${{ secrets.MACOS_NOTARIZATION_TEAM_ID }}
xcode-path: ${{ matrix.xcode-path }} xcode-path: '/Applications/Xcode_16.app'
- name: Add possible alpha/beta tags to installer name - name: Add possible alpha/beta tags to installer name
run: mv Cryptomator-*.dmg Cryptomator-${{ needs.get-version.outputs.semVerStr }}-${{ matrix.output-suffix }}.dmg run: mv Cryptomator-*.dmg Cryptomator-${{ needs.get-version.outputs.semVerStr }}-${{ matrix.output-suffix }}.dmg
- name: Create detached GPG signature with key 615D449FE6E6A235 - name: Create detached GPG signature with key 615D449FE6E6A235
@@ -250,14 +247,16 @@ jobs:
run: security delete-keychain $RUNNER_TEMP/codesign.keychain-db run: security delete-keychain $RUNNER_TEMP/codesign.keychain-db
continue-on-error: true continue-on-error: true
- name: Upload artifacts - name: Upload artifacts
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
with: with:
name: dmg-${{ matrix.output-suffix }} name: dmg-${{ matrix.output-suffix }}
path: Cryptomator-*.dmg path: |
Cryptomator-*.dmg
Cryptomator-*.asc
if-no-files-found: error if-no-files-found: error
- name: Publish dmg on GitHub Releases - name: Publish dmg on GitHub Releases
if: startsWith(github.ref, 'refs/tags/') if: startsWith(github.ref, 'refs/tags/') && github.event.action == 'published'
uses: softprops/action-gh-release@v1 uses: softprops/action-gh-release@v2
with: with:
fail_on_unmatched_files: true fail_on_unmatched_files: true
token: ${{ secrets.CRYPTOBOT_RELEASE_TOKEN }} token: ${{ secrets.CRYPTOBOT_RELEASE_TOKEN }}
+1 -1
View File
@@ -12,7 +12,7 @@ jobs:
issues: write issues: write
pull-requests: write pull-requests: write
steps: steps:
- uses: actions/stale@v8 - uses: actions/stale@v9
with: with:
days-before-stale: 14 days-before-stale: 14
days-before-close: 0 days-before-close: 0
+1 -1
View File
@@ -19,7 +19,7 @@ jobs:
GPG_PRIVATE_KEY: ${{ secrets.RELEASES_GPG_PRIVATE_KEY }} GPG_PRIVATE_KEY: ${{ secrets.RELEASES_GPG_PRIVATE_KEY }}
GPG_PASSPHRASE: ${{ secrets.RELEASES_GPG_PASSPHRASE }} GPG_PASSPHRASE: ${{ secrets.RELEASES_GPG_PASSPHRASE }}
- name: Publish asc on GitHub Releases - name: Publish asc on GitHub Releases
uses: softprops/action-gh-release@v1 uses: softprops/action-gh-release@v2
with: with:
fail_on_unmatched_files: true fail_on_unmatched_files: true
token: ${{ secrets.CRYPTOBOT_RELEASE_TOKEN }} token: ${{ secrets.CRYPTOBOT_RELEASE_TOKEN }}
+6 -5
View File
@@ -4,7 +4,8 @@ on:
pull_request: pull_request:
env: env:
JAVA_VERSION: 20 JAVA_DIST: 'zulu'
JAVA_VERSION: 23
defaults: defaults:
run: run:
@@ -16,11 +17,11 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
if: "!contains(github.event.head_commit.message, '[ci skip]') && !contains(github.event.head_commit.message, '[skip ci]')" if: "!contains(github.event.head_commit.message, '[ci skip]') && !contains(github.event.head_commit.message, '[skip ci]')"
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- uses: actions/setup-java@v3 - uses: actions/setup-java@v4
with: with:
distribution: 'zulu' distribution: ${{ env.JAVA_DIST }}
java-version: ${{ env.JAVA_VERSION }} java-version: ${{ env.JAVA_VERSION }}
cache: 'maven' cache: 'maven'
- name: Build and Test - name: Build and Test
run: xvfb-run mvn -B clean install jacoco:report -Pcoverage,dependency-check run: xvfb-run mvn -B clean install jacoco:report -Pcoverage -Djavafx.platform=linux
+29 -7
View File
@@ -6,19 +6,26 @@ on:
- 'release/**' - 'release/**'
- 'hotfix/**' - 'hotfix/**'
env:
JAVA_VERSION: 20
defaults: defaults:
run: run:
shell: bash shell: bash
env:
JAVA_DIST: 'zulu'
JAVA_VERSION: 23
jobs: jobs:
release-check-precondition: check-preconditions:
name: Validate commits pushed to release/hotfix branch to fulfill release requirements name: Validate commits pushed to release/hotfix branch to fulfill release requirements
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- name: Setup Java
uses: actions/setup-java@v4
with:
distribution: ${{ env.JAVA_DIST }}
java-version: ${{ env.JAVA_VERSION }}
cache: 'maven'
- id: validate-pom-version - id: validate-pom-version
name: Validate POM version name: Validate POM version
run: | run: |
@@ -37,7 +44,22 @@ jobs:
fi fi
- name: Validate release in org.cryptomator.Cryptomator.metainfo.xml file - name: Validate release in org.cryptomator.Cryptomator.metainfo.xml file
run: | run: |
if ! grep -q "<release date=\".*\" version=\"${{ steps.validate-pom-version.outputs.semVerStr }}\"/>" dist/linux/common/org.cryptomator.Cryptomator.metainfo.xml; then if ! grep -q "<release date=\".*\" version=\"${{ steps.validate-pom-version.outputs.semVerStr }}\">" dist/linux/common/org.cryptomator.Cryptomator.metainfo.xml; then
echo "Release not set in dist/linux/common/org.cryptomator.Cryptomator.metainfo.xml" echo "Release not set in dist/linux/common/org.cryptomator.Cryptomator.metainfo.xml"
exit 1 exit 1
fi fi
- name: Cache NVD DB
uses: actions/cache@v4
with:
path: ~/.m2/repository/org/owasp/dependency-check-data/
key: dependency-check-${{ github.run_id }}
restore-keys: |
dependency-check
env:
SEGMENT_DOWNLOAD_TIMEOUT_MINS: 5
- name: Run org.owasp:dependency-check plugin
id: dependency-check
continue-on-error: true
run: mvn -B verify -Pdependency-check -DskipTests -Djavafx.platform=linux
env:
NVD_API_KEY: ${{ secrets.NVD_API_KEY }}
+1 -1
View File
@@ -12,7 +12,7 @@ jobs:
issues: write issues: write
pull-requests: write pull-requests: write
steps: steps:
- uses: actions/stale@v8 - uses: actions/stale@v9
with: with:
days-before-stale: 365 days-before-stale: 365
days-before-close: 90 days-before-close: 90
+129 -89
View File
@@ -11,14 +11,16 @@ on:
isDebug: isDebug:
description: 'Build debug version with console output' description: 'Build debug version with console output'
type: boolean type: boolean
default: false
env: env:
JAVA_VERSION: 20 JAVA_DIST: 'zulu'
JAVA_DIST: 'temurin' JAVA_VERSION: '23.0.1+11'
JAVA_CACHE: 'maven' OPENJFX_JMODS_AMD64: 'https://download2.gluonhq.com/openjfx/22.0.2/openjfx-22.0.2_windows-x64_bin-jmods.zip'
JFX_JMODS_URL: 'https://download2.gluonhq.com/openjfx/20.0.2/openjfx-20.0.2_windows-x64_bin-jmods.zip' OPENJFX_JMODS_AMD64_HASH: 'f9376d200f5c5b85327d575c1ec1482e6455f19916577f7e2fc9be2f48bb29b6'
JFX_JMODS_HASH: '18625bbc13c57dbf802486564247a8d8cab72ec558c240a401bf6440384ebd77' WINFSP_MSI: 'https://github.com/winfsp/winfsp/releases/download/v2.0/winfsp-2.0.23075.msi'
WINFSP_UNINSTALLER: 'https://github.com/cryptomator/winfsp-uninstaller/releases/latest/download/winfsp-uninstaller.exe'
defaults: defaults:
run: run:
@@ -38,21 +40,23 @@ jobs:
LOOPBACK_ALIAS: 'cryptomator-vault' LOOPBACK_ALIAS: 'cryptomator-vault'
WIN_CONSOLE_FLAG: '' WIN_CONSOLE_FLAG: ''
steps: steps:
- uses: actions/checkout@v3 - name: Upgrade WIX to latest version
run: choco install wixtoolset --version 3.14.1
shell: pwsh
- uses: actions/checkout@v4
- name: Setup Java - name: Setup Java
uses: actions/setup-java@v3 uses: actions/setup-java@v4
with: with:
distribution: ${{ env.JAVA_DIST }} distribution: ${{ env.JAVA_DIST }}
java-version: ${{ env.JAVA_VERSION }} java-version: ${{ env.JAVA_VERSION }}
java-package: 'jdk'
check-latest: true check-latest: true
cache: ${{ env.JAVA_CACHE }} cache: 'maven'
- name: Download and extract JavaFX jmods from Gluon - 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 #In the last step we move all jmods files a dir level up because jmods are placed inside a directory in the zip
run: | run: |
curl --output jfxjmods.zip -L "${{ env.JFX_JMODS_URL }}" curl --output jfxjmods.zip -L "${{ env.OPENJFX_JMODS_AMD64 }}"
if(!(Get-FileHash -Path jfxjmods.zip -Algorithm SHA256).Hash.ToLower().equals("${{ env.JFX_JMODS_HASH }}")) { if(!(Get-FileHash -Path jfxjmods.zip -Algorithm SHA256).Hash.ToLower().equals("${{ env.OPENJFX_JMODS_AMD64_HASH }}")) {
throw "Wrong checksum of JMOD archive downloaded from ${{ env.JFX_JMODS_URL }}."; throw "Wrong checksum of JMOD archive downloaded from ${{ env.OPENJFX_JMODS_AMD64 }}.";
} }
Expand-Archive -Path jfxjmods.zip -DestinationPath jfxjmods Expand-Archive -Path jfxjmods.zip -DestinationPath jfxjmods
Get-ChildItem -Path jfxjmods -Recurse -Filter "*.jmod" | ForEach-Object { Move-Item -Path $_ -Destination $_.Directory.Parent} Get-ChildItem -Path jfxjmods -Recurse -Filter "*.jmod" | ForEach-Object { Move-Item -Path $_ -Destination $_.Directory.Parent}
@@ -73,23 +77,24 @@ jobs:
- name: Set version - name: Set version
run : mvn versions:set -DnewVersion=${{ needs.get-version.outputs.semVerStr }} run : mvn versions:set -DnewVersion=${{ needs.get-version.outputs.semVerStr }}
- name: Run maven - name: Run maven
run: mvn -B clean package -Pdependency-check,win -DskipTests run: mvn -B clean package -Pwin -DskipTests -Djavafx.platform=win
- name: Patch target dir - name: Patch target dir
run: | run: |
cp LICENSE.txt target cp LICENSE.txt target
cp target/cryptomator-*.jar target/mods cp target/cryptomator-*.jar target/mods
- name: Run jlink - name: Run jlink
#Remark: no compression is applied for improved build compression later (here msi)
run: > run: >
${JAVA_HOME}/bin/jlink ${JAVA_HOME}/bin/jlink
--verbose --verbose
--output runtime --output runtime
--module-path "jfxjmods;${JAVA_HOME}/jmods" --module-path "jfxjmods;${JAVA_HOME}/jmods"
--add-modules java.base,java.desktop,java.instrument,java.logging,java.naming,java.net.http,java.scripting,java.sql,java.xml,javafx.base,javafx.graphics,javafx.controls,javafx.fxml,jdk.unsupported,jdk.crypto.ec,jdk.accessibility,jdk.management.jfr --add-modules java.base,java.desktop,java.instrument,java.logging,java.naming,java.net.http,java.scripting,java.sql,java.xml,javafx.base,javafx.graphics,javafx.controls,javafx.fxml,jdk.unsupported,jdk.accessibility,jdk.management.jfr,java.compiler
--strip-native-commands --strip-native-commands
--no-header-files --no-header-files
--no-man-pages --no-man-pages
--strip-debug --strip-debug
--compress=1 --compress zip-0
- name: Change win-console flag if debug is active - name: Change win-console flag if debug is active
if: ${{ inputs.isDebug }} if: ${{ inputs.isDebug }}
run: echo "WIN_CONSOLE_FLAG=--win-console" >> $GITHUB_ENV run: echo "WIN_CONSOLE_FLAG=--win-console" >> $GITHUB_ENV
@@ -105,10 +110,10 @@ jobs:
--dest appdir --dest appdir
--name Cryptomator --name Cryptomator
--vendor "Skymatic GmbH" --vendor "Skymatic GmbH"
--copyright "(C) 2016 - 2023 Skymatic GmbH" --copyright "(C) 2016 - 2024 Skymatic GmbH"
--app-version "${{ needs.get-version.outputs.semVerNum }}.${{ needs.get-version.outputs.revNum }}" --app-version "${{ needs.get-version.outputs.semVerNum }}.${{ needs.get-version.outputs.revNum }}"
--java-options "--enable-preview" --java-options "--enable-preview"
--java-options "--enable-native-access=org.cryptomator.jfuse.win" --java-options "--enable-native-access=org.cryptomator.jfuse.win,org.cryptomator.integrations.win"
--java-options "-Xss5m" --java-options "-Xss5m"
--java-options "-Xmx256m" --java-options "-Xmx256m"
--java-options "-Dcryptomator.appVersion=\"${{ needs.get-version.outputs.semVerStr }}\"" --java-options "-Dcryptomator.appVersion=\"${{ needs.get-version.outputs.semVerStr }}\""
@@ -125,6 +130,7 @@ jobs:
--java-options "-Dcryptomator.buildNumber=\"msi-${{ needs.get-version.outputs.revNum }}\"" --java-options "-Dcryptomator.buildNumber=\"msi-${{ needs.get-version.outputs.revNum }}\""
--java-options "-Dcryptomator.integrationsWin.autoStartShellLinkName=\"Cryptomator\"" --java-options "-Dcryptomator.integrationsWin.autoStartShellLinkName=\"Cryptomator\""
--java-options "-Dcryptomator.integrationsWin.keychainPaths=\"@{appdata}/Cryptomator/keychain.json;@{userhome}/AppData/Roaming/Cryptomator/keychain.json\"" --java-options "-Dcryptomator.integrationsWin.keychainPaths=\"@{appdata}/Cryptomator/keychain.json;@{userhome}/AppData/Roaming/Cryptomator/keychain.json\""
--java-options "-Dcryptomator.integrationsWin.windowsHelloKeychainPaths=\"@{appdata}/Cryptomator/windowsHelloKeychain.json;@{userhome}/AppData/Roaming/Cryptomator/windowsHelloKeychain.json\""
--java-options "-Djavafx.verbose=${{ inputs.isDebug }}" --java-options "-Djavafx.verbose=${{ inputs.isDebug }}"
--resource-dir dist/win/resources --resource-dir dist/win/resources
--icon dist/win/resources/Cryptomator.ico --icon dist/win/resources/Cryptomator.ico
@@ -145,26 +151,56 @@ jobs:
- name: Fix permissions - name: Fix permissions
run: attrib -r appdir/Cryptomator/Cryptomator.exe run: attrib -r appdir/Cryptomator/Cryptomator.exe
shell: pwsh shell: pwsh
- name: Extract integrations DLL for code signing - name: Extract jars with DLLs for Codesigning
shell: pwsh shell: pwsh
run: gci ./appdir/Cryptomator/app/mods/ -File integrations-win-*.jar | ForEach-Object {Set-Location -Path $_.Directory; jar --file=$($_.FullName) --extract integrations.dll } run: |
Add-Type -AssemblyName "System.io.compression.filesystem"
$jarFolder = Resolve-Path ".\appdir\Cryptomator\app\mods"
$jarExtractDir = New-Item -Path ".\appdir\jar-extract" -ItemType Directory
#for all jars inspect
Get-ChildItem -Path $jarFolder -Filter "*.jar" | ForEach-Object {
$jar = [Io.compression.zipfile]::OpenRead($_.FullName)
if (@($jar.Entries | Where-Object {$_.Name.ToString().EndsWith(".dll")} | Select-Object -First 1).Count -gt 0) {
#jars containing dlls extract
Set-Location $jarExtractDir
Expand-Archive -Path $_.FullName
}
$jar.Dispose()
}
- name: Extract wixhelper.dll for Codesigning #see https://github.com/cryptomator/cryptomator/issues/3130
shell: pwsh
run: |
New-Item -Path appdir/jpackage-jmod -ItemType Directory
& $env:JAVA_HOME\bin\jmod.exe extract --dir jpackage-jmod "${env:JAVA_HOME}\jmods\jdk.jpackage.jmod"
Get-ChildItem -Recurse -Path "jpackage-jmod" -File wixhelper.dll | Select-Object -Last 1 | Copy-Item -Destination "appdir"
- name: Codesign - name: Codesign
uses: skymatic/code-sign-action@v2 uses: skymatic/code-sign-action@v3
with: with:
certificate: ${{ secrets.WIN_CODESIGN_P12_BASE64 }} certificate: ${{ secrets.WIN_CODESIGN_P12_BASE64 }}
password: ${{ secrets.WIN_CODESIGN_P12_PW }} password: ${{ secrets.WIN_CODESIGN_P12_PW }}
certificatesha1: 5FC94CE149E5B511E621F53A060AC67CBD446B3A certificatesha1: 5FC94CE149E5B511E621F53A060AC67CBD446B3A
description: Cryptomator description: Cryptomator
timestampUrl: 'http://timestamp.digicert.com' timestampUrl: 'http://timestamp.digicert.com'
folder: appdir/Cryptomator folder: appdir
recursive: true recursive: true
- name: Repack signed DLL into jar - name: Replace DLLs inside jars with signed ones
shell: pwsh shell: pwsh
run: | 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} $jarExtractDir = Resolve-Path ".\appdir\jar-extract"
$jarFolder = Resolve-Path ".\appdir\Cryptomator\app\mods"
Get-ChildItem -Path $jarExtractDir | ForEach-Object {
$jarName = $_.Name
$jarFile = "${jarFolder}\${jarName}.jar"
Set-Location $_
Get-ChildItem -Path $_ -Recurse -File "*.dll" | ForEach-Object {
# update jar with signed dll
jar --file="$jarFile" --update $(Resolve-Path -Relative -Path $_)
}
}
- name: Generate license for MSI - name: Generate license for MSI
run: > run: >
mvn -B license:add-third-party mvn -B license:add-third-party "-Djavafx.platform=win"
"-Dlicense.thirdPartyFilename=license.rtf" "-Dlicense.thirdPartyFilename=license.rtf"
"-Dlicense.outputDirectory=dist/win/resources" "-Dlicense.outputDirectory=dist/win/resources"
"-Dlicense.fileTemplate=dist/win/resources/licenseTemplate.ftl" "-Dlicense.fileTemplate=dist/win/resources/licenseTemplate.ftl"
@@ -183,20 +219,21 @@ jobs:
--dest installer --dest installer
--name Cryptomator --name Cryptomator
--vendor "Skymatic GmbH" --vendor "Skymatic GmbH"
--copyright "(C) 2016 - 2023 Skymatic GmbH" --copyright "(C) 2016 - 2024 Skymatic GmbH"
--app-version "${{ needs.get-version.outputs.semVerNum }}.${{ needs.get-version.outputs.revNum}}" --app-version "${{ needs.get-version.outputs.semVerNum }}.${{ needs.get-version.outputs.revNum}}"
--win-menu --win-menu
--win-dir-chooser --win-dir-chooser
--win-shortcut-prompt --win-shortcut-prompt
--win-update-url "https:\\cryptomator.org" --win-update-url "https:\\cryptomator.org\downloads"
--win-menu-group Cryptomator --win-menu-group Cryptomator
--resource-dir dist/win/resources --resource-dir dist/win/resources
--license-file dist/win/resources/license.rtf --license-file dist/win/resources/license.rtf
--file-associations dist/win/resources/FAvaultFile.properties --file-associations dist/win/resources/FAvaultFile.properties
env: env:
JP_WIXWIZARD_RESOURCES: ${{ github.workspace }}/dist/win/resources # requires abs path, used in resources/main.wxs JP_WIXWIZARD_RESOURCES: ${{ github.workspace }}/dist/win/resources # requires abs path, used in resources/main.wxs
JP_WIXHELPER_DIR: ${{ github.workspace }}\appdir
- name: Codesign MSI - name: Codesign MSI
uses: skymatic/code-sign-action@v2 uses: skymatic/code-sign-action@v3
with: with:
certificate: ${{ secrets.WIN_CODESIGN_P12_BASE64 }} certificate: ${{ secrets.WIN_CODESIGN_P12_BASE64 }}
password: ${{ secrets.WIN_CODESIGN_P12_PW }} password: ${{ secrets.WIN_CODESIGN_P12_PW }}
@@ -214,45 +251,36 @@ jobs:
GPG_PRIVATE_KEY: ${{ secrets.RELEASES_GPG_PRIVATE_KEY }} GPG_PRIVATE_KEY: ${{ secrets.RELEASES_GPG_PRIVATE_KEY }}
GPG_PASSPHRASE: ${{ secrets.RELEASES_GPG_PASSPHRASE }} GPG_PASSPHRASE: ${{ secrets.RELEASES_GPG_PASSPHRASE }}
- name: Upload artifacts - name: Upload artifacts
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
with: with:
name: msi name: msi
path: | path: |
Cryptomator-*.msi Cryptomator-*.msi
Cryptomator-*.asc Cryptomator-*.asc
if-no-files-found: error if-no-files-found: error
- name: Publish .msi on GitHub Releases
if: startsWith(github.ref, 'refs/tags/')
uses: softprops/action-gh-release@v1
with:
fail_on_unmatched_files: true
token: ${{ secrets.CRYPTOBOT_RELEASE_TOKEN }}
files: |
*.msi
*.asc
build-exe: build-exe:
name: Build .exe installer name: Build .exe installer
runs-on: windows-latest runs-on: windows-latest
needs: [get-version, build-msi] needs: [get-version, build-msi]
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- name: Download .msi - name: Download .msi
uses: actions/download-artifact@v3 uses: actions/download-artifact@v4
with: with:
name: msi name: msi
path: dist/win/bundle/resources path: dist/win/bundle/resources
- name: Strip version info from msi file name - name: Strip version info from msi file name
run: mv dist/win/bundle/resources/Cryptomator*.msi dist/win/bundle/resources/Cryptomator.msi run: mv dist/win/bundle/resources/Cryptomator*.msi dist/win/bundle/resources/Cryptomator.msi
- uses: actions/setup-java@v3 - uses: actions/setup-java@v4
with: with:
distribution: ${{ env.JAVA_DIST }} distribution: ${{ env.JAVA_DIST }}
java-version: ${{ env.JAVA_VERSION }} java-version: ${{ env.JAVA_VERSION }}
check-latest: true check-latest: true
cache: ${{ env.JAVA_CACHE }} cache: 'maven'
- name: Generate license for exe - name: Generate license for exe
run: > run: >
mvn -B license:add-third-party mvn -B license:add-third-party "-Djavafx.platform=win"
"-Dlicense.thirdPartyFilename=license.rtf" "-Dlicense.thirdPartyFilename=license.rtf"
"-Dlicense.fileTemplate=dist/win/bundle/resources/licenseTemplate.ftl" "-Dlicense.fileTemplate=dist/win/bundle/resources/licenseTemplate.ftl"
"-Dlicense.outputDirectory=dist/win/bundle/resources" "-Dlicense.outputDirectory=dist/win/bundle/resources"
@@ -263,8 +291,11 @@ jobs:
shell: pwsh shell: pwsh
- name: Download WinFsp - name: Download WinFsp
run: | run: |
$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 ${{ env.WINFSP_MSI }}
curl --output dist/win/bundle/resources/winfsp.msi -L $winfspUrl shell: pwsh
- name: Download Legacy-WinFsp uninstaller
run: |
curl --output dist/win/bundle/resources/winfsp-uninstaller.exe -L ${{ env.WINFSP_UNINSTALLER }}
shell: pwsh shell: pwsh
- name: Compile to wixObj file - name: Compile to wixObj file
run: > run: >
@@ -274,7 +305,7 @@ jobs:
-out dist/win/bundle/ -out dist/win/bundle/
-dBundleVersion="${{ needs.get-version.outputs.semVerNum }}.${{ needs.get-version.outputs.revNum }}" -dBundleVersion="${{ needs.get-version.outputs.semVerNum }}.${{ needs.get-version.outputs.revNum }}"
-dBundleVendor="Skymatic GmbH" -dBundleVendor="Skymatic GmbH"
-dBundleCopyright="(C) 2016 - 2023 Skymatic GmbH" -dBundleCopyright="(C) 2016 - 2024 Skymatic GmbH"
-dAboutUrl="https://cryptomator.org" -dAboutUrl="https://cryptomator.org"
-dHelpUrl="https://cryptomator.org/contact" -dHelpUrl="https://cryptomator.org/contact"
-dUpdateUrl="https://cryptomator.org/downloads/" -dUpdateUrl="https://cryptomator.org/downloads/"
@@ -290,7 +321,7 @@ jobs:
-ib installer/unsigned/Cryptomator-Installer.exe -ib installer/unsigned/Cryptomator-Installer.exe
-o tmp/engine.exe -o tmp/engine.exe
- name: Codesign burn engine - name: Codesign burn engine
uses: skymatic/code-sign-action@v2 uses: skymatic/code-sign-action@v3
with: with:
certificate: ${{ secrets.WIN_CODESIGN_P12_BASE64 }} certificate: ${{ secrets.WIN_CODESIGN_P12_BASE64 }}
password: ${{ secrets.WIN_CODESIGN_P12_PW }} password: ${{ secrets.WIN_CODESIGN_P12_PW }}
@@ -304,7 +335,7 @@ jobs:
-ab tmp/engine.exe installer/unsigned/Cryptomator-Installer.exe -ab tmp/engine.exe installer/unsigned/Cryptomator-Installer.exe
-o installer/Cryptomator-Installer.exe -o installer/Cryptomator-Installer.exe
- name: Codesign EXE - name: Codesign EXE
uses: skymatic/code-sign-action@v2 uses: skymatic/code-sign-action@v3
with: with:
certificate: ${{ secrets.WIN_CODESIGN_P12_BASE64 }} certificate: ${{ secrets.WIN_CODESIGN_P12_BASE64 }}
password: ${{ secrets.WIN_CODESIGN_P12_PW }} password: ${{ secrets.WIN_CODESIGN_P12_PW }}
@@ -322,59 +353,68 @@ jobs:
GPG_PRIVATE_KEY: ${{ secrets.RELEASES_GPG_PRIVATE_KEY }} GPG_PRIVATE_KEY: ${{ secrets.RELEASES_GPG_PRIVATE_KEY }}
GPG_PASSPHRASE: ${{ secrets.RELEASES_GPG_PASSPHRASE }} GPG_PASSPHRASE: ${{ secrets.RELEASES_GPG_PASSPHRASE }}
- name: Upload artifacts - name: Upload artifacts
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
with: with:
name: exe name: exe
path: | path: |
Cryptomator-*.exe Cryptomator-*.exe
Cryptomator-*.asc Cryptomator-*.asc
if-no-files-found: error if-no-files-found: error
publish:
name: Publish installers to the github release
if: startsWith(github.ref, 'refs/tags/') && github.event.action == 'published'
runs-on: ubuntu-latest
needs: [build-msi, build-exe]
outputs:
download-url-msi: ${{ fromJSON(steps.publish.outputs.assets)[0].browser_download_url }}
download-url-exe: ${{ fromJSON(steps.publish.outputs.assets)[1].browser_download_url }}
steps:
- name: Download installers
uses: actions/download-artifact@v4
with:
merge-multiple: true
- name: Publish .msi on GitHub Releases - name: Publish .msi on GitHub Releases
if: startsWith(github.ref, 'refs/tags/') id: publish
uses: softprops/action-gh-release@v1 uses: softprops/action-gh-release@v2
with: with:
fail_on_unmatched_files: true fail_on_unmatched_files: true
token: ${{ secrets.CRYPTOBOT_RELEASE_TOKEN }} token: ${{ secrets.CRYPTOBOT_RELEASE_TOKEN }}
# do not change ordering of filelist, required for correct job output
files: | files: |
Cryptomator-*.exe *.msi
Cryptomator-*.asc *.exe
*.asc
allowlist: allowlist-msi:
name: Anti Virus Allowlisting uses: ./.github/workflows/av-whitelist.yml
if: startsWith(github.ref, 'refs/tags/') needs: [publish]
with:
url: ${{ needs.publish.outputs.download-url-msi }}
secrets: inherit
allowlist-exe:
uses: ./.github/workflows/av-whitelist.yml
needs: [publish]
with:
url: ${{ needs.publish.outputs.download-url-exe }}
secrets: inherit
notify-winget:
name: Notify for winget-release
if: needs.get-version.outputs.versionType == 'stable'
needs: [publish, get-version]
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: [build-msi, build-exe]
steps: steps:
- name: Download .msi - name: Slack Notification
uses: actions/download-artifact@v3 uses: rtCamp/action-slack-notify@v2
with: env:
name: msi SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }}
path: msi SLACK_USERNAME: 'Cryptobot'
- name: Download .exe SLACK_ICON: false
uses: actions/download-artifact@v3 SLACK_ICON_EMOJI: ':bot:'
with: SLACK_CHANNEL: 'cryptomator-desktop'
name: exe SLACK_TITLE: "MSI of ${{ github.event.repository.name }} ${{ github.event.release.tag_name }} published."
path: exe SLACK_MESSAGE: "Ready to <https://github.com/${{ github.repository }}/actions/workflows/winget.yml| release to winget>."
- name: Collect files SLACK_FOOTER: false
run: | MSG_MINIMAL: true
mkdir files
cp msi/*.msi files
cp exe/*.exe files
- name: Upload to Kaspersky
uses: SamKirkland/FTP-Deploy-Action@v4.3.4
with:
protocol: ftps
server: allowlist.kaspersky-labs.com
port: 990
username: ${{ secrets.ALLOWLIST_KASPERSKY_USERNAME }}
password: ${{ secrets.ALLOWLIST_KASPERSKY_PASSWORD }}
local-dir: files/
- name: Upload to Avast
uses: SamKirkland/FTP-Deploy-Action@v4.3.4
with:
protocol: ftp
server: whitelisting.avast.com
port: 21
username: ${{ secrets.ALLOWLIST_AVAST_USERNAME }}
password: ${{ secrets.ALLOWLIST_AVAST_PASSWORD }}
local-dir: files/
+27
View File
@@ -0,0 +1,27 @@
name: Publish MSI to winget-pkgs
on:
workflow_dispatch:
inputs:
tag:
description: 'Release tag'
required: true
jobs:
winget:
name: Publish winget package
runs-on: windows-latest
steps:
- name: Sync winget-pkgs fork
run: |
gh repo sync cryptomator/winget-pkgs -b master --force
env:
GH_TOKEN: ${{ secrets.CRYPTOBOT_WINGET_TOKEN }}
- name: Submit package
uses: vedantmgoyal2009/winget-releaser@main
with:
identifier: Cryptomator.Cryptomator
version: ${{ inputs.tag }}
release-tag: ${{ inputs.tag }}
installers-regex: '\.msi$'
token: ${{ secrets.CRYPTOBOT_WINGET_TOKEN }}
+17 -19
View File
@@ -14,32 +14,30 @@
<option name="dagger.fastInit" value="enabled" /> <option name="dagger.fastInit" value="enabled" />
<option name="dagger.formatGeneratedSource" value="enabled" /> <option name="dagger.formatGeneratedSource" value="enabled" />
<processorPath useClasspath="false"> <processorPath useClasspath="false">
<entry name="$MAVEN_REPOSITORY$/com/google/dagger/dagger-compiler/2.45/dagger-compiler-2.45.jar" /> <entry name="$MAVEN_REPOSITORY$/com/google/dagger/dagger-compiler/2.52/dagger-compiler-2.52.jar" />
<entry name="$MAVEN_REPOSITORY$/com/google/dagger/dagger/2.45/dagger-2.45.jar" /> <entry name="$MAVEN_REPOSITORY$/com/google/dagger/dagger/2.52/dagger-2.52.jar" />
<entry name="$MAVEN_REPOSITORY$/jakarta/inject/jakarta.inject-api/2.0.1/jakarta.inject-api-2.0.1.jar" />
<entry name="$MAVEN_REPOSITORY$/javax/inject/javax.inject/1/javax.inject-1.jar" /> <entry name="$MAVEN_REPOSITORY$/javax/inject/javax.inject/1/javax.inject-1.jar" />
<entry name="$MAVEN_REPOSITORY$/com/google/dagger/dagger-producers/2.45/dagger-producers-2.45.jar" /> <entry name="$MAVEN_REPOSITORY$/com/google/dagger/dagger-spi/2.52/dagger-spi-2.52.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" />
<entry name="$MAVEN_REPOSITORY$/com/google/code/findbugs/jsr305/3.0.2/jsr305-3.0.2.jar" /> <entry name="$MAVEN_REPOSITORY$/com/google/code/findbugs/jsr305/3.0.2/jsr305-3.0.2.jar" />
<entry name="$MAVEN_REPOSITORY$/org/checkerframework/checker-qual/3.12.0/checker-qual-3.12.0.jar" /> <entry name="$MAVEN_REPOSITORY$/com/google/devtools/ksp/symbol-processing-api/1.9.24-1.0.20/symbol-processing-api-1.9.24-1.0.20.jar" />
<entry name="$MAVEN_REPOSITORY$/com/google/errorprone/error_prone_annotations/2.7.1/error_prone_annotations-2.7.1.jar" /> <entry name="$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib-jdk8/1.9.0/kotlin-stdlib-jdk8-1.9.0.jar" />
<entry name="$MAVEN_REPOSITORY$/com/google/j2objc/j2objc-annotations/1.3/j2objc-annotations-1.3.jar" /> <entry name="$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib/1.9.24/kotlin-stdlib-1.9.24.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.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$/org/jetbrains/annotations/13.0/annotations-13.0.jar" />
<entry name="$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib-jdk7/1.9.0/kotlin-stdlib-jdk7-1.9.0.jar" />
<entry name="$MAVEN_REPOSITORY$/com/google/guava/failureaccess/1.0.2/failureaccess-1.0.2.jar" />
<entry name="$MAVEN_REPOSITORY$/com/google/guava/guava/33.0.0-jre/guava-33.0.0-jre.jar" />
<entry name="$MAVEN_REPOSITORY$/com/google/guava/listenablefuture/9999.0-empty-to-avoid-conflict-with-guava/listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar" />
<entry name="$MAVEN_REPOSITORY$/org/checkerframework/checker-qual/3.41.0/checker-qual-3.41.0.jar" />
<entry name="$MAVEN_REPOSITORY$/com/google/errorprone/error_prone_annotations/2.23.0/error_prone_annotations-2.23.0.jar" />
<entry name="$MAVEN_REPOSITORY$/com/google/j2objc/j2objc-annotations/2.8/j2objc-annotations-2.8.jar" />
<entry name="$MAVEN_REPOSITORY$/com/squareup/javapoet/1.13.0/javapoet-1.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/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$/com/google/errorprone/javac-shaded/9-dev-r4023-3/javac-shaded-9-dev-r4023-3.jar" />
<entry name="$MAVEN_REPOSITORY$/com/squareup/kotlinpoet/1.11.0/kotlinpoet-1.11.0.jar" />
<entry name="$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-reflect/1.6.10/kotlin-reflect-1.6.10.jar" />
<entry name="$MAVEN_REPOSITORY$/net/ltgt/gradle/incap/incap/0.2/incap-0.2.jar" /> <entry name="$MAVEN_REPOSITORY$/net/ltgt/gradle/incap/incap/0.2/incap-0.2.jar" />
<entry name="$MAVEN_REPOSITORY$/org/jetbrains/kotlinx/kotlinx-metadata-jvm/0.5.0/kotlinx-metadata-jvm-0.5.0.jar" /> <entry name="$MAVEN_REPOSITORY$/org/checkerframework/checker-compat-qual/2.5.5/checker-compat-qual-2.5.5.jar" />
</processorPath> </processorPath>
<module name="cryptomator" /> <module name="cryptomator" />
</profile> </profile>
+1 -1
View File
@@ -8,7 +8,7 @@
</list> </list>
</option> </option>
</component> </component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_20_PREVIEW" project-jdk-name="20" project-jdk-type="JavaSDK"> <component name="ProjectRootManager" version="2" languageLevel="JDK_23" project-jdk-name="23" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" /> <output url="file://$PROJECT_DIR$/out" />
</component> </component>
</project> </project>
+1 -1
View File
@@ -2,7 +2,7 @@
<configuration default="false" name="Cryptomator Windows" type="Application" factoryName="Application"> <configuration default="false" name="Cryptomator Windows" type="Application" factoryName="Application">
<option name="MAIN_CLASS_NAME" value="org.cryptomator.launcher.Cryptomator" /> <option name="MAIN_CLASS_NAME" value="org.cryptomator.launcher.Cryptomator" />
<module name="cryptomator" /> <module name="cryptomator" />
<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" /> <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.integrationsWin.windowsHelloKeychainPaths=&quot;@{appdata}/Cryptomator/windowsHelloKeychain.json;@{userhome}/AppData/Roaming/Cryptomator/windowsHelloKeychain.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,org.cryptomator.integrations.win" />
<method v="2"> <method v="2">
<option name="Make" enabled="true" /> <option name="Make" enabled="true" />
</method> </method>
+1 -1
View File
@@ -2,7 +2,7 @@
<configuration default="false" name="Cryptomator Windows Dev" type="Application" factoryName="Application"> <configuration default="false" name="Cryptomator Windows Dev" type="Application" factoryName="Application">
<option name="MAIN_CLASS_NAME" value="org.cryptomator.launcher.Cryptomator" /> <option name="MAIN_CLASS_NAME" value="org.cryptomator.launcher.Cryptomator" />
<module name="cryptomator" /> <module name="cryptomator" />
<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" /> <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.integrationsWin.windowsHelloKeychainPaths=&quot;@{appdata}/Cryptomator-Dev/windowsHelloKeychain.json;@{userhome}/AppData/Roaming/Cryptomator-Dev/windowsHelloKeychain.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,org.cryptomator.integrations.win" />
<method v="2"> <method v="2">
<option name="Make" enabled="true" /> <option name="Make" enabled="true" />
</method> </method>
+1 -1
View File
@@ -5,7 +5,7 @@
</envs> </envs>
<option name="MAIN_CLASS_NAME" value="org.cryptomator.launcher.Cryptomator" /> <option name="MAIN_CLASS_NAME" value="org.cryptomator.launcher.Cryptomator" />
<module name="cryptomator" /> <module name="cryptomator" />
<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" /> <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}/Library/Application Support/Cryptomator-Dev/mnt&quot; -Dcryptomator.showTrayIcon=true -Dcryptomator.integrationsMac.keychainServiceName=Cryptomator -Xss2m -Xmx512m -ea --enable-preview --enable-native-access=org.cryptomator.jfuse.mac" />
<method v="2"> <method v="2">
<option name="Make" enabled="true" /> <option name="Make" enabled="true" />
</method> </method>
+4 -11
View File
@@ -17,22 +17,15 @@ Cryptomator is provided free of charge as an open-source project despite the hig
### Gold Sponsors ### Gold Sponsors
<table> Become our Gold Sponsor and showcase your brand to a targeted audience! Please contact us if you are interested.
<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>
</tr>
</tbody>
</table>
### Silver Sponsors ### Silver Sponsors
<table> <table>
<tbody> <tbody>
<tr> <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.gee-whiz.de/"><img src="https://cryptomator.org/img/sponsors/geewhiz.svg" alt="gee-whiz" height="56"></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.route4me.com/"><img src="https://cryptomator.org/img/sponsors/route4me.svg" alt="Route4Me" height="56"></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> </tr>
</tbody> </tbody>
</table> </table>
@@ -85,7 +78,7 @@ For more information on the security details visit [cryptomator.org](https://doc
### Dependencies ### Dependencies
* JDK 19 (e.g. temurin) * JDK 22 (e.g. temurin, zulu)
* Maven 3 * Maven 3
### Run Maven ### Run Maven
+3 -1
View File
@@ -1,4 +1,6 @@
# created during build # downloaded/created during build
openjfx-jmods.zip
*.jmod
Cryptomator.AppDir Cryptomator.AppDir
*.AppImage *.AppImage
*.AppImage.zsync *.AppImage.zsync
+44 -13
View File
@@ -1,4 +1,5 @@
#!/bin/bash #!/bin/bash
set -e
cd $(dirname $0) cd $(dirname $0)
REVISION_NO=`git rev-list --count HEAD` REVISION_NO=`git rev-list --count HEAD`
@@ -7,31 +8,62 @@ REVISION_NO=`git rev-list --count HEAD`
if [ -z "${JAVA_HOME}" ]; then echo "JAVA_HOME not set. Run using JAVA_HOME=/path/to/jdk ./build.sh"; exit 1; fi if [ -z "${JAVA_HOME}" ]; then echo "JAVA_HOME not set. Run using JAVA_HOME=/path/to/jdk ./build.sh"; exit 1; fi
command -v mvn >/dev/null 2>&1 || { echo >&2 "mvn not found."; exit 1; } command -v mvn >/dev/null 2>&1 || { echo >&2 "mvn not found."; exit 1; }
command -v curl >/dev/null 2>&1 || { echo >&2 "curl not found."; exit 1; } command -v curl >/dev/null 2>&1 || { echo >&2 "curl not found."; exit 1; }
command -v unzip >/dev/null 2>&1 || { echo >&2 "unzip not found."; exit 1; }
VERSION=$(mvn -f ../../../pom.xml help:evaluate -Dexpression=project.version -q -DforceStdout) VERSION=$(mvn -f ../../../pom.xml help:evaluate -Dexpression=project.version -q -DforceStdout)
SEMVER_STR=${VERSION} SEMVER_STR=${VERSION}
CPU_ARCH=$(uname -p)
if [[ ! "${CPU_ARCH}" =~ x86_64|aarch64 ]]; then echo "Platform ${CPU_ARCH} not supported"; exit 1; fi
mvn -f ../../../pom.xml versions:set -DnewVersion=${SEMVER_STR} mvn -f ../../../pom.xml versions:set -DnewVersion=${SEMVER_STR}
# compile # compile
mvn -B -f ../../../pom.xml clean package -Plinux -DskipTests mvn -B -f ../../../pom.xml clean package -Plinux -DskipTests -Djavafx.platform=linux
cp ../../../LICENSE.txt ../../../target cp ../../../LICENSE.txt ../../../target
cp ../../../target/cryptomator-*.jar ../../../target/mods cp ../../../target/cryptomator-*.jar ../../../target/mods
JAVAFX_VERSION=22.0.2
JAVAFX_ARCH="x64"
JAVAFX_JMODS_SHA256='d44bff3b94d5668fdee18a938d7b1269026d663d44765f02d29a9bdfd3fa1eb0'
if [ "${CPU_ARCH}" = "aarch64" ]; then
JAVAFX_ARCH="aarch64"
JAVAFX_JMODS_SHA256='3d5457136690c4f5bb9522d38b45218e045bdac13c24aa4c808c7c8d17d039c7'
fi
# download javaFX jmods
JAVAFX_JMODS_URL="https://download2.gluonhq.com/openjfx/${JAVAFX_VERSION}/openjfx-${JAVAFX_VERSION}_linux-${JAVAFX_ARCH}_bin-jmods.zip"
curl -L ${JAVAFX_JMODS_URL} -o openjfx-jmods.zip
echo "${JAVAFX_JMODS_SHA256} openjfx-jmods.zip" | shasum -a256 --check
mkdir -p openjfx-jmods
unzip -o -j openjfx-jmods.zip \*/javafx.base.jmod \*/javafx.controls.jmod \*/javafx.fxml.jmod \*/javafx.graphics.jmod -d openjfx-jmods
JMOD_VERSION=$(jmod describe ./openjfx-jmods/javafx.base.jmod | head -1)
JMOD_VERSION=${JMOD_VERSION#*@}
JMOD_VERSION=${JMOD_VERSION%%.*}
POM_JFX_VERSION=$(mvn help:evaluate "-Dexpression=javafx.version" -q -DforceStdout -B -f ../../../pom.xml)
POM_JFX_VERSION=${POM_JFX_VERSION#*@}
POM_JFX_VERSION=${POM_JFX_VERSION%%.*}
if [ $POM_JFX_VERSION -ne $JMOD_VERSION ]; then
>&2 echo "Major JavaFX version in pom.xml (${POM_JFX_VERSION}) != amd64 jmod version (${JMOD_VERSION})"
exit 1
fi
# add runtime # add runtime
${JAVA_HOME}/bin/jlink \ ${JAVA_HOME}/bin/jlink \
--verbose \ --verbose \
--output runtime \ --output runtime \
--module-path "${JAVA_HOME}/jmods" \ --module-path "${JAVA_HOME}/jmods:openjfx-jmods" \
--add-modules java.base,java.desktop,java.instrument,java.logging,java.naming,java.net.http,java.scripting,java.sql,java.xml,javafx.base,javafx.graphics,javafx.controls,javafx.fxml,jdk.unsupported,jdk.crypto.ec,jdk.security.auth,jdk.accessibility,jdk.management.jfr,jdk.net \ --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.security.auth,jdk.accessibility,jdk.management.jfr,jdk.net,java.compiler \
--strip-native-commands \ --strip-native-commands \
--no-header-files \ --no-header-files \
--no-man-pages \ --no-man-pages \
--strip-debug \ --strip-debug \
--compress=1 --compress zip-0
# create app dir # create app dir
envsubst '${SEMVER_STR} ${REVISION_NUM}' < ../launcher-gtk2.properties > launcher-gtk2.properties
${JAVA_HOME}/bin/jpackage \ ${JAVA_HOME}/bin/jpackage \
--verbose \ --verbose \
--type app-image \ --type app-image \
@@ -44,7 +76,7 @@ ${JAVA_HOME}/bin/jpackage \
--vendor "Skymatic GmbH" \ --vendor "Skymatic GmbH" \
--java-options "--enable-preview" \ --java-options "--enable-preview" \
--java-options "--enable-native-access=org.cryptomator.jfuse.linux.amd64,org.cryptomator.jfuse.linux.aarch64,org.purejava.appindicator" \ --java-options "--enable-native-access=org.cryptomator.jfuse.linux.amd64,org.cryptomator.jfuse.linux.aarch64,org.purejava.appindicator" \
--copyright "(C) 2016 - 2023 Skymatic GmbH" \ --copyright "(C) 2016 - 2024 Skymatic GmbH" \
--java-options "-Xss5m" \ --java-options "-Xss5m" \
--java-options "-Xmx256m" \ --java-options "-Xmx256m" \
--app-version "${VERSION}.${REVISION_NO}" \ --app-version "${VERSION}.${REVISION_NO}" \
@@ -59,7 +91,6 @@ ${JAVA_HOME}/bin/jpackage \
--java-options "-Dcryptomator.showTrayIcon=true" \ --java-options "-Dcryptomator.showTrayIcon=true" \
--java-options "-Dcryptomator.integrationsLinux.trayIconsDir=\"@{appdir}/usr/share/icons/hicolor/symbolic/apps\"" \ --java-options "-Dcryptomator.integrationsLinux.trayIconsDir=\"@{appdir}/usr/share/icons/hicolor/symbolic/apps\"" \
--java-options "-Dcryptomator.buildNumber=\"appimage-${REVISION_NO}\"" \ --java-options "-Dcryptomator.buildNumber=\"appimage-${REVISION_NO}\"" \
--add-launcher cryptomator-gtk2=launcher-gtk2.properties \
--resource-dir ../resources --resource-dir ../resources
# transform AppDir # transform AppDir
@@ -83,17 +114,17 @@ ln -s usr/share/applications/org.cryptomator.Cryptomator.desktop Cryptomator.App
ln -s bin/cryptomator.sh Cryptomator.AppDir/AppRun ln -s bin/cryptomator.sh Cryptomator.AppDir/AppRun
# load AppImageTool # load AppImageTool
curl -L https://github.com/AppImage/AppImageKit/releases/download/13/appimagetool-x86_64.AppImage -o /tmp/appimagetool.AppImage curl -L https://github.com/AppImage/AppImageKit/releases/download/13/appimagetool-${CPU_ARCH}.AppImage -o /tmp/appimagetool.AppImage
chmod +x /tmp/appimagetool.AppImage chmod +x /tmp/appimagetool.AppImage
# create AppImage # create AppImage
/tmp/appimagetool.AppImage \ /tmp/appimagetool.AppImage \
Cryptomator.AppDir \ Cryptomator.AppDir \
cryptomator-${SEMVER_STR}-x86_64.AppImage \ cryptomator-${SEMVER_STR}-${CPU_ARCH}.AppImage \
-u 'gh-releases-zsync|cryptomator|cryptomator|latest|cryptomator-*-x86_64.AppImage.zsync' -u 'gh-releases-zsync|cryptomator|cryptomator|latest|cryptomator-*-${CPU_ARCH}.AppImage.zsync'
echo "" echo ""
echo "Done. AppImage successfully created: cryptomator-${SEMVER_STR}-x86_64.AppImage" echo "Done. AppImage successfully created: cryptomator-${SEMVER_STR}-${CPU_ARCH}.AppImage"
echo ""
echo >&2 "To clean up, run: rm -rf Cryptomator.AppDir appdir runtime squashfs-root openjfx-jmods; rm /tmp/appimagetool.AppImage openjfx-jmods.zip"
echo "" echo ""
echo >&2 "To clean up, run: rm -rf Cryptomator.AppDir appdir jni runtime squashfs-root; rm launcher-gtk2.properties /tmp/appimagetool.AppImage"
echo ""
+126 -38
View File
@@ -5,26 +5,27 @@
<metadata_license>FSFAP</metadata_license> <metadata_license>FSFAP</metadata_license>
<project_license>GPL-3.0-or-later</project_license> <project_license>GPL-3.0-or-later</project_license>
<name>Cryptomator</name> <name>Cryptomator</name>
<summary>Multi-platform client-side encryption tool optimized for cloud storages</summary> <summary>Encryption made easy and optimized for the cloud</summary>
<description> <description>
<p> <p>
Cryptomator provides transparent, client-side encryption for your cloud. Protect your documents from unauthorized Cryptomator provides easy-to-use, transparent, client-side encryption for your cloud.
access. Cryptomator is free and open source software, so you can rest assured there are no backdoors. It protects your documents from unauthorized access and prying eyes, while you will still be able to view and edit your documents locally.
By not requiring any registration or account and performing all encryption locally, it gives you back control over your data and ensures your privacy.
Cryptomator is offered for all major platforms (including Android and iOS).
</p> </p>
<p> <p>
Cryptomator encrypts file contents and names using AES. Your passphrase is protected against bruteforcing attempts Cryptomator encrypts file contents and names using the widespread industry standard AES.
using scrypt. Directory structures get obfuscated. The only thing which cannot be encrypted without breaking your Your passphrase is protected against brute forcing attempts using scrypt.
cloud synchronization is the modification date of your files. Additionally, directory structures get obfuscated.
For more info about the Cryptomator encryption scheme, check out the online documentation.
</p> </p>
<p> <p>
Cryptomator is a free and open source software licensed under the GPLv3. This allows anyone to check our code. It Cryptomator is a free and open-source software licensed under the GPLv3.
is impossible to introduce backdoors for third parties. Also we cannot hide vulnerabilities. And the best thing This allows anyone to check our code.
is: There is no need to trust us, as you can control us! Thus, it is impossible to introduce backdoors for third parties or to hide vulnerabilities, so you do not need to trust Cryptomator.
</p> Also, vendor lock-ins are impossible.
<p> Even if we decided to stop development: The source code is already cloned by hundreds of other developers and development can be picked up by others.
Vendor lock-ins are impossible. Even if we decided to stop development: The source code is already cloned by
hundreds of other developers. As you don't need an account, you will never stand in front of locked doors.
</p> </p>
</description> </description>
@@ -42,7 +43,7 @@
</provides> </provides>
<screenshots> <screenshots>
<screenshot> <screenshot type="default">
<caption>Light theme</caption> <caption>Light theme</caption>
<image>https://user-images.githubusercontent.com/11858409/156986109-6e58f59c-8b8c-4501-b33b-bb1e33007cea.png</image> <image>https://user-images.githubusercontent.com/11858409/156986109-6e58f59c-8b8c-4501-b33b-bb1e33007cea.png</image>
</screenshot> </screenshot>
@@ -52,41 +53,128 @@
</screenshot> </screenshot>
</screenshots> </screenshots>
<branding>
<color type="primary" scheme_preference="light">#EBF5EB</color>
<color type="primary" scheme_preference="dark">#2F4858</color>
</branding>
<url type="homepage">https://cryptomator.org/</url> <url type="homepage">https://cryptomator.org/</url>
<url type="bugtracker">https://github.com/cryptomator/cryptomator/issues/</url> <url type="bugtracker">https://github.com/cryptomator/cryptomator/issues/</url>
<url type="donation">https://cryptomator.org/donate</url> <url type="donation">https://cryptomator.org/donate</url>
<url type="faq">https://community.cryptomator.org/c/kb/faq</url> <url type="faq">https://community.cryptomator.org/c/kb/faq</url>
<url type="help">https://community.cryptomator.org/</url> <url type="help">https://docs.cryptomator.org/</url>
<url type="translate">https://translate.cryptomator.org</url> <url type="translate">https://translate.cryptomator.org</url>
<developer_name>Skymatic GmbH</developer_name> <developer id="de.skymatic">
<name>Skymatic GmbH</name>
</developer>
<content_rating type="oars-1.1"> <content_rating type="oars-1.1">
<content_attribute id="social-info">mild</content_attribute> <!-- update checker connects to https://api.cryptomator.org/updates/latestVersion.json --> <content_attribute id="social-info">mild</content_attribute> <!-- update checker connects to https://api.cryptomator.org/updates/latestVersion.json -->
</content_rating> </content_rating>
<releases> <releases>
<release date="2023-08-11" version="1.9.4"/> <release date="2024-11-19" version="1.14.2">
<release date="2023-08-07" version="1.9.3"/> <url type="details">https://github.com/cryptomator/cryptomator/releases/1.14.2</url>
<release date="2023-07-24" version="1.9.2"/> </release>
<release date="2023-06-07" version="1.9.1"/> <release date="2024-09-17" version="1.14.0">
<release date="2023-05-30" version="1.9.0"/> <url type="details">https://github.com/cryptomator/cryptomator/releases/1.14.0</url>
<release date="2023-04-25" version="1.8.0"/> </release>
<release date="2023-04-07" version="1.7.5"/> <release date="2024-06-26" version="1.13.0">
<release date="2023-04-05" version="1.7.4"/> <url type="details">https://github.com/cryptomator/cryptomator/releases/1.13.0</url>
<release date="2023-03-15" version="1.7.3"/> </release>
<release date="2023-03-07" version="1.7.2"/> <release date="2024-03-27" version="1.12.4">
<release date="2023-03-03" version="1.7.1"/> <url type="details">https://github.com/cryptomator/cryptomator/releases/1.12.4</url>
<release date="2023-03-01" version="1.7.0"/> </release>
<release date="2022-12-14" version="1.6.17"/> <release date="2024-02-27" version="1.12.3">
<release date="2022-12-06" version="1.6.16"/> <url type="details">https://github.com/cryptomator/cryptomator/releases/1.12.3</url>
<release date="2022-10-06" version="1.6.15"/> </release>
<release date="2022-08-31" version="1.6.14"/> <release date="2024-02-09" version="1.12.2">
<release date="2022-07-27" version="1.6.12"/> <url type="details">https://github.com/cryptomator/cryptomator/releases/1.12.2</url>
<release date="2022-07-26" version="1.6.11"/> </release>
<release date="2022-05-03" version="1.6.10"/> <release date="2024-02-07" version="1.12.1">
<release date="2022-04-27" version="1.6.9"/> <url type="details">https://github.com/cryptomator/cryptomator/releases/1.12.1</url>
<release date="2022-03-30" version="1.6.8"/> </release>
<release date="2021-12-16" version="1.6.5"/> <release date="2024-02-06" version="1.12.0">
<url type="details">https://github.com/cryptomator/cryptomator/releases/1.12.0</url>
</release>
<release date="2023-12-05" version="1.11.1">
<url type="details">https://github.com/cryptomator/cryptomator/releases/1.11.1</url>
</release>
<release date="2023-11-08" version="1.11.0">
<url type="details">https://github.com/cryptomator/cryptomator/releases/1.11.0</url>
</release>
<release date="2023-09-20" version="1.10.1">
<url type="details">https://github.com/cryptomator/cryptomator/releases/1.10.1</url>
</release>
<release date="2023-09-11" version="1.10.0">
<url type="details">https://github.com/cryptomator/cryptomator/releases/1.10.0</url>
</release>
<release date="2023-08-11" version="1.9.4">
<url type="details">https://github.com/cryptomator/cryptomator/releases/1.9.4</url>
</release>
<release date="2023-08-07" version="1.9.3">
<url type="details">https://github.com/cryptomator/cryptomator/releases/1.9.3</url>
</release>
<release date="2023-07-24" version="1.9.2">
<url type="details">https://github.com/cryptomator/cryptomator/releases/1.9.2</url>
</release>
<release date="2023-06-07" version="1.9.1">
<url type="details">https://github.com/cryptomator/cryptomator/releases/1.9.1</url>
</release>
<release date="2023-05-30" version="1.9.0">
<url type="details">https://github.com/cryptomator/cryptomator/releases/1.9.0</url>
</release>
<release date="2023-04-25" version="1.8.0">
<url type="details">https://github.com/cryptomator/cryptomator/releases/1.8.0</url>
</release>
<release date="2023-04-07" version="1.7.5">
<url type="details">https://github.com/cryptomator/cryptomator/releases/1.7.5</url>
</release>
<release date="2023-04-05" version="1.7.4">
<url type="details">https://github.com/cryptomator/cryptomator/releases/1.7.4</url>
</release>
<release date="2023-03-15" version="1.7.3">
<url type="details">https://github.com/cryptomator/cryptomator/releases/1.7.3</url>
</release>
<release date="2023-03-07" version="1.7.2">
<url type="details">https://github.com/cryptomator/cryptomator/releases/1.7.2</url>
</release>
<release date="2023-03-03" version="1.7.1">
<url type="details">https://github.com/cryptomator/cryptomator/releases/1.7.1</url>
</release>
<release date="2023-03-01" version="1.7.0">
<url type="details">https://github.com/cryptomator/cryptomator/releases/1.7.0</url>
</release>
<release date="2022-12-14" version="1.6.17">
<url type="details">https://github.com/cryptomator/cryptomator/releases/1.6.17</url>
</release>
<release date="2022-12-06" version="1.6.16">
<url type="details">https://github.com/cryptomator/cryptomator/releases/1.6.16</url>
</release>
<release date="2022-10-06" version="1.6.15">
<url type="details">https://github.com/cryptomator/cryptomator/releases/1.6.15</url>
</release>
<release date="2022-08-31" version="1.6.14">
<url type="details">https://github.com/cryptomator/cryptomator/releases/1.6.14</url>
</release>
<release date="2022-07-27" version="1.6.12">
<url type="details">https://github.com/cryptomator/cryptomator/releases/1.6.12</url>
</release>
<release date="2022-07-26" version="1.6.11">
<url type="details">https://github.com/cryptomator/cryptomator/releases/1.6.11</url>
</release>
<release date="2022-05-03" version="1.6.10">
<url type="details">https://github.com/cryptomator/cryptomator/releases/1.6.10</url>
</release>
<release date="2022-04-27" version="1.6.9">
<url type="details">https://github.com/cryptomator/cryptomator/releases/1.6.9</url>
</release>
<release date="2022-03-30" version="1.6.8">
<url type="details">https://github.com/cryptomator/cryptomator/releases/1.6.8</url>
</release>
<release date="2021-12-16" version="1.6.5">
<url type="details">https://github.com/cryptomator/cryptomator/releases/1.6.5</url>
</release>
</releases> </releases>
</component> </component>
+1 -1
View File
@@ -2,7 +2,7 @@ Source: cryptomator
Maintainer: Cryptobot <releases@cryptomator.org> Maintainer: Cryptobot <releases@cryptomator.org>
Section: utils Section: utils
Priority: optional Priority: optional
Build-Depends: debhelper (>=10), coffeelibs-jdk-20, libgtk2.0-0, libgtk-3-0, libxxf86vm1, libgl1 Build-Depends: debhelper (>=10), coffeelibs-jdk-22 (>= 22.0.1+8-0ppa1), libgtk-3-0, libxxf86vm1, libgl1
Standards-Version: 4.5.0 Standards-Version: 4.5.0
Homepage: https://cryptomator.org Homepage: https://cryptomator.org
Vcs-Git: https://github.com/cryptomator/cryptomator.git Vcs-Git: https://github.com/cryptomator/cryptomator.git
+2 -2
View File
@@ -4,11 +4,11 @@ Upstream-Contact: Cryptomator <info@cryptomator.org>
Source: https://cryptomator.org Source: https://cryptomator.org
Files: * Files: *
Copyright: 2016-2023 Skymatic GmbH Copyright: 2016-2024 Skymatic GmbH
License: GPL-3+ License: GPL-3+
Files: debian/org.cryptomator.Cryptomator.appdata.xml Files: debian/org.cryptomator.Cryptomator.appdata.xml
Copyright: 2016-2023 Skymatic GmbH Copyright: 2016-2024 Skymatic GmbH
License: FSFAP License: FSFAP
License: GPL-3+ License: GPL-3+
+7 -4
View File
@@ -4,7 +4,7 @@
# Uncomment this to turn on verbose mode. # Uncomment this to turn on verbose mode.
#export DH_VERBOSE=1 #export DH_VERBOSE=1
JAVA_HOME = /usr/lib/jvm/java-20-coffeelibs JAVA_HOME = /usr/lib/jvm/java-23-coffeelibs
DEB_BUILD_ARCH ?= $(shell dpkg-architecture -qDEB_BUILD_ARCH) DEB_BUILD_ARCH ?= $(shell dpkg-architecture -qDEB_BUILD_ARCH)
ifeq ($(DEB_BUILD_ARCH),amd64) ifeq ($(DEB_BUILD_ARCH),amd64)
JMODS_PATH = jmods/amd64:${JAVA_HOME}/jmods JMODS_PATH = jmods/amd64:${JAVA_HOME}/jmods
@@ -24,15 +24,16 @@ override_dh_auto_clean:
override_dh_auto_build: override_dh_auto_build:
mkdir resources mkdir resources
ln -s ../common/org.cryptomator.Cryptomator512.png resources/cryptomator.png ln -s ../common/org.cryptomator.Cryptomator512.png resources/cryptomator.png
# Remark: no compression is applied for improved build compression later (here deb)
$(JAVA_HOME)/bin/jlink \ $(JAVA_HOME)/bin/jlink \
--output runtime \ --output runtime \
--module-path "${JMODS_PATH}" \ --module-path "${JMODS_PATH}" \
--add-modules java.base,java.desktop,java.instrument,java.logging,java.naming,java.net.http,java.scripting,java.sql,java.xml,javafx.base,javafx.graphics,javafx.controls,javafx.fxml,jdk.unsupported,jdk.crypto.ec,jdk.security.auth,jdk.accessibility,jdk.management.jfr,jdk.net \ --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.security.auth,jdk.accessibility,jdk.management.jfr,jdk.net,java.compiler \
--strip-native-commands \ --strip-native-commands \
--no-header-files \ --no-header-files \
--no-man-pages \ --no-man-pages \
--strip-debug \ --strip-debug \
--compress=2 --compress zip-0
$(JAVA_HOME)/bin/jpackage \ $(JAVA_HOME)/bin/jpackage \
--type app-image \ --type app-image \
--runtime-image runtime \ --runtime-image runtime \
@@ -44,7 +45,7 @@ override_dh_auto_build:
--vendor "Skymatic GmbH" \ --vendor "Skymatic GmbH" \
--java-options "--enable-preview" \ --java-options "--enable-preview" \
--java-options "--enable-native-access=org.cryptomator.jfuse.linux.amd64,org.cryptomator.jfuse.linux.aarch64,org.purejava.appindicator" \ --java-options "--enable-native-access=org.cryptomator.jfuse.linux.amd64,org.cryptomator.jfuse.linux.aarch64,org.purejava.appindicator" \
--copyright "(C) 2016 - 2023 Skymatic GmbH" \ --copyright "(C) 2016 - 2024 Skymatic GmbH" \
--java-options "-Xss5m" \ --java-options "-Xss5m" \
--java-options "-Xmx256m" \ --java-options "-Xmx256m" \
--java-options "-Dfile.encoding=\"utf-8\"" \ --java-options "-Dfile.encoding=\"utf-8\"" \
@@ -59,6 +60,8 @@ override_dh_auto_build:
--java-options "-Dcryptomator.integrationsLinux.trayIconsDir=\"/usr/share/icons/hicolor/symbolic/apps\"" \ --java-options "-Dcryptomator.integrationsLinux.trayIconsDir=\"/usr/share/icons/hicolor/symbolic/apps\"" \
--java-options "-Dcryptomator.buildNumber=\"deb-${REVISION_NUM}\"" \ --java-options "-Dcryptomator.buildNumber=\"deb-${REVISION_NUM}\"" \
--java-options "-Dcryptomator.appVersion=\"${SEMVER_STR}\"" \ --java-options "-Dcryptomator.appVersion=\"${SEMVER_STR}\"" \
--java-options "-Dcryptomator.disableUpdateCheck=\"${DISABLE_UPDATE_CHECK}\"" \
--java-options "-Dcryptomator.integrationsLinux.autoStartCmd=\"cryptomator\"" \
--app-version "${VERSION_NUM}.${REVISION_NUM}" \ --app-version "${VERSION_NUM}.${REVISION_NUM}" \
--resource-dir resources \ --resource-dir resources \
--verbose --verbose
-14
View File
@@ -1,14 +0,0 @@
java-options=-Xss5m \
-Xmx256m \
--enable-preview \
--enable-native-access=org.cryptomator.jfuse.linux.amd64,org.cryptomator.jfuse.linux.aarch64 \
-Dfile.encoding=\"utf-8\" \
-Dcryptomator.appVersion=\"${SEMVER_STR}\" \
-Dcryptomator.logDir=\"~/.local/share/Cryptomator/logs\" \
-Dcryptomator.pluginDir=\"~/.local/share/Cryptomator/plugins\" \
-Dcryptomator.settingsPath=\"~/.config/Cryptomator/settings.json:~/.Cryptomator/settings.json\" \
-Dcryptomator.ipcSocketPath=\"~/.config/Cryptomator/ipc.socket\" \
-Dcryptomator.mountPointsDir=\"~/.local/share/Cryptomator/mnt\" \
-Dcryptomator.showTrayIcon=false \
-Dcryptomator.buildNumber=\"appimage-${REVISION_NUM}\" \
-Djdk.gtk.version=2
+1
View File
@@ -0,0 +1 @@
embedded.provisionprofile
+8
View File
@@ -2,6 +2,10 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0"> <plist version="1.0">
<dict> <dict>
<key>com.apple.application-identifier</key>
<string>###APP_IDENTIFIER_PREFIX###org.cryptomator</string>
<key>com.apple.developer.team-identifier</key>
<string>###TEAM_IDENTIFIER###</string>
<key>com.apple.security.cs.allow-jit</key> <key>com.apple.security.cs.allow-jit</key>
<true/> <true/>
<key>com.apple.security.cs.allow-unsigned-executable-memory</key> <key>com.apple.security.cs.allow-unsigned-executable-memory</key>
@@ -10,5 +14,9 @@
<true/> <true/>
<key>com.apple.security.cs.disable-library-validation</key> <key>com.apple.security.cs.disable-library-validation</key>
<true/> <true/>
<key>keychain-access-groups</key>
<array>
<string>###APP_IDENTIFIER_PREFIX###org.cryptomator</string>
</array>
</dict> </dict>
</plist> </plist>
+5 -2
View File
@@ -1,6 +1,9 @@
# created during build # downloaded/created during build
Cryptomator.app/ Cryptomator.app/
runtime/ runtime/
dmg/ dmg/
*.dmg *.dmg
license.rtf license.rtf
openjfx-jmods.zip
*.jmod
Cryptomator.entitlements
+36 -20
View File
@@ -1,12 +1,15 @@
#!/bin/bash #!/bin/bash
# parse options # parse options
usage() { echo "Usage: $0 [-s <codesign-identity>]" 1>&2; exit 1; } usage() { echo "Usage: $0 [-s <codesign-identity>] [-t <team-identifier>]" 1>&2; exit 1; }
while getopts ":s:" o; do while getopts ":s:t:" o; do
case "${o}" in case "${o}" in
s) s)
CODESIGN_IDENTITY=${OPTARG} CODESIGN_IDENTITY=${OPTARG}
;; ;;
t)
TEAM_IDENTIFIER=${OPTARG}
;;
*) *)
usage usage
;; ;;
@@ -21,7 +24,7 @@ rm -rf runtime dmg *.app *.dmg
# set variables # set variables
APP_NAME="Cryptomator" APP_NAME="Cryptomator"
VENDOR="Skymatic GmbH" VENDOR="Skymatic GmbH"
COPYRIGHT_YEARS="2016 - 2023" COPYRIGHT_YEARS="2016 - 2024"
PACKAGE_IDENTIFIER="org.cryptomator" PACKAGE_IDENTIFIER="org.cryptomator"
MAIN_JAR_GLOB="cryptomator-*.jar" MAIN_JAR_GLOB="cryptomator-*.jar"
MODULE_AND_MAIN_CLASS="org.cryptomator.desktop/org.cryptomator.launcher.Cryptomator" MODULE_AND_MAIN_CLASS="org.cryptomator.desktop/org.cryptomator.launcher.Cryptomator"
@@ -29,13 +32,17 @@ 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'` 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" FUSE_LIB="FUSE-T"
ARCH="undefined" JAVAFX_VERSION=22.0.2
JAVAFX_ARCH="undefined"
JAVAFX_JMODS_SHA256="undefined"
if [ "$(machine)" = "arm64e" ]; then if [ "$(machine)" = "arm64e" ]; then
ARCH="aarch64" JAVAFX_ARCH="aarch64"
JAVAFX_JMODS_SHA256="813c6748f7c99cb7a579d48b48a087b4682b1fad1fc1a4fe5f9b21cf872b15a7"
else else
ARCH="x64" JAVAFX_ARCH="x64"
JAVAFX_JMODS_SHA256="115cb08bb59d880cfff6e51e0bf0dcc45785ed9d456b8b8425597b04da6ab3d4"
fi fi
OPENJFX_JMODS="https://download2.gluonhq.com/openjfx/20.0.2/openjfx-20.0.2_osx-${ARCH}_bin-jmods.zip" JAVAFX_JMODS_URL="https://download2.gluonhq.com/openjfx/${JAVAFX_VERSION}/openjfx-${JAVAFX_VERSION}_osx-${JAVAFX_ARCH}_bin-jmods.zip"
# check preconditions # check preconditions
if [ -z "${JAVA_HOME}" ]; then echo "JAVA_HOME not set. Run using JAVA_HOME=/path/to/jdk ./build.sh"; exit 1; fi if [ -z "${JAVA_HOME}" ]; then echo "JAVA_HOME not set. Run using JAVA_HOME=/path/to/jdk ./build.sh"; exit 1; fi
@@ -47,35 +54,37 @@ if [ -n "${CODESIGN_IDENTITY}" ]; then
fi fi
# download and check jmods # download and check jmods
curl -L ${OPENJFX_JMODS} -o openjfx-jmods.zip curl -L ${JAVAFX_JMODS_URL} -o openjfx-jmods.zip
echo "${JAVAFX_JMODS_SHA256} openjfx-jmods.zip" | shasum -a256 --check
mkdir -p openjfx-jmods/ mkdir -p openjfx-jmods/
unzip -j openjfx-jmods.zip \*/javafx.base.jmod \*/javafx.controls.jmod \*/javafx.fxml.jmod \*/javafx.graphics.jmod -d openjfx-jmods/ unzip -jo openjfx-jmods.zip \*/javafx.base.jmod \*/javafx.controls.jmod \*/javafx.fxml.jmod \*/javafx.graphics.jmod -d openjfx-jmods
JMOD_VERSION=$(jmod describe openjfx-jmods/javafx.base.jmod | head -1) JMOD_VERSION=$(jmod describe openjfx-jmods/javafx.base.jmod | head -1)
JMOD_VERSION=${JMOD_VERSION#*@} JMOD_VERSION=${JMOD_VERSION#*@}
JMOD_VERSION=${JMOD_VERSION%%.*} JMOD_VERSION=${JMOD_VERSION%%.*}
POM_JFX_VERSION=$(mvn help:evaluate "-Dexpression=javafx.version" -q -DforceStdout) POM_JFX_VERSION=$(mvn -f../../../pom.xml help:evaluate "-Dexpression=javafx.version" -q -DforceStdout)
POM_JFX_VERSION=${POM_JFX_VERSION#*@} POM_JFX_VERSION=${POM_JFX_VERSION#*@}
POM_JFX_VERSION=${POM_JFX_VERSION%%.*} POM_JFX_VERSION=${POM_JFX_VERSION%%.*}
if [ $POM_JFX_VERSION -ne $JMOD_VERSION ]; then if [ "${POM_JFX_VERSION}" -ne "${JMOD_VERSION}" ]; then
>&2 echo "Major JavaFX version in pom.xml (${POM_JFX_VERSION}) != jmod version (${JMOD_VERSION})" >&2 echo "Major JavaFX version in pom.xml (${POM_JFX_VERSION}) != jmod version (${JMOD_VERSION})"
exit 1 exit 1
fi fi
# compile # compile
mvn -B -f../../../pom.xml clean package -DskipTests -Pmac mvn -B -Djavafx.platform=mac -f../../../pom.xml clean package -DskipTests -Pmac
cp ../../../LICENSE.txt ../../../target
cp ../../../target/${MAIN_JAR_GLOB} ../../../target/mods cp ../../../target/${MAIN_JAR_GLOB} ../../../target/mods
# add runtime # add runtime
${JAVA_HOME}/bin/jlink \ ${JAVA_HOME}/bin/jlink \
--output runtime \ --output runtime \
--module-path "${JAVA_HOME}/jmods:openjfx-jmods" \ --module-path "${JAVA_HOME}/jmods:openjfx-jmods" \
--add-modules java.base,java.desktop,java.instrument,java.logging,java.naming,java.net.http,java.scripting,java.sql,java.xml,javafx.base,javafx.graphics,javafx.controls,javafx.fxml,jdk.unsupported,jdk.crypto.ec,jdk.security.auth,jdk.accessibility,jdk.management.jfr \ --add-modules java.base,java.desktop,java.instrument,java.logging,java.naming,java.net.http,java.scripting,java.sql,java.xml,javafx.base,javafx.graphics,javafx.controls,javafx.fxml,jdk.unsupported,jdk.security.auth,jdk.accessibility,jdk.management.jfr,java.compiler \
--strip-native-commands \ --strip-native-commands \
--no-header-files \ --no-header-files \
--no-man-pages \ --no-man-pages \
--strip-debug \ --strip-debug \
--compress=1 --compress zip-0
# create app dir # create app dir
${JAVA_HOME}/bin/jpackage \ ${JAVA_HOME}/bin/jpackage \
@@ -115,9 +124,10 @@ ${JAVA_HOME}/bin/jpackage \
cp ../resources/${APP_NAME}-Vault.icns ${APP_NAME}.app/Contents/Resources/ cp ../resources/${APP_NAME}-Vault.icns ${APP_NAME}.app/Contents/Resources/
sed -i '' "s|###BUNDLE_SHORT_VERSION_STRING###|${VERSION_NO}|g" ${APP_NAME}.app/Contents/Info.plist sed -i '' "s|###BUNDLE_SHORT_VERSION_STRING###|${VERSION_NO}|g" ${APP_NAME}.app/Contents/Info.plist
sed -i '' "s|###BUNDLE_VERSION###|${REVISION_NO}|g" ${APP_NAME}.app/Contents/Info.plist sed -i '' "s|###BUNDLE_VERSION###|${REVISION_NO}|g" ${APP_NAME}.app/Contents/Info.plist
cp ../embedded.provisionprofile ${APP_NAME}.app/Contents/
# generate license # generate license
mvn -B -f../../../pom.xml license:add-third-party \ mvn -B -Djavafx.platform=mac -f../../../pom.xml license:add-third-party \
-Dlicense.thirdPartyFilename=license.rtf \ -Dlicense.thirdPartyFilename=license.rtf \
-Dlicense.outputDirectory=dist/mac/dmg/resources \ -Dlicense.outputDirectory=dist/mac/dmg/resources \
-Dlicense.fileTemplate=resources/licenseTemplate.ftl \ -Dlicense.fileTemplate=resources/licenseTemplate.ftl \
@@ -127,7 +137,11 @@ mvn -B -f../../../pom.xml license:add-third-party \
-Dlicense.licenseMergesUrl=file://$(pwd)/../../../license/merges -Dlicense.licenseMergesUrl=file://$(pwd)/../../../license/merges
# codesign # codesign
if [ -n "${CODESIGN_IDENTITY}" ]; then if [ -n "${CODESIGN_IDENTITY}" ] && [ -n "${TEAM_IDENTIFIER}" ]; then
echo "Codesigning jdk files..."
find ${APP_NAME}.app/Contents/runtime/Contents/Home/lib/ -name '*.dylib' -exec codesign --force -s ${CODESIGN_IDENTITY} {} \;
find ${APP_NAME}.app/Contents/runtime/Contents/Home/lib/ -name 'jspawnhelper' -exec codesign --force -o runtime -s ${CODESIGN_IDENTITY} {} \;
echo "Codesigning jar contents..."
find ${APP_NAME}.app/Contents/runtime/Contents/MacOS -name '*.dylib' -exec codesign --force -s ${CODESIGN_IDENTITY} {} \; find ${APP_NAME}.app/Contents/runtime/Contents/MacOS -name '*.dylib' -exec codesign --force -s ${CODESIGN_IDENTITY} {} \;
for JAR_PATH in `find ${APP_NAME}.app -name "*.jar"`; do for JAR_PATH in `find ${APP_NAME}.app -name "*.jar"`; do
if [[ `unzip -l ${JAR_PATH} | grep '.dylib\|.jnilib'` ]]; then if [[ `unzip -l ${JAR_PATH} | grep '.dylib\|.jnilib'` ]]; then
@@ -145,7 +159,10 @@ if [ -n "${CODESIGN_IDENTITY}" ]; then
fi fi
done done
echo "Codesigning ${APP_NAME}.app..." echo "Codesigning ${APP_NAME}.app..."
codesign --force --deep --entitlements ../${APP_NAME}.entitlements -o runtime -s ${CODESIGN_IDENTITY} ${APP_NAME}.app cp ../${APP_NAME}.entitlements .
sed -i '' "s|###APP_IDENTIFIER_PREFIX###|${TEAM_IDENTIFIER}.|g" ${APP_NAME}.entitlements
sed -i '' "s|###TEAM_IDENTIFIER###|${TEAM_IDENTIFIER}|g" ${APP_NAME}.entitlements
codesign --force --deep --entitlements ${APP_NAME}.entitlements -o runtime -s ${CODESIGN_IDENTITY} ${APP_NAME}.app
fi fi
# prepare dmg contents # prepare dmg contents
@@ -168,6 +185,5 @@ create-dmg \
--app-drop-link 512 245 \ --app-drop-link 512 245 \
--eula "resources/license.rtf" \ --eula "resources/license.rtf" \
--icon ".background" 128 758 \ --icon ".background" 128 758 \
--icon ".fseventsd" 320 758 \
--icon ".VolumeIcon.icns" 512 758 \ --icon ".VolumeIcon.icns" 512 758 \
${APP_NAME}-${VERSION_NO}.dmg dmg ${APP_NAME}-${VERSION_NO}.dmg dmg
+1 -1
View File
@@ -17,7 +17,7 @@
\f1\b0 \ \f1\b0 \
\ \
\f0\b \'a9 2016 \'96 2023 Skymatic GmbH \f0\b \'a9 2016 \'96 2024 Skymatic GmbH
\f1\b0 \ \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.\ 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.\
+1 -1
View File
@@ -3,7 +3,7 @@
<plist version="1.0"> <plist version="1.0">
<dict> <dict>
<key>LSMinimumSystemVersion</key> <key>LSMinimumSystemVersion</key>
<string>10.13.0</string> <string>11</string>
<key>CFBundleDevelopmentRegion</key> <key>CFBundleDevelopmentRegion</key>
<string>English</string> <string>English</string>
<key>CFBundleAllowMixedLocalizations</key> <key>CFBundleAllowMixedLocalizations</key>
+3
View File
@@ -4,4 +4,7 @@ installer
*.wixobj *.wixobj
*.pdb *.pdb
*.msi *.msi
*.exe
*.jmod
resources/jfxJmods.zip
license.rtf license.rtf
+29 -21
View File
@@ -41,7 +41,7 @@ Write-Output "`$Env:JAVA_HOME=$Env:JAVA_HOME"
$copyright = "(C) $CopyrightStartYear - $((Get-Date).Year) $Vendor" $copyright = "(C) $CopyrightStartYear - $((Get-Date).Year) $Vendor"
# compile # compile
&mvn -B -f $buildDir/../../pom.xml clean package -DskipTests -Pwin &mvn -B -f $buildDir/../../pom.xml clean package -DskipTests -Pwin "-Djavafx.platform=win"
Copy-Item "$buildDir\..\..\target\$MainJarGlob.jar" -Destination "$buildDir\..\..\target\mods" Copy-Item "$buildDir\..\..\target\$MainJarGlob.jar" -Destination "$buildDir\..\..\target\mods"
# add runtime # add runtime
@@ -51,34 +51,36 @@ if ($clean -and (Test-Path -Path $runtimeImagePath)) {
} }
## download jfx jmods ## download jfx jmods
$jmodsVersion='20.0.2' $javaFxVersion='22.0.2'
$jmodsUrl = "https://download2.gluonhq.com/openjfx/${jmodsVersion}/openjfx-${jmodsVersion}_windows-x64_bin-jmods.zip" $javaFxJmodsUrl = "https://download2.gluonhq.com/openjfx/${javaFxVersion}/openjfx-${javaFxVersion}_windows-x64_bin-jmods.zip"
$jfxJmodsChecksum = '18625bbc13c57dbf802486564247a8d8cab72ec558c240a401bf6440384ebd77' $javaFxJmodsSHA256 = 'f9376d200f5c5b85327d575c1ec1482e6455f19916577f7e2fc9be2f48bb29b6'
$jfxJmodsZip = '.\resources\jfxJmods.zip' $javaFxJmods = '.\resources\jfxJmods.zip'
if( !(Test-Path -Path $jfxJmodsZip) ) { if( !(Test-Path -Path $javaFxJmods) ) {
Write-Output "Downloading ${jmodsUrl}..." Write-Output "Downloading ${javaFxJmodsUrl}..."
Invoke-WebRequest $jmodsUrl -OutFile $jfxJmodsZip # redirects are followed by default Invoke-WebRequest $javaFxJmodsUrl -OutFile $javaFxJmods # redirects are followed by default
} }
$jmodsChecksumActual = $(Get-FileHash -Path $jfxJmodsZip -Algorithm SHA256).Hash $jmodsChecksumActual = $(Get-FileHash -Path $javaFxJmods -Algorithm SHA256).Hash
if( $jmodsChecksumActual -ne $jfxJmodsChecksum ) { if( $jmodsChecksumActual -ne $javaFxJmodsSHA256 ) {
Write-Error "Checksum mismatch for jfxJmods.zip. Expected: $jfxJmodsChecksum, actual: $jmodsChecksumActual" Write-Error "Checksum mismatch for jfxJmods.zip. Expected: $javaFxJmodsSHA256
exit 1; , actual: $jmodsChecksumActual"
exit 1;
} }
Expand-Archive -Force -Path $jfxJmodsZip -DestinationPath ".\resources\" Expand-Archive -Path $javaFxJmods -Force -DestinationPath ".\resources\"
Move-Item -Path ".\resources\javafx-jmods-*" -Destination ".\resources\javafx-jmods" -ErrorAction Stop Remove-Item -Recurse -Force -Path ".\resources\javafx-jmods"
Move-Item -Force -Path ".\resources\javafx-jmods-*" -Destination ".\resources\javafx-jmods" -ErrorAction Stop
## create custom runtime
& "$Env:JAVA_HOME\bin\jlink" ` & "$Env:JAVA_HOME\bin\jlink" `
--verbose ` --verbose `
--output runtime ` --output runtime `
--module-path "$Env:JAVA_HOME/jmods;$buildDir/resources/javafx-jmods" ` --module-path "$Env:JAVA_HOME/jmods;$buildDir/resources/javafx-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,javafx.base,javafx.graphics,javafx.controls,javafx.fxml ` --add-modules java.base,java.desktop,java.instrument,java.logging,java.naming,java.net.http,java.scripting,java.sql,java.xml,jdk.unsupported,jdk.accessibility,jdk.management.jfr,java.compiler,javafx.base,javafx.graphics,javafx.controls,javafx.fxml `
--strip-native-commands ` --strip-native-commands `
--no-header-files ` --no-header-files `
--no-man-pages ` --no-man-pages `
--strip-debug ` --strip-debug `
--compress=1 --compress "zip-0" #do not compress to have improved msi compression
$appPath = ".\$AppName" $appPath = ".\$AppName"
if ($clean -and (Test-Path -Path $appPath)) { if ($clean -and (Test-Path -Path $appPath)) {
@@ -98,7 +100,7 @@ if ($clean -and (Test-Path -Path $appPath)) {
--vendor $Vendor ` --vendor $Vendor `
--copyright $copyright ` --copyright $copyright `
--java-options "--enable-preview" ` --java-options "--enable-preview" `
--java-options "--enable-native-access=org.cryptomator.jfuse.win" ` --java-options "--enable-native-access=org.cryptomator.jfuse.win,org.cryptomator.integrations.win" `
--java-options "-Xss5m" ` --java-options "-Xss5m" `
--java-options "-Xmx256m" ` --java-options "-Xmx256m" `
--java-options "-Dcryptomator.appVersion=`"$semVerNo`"" ` --java-options "-Dcryptomator.appVersion=`"$semVerNo`"" `
@@ -120,7 +122,7 @@ if ($clean -and (Test-Path -Path $appPath)) {
--icon resources/$AppName.ico --icon resources/$AppName.ico
#Create RTF license for msi #Create RTF license for msi
&mvn -B -f $buildDir/../../pom.xml license:add-third-party ` &mvn -B -f $buildDir/../../pom.xml license:add-third-party "-Djavafx.platform=win" `
"-Dlicense.thirdPartyFilename=license.rtf" ` "-Dlicense.thirdPartyFilename=license.rtf" `
"-Dlicense.fileTemplate=$buildDir\resources\licenseTemplate.ftl" ` "-Dlicense.fileTemplate=$buildDir\resources\licenseTemplate.ftl" `
"-Dlicense.outputDirectory=$buildDir\resources\" ` "-Dlicense.outputDirectory=$buildDir\resources\" `
@@ -143,6 +145,7 @@ try {
# create .msi # create .msi
$Env:JP_WIXWIZARD_RESOURCES = "$buildDir\resources" $Env:JP_WIXWIZARD_RESOURCES = "$buildDir\resources"
$Env:JP_WIXHELPER_DIR = "."
& "$Env:JAVA_HOME\bin\jpackage" ` & "$Env:JAVA_HOME\bin\jpackage" `
--verbose ` --verbose `
--type msi ` --type msi `
@@ -164,7 +167,7 @@ $Env:JP_WIXWIZARD_RESOURCES = "$buildDir\resources"
--file-associations resources/FAvaultFile.properties --file-associations resources/FAvaultFile.properties
#Create RTF license for bundle #Create RTF license for bundle
&mvn -B -f $buildDir/../../pom.xml license:add-third-party ` &mvn -B -f $buildDir/../../pom.xml license:add-third-party "-Djavafx.platform=win" `
"-Dlicense.thirdPartyFilename=license.rtf" ` "-Dlicense.thirdPartyFilename=license.rtf" `
"-Dlicense.fileTemplate=$buildDir\bundle\resources\licenseTemplate.ftl" ` "-Dlicense.fileTemplate=$buildDir\bundle\resources\licenseTemplate.ftl" `
"-Dlicense.outputDirectory=$buildDir\bundle\resources\" ` "-Dlicense.outputDirectory=$buildDir\bundle\resources\" `
@@ -174,10 +177,15 @@ $Env:JP_WIXWIZARD_RESOURCES = "$buildDir\resources"
"-Dlicense.licenseMergesUrl=file:///$buildDir/../../license/merges" "-Dlicense.licenseMergesUrl=file:///$buildDir/../../license/merges"
# download Winfsp # download Winfsp
$winfspMsiUrl= (Select-String -Path ".\bundle\resources\winFspMetaData.wxi" -Pattern '<\?define BundledWinFspDownloadLink="(.+)".*?>').Matches.Groups[1].Value $winfspMsiUrl= 'https://github.com/winfsp/winfsp/releases/download/v2.0/winfsp-2.0.23075.msi'
Write-Output "Downloading ${winfspMsiUrl}..." Write-Output "Downloading ${winfspMsiUrl}..."
Invoke-WebRequest $winfspMsiUrl -OutFile ".\bundle\resources\winfsp.msi" # redirects are followed by default Invoke-WebRequest $winfspMsiUrl -OutFile ".\bundle\resources\winfsp.msi" # redirects are followed by default
# download legacy-winfsp uninstaller
$winfspUninstaller= 'https://github.com/cryptomator/winfsp-uninstaller/releases/latest/download/winfsp-uninstaller.exe'
Write-Output "Downloading ${winfspUninstaller}..."
Invoke-WebRequest $winfspUninstaller -OutFile ".\bundle\resources\winfsp-uninstaller.exe" # redirects are followed by default
# copy MSI to bundle resources # copy MSI to bundle resources
Copy-Item ".\installer\$AppName-*.msi" -Destination ".\bundle\resources\$AppName.msi" Copy-Item ".\installer\$AppName-*.msi" -Destination ".\bundle\resources\$AppName.msi"
+25 -20
View File
@@ -1,5 +1,6 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<!-- For Built in variables, see https://wixtoolset.org/docs/tools/burn/builtin-variables/-->
<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"> <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--> <!-- see https://wixtoolset.org/documentation/manual/v3/xsd/wix/bundle.html-->
<!-- Attributes explicitly not used: <!-- Attributes explicitly not used:
@@ -10,21 +11,10 @@
AboutUrl="$(var.AboutUrl)" HelpUrl="$(var.HelpUrl)" UpdateUrl="$(var.UpdateUrl)" Copyright="$(var.BundleCopyright)" IconSourceFile="bundle\resources\Cryptomator.ico"> AboutUrl="$(var.AboutUrl)" HelpUrl="$(var.HelpUrl)" UpdateUrl="$(var.UpdateUrl)" Copyright="$(var.BundleCopyright)" IconSourceFile="bundle\resources\Cryptomator.ico">
<!-- detect outdated WinFsp installations --> <!-- detect outdated WinFsp installations -->
<?include "resources\winFspMetaData.wxi" ?>
<util:ProductSearch <util:ProductSearch
Variable="InstalledWinFspVersion" Variable="InstalledLegacyWinFspVersion"
Result="version" Result="version"
UpgradeCode="82F812D9-4083-4EF1-8BC8-0F1EDA05B46B" 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/--> <!-- for definition of the standard themes, see https://github.com/wixtoolset/wix3/blob/master/src/ext/BalExtension/wixstdba/Resources/-->
<BootstrapperApplicationRef Id="WixStandardBootstrapperApplication.RtfLargeLicense"> <BootstrapperApplicationRef Id="WixStandardBootstrapperApplication.RtfLargeLicense">
@@ -36,26 +26,41 @@
SuppressOptionsUI="yes" SuppressOptionsUI="yes"
ThemeFile="bundle\customBootstrapperTheme.xml" ThemeFile="bundle\customBootstrapperTheme.xml"
LocalizationFile="bundle\customBootstrapperTheme.wxl" LocalizationFile="bundle\customBootstrapperTheme.wxl"
LogoFile="bundle\resources\logo.png" LogoFile="bundle\resources\logo.png"/>
/>
<Payload SourceFile="bundle\resources\logoSide.png" /> <Payload SourceFile="bundle\resources\logoSide.png" />
</BootstrapperApplicationRef> </BootstrapperApplicationRef>
<Chain> <Chain>
<ExePackage Cache="yes" PerMachine="yes" Permanent="no"
SourceFile="resources\winfsp-uninstaller.exe"
DisplayName="Removing outdated WinFsp Driver"
Description="Executable to remove old winfsp"
DetectCondition="false"
InstallCondition="(InstalledLegacyWinFspVersion &lt;&gt; v0.0.0.0) AND ((WixBundleAction = 7) OR (WixBundleAction = 5))">
<CommandLine Condition="WixBundleUILevel &lt;= 3" InstallArgument="-q -l &quot;[WixBundleLog].winfsp-uninstaller.log&quot;" RepairArgument="-q" UninstallArgument="-s" />
<!-- XML allows line breaks in attributes, hence keep the line breaks here -->
<CommandLine Condition="WixBundleUILevel &gt; 3" InstallArgument="-l &quot;[WixBundleLog].winfsp-uninstaller.log&quot; -t &quot;Cryptomator Installer&quot; -m &quot;Cryptomator requires a newer version of the WinFsp driver. The installer will now uninstall WinFsp, possibly reboot, and afterwards proceed with the installation.
Do you want to continue?&quot;" RepairArgument="-q" UninstallArgument="-s" />
<ExitCode Behavior="success" Value="0"/>
<ExitCode Behavior="success" Value="1"/>
<ExitCode Behavior="error" Value="2"/>
<ExitCode Behavior="error" Value="3"/>
<ExitCode Behavior="forceReboot" Value="4"/>
<ExitCode Behavior="success" Value="5"/>
</ExePackage>
<!-- see https://wixtoolset.org/documentation/manual/v3/xsd/wix/msipackage.html--> <!-- see https://wixtoolset.org/documentation/manual/v3/xsd/wix/msipackage.html-->
<MsiPackage <MsiPackage
SourceFile="resources\Cryptomator.msi" SourceFile="resources\Cryptomator.msi"
CacheId="cryptomator-bundle-cryptomator" CacheId="cryptomator-bundle-cryptomator"
DisplayInternalUI="no" DisplayInternalUI="no"
Visible="no" Visible="no"/>
/>
<MsiPackage <MsiPackage
SourceFile="resources\winfsp.msi" SourceFile="resources\winfsp.msi"
CacheId="cryptomator-bundle-winfsp" CacheId="cryptomator-bundle-winfsp"
Visible="yes" Visible="yes"
DisplayInternalUI="no" DisplayInternalUI="no"
Vital="no" Permanent="yes"/>
Permanent="yes"
/>
</Chain> </Chain>
</Bundle> </Bundle>
</Wix> </Wix>
+1 -1
View File
@@ -10,7 +10,7 @@
\vieww12000\viewh15840\viewkind0 \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 \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 \par
\b\'a9 2016 \'96 2023 Skymatic GmbH \b0\par \b\'a9 2016 \'96 2024 Skymatic GmbH \b0\par
\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 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 \par
-7
View File
@@ -1,7 +0,0 @@
<?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>
-5
View File
@@ -1,5 +0,0 @@
@echo off
:: see comments in file ./version170-migrate-settings.ps1
cd %~dp0
powershell -NoLogo -NoProfile -NonInteractive -ExecutionPolicy RemoteSigned -Command .\version170-migrate-settings.ps1
-35
View File
@@ -1,35 +0,0 @@
# 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
}
}
+1 -1
View File
@@ -10,7 +10,7 @@
\vieww12000\viewh15840\viewkind0 \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 \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 \par
\b\'a9 2016 \'96 2023 Skymatic GmbH \b0\par \b\'a9 2016 \'96 2024 Skymatic GmbH \b0\par
\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 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 \par
+1 -7
View File
@@ -70,7 +70,7 @@
<CustomAction Id="JpDisallowDowngrade" Error="!(loc.DowngradeErrorMessage)" /> <CustomAction Id="JpDisallowDowngrade" Error="!(loc.DowngradeErrorMessage)" />
<?endif?> <?endif?>
<Binary Id="JpCaDll" SourceFile="wixhelper.dll"/> <Binary Id="JpCaDll" SourceFile="$(env.JP_WIXHELPER_DIR)\wixhelper.dll"/>
<CustomAction Id="JpFindRelatedProducts" BinaryKey="JpCaDll" DllEntry="FindRelatedProductsEx" /> <CustomAction Id="JpFindRelatedProducts" BinaryKey="JpCaDll" DllEntry="FindRelatedProductsEx" />
<?ifndef SkipCryptomatorLegacyCheck ?> <?ifndef SkipCryptomatorLegacyCheck ?>
@@ -139,11 +139,6 @@
Sequence="execute" Before="PatchWebDAV" /> Sequence="execute" Before="PatchWebDAV" />
<CustomAction Id="PatchWebDAV" BinaryKey="WixCA" DllEntry="WixQuietExec64" Execute="deferred" Return="ignore" Impersonate="no"/> <CustomAction Id="PatchWebDAV" BinaryKey="WixCA" DllEntry="WixQuietExec64" Execute="deferred" Return="ignore" Impersonate="no"/>
<!-- Special Settings migration for 1.7.0,. Should be removed eventually, for more info, see ../contrib/version170-migrate-settings.ps1-->
<SetProperty Id="V170MigrateSettings" Value="&quot;[INSTALLDIR]version170-migrate-settings.bat&quot;"
Sequence="execute" Before="V170MigrateSettings" />
<CustomAction Id="V170MigrateSettings" BinaryKey="WixCA" DllEntry="WixQuietExec64" Execute="deferred" Return="ignore" Impersonate="no"/>
<!-- Running App detection and exit --> <!-- Running App detection and exit -->
<Property Id="FOUNDRUNNINGAPP" Admin="yes"/> <Property Id="FOUNDRUNNINGAPP" Admin="yes"/>
<util:CloseApplication <util:CloseApplication
@@ -195,7 +190,6 @@
<RemoveExistingProducts After="InstallValidate"/> <!-- Moved from CostInitialize, due to WixCloseApplications --> <RemoveExistingProducts After="InstallValidate"/> <!-- Moved from CostInitialize, due to WixCloseApplications -->
<Custom Action="PatchWebDAV" After="InstallFiles">NOT Installed OR REINSTALL</Custom> <Custom Action="PatchWebDAV" After="InstallFiles">NOT Installed OR REINSTALL</Custom>
<Custom Action="V170MigrateSettings" After="InstallFiles">NOT Installed OR REINSTALL</Custom>
</InstallExecuteSequence> </InstallExecuteSequence>
<InstallUISequence> <InstallUISequence>
+56 -66
View File
@@ -3,7 +3,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>org.cryptomator</groupId> <groupId>org.cryptomator</groupId>
<artifactId>cryptomator</artifactId> <artifactId>cryptomator</artifactId>
<version>1.10.0</version> <version>1.15.0-SNAPSHOT</version>
<name>Cryptomator Desktop App</name> <name>Cryptomator Desktop App</name>
<organization> <organization>
@@ -26,56 +26,59 @@
<properties> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.jdk.version>20</project.jdk.version> <project.jdk.version>23</project.jdk.version>
<!-- Group IDs of jars that need to stay on the class path for now --> <!-- Group IDs of jars that need to stay on the class path for now -->
<!-- remove them, as soon they got modularized or support is dropped (i.e., WebDAV) --> <!-- remove them, as soon they got modularized or support is dropped (i.e., WebDAV) -->
<nonModularGroupIds>org.ow2.asm,org.apache.jackrabbit,org.apache.httpcomponents</nonModularGroupIds> <nonModularGroupIds>org.ow2.asm,org.apache.jackrabbit,org.apache.httpcomponents</nonModularGroupIds>
<!-- cryptomator dependencies --> <!-- cryptomator dependencies -->
<cryptomator.cryptofs.version>2.6.7</cryptomator.cryptofs.version> <cryptomator.cryptofs.version>2.7.1</cryptomator.cryptofs.version>
<cryptomator.integrations.version>1.3.0</cryptomator.integrations.version> <cryptomator.integrations.version>1.4.0</cryptomator.integrations.version>
<cryptomator.integrations.win.version>1.2.2</cryptomator.integrations.win.version> <cryptomator.integrations.win.version>1.4.1</cryptomator.integrations.win.version>
<cryptomator.integrations.mac.version>1.2.1</cryptomator.integrations.mac.version> <cryptomator.integrations.mac.version>1.3.0</cryptomator.integrations.mac.version>
<cryptomator.integrations.linux.version>1.3.0-beta6</cryptomator.integrations.linux.version> <cryptomator.integrations.linux.version>1.5.1</cryptomator.integrations.linux.version>
<cryptomator.fuse.version>3.0.0</cryptomator.fuse.version> <cryptomator.fuse.version>5.0.2</cryptomator.fuse.version>
<cryptomator.dokany.version>2.0.0</cryptomator.dokany.version> <cryptomator.webdav.version>2.0.7</cryptomator.webdav.version>
<cryptomator.webdav.version>2.0.3</cryptomator.webdav.version>
<!-- 3rd party dependencies --> <!-- 3rd party dependencies -->
<commons-lang3.version>3.13.0</commons-lang3.version> <commons-lang3.version>3.17.0</commons-lang3.version>
<dagger.version>2.47</dagger.version> <dagger.version>2.52</dagger.version>
<easybind.version>2.2</easybind.version> <easybind.version>2.2</easybind.version>
<guava.version>32.1.2-jre</guava.version> <jackson.version>2.18.1</jackson.version>
<jackson.version>2.15.2</jackson.version> <javafx.version>22.0.2</javafx.version>
<javafx.version>20.0.2</javafx.version>
<jwt.version>4.4.0</jwt.version> <jwt.version>4.4.0</jwt.version>
<nimbus-jose.version>9.31</nimbus-jose.version> <nimbus-jose.version>9.37.3</nimbus-jose.version>
<logback.version>1.4.11</logback.version> <logback.version>1.5.12</logback.version>
<slf4j.version>2.0.7</slf4j.version> <slf4j.version>2.0.16</slf4j.version>
<tinyoauth2.version>0.6.0</tinyoauth2.version> <tinyoauth2.version>0.8.0</tinyoauth2.version>
<zxcvbn.version>1.8.2</zxcvbn.version> <zxcvbn.version>1.9.0</zxcvbn.version>
<!-- test dependencies --> <!-- test dependencies -->
<junit.jupiter.version>5.10.0</junit.jupiter.version> <junit.jupiter.version>5.11.3</junit.jupiter.version>
<mockito.version>5.5.0</mockito.version> <mockito.version>5.14.2</mockito.version>
<hamcrest.version>2.2</hamcrest.version> <hamcrest.version>3.0</hamcrest.version>
<!-- build-time dependencies --> <!-- build-time dependencies -->
<jetbrains.annotations.version>24.0.1</jetbrains.annotations.version> <jetbrains.annotations.version>26.0.1</jetbrains.annotations.version>
<dependency-check.version>8.4.0</dependency-check.version> <dependency-check.version>11.1.0</dependency-check.version>
<jacoco.version>0.8.10</jacoco.version> <jacoco.version>0.8.12</jacoco.version>
<license-generator.version>2.2.0</license-generator.version> <license-generator.version>2.4.0</license-generator.version>
<junit-tree-reporter.version>1.2.1</junit-tree-reporter.version> <junit-tree-reporter.version>1.3.0</junit-tree-reporter.version>
<mvn-compiler.version>3.11.0</mvn-compiler.version> <mvn-compiler.version>3.13.0</mvn-compiler.version>
<mvn-resources.version>3.3.1</mvn-resources.version> <mvn-resources.version>3.3.1</mvn-resources.version>
<mvn-dependency.version>3.6.0</mvn-dependency.version> <mvn-dependency.version>3.8.1</mvn-dependency.version>
<mvn-surefire.version>3.1.2</mvn-surefire.version> <mvn-surefire.version>3.5.2</mvn-surefire.version>
<mvn-jar.version>3.3.0</mvn-jar.version> <mvn-jar.version>3.4.2</mvn-jar.version>
</properties> </properties>
<dependencies> <dependencies>
<!-- Cryptomator Libs --> <!-- Cryptomator Libs -->
<dependency>
<groupId>org.cryptomator</groupId>
<artifactId>cryptolib</artifactId>
<version>2.2.0</version>
</dependency>
<dependency> <dependency>
<groupId>org.cryptomator</groupId> <groupId>org.cryptomator</groupId>
<artifactId>cryptofs</artifactId> <artifactId>cryptofs</artifactId>
@@ -86,11 +89,6 @@
<artifactId>fuse-nio-adapter</artifactId> <artifactId>fuse-nio-adapter</artifactId>
<version>${cryptomator.fuse.version}</version> <version>${cryptomator.fuse.version}</version>
</dependency> </dependency>
<dependency>
<groupId>org.cryptomator</groupId>
<artifactId>dokany-nio-adapter</artifactId>
<version>${cryptomator.dokany.version}</version>
</dependency>
<dependency> <dependency>
<groupId>org.cryptomator</groupId> <groupId>org.cryptomator</groupId>
<artifactId>webdav-nio-adapter</artifactId> <artifactId>webdav-nio-adapter</artifactId>
@@ -164,11 +162,18 @@
<artifactId>nimbus-jose-jwt</artifactId> <artifactId>nimbus-jose-jwt</artifactId>
<version>${nimbus-jose.version}</version> <version>${nimbus-jose.version}</version>
</dependency> </dependency>
<!-- Jackson -->
<dependency> <dependency>
<groupId>com.fasterxml.jackson.core</groupId> <groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId> <artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version> <version>${jackson.version}</version>
</dependency> </dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>${jackson.version}</version>
</dependency>
<!-- EasyBind --> <!-- EasyBind -->
<dependency> <dependency>
@@ -185,40 +190,23 @@
</dependency> </dependency>
<!-- Google --> <!-- Google -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>${guava.version}</version>
<exclusions>
<!-- see https://github.com/google/guava/wiki/UseGuavaInYourBuild#what-about-guavas-own-dependencies -->
<exclusion>
<groupId>com.google.guava</groupId>
<artifactId>listenablefuture</artifactId>
</exclusion>
<exclusion>
<groupId>com.google.code.findbugs</groupId>
<artifactId>jsr305</artifactId>
</exclusion>
<exclusion>
<groupId>org.checkerframework</groupId>
<artifactId>checker-qual</artifactId>
</exclusion>
<exclusion>
<groupId>com.google.errorprone</groupId>
<artifactId>error_prone_annotations</artifactId>
</exclusion>
<exclusion>
<groupId>com.google.j2objc</groupId>
<artifactId>j2objc-annotations</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency> <dependency>
<groupId>com.google.dagger</groupId> <groupId>com.google.dagger</groupId>
<artifactId>dagger</artifactId> <artifactId>dagger</artifactId>
<version>${dagger.version}</version> <version>${dagger.version}</version>
</dependency> </dependency>
<dependency>
<groupId>jakarta.inject</groupId>
<artifactId>jakarta.inject-api</artifactId>
<version>2.0.1</version>
</dependency>
<!-- Caffeine -->
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
<version>3.1.8</version>
</dependency>
<!-- JUnit / Mockito / Hamcrest --> <!-- JUnit / Mockito / Hamcrest -->
<dependency> <dependency>
<groupId>org.junit.jupiter</groupId> <groupId>org.junit.jupiter</groupId>
@@ -460,17 +448,19 @@
<groupId>org.owasp</groupId> <groupId>org.owasp</groupId>
<artifactId>dependency-check-maven</artifactId> <artifactId>dependency-check-maven</artifactId>
<configuration> <configuration>
<cveValidForHours>24</cveValidForHours> <nvdValidForHours>24</nvdValidForHours>
<failBuildOnCVSS>0</failBuildOnCVSS> <failBuildOnCVSS>0</failBuildOnCVSS>
<skipTestScope>true</skipTestScope> <skipTestScope>true</skipTestScope>
<detail>true</detail> <detail>true</detail>
<suppressionFile>suppression.xml</suppressionFile> <suppressionFile>suppression.xml</suppressionFile>
<nvdApiKeyEnvironmentVariable>NVD_API_KEY</nvdApiKeyEnvironmentVariable>
</configuration> </configuration>
<executions> <executions>
<execution> <execution>
<goals> <goals>
<goal>check</goal> <goal>check</goal>
</goals> </goals>
<phase>validate</phase>
</execution> </execution>
</executions> </executions>
</plugin> </plugin>
+9 -6
View File
@@ -2,7 +2,8 @@ import ch.qos.logback.classic.spi.Configurator;
import org.cryptomator.common.locationpresets.DropboxLinuxLocationPresetsProvider; import org.cryptomator.common.locationpresets.DropboxLinuxLocationPresetsProvider;
import org.cryptomator.common.locationpresets.DropboxMacLocationPresetsProvider; import org.cryptomator.common.locationpresets.DropboxMacLocationPresetsProvider;
import org.cryptomator.common.locationpresets.DropboxWindowsLocationPresetsProvider; import org.cryptomator.common.locationpresets.DropboxWindowsLocationPresetsProvider;
import org.cryptomator.common.locationpresets.GoogleDriveLocationPresetsProvider; import org.cryptomator.common.locationpresets.GoogleDriveMacLocationPresetsProvider;
import org.cryptomator.common.locationpresets.GoogleDriveWindowsLocationPresetsProvider;
import org.cryptomator.common.locationpresets.ICloudMacLocationPresetsProvider; import org.cryptomator.common.locationpresets.ICloudMacLocationPresetsProvider;
import org.cryptomator.common.locationpresets.ICloudWindowsLocationPresetsProvider; import org.cryptomator.common.locationpresets.ICloudWindowsLocationPresetsProvider;
import org.cryptomator.common.locationpresets.LeitzcloudLocationPresetsProvider; import org.cryptomator.common.locationpresets.LeitzcloudLocationPresetsProvider;
@@ -21,7 +22,6 @@ open module org.cryptomator.desktop {
requires org.cryptomator.cryptolib; requires org.cryptomator.cryptolib;
requires org.cryptomator.cryptofs; requires org.cryptomator.cryptofs;
requires org.cryptomator.frontend.dokany;
requires org.cryptomator.frontend.fuse; requires org.cryptomator.frontend.fuse;
requires org.cryptomator.frontend.webdav; requires org.cryptomator.frontend.webdav;
requires org.cryptomator.integrations.api; requires org.cryptomator.integrations.api;
@@ -32,13 +32,13 @@ open module org.cryptomator.desktop {
requires javafx.graphics; requires javafx.graphics;
requires javafx.controls; requires javafx.controls;
requires javafx.fxml; requires javafx.fxml;
requires jdk.crypto.ec;
// 3rd party: // 3rd party:
requires ch.qos.logback.classic; requires ch.qos.logback.classic;
requires ch.qos.logback.core; requires ch.qos.logback.core;
requires com.auth0.jwt; requires com.auth0.jwt;
requires com.google.common; requires com.google.common;
requires com.fasterxml.jackson.databind; requires com.fasterxml.jackson.databind;
requires com.fasterxml.jackson.datatype.jsr310;
requires com.nimbusds.jose.jwt; requires com.nimbusds.jose.jwt;
requires com.nulabinc.zxcvbn; requires com.nulabinc.zxcvbn;
requires com.tobiasdiez.easybind; requires com.tobiasdiez.easybind;
@@ -47,8 +47,11 @@ open module org.cryptomator.desktop {
requires org.slf4j; requires org.slf4j;
requires org.apache.commons.lang3; requires org.apache.commons.lang3;
/* TODO: filename-based modules: */ /* dagger bs */
requires static javax.inject; /* ugly dagger/guava crap */ requires jakarta.inject;
requires static javax.inject;
requires java.compiler;
requires com.github.benmanes.caffeine;
uses org.cryptomator.common.locationpresets.LocationPresetsProvider; uses org.cryptomator.common.locationpresets.LocationPresetsProvider;
@@ -56,7 +59,7 @@ open module org.cryptomator.desktop {
provides Configurator with LogbackConfiguratorFactory; provides Configurator with LogbackConfiguratorFactory;
provides LocationPresetsProvider with // provides LocationPresetsProvider with //
DropboxWindowsLocationPresetsProvider, DropboxMacLocationPresetsProvider, DropboxLinuxLocationPresetsProvider, // DropboxWindowsLocationPresetsProvider, DropboxMacLocationPresetsProvider, DropboxLinuxLocationPresetsProvider, //
GoogleDriveLocationPresetsProvider, // GoogleDriveMacLocationPresetsProvider, GoogleDriveWindowsLocationPresetsProvider, //
ICloudWindowsLocationPresetsProvider, ICloudMacLocationPresetsProvider, // ICloudWindowsLocationPresetsProvider, ICloudMacLocationPresetsProvider, //
LeitzcloudLocationPresetsProvider, // LeitzcloudLocationPresetsProvider, //
MegaLocationPresetsProvider, // MegaLocationPresetsProvider, //
@@ -0,0 +1,20 @@
package org.cryptomator;
import javafx.application.Platform;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
public class JavaFXUtil {
public static boolean startPlatform() throws InterruptedException {
CountDownLatch latch = new CountDownLatch(1);
try {
Platform.startup(latch::countDown);
} catch (IllegalStateException e) {
//already initialized
latch.countDown();
}
return latch.await(5, TimeUnit.SECONDS);
}
}
@@ -5,10 +5,8 @@
*******************************************************************************/ *******************************************************************************/
package org.cryptomator.common; package org.cryptomator.common;
import com.tobiasdiez.easybind.EasyBind;
import dagger.Module; import dagger.Module;
import dagger.Provides; import dagger.Provides;
import org.apache.commons.lang3.SystemUtils;
import org.cryptomator.common.keychain.KeychainModule; import org.cryptomator.common.keychain.KeychainModule;
import org.cryptomator.common.mount.MountModule; import org.cryptomator.common.mount.MountModule;
import org.cryptomator.common.settings.Settings; import org.cryptomator.common.settings.Settings;
@@ -22,8 +20,6 @@ import org.slf4j.LoggerFactory;
import javax.inject.Named; import javax.inject.Named;
import javax.inject.Singleton; import javax.inject.Singleton;
import javafx.beans.value.ObservableValue;
import java.net.InetSocketAddress;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom; import java.security.SecureRandom;
import java.util.Comparator; import java.util.Comparator;
@@ -136,13 +132,4 @@ public abstract class CommonsModule {
LOG.error("Uncaught exception in " + thread.getName(), throwable); LOG.error("Uncaught exception in " + thread.getName(), throwable);
} }
@Provides
@Singleton
static ObservableValue<InetSocketAddress> provideServerSocketAddressBinding(Settings settings) {
return settings.port.map(port -> {
String host = SystemUtils.IS_OS_WINDOWS ? "127.0.0.1" : "localhost";
return InetSocketAddress.createUnresolved(host, settings.port.intValue());
});
}
} }
@@ -2,6 +2,7 @@ package org.cryptomator.common;
import com.google.common.base.Splitter; import com.google.common.base.Splitter;
import com.google.common.base.Strings; import com.google.common.base.Strings;
import org.jetbrains.annotations.VisibleForTesting;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -22,6 +23,7 @@ public class Environment {
private static final String SETTINGS_PATH_PROP_NAME = "cryptomator.settingsPath"; private static final String SETTINGS_PATH_PROP_NAME = "cryptomator.settingsPath";
private static final String IPC_SOCKET_PATH_PROP_NAME = "cryptomator.ipcSocketPath"; private static final String IPC_SOCKET_PATH_PROP_NAME = "cryptomator.ipcSocketPath";
private static final String KEYCHAIN_PATHS_PROP_NAME = "cryptomator.integrationsWin.keychainPaths"; private static final String KEYCHAIN_PATHS_PROP_NAME = "cryptomator.integrationsWin.keychainPaths";
private static final String WINDOWS_HELLO_KEYCHAIN_PATHS_PROP_NAME = "cryptomator.integrationsWin.windowsHelloKeychainPaths";
private static final String P12_PATH_PROP_NAME = "cryptomator.p12Path"; private static final String P12_PATH_PROP_NAME = "cryptomator.p12Path";
private static final String LOG_DIR_PROP_NAME = "cryptomator.logDir"; private static final String LOG_DIR_PROP_NAME = "cryptomator.logDir";
private static final String LOOPBACK_ALIAS_PROP_NAME = "cryptomator.loopbackAlias"; private static final String LOOPBACK_ALIAS_PROP_NAME = "cryptomator.loopbackAlias";
@@ -31,6 +33,7 @@ public class Environment {
private static final String BUILD_NUMBER_PROP_NAME = "cryptomator.buildNumber"; private static final String BUILD_NUMBER_PROP_NAME = "cryptomator.buildNumber";
private static final String PLUGIN_DIR_PROP_NAME = "cryptomator.pluginDir"; private static final String PLUGIN_DIR_PROP_NAME = "cryptomator.pluginDir";
private static final String TRAY_ICON_PROP_NAME = "cryptomator.showTrayIcon"; private static final String TRAY_ICON_PROP_NAME = "cryptomator.showTrayIcon";
private static final String DISABLE_UPDATE_CHECK_PROP_NAME = "cryptomator.disableUpdateCheck";
private Environment() {} private Environment() {}
@@ -43,15 +46,17 @@ public class Environment {
logCryptomatorSystemProperty(SETTINGS_PATH_PROP_NAME); logCryptomatorSystemProperty(SETTINGS_PATH_PROP_NAME);
logCryptomatorSystemProperty(IPC_SOCKET_PATH_PROP_NAME); logCryptomatorSystemProperty(IPC_SOCKET_PATH_PROP_NAME);
logCryptomatorSystemProperty(KEYCHAIN_PATHS_PROP_NAME); logCryptomatorSystemProperty(KEYCHAIN_PATHS_PROP_NAME);
logCryptomatorSystemProperty(WINDOWS_HELLO_KEYCHAIN_PATHS_PROP_NAME);
logCryptomatorSystemProperty(P12_PATH_PROP_NAME);
logCryptomatorSystemProperty(LOG_DIR_PROP_NAME); logCryptomatorSystemProperty(LOG_DIR_PROP_NAME);
logCryptomatorSystemProperty(LOOPBACK_ALIAS_PROP_NAME); logCryptomatorSystemProperty(LOOPBACK_ALIAS_PROP_NAME);
logCryptomatorSystemProperty(PLUGIN_DIR_PROP_NAME);
logCryptomatorSystemProperty(MOUNTPOINT_DIR_PROP_NAME); logCryptomatorSystemProperty(MOUNTPOINT_DIR_PROP_NAME);
logCryptomatorSystemProperty(MIN_PW_LENGTH_PROP_NAME); logCryptomatorSystemProperty(MIN_PW_LENGTH_PROP_NAME);
logCryptomatorSystemProperty(APP_VERSION_PROP_NAME); logCryptomatorSystemProperty(APP_VERSION_PROP_NAME);
logCryptomatorSystemProperty(BUILD_NUMBER_PROP_NAME); logCryptomatorSystemProperty(BUILD_NUMBER_PROP_NAME);
logCryptomatorSystemProperty(PLUGIN_DIR_PROP_NAME);
logCryptomatorSystemProperty(TRAY_ICON_PROP_NAME); logCryptomatorSystemProperty(TRAY_ICON_PROP_NAME);
logCryptomatorSystemProperty(P12_PATH_PROP_NAME); logCryptomatorSystemProperty(DISABLE_UPDATE_CHECK_PROP_NAME);
} }
public static Environment getInstance() { public static Environment getInstance() {
@@ -74,10 +79,6 @@ public class Environment {
return getPaths(SETTINGS_PATH_PROP_NAME); return getPaths(SETTINGS_PATH_PROP_NAME);
} }
public Stream<Path> getP12Path() {
return getPaths(P12_PATH_PROP_NAME);
}
public Stream<Path> getIpcSocketPath() { public Stream<Path> getIpcSocketPath() {
return getPaths(IPC_SOCKET_PATH_PROP_NAME); return getPaths(IPC_SOCKET_PATH_PROP_NAME);
} }
@@ -86,6 +87,14 @@ public class Environment {
return getPaths(KEYCHAIN_PATHS_PROP_NAME); return getPaths(KEYCHAIN_PATHS_PROP_NAME);
} }
public Stream<Path> getWindowsHelloKeychainPath() {
return getPaths(WINDOWS_HELLO_KEYCHAIN_PATHS_PROP_NAME);
}
public Stream<Path> getP12Path() {
return getPaths(P12_PATH_PROP_NAME);
}
public Optional<Path> getLogDir() { public Optional<Path> getLogDir() {
return getPath(LOG_DIR_PROP_NAME); return getPath(LOG_DIR_PROP_NAME);
} }
@@ -94,14 +103,14 @@ public class Environment {
return Optional.ofNullable(System.getProperty(LOOPBACK_ALIAS_PROP_NAME)); return Optional.ofNullable(System.getProperty(LOOPBACK_ALIAS_PROP_NAME));
} }
public Optional<Path> getPluginDir() {
return getPath(PLUGIN_DIR_PROP_NAME);
}
public Optional<Path> getMountPointsDir() { public Optional<Path> getMountPointsDir() {
return getPath(MOUNTPOINT_DIR_PROP_NAME); return getPath(MOUNTPOINT_DIR_PROP_NAME);
} }
public int getMinPwLength() {
return Integer.getInteger(MIN_PW_LENGTH_PROP_NAME, DEFAULT_MIN_PW_LENGTH);
}
/** /**
* Returns the app version defined in the {@value APP_VERSION_PROP_NAME} property or returns "SNAPSHOT". * Returns the app version defined in the {@value APP_VERSION_PROP_NAME} property or returns "SNAPSHOT".
* *
@@ -115,20 +124,24 @@ public class Environment {
return Optional.ofNullable(System.getProperty(BUILD_NUMBER_PROP_NAME)); return Optional.ofNullable(System.getProperty(BUILD_NUMBER_PROP_NAME));
} }
public int getMinPwLength() { public Optional<Path> getPluginDir() {
return Integer.getInteger(MIN_PW_LENGTH_PROP_NAME, DEFAULT_MIN_PW_LENGTH); return getPath(PLUGIN_DIR_PROP_NAME);
} }
public boolean showTrayIcon() { public boolean showTrayIcon() {
return Boolean.getBoolean(TRAY_ICON_PROP_NAME); return Boolean.getBoolean(TRAY_ICON_PROP_NAME);
} }
public boolean disableUpdateCheck() {
return Boolean.getBoolean(DISABLE_UPDATE_CHECK_PROP_NAME);
}
private Optional<Path> getPath(String propertyName) { private Optional<Path> getPath(String propertyName) {
String value = System.getProperty(propertyName); String value = System.getProperty(propertyName);
return Optional.ofNullable(value).map(Paths::get); return Optional.ofNullable(value).map(Paths::get);
} }
// visible for testing @VisibleForTesting
Stream<Path> getPaths(String propertyName) { Stream<Path> getPaths(String propertyName) {
Stream<String> rawSettingsPaths = getRawList(propertyName, System.getProperty("path.separator").charAt(0)); Stream<String> rawSettingsPaths = getRawList(propertyName, System.getProperty("path.separator").charAt(0));
return rawSettingsPaths.filter(Predicate.not(Strings::isNullOrEmpty)).map(Path::of); return rawSettingsPaths.filter(Predicate.not(Strings::isNullOrEmpty)).map(Path::of);
@@ -3,6 +3,7 @@ package org.cryptomator.common;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import com.google.common.base.Strings; import com.google.common.base.Strings;
import com.google.common.base.Throwables; import com.google.common.base.Throwables;
import org.jetbrains.annotations.VisibleForTesting;
import java.util.Locale; import java.util.Locale;
import java.util.Objects; import java.util.Objects;
@@ -114,7 +115,7 @@ public class ErrorCode {
* @param bottomFrames Other stack frames, potentially forming the bottom of the stack of <code>allFrames</code> * @param bottomFrames Other stack frames, potentially forming the bottom of the stack of <code>allFrames</code>
* @return The number of additional frames in <code>allFrames</code>. In most cases this should be equal to the difference in size. * @return The number of additional frames in <code>allFrames</code>. In most cases this should be equal to the difference in size.
*/ */
// visible for testing @VisibleForTesting
static int countTopmostFrames(StackTraceElement[] allFrames, StackTraceElement[] bottomFrames) { static int countTopmostFrames(StackTraceElement[] allFrames, StackTraceElement[] bottomFrames) {
if (allFrames.length < bottomFrames.length) { if (allFrames.length < bottomFrames.length) {
// if frames had been stacked on top of bottomFrames, allFrames would be larger // if frames had been stacked on top of bottomFrames, allFrames would be larger
@@ -124,7 +125,7 @@ public class ErrorCode {
} }
} }
// visible for testing @VisibleForTesting
static <T> int commonSuffixLength(T[] set, T[] subset) { static <T> int commonSuffixLength(T[] set, T[] subset) {
Preconditions.checkArgument(set.length >= subset.length); Preconditions.checkArgument(set.length >= subset.length);
// iterate items backwards as long as they are identical // iterate items backwards as long as they are identical
@@ -5,6 +5,7 @@ import org.slf4j.LoggerFactory;
import java.util.Map; import java.util.Map;
import java.util.Properties; import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
public class SubstitutingProperties extends PropertiesDecorator { public class SubstitutingProperties extends PropertiesDecorator {
@@ -58,7 +59,7 @@ public class SubstitutingProperties extends PropertiesDecorator {
LoggerFactory.getLogger(SubstitutingProperties.class).warn("Variable {} used for substitution not found in {}. Replaced with empty string.", key, src); LoggerFactory.getLogger(SubstitutingProperties.class).warn("Variable {} used for substitution not found in {}. Replaced with empty string.", key, src);
return ""; return "";
} else { } else {
return val.replace("\\", "\\\\"); return Matcher.quoteReplacement(val);
} }
} }
@@ -1,8 +1,7 @@
package org.cryptomator.common.keychain; package org.cryptomator.common.keychain;
import com.google.common.cache.CacheBuilder; import com.github.benmanes.caffeine.cache.Caffeine;
import com.google.common.cache.CacheLoader; import com.github.benmanes.caffeine.cache.LoadingCache;
import com.google.common.cache.LoadingCache;
import org.cryptomator.integrations.keychain.KeychainAccessException; import org.cryptomator.integrations.keychain.KeychainAccessException;
import org.cryptomator.integrations.keychain.KeychainAccessProvider; import org.cryptomator.integrations.keychain.KeychainAccessProvider;
@@ -24,9 +23,9 @@ public class KeychainManager implements KeychainAccessProvider {
@Inject @Inject
KeychainManager(ObjectExpression<KeychainAccessProvider> selectedKeychain) { KeychainManager(ObjectExpression<KeychainAccessProvider> selectedKeychain) {
this.keychain = selectedKeychain; this.keychain = selectedKeychain;
this.passphraseStoredProperties = CacheBuilder.newBuilder() // this.passphraseStoredProperties = Caffeine.newBuilder() //
.weakValues() // .softValues() //
.build(CacheLoader.from(this::createStoredPassphraseProperty)); .build(this::createStoredPassphraseProperty);
keychain.addListener(ignored -> passphraseStoredProperties.invalidateAll()); keychain.addListener(ignored -> passphraseStoredProperties.invalidateAll());
} }
@@ -45,7 +44,12 @@ public class KeychainManager implements KeychainAccessProvider {
@Override @Override
public void storePassphrase(String key, String displayName, CharSequence passphrase) throws KeychainAccessException { public void storePassphrase(String key, String displayName, CharSequence passphrase) throws KeychainAccessException {
getKeychainOrFail().storePassphrase(key, displayName, passphrase); storePassphrase(key, displayName, passphrase, true); //TODO: currently only TouchID is using this parameter, so this is okayish
}
@Override
public void storePassphrase(String key, String displayName, CharSequence passphrase, boolean requireOsAuthentication) throws KeychainAccessException {
getKeychainOrFail().storePassphrase(key, displayName, passphrase, requireOsAuthentication);
setPassphraseStored(key, true); setPassphraseStored(key, true);
} }
@@ -102,13 +106,11 @@ public class KeychainManager implements KeychainAccessProvider {
} }
private void setPassphraseStored(String key, boolean value) { private void setPassphraseStored(String key, boolean value) {
BooleanProperty property = passphraseStoredProperties.getIfPresent(key); BooleanProperty property = passphraseStoredProperties.get(key, _ -> new SimpleBooleanProperty(value));
if (property != null) { if (Platform.isFxApplicationThread()) {
if (Platform.isFxApplicationThread()) { property.set(value);
property.set(value); } else {
} else { Platform.runLater(() -> property.set(value));
Platform.runLater(() -> property.set(value));
}
} }
} }
@@ -124,7 +126,7 @@ public class KeychainManager implements KeychainAccessProvider {
* @see #isPassphraseStored(String) * @see #isPassphraseStored(String)
*/ */
public ReadOnlyBooleanProperty getPassphraseStoredProperty(String key) { public ReadOnlyBooleanProperty getPassphraseStoredProperty(String key) {
return passphraseStoredProperties.getUnchecked(key); return passphraseStoredProperties.get(key);
} }
private BooleanProperty createStoredPassphraseProperty(String key) { private BooleanProperty createStoredPassphraseProperty(String key) {
@@ -135,4 +137,8 @@ public class KeychainManager implements KeychainAccessProvider {
} }
} }
public ObjectExpression<KeychainAccessProvider> getKeychainImplementation() {
return this.keychain;
}
} }
@@ -0,0 +1,144 @@
package org.cryptomator.common.locationpresets;
import org.cryptomator.integrations.common.CheckAvailability;
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.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.function.Predicate;
import java.util.regex.Pattern;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
import static org.cryptomator.integrations.common.OperatingSystem.Value.MAC;
@OperatingSystem(MAC)
@CheckAvailability
public final class GoogleDriveMacLocationPresetsProvider implements LocationPresetsProvider {
private static final Path ROOT_LOCATION = LocationPresetsProvider.resolveLocation("~/Library/CloudStorage/").toAbsolutePath();
private static final Predicate<String> PATTERN = Pattern.compile("^GoogleDrive-[^/]+$").asMatchPredicate();
private static final List<Path> FALLBACK_LOCATIONS = List.of( //
LocationPresetsProvider.resolveLocation("~/GoogleDrive/My Drive"), //
LocationPresetsProvider.resolveLocation("~/Google Drive/My Drive"), //
LocationPresetsProvider.resolveLocation("~/GoogleDrive"), //
LocationPresetsProvider.resolveLocation("~/Google Drive") //
);
@Override
public Stream<LocationPreset> getLocations() {
List<LocationPreset> cloudStorageDirLocations = getCloudStorageDirLocations();
return cloudStorageDirLocations.isEmpty() ? getFallbackLocation().stream() : cloudStorageDirLocations.stream();
}
@CheckAvailability
public static boolean isPresent() {
return isRootLocationPresent() || FALLBACK_LOCATIONS.stream().anyMatch(Files::isDirectory);
}
/**
* Checks if a root location directory is present that matches the specified pattern.
* <p>
* This method scans the {@code ROOT_LOCATION} directory for subdirectories and tests each one against a pre-defined pattern ({@code PATTERN}).
*
* @return {@code true} if a matching root location is present, otherwise {@code false}.
*/
public static boolean isRootLocationPresent() {
try (var dirStream = Files.list(ROOT_LOCATION)) {
return dirStream.anyMatch(path -> Files.isDirectory(path) && PATTERN.test(path.getFileName().toString()));
} catch (IOException | UncheckedIOException e) {
return false;
}
}
/**
* Returns Google Drive preset String.
*
* @param accountPath The path to the Google Drive account directory (e.g. {@code ~/Library/CloudStorage/GoogleDrive-username})
* @return {@code String}. For example: "Google Drive - username"
*/
private String getDriveLocationString(Path accountPath) {
String accountName = accountPath.getFileName().toString().replace("GoogleDrive-", "");
return "Google Drive - " + accountName;
}
/**
* Retrieves a list of cloud storage directory locations based on the {@code ROOT_LOCATION}.
* <p>
* This method lists all directories in the {@code ROOT_LOCATION}, filters them based on whether their names match
* a predefined pattern ({@code PATTERN}), and then extracts presets using {@code getPresetsFromAccountPath(Path)}.
* <p>
*
* @return a list of {@code LocationPreset} objects representing valid cloud storage directory locations.
*/
private List<LocationPreset> getCloudStorageDirLocations() {
try (var dirStream = Files.list(ROOT_LOCATION)) {
return dirStream.filter(path -> Files.isDirectory(path) && PATTERN.test(path.getFileName().toString()))
.flatMap(this::getPresetsFromAccountPath)
.toList();
} catch (IOException | UncheckedIOException e) {
return List.of();
}
}
/**
* Retrieves a stream of {@code LocationPreset} objects from a given Google Drive account path.
* <p>
* This method lists all directories within the provided {@code accountPath} and filters them
* to identify folders whose names match any of the translations defined in {@code MY_DRIVE_TRANSLATIONS}.
*
* @param accountPath the root path of the Google Drive account to scan.
* @return a stream of {@code LocationPreset} objects representing matching directories.
*/
private Stream<LocationPreset> getPresetsFromAccountPath(Path accountPath) {
try (var driveStream = Files.list(accountPath)) {
return driveStream
.filter(preset -> MY_DRIVE_TRANSLATIONS
.contains(preset.getFileName().toString()))
.map(drivePath -> new LocationPreset(
getDriveLocationString(accountPath),
drivePath
)).toList().stream();
} catch (IOException e) {
return Stream.empty();
}
}
/**
* Returns a list containing a fallback location preset for Google Drive.
* <p>
* This method iterates through the predefined fallback locations, checks if any of them is a directory,
* and creates a {@code LocationPreset} object for the first matching directory found.
*
* @return a list containing a single fallback location preset if a valid directory is found, otherwise an empty list.
* @deprecated This method is intended for legacy support and may be removed in future releases.
*/
@Deprecated
private List<LocationPreset> getFallbackLocation() {
return FALLBACK_LOCATIONS.stream()
.filter(Files::isDirectory)
.map(location -> new LocationPreset("Google Drive", location))
.findFirst()
.stream()
.toList();
}
/**
* Set of translations for "My Drive" in various languages.
* <p>
* This constant is used to identify different language-specific labels for "My Drive" in Google Drive.
* <p>
* The translations were originally extracted from the Chromium projects Chrome OS translation files.
* <p>
* Source: `ui/chromeos/translations` directory in the Chromium repository.
*/
private static final Set<String> MY_DRIVE_TRANSLATIONS = Set.of("My Drive", "የእኔ Drive", "ملفاتي", "মোৰ ড্ৰাইভ", "Diskim", "Мой Дыск", "Моят диск", "আমার ড্রাইভ", "Moj disk", "La meva unitat", "Můj disk", "Mit drev", "Meine Ablage", "Το Drive μου", "Mi unidad", "Minu ketas", "Nire unitatea", "Aking Drive", "Oma Drive", "Mon disque", "Mon Drive", "A miña unidade", "મારી ડ્રાઇવ", "मेरी ड्राइव", "Saját meghajtó", "Իմ դրայվը", "Drive Saya", "Drifið mitt", "I miei file", "האחסון שלי", "マイドライブ", "ჩემი Drive", "Менің Drive дискім", "ដ្រាយរបស់ខ្ញុំ", "ನನ್ನ ಡ್ರೈವ್", "내 드라이브", "Менин Drive'ым", "Mano Diskas", "Mans disks", "Мојот Drive", "എന്റെ ഡ്രൈവ്", "Миний Драйв", "माझा ड्राइव्ह", "मेरो ड्राइभ", "Mijn Drive", "Min disk", "ମୋ ଡ୍ରାଇଭ୍", "Mój dysk", "Meu Drive", "O meu disco", "Contul meu Drive", "Мой диск", "මගේ Drive", "Môj disk", "Disku im", "Мој диск", "Min enhet", "Hifadhi Yangu", "எனது இயக்ககம்", "నా డ్రైవ్‌", "ไดรฟ์ของฉัน", "Drive'ım", "Мій диск", "میری ڈرائیو", "Drive của tôi", "我的云端硬盘", "我的雲端硬碟", "IDrayivu yami");
}
@@ -9,13 +9,11 @@ import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.stream.Stream; import java.util.stream.Stream;
import static org.cryptomator.integrations.common.OperatingSystem.Value.MAC;
import static org.cryptomator.integrations.common.OperatingSystem.Value.WINDOWS; import static org.cryptomator.integrations.common.OperatingSystem.Value.WINDOWS;
@OperatingSystem(WINDOWS) @OperatingSystem(WINDOWS)
@OperatingSystem(MAC)
@CheckAvailability @CheckAvailability
public final class GoogleDriveLocationPresetsProvider implements LocationPresetsProvider { public final class GoogleDriveWindowsLocationPresetsProvider implements LocationPresetsProvider {
private static final List<Path> LOCATIONS = Arrays.asList( // private static final List<Path> LOCATIONS = Arrays.asList( //
LocationPresetsProvider.resolveLocation("~/GoogleDrive/My Drive"), // LocationPresetsProvider.resolveLocation("~/GoogleDrive/My Drive"), //
@@ -37,5 +35,4 @@ public final class GoogleDriveLocationPresetsProvider implements LocationPresets
.findFirst() // .findFirst() //
.stream(); .stream();
} }
} }
@@ -62,7 +62,7 @@ public final class OneDriveWindowsLocationPresetsProvider implements LocationPre
ProcessBuilder command = new ProcessBuilder(args); ProcessBuilder command = new ProcessBuilder(args);
Process p = command.start(); Process p = command.start();
waitForSuccess(p, 3, "`reg query`"); waitForSuccess(p, 3, "`reg query`");
return p.inputReader(StandardCharsets.UTF_8).lines().filter(outputFilter); return p.inputReader(StandardCharsets.ISO_8859_1).lines().filter(outputFilter);
} }
@@ -1,6 +0,0 @@
package org.cryptomator.common.mount;
import org.cryptomator.integrations.mount.MountService;
public record ActualMountService(MountService service, boolean isDesired) {
}
@@ -0,0 +1,14 @@
package org.cryptomator.common.mount;
import org.cryptomator.integrations.mount.MountFailedException;
/**
* Thrown by {@link Mounter} to indicate that the selected mount service can not be used
* due to incompatibilities with a different mount service that is already in use.
*/
public class ConflictingMountServiceException extends MountFailedException {
public ConflictingMountServiceException(String msg) {
super(msg);
}
}
@@ -4,21 +4,18 @@ import dagger.Module;
import dagger.Provides; import dagger.Provides;
import org.cryptomator.common.ObservableUtil; import org.cryptomator.common.ObservableUtil;
import org.cryptomator.common.settings.Settings; import org.cryptomator.common.settings.Settings;
import org.cryptomator.integrations.mount.Mount;
import org.cryptomator.integrations.mount.MountService; import org.cryptomator.integrations.mount.MountService;
import javax.inject.Named; import javax.inject.Named;
import javax.inject.Singleton; import javax.inject.Singleton;
import javafx.beans.value.ObservableValue; import javafx.beans.value.ObservableValue;
import java.util.List; import java.util.List;
import java.util.concurrent.atomic.AtomicReference; import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
@Module @Module
public class MountModule { public class MountModule {
private static final AtomicReference<MountService> formerSelectedMountService = new AtomicReference<>(null);
private static final List<String> problematicFuseMountServices = List.of("org.cryptomator.frontend.fuse.mount.MacFuseMountProvider", "org.cryptomator.frontend.fuse.mount.FuseTMountProvider");
@Provides @Provides
@Singleton @Singleton
static List<MountService> provideSupportedMountServices() { static List<MountService> provideSupportedMountServices() {
@@ -27,46 +24,18 @@ public class MountModule {
@Provides @Provides
@Singleton @Singleton
@Named("FUPFMS") static ObservableValue<MountService> provideDefaultMountService(List<MountService> mountProviders, Settings settings) {
static AtomicReference<MountService> provideFirstUsedProblematicFuseMountService() { var fallbackProvider = mountProviders.stream().findFirst().get(); //there should always be a mount provider, at least webDAV
return new AtomicReference<>(null); return ObservableUtil.mapWithDefault(settings.mountService, //
serviceName -> mountProviders.stream().filter(s -> s.getClass().getName().equals(serviceName)).findFirst().orElse(fallbackProvider), //
fallbackProvider);
} }
@Provides @Provides
@Singleton @Singleton
static ObservableValue<ActualMountService> provideMountService(Settings settings, List<MountService> serviceImpls, @Named("FUPFMS") AtomicReference<MountService> fupfms) { @Named("usedMountServices")
var fallbackProvider = serviceImpls.stream().findFirst().orElse(null); static Set<MountService> provideSetOfUsedMountServices() {
return ConcurrentHashMap.newKeySet();
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());
}
}
@@ -1,6 +1,7 @@
package org.cryptomator.common.mount; package org.cryptomator.common.mount;
import org.apache.commons.lang3.SystemUtils; import org.apache.commons.lang3.SystemUtils;
import org.jetbrains.annotations.VisibleForTesting;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -66,7 +67,7 @@ public final class MountWithinParentUtil {
} }
} }
//visible for testing @VisibleForTesting
static MountPointState getMountPointState(Path path) throws IOException, IllegalMountPointException { static MountPointState getMountPointState(Path path) throws IOException, IllegalMountPointException {
if (Files.notExists(path, LinkOption.NOFOLLOW_LINKS)) { if (Files.notExists(path, LinkOption.NOFOLLOW_LINKS)) {
return MountPointState.NOT_EXISTING; return MountPointState.NOT_EXISTING;
@@ -82,7 +83,7 @@ public final class MountWithinParentUtil {
return MountPointState.BROKEN_JUNCTION; return MountPointState.BROKEN_JUNCTION;
} }
//visible for testing @VisibleForTesting
enum MountPointState { enum MountPointState {
NOT_EXISTING, NOT_EXISTING,
@@ -93,7 +94,7 @@ public final class MountWithinParentUtil {
} }
//visible for testing @VisibleForTesting
static void removeResidualHideaway(Path mountPoint, Path hideaway) throws IOException { static void removeResidualHideaway(Path mountPoint, Path hideaway) throws IOException {
checkIsHideawayDirectory(mountPoint, hideaway); checkIsHideawayDirectory(mountPoint, hideaway);
Files.delete(hideaway); //Fails if not empty Files.delete(hideaway); //Fails if not empty
@@ -155,7 +156,7 @@ public final class MountWithinParentUtil {
} }
} }
//visible for testing @VisibleForTesting
static Path getHideaway(Path mountPoint) { static Path getHideaway(Path mountPoint) {
return mountPoint.resolveSibling(HIDEAWAY_PREFIX + mountPoint.getFileName().toString() + HIDEAWAY_SUFFIX); return mountPoint.resolveSibling(HIDEAWAY_PREFIX + mountPoint.getFileName().toString() + HIDEAWAY_SUFFIX);
} }
@@ -7,13 +7,19 @@ import org.cryptomator.integrations.mount.Mount;
import org.cryptomator.integrations.mount.MountBuilder; import org.cryptomator.integrations.mount.MountBuilder;
import org.cryptomator.integrations.mount.MountFailedException; import org.cryptomator.integrations.mount.MountFailedException;
import org.cryptomator.integrations.mount.MountService; import org.cryptomator.integrations.mount.MountService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton; import javax.inject.Singleton;
import javafx.beans.value.ObservableValue; import javafx.beans.value.ObservableValue;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.List;
import java.util.Map;
import java.util.Set;
import static org.cryptomator.integrations.mount.MountCapability.MOUNT_AS_DRIVE_LETTER; 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_EXISTING_DIR;
@@ -24,24 +30,41 @@ import static org.cryptomator.integrations.mount.MountCapability.UNMOUNT_FORCED;
@Singleton @Singleton
public class Mounter { public class Mounter {
private final Settings settings; private static final Logger LOG = LoggerFactory.getLogger(Mounter.class);
// mount providers (key) can not be used if any of the conflicting mount providers (values) are already in use
private static final Map<String, Set<String>> CONFLICTING_MOUNT_SERVICES = Map.of(
"org.cryptomator.frontend.fuse.mount.MacFuseMountProvider", Set.of("org.cryptomator.frontend.fuse.mount.FuseTMountProvider"),
"org.cryptomator.frontend.fuse.mount.FuseTMountProvider", Set.of("org.cryptomator.frontend.fuse.mount.MacFuseMountProvider")
);
private final Environment env; private final Environment env;
private final Settings settings;
private final WindowsDriveLetters driveLetters; private final WindowsDriveLetters driveLetters;
private final ObservableValue<ActualMountService> mountServiceObservable; private final List<MountService> mountProviders;
private final Set<MountService> usedMountServices;
private final ObservableValue<MountService> defaultMountService;
@Inject @Inject
public Mounter(Settings settings, Environment env, WindowsDriveLetters driveLetters, ObservableValue<ActualMountService> mountServiceObservable) { public Mounter(Environment env, //
this.settings = settings; Settings settings, //
WindowsDriveLetters driveLetters, //
List<MountService> mountProviders, //
@Named("usedMountServices") Set<MountService> usedMountServices, //
ObservableValue<MountService> defaultMountService) {
this.env = env; this.env = env;
this.settings = settings;
this.driveLetters = driveLetters; this.driveLetters = driveLetters;
this.mountServiceObservable = mountServiceObservable; this.mountProviders = mountProviders;
this.usedMountServices = usedMountServices;
this.defaultMountService = defaultMountService;
} }
private class SettledMounter { private class SettledMounter {
private MountService service; private final MountService service;
private MountBuilder builder; private final MountBuilder builder;
private VaultSettings vaultSettings; private final VaultSettings vaultSettings;
public SettledMounter(MountService service, MountBuilder builder, VaultSettings vaultSettings) { public SettledMounter(MountService service, MountBuilder builder, VaultSettings vaultSettings) {
this.service = service; this.service = service;
@@ -53,8 +76,13 @@ public class Mounter {
for (var capability : service.capabilities()) { for (var capability : service.capabilities()) {
switch (capability) { switch (capability) {
case FILE_SYSTEM_NAME -> builder.setFileSystemName("cryptoFs"); case FILE_SYSTEM_NAME -> builder.setFileSystemName("cryptoFs");
case LOOPBACK_PORT -> 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) if (vaultSettings.mountService.getValue() == null) {
builder.setLoopbackPort(settings.port.get());
} else {
builder.setLoopbackPort(vaultSettings.port.get());
}
}
case LOOPBACK_HOST_NAME -> env.getLoopbackAlias().ifPresent(builder::setLoopbackHostName); case LOOPBACK_HOST_NAME -> env.getLoopbackAlias().ifPresent(builder::setLoopbackHostName);
case READ_ONLY -> builder.setReadOnly(vaultSettings.usesReadOnlyMode.get()); case READ_ONLY -> builder.setReadOnly(vaultSettings.usesReadOnlyMode.get());
case MOUNT_FLAGS -> { case MOUNT_FLAGS -> {
@@ -103,9 +131,7 @@ public class Mounter {
} }
} else if (canMountToParent && !canMountToDir) { } else if (canMountToParent && !canMountToDir) {
MountWithinParentUtil.prepareParentNoMountPoint(userChosenMountPoint); MountWithinParentUtil.prepareParentNoMountPoint(userChosenMountPoint);
cleanup = () -> { cleanup = () -> MountWithinParentUtil.cleanup(userChosenMountPoint);
MountWithinParentUtil.cleanup(userChosenMountPoint);
};
} }
try { try {
builder.setMountpoint(userChosenMountPoint); builder.setMountpoint(userChosenMountPoint);
@@ -131,13 +157,26 @@ public class Mounter {
} }
public MountHandle mount(VaultSettings vaultSettings, Path cryptoFsRoot) throws IOException, MountFailedException { public MountHandle mount(VaultSettings vaultSettings, Path cryptoFsRoot) throws IOException, MountFailedException {
var mountService = this.mountServiceObservable.getValue().service(); var mountService = mountProviders.stream().filter(s -> s.getClass().getName().equals(vaultSettings.mountService.getValue())).findFirst().orElse(defaultMountService.getValue());
if (isConflictingMountService(mountService)) {
var msg = mountService.getClass() + " unavailable due to conflict with either of " + CONFLICTING_MOUNT_SERVICES.get(mountService.getClass().getName());
throw new ConflictingMountServiceException(msg);
}
usedMountServices.add(mountService);
var builder = mountService.forFileSystem(cryptoFsRoot); var builder = mountService.forFileSystem(cryptoFsRoot);
var internal = new SettledMounter(mountService, builder, vaultSettings); var internal = new SettledMounter(mountService, builder, vaultSettings); // FIXME: no need for an inner class
var cleanup = internal.prepare(); var cleanup = internal.prepare();
return new MountHandle(builder.mount(), mountService.hasCapability(UNMOUNT_FORCED), cleanup); return new MountHandle(builder.mount(), mountService.hasCapability(UNMOUNT_FORCED), cleanup);
} }
public boolean isConflictingMountService(MountService service) {
var conflictingServices = CONFLICTING_MOUNT_SERVICES.getOrDefault(service.getClass().getName(), Set.of());
return usedMountServices.stream().map(MountService::getClass).map(Class::getName).anyMatch(conflictingServices::contains);
}
public record MountHandle(Mount mountObj, boolean supportsUnmountForced, Runnable specialCleanup) { public record MountHandle(Mount mountObj, boolean supportsUnmountForced, Runnable specialCleanup) {
} }
@@ -25,30 +25,33 @@ import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections; import javafx.collections.FXCollections;
import javafx.collections.ObservableList; import javafx.collections.ObservableList;
import javafx.geometry.NodeOrientation; import javafx.geometry.NodeOrientation;
import java.time.Instant;
import java.util.function.Consumer; import java.util.function.Consumer;
public class Settings { public class Settings {
private static final Logger LOG = LoggerFactory.getLogger(Settings.class); 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_CHECK_FOR_UPDATES = false;
static final boolean DEFAULT_START_HIDDEN = false; static final boolean DEFAULT_START_HIDDEN = false;
static final boolean DEFAULT_AUTO_CLOSE_VAULTS = false; static final boolean DEFAULT_AUTO_CLOSE_VAULTS = false;
static final boolean DEFAULT_USE_KEYCHAIN = true; static final boolean DEFAULT_USE_KEYCHAIN = true;
static final boolean DEFAULT_USE_QUICKACCESS = true;
static final int DEFAULT_PORT = 42427; static final int DEFAULT_PORT = 42427;
static final int DEFAULT_NUM_TRAY_NOTIFICATIONS = 3; static final int DEFAULT_NUM_TRAY_NOTIFICATIONS = 3;
static final boolean DEFAULT_DEBUG_MODE = false; static final boolean DEFAULT_DEBUG_MODE = false;
static final UiTheme DEFAULT_THEME = UiTheme.LIGHT; static final UiTheme DEFAULT_THEME = UiTheme.LIGHT;
@Deprecated // to be changed to "whatever is available" eventually @Deprecated // to be changed to "whatever is available" eventually
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_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_QUICKACCESS_SERVICE = SystemUtils.IS_OS_WINDOWS ? "org.cryptomator.windows.quickaccess.ExplorerQuickAccessService" : //
SystemUtils.IS_OS_LINUX ? "org.cryptomator.linux.quickaccess.NautilusBookmarks" : null;
static final String DEFAULT_USER_INTERFACE_ORIENTATION = NodeOrientation.LEFT_TO_RIGHT.name(); static final String DEFAULT_USER_INTERFACE_ORIENTATION = NodeOrientation.LEFT_TO_RIGHT.name();
static final boolean DEFAULT_SHOW_MINIMIZE_BUTTON = false; public static final Instant DEFAULT_TIMESTAMP = Instant.parse("2000-01-01T00:00:00Z");
static final String DEFAULT_LAST_UPDATE_CHECK = "2000-01-01";
public final ObservableList<VaultSettings> directories; public final ObservableList<VaultSettings> directories;
public final BooleanProperty askedForUpdateCheck;
public final BooleanProperty checkForUpdates;
public final BooleanProperty startHidden; public final BooleanProperty startHidden;
public final BooleanProperty autoCloseVaults; public final BooleanProperty autoCloseVaults;
public final BooleanProperty useKeychain; public final BooleanProperty useKeychain;
@@ -57,17 +60,21 @@ public class Settings {
public final BooleanProperty debugMode; public final BooleanProperty debugMode;
public final ObjectProperty<UiTheme> theme; public final ObjectProperty<UiTheme> theme;
public final StringProperty keychainProvider; public final StringProperty keychainProvider;
public final BooleanProperty useQuickAccess;
public final StringProperty quickAccessService;
public final ObjectProperty<NodeOrientation> userInterfaceOrientation; public final ObjectProperty<NodeOrientation> userInterfaceOrientation;
public final StringProperty licenseKey; public final StringProperty licenseKey;
public final BooleanProperty showMinimizeButton;
public final BooleanProperty showTrayIcon; public final BooleanProperty showTrayIcon;
public final BooleanProperty compactMode;
public final IntegerProperty windowXPosition; public final IntegerProperty windowXPosition;
public final IntegerProperty windowYPosition; public final IntegerProperty windowYPosition;
public final IntegerProperty windowWidth; public final IntegerProperty windowWidth;
public final IntegerProperty windowHeight; public final IntegerProperty windowHeight;
public final StringProperty language; public final StringProperty language;
public final StringProperty mountService; public final StringProperty mountService;
public final StringProperty lastUpdateCheck; public final BooleanProperty checkForUpdates;
public final ObjectProperty<Instant> lastUpdateCheckReminder;
public final ObjectProperty<Instant> lastSuccessfulUpdateCheck;
private Consumer<Settings> saveCmd; private Consumer<Settings> saveCmd;
@@ -84,11 +91,10 @@ public class Settings {
*/ */
Settings(SettingsJson json) { Settings(SettingsJson json) {
this.directories = FXCollections.observableArrayList(VaultSettings::observables); 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.startHidden = new SimpleBooleanProperty(this, "startHidden", json.startHidden);
this.autoCloseVaults = new SimpleBooleanProperty(this, "autoCloseVaults", json.autoCloseVaults); this.autoCloseVaults = new SimpleBooleanProperty(this, "autoCloseVaults", json.autoCloseVaults);
this.useKeychain = new SimpleBooleanProperty(this, "useKeychain", json.useKeychain); this.useKeychain = new SimpleBooleanProperty(this, "useKeychain", json.useKeychain);
this.useQuickAccess = new SimpleBooleanProperty(this, "addToQuickAccess", json.useQuickAccess);
this.port = new SimpleIntegerProperty(this, "webDavPort", json.port); this.port = new SimpleIntegerProperty(this, "webDavPort", json.port);
this.numTrayNotifications = new SimpleIntegerProperty(this, "numTrayNotifications", json.numTrayNotifications); this.numTrayNotifications = new SimpleIntegerProperty(this, "numTrayNotifications", json.numTrayNotifications);
this.debugMode = new SimpleBooleanProperty(this, "debugMode", json.debugMode); this.debugMode = new SimpleBooleanProperty(this, "debugMode", json.debugMode);
@@ -96,26 +102,28 @@ public class Settings {
this.keychainProvider = new SimpleStringProperty(this, "keychainProvider", json.keychainProvider); this.keychainProvider = new SimpleStringProperty(this, "keychainProvider", json.keychainProvider);
this.userInterfaceOrientation = new SimpleObjectProperty<>(this, "userInterfaceOrientation", parseEnum(json.uiOrientation, NodeOrientation.class, NodeOrientation.LEFT_TO_RIGHT)); this.userInterfaceOrientation = new SimpleObjectProperty<>(this, "userInterfaceOrientation", parseEnum(json.uiOrientation, NodeOrientation.class, NodeOrientation.LEFT_TO_RIGHT));
this.licenseKey = new SimpleStringProperty(this, "licenseKey", json.licenseKey); 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.showTrayIcon = new SimpleBooleanProperty(this, "showTrayIcon", json.showTrayIcon);
this.compactMode = new SimpleBooleanProperty(this, "compactMode", json.compactMode);
this.windowXPosition = new SimpleIntegerProperty(this, "windowXPosition", json.windowXPosition); this.windowXPosition = new SimpleIntegerProperty(this, "windowXPosition", json.windowXPosition);
this.windowYPosition = new SimpleIntegerProperty(this, "windowYPosition", json.windowYPosition); this.windowYPosition = new SimpleIntegerProperty(this, "windowYPosition", json.windowYPosition);
this.windowWidth = new SimpleIntegerProperty(this, "windowWidth", json.windowWidth); this.windowWidth = new SimpleIntegerProperty(this, "windowWidth", json.windowWidth);
this.windowHeight = new SimpleIntegerProperty(this, "windowHeight", json.windowHeight); this.windowHeight = new SimpleIntegerProperty(this, "windowHeight", json.windowHeight);
this.language = new SimpleStringProperty(this, "language", json.language); this.language = new SimpleStringProperty(this, "language", json.language);
this.mountService = new SimpleStringProperty(this, "mountService", json.mountService); this.mountService = new SimpleStringProperty(this, "mountService", json.mountService);
this.lastUpdateCheck = new SimpleStringProperty(this, "lastUpdateCheck", json.lastUpdateCheck); this.quickAccessService = new SimpleStringProperty(this, "quickAccessService", json.quickAccessService);
this.checkForUpdates = new SimpleBooleanProperty(this, "checkForUpdates", json.checkForUpdatesEnabled);
this.lastUpdateCheckReminder = new SimpleObjectProperty<>(this, "lastUpdateCheckReminder", json.lastReminderForUpdateCheck);
this.lastSuccessfulUpdateCheck = new SimpleObjectProperty<>(this, "lastSuccessfulUpdateCheck", json.lastSuccessfulUpdateCheck);
this.directories.addAll(json.directories.stream().map(VaultSettings::new).toList()); this.directories.addAll(json.directories.stream().map(VaultSettings::new).toList());
migrateLegacySettings(json); migrateLegacySettings(json);
directories.addListener(this::somethingChanged); directories.addListener(this::somethingChanged);
askedForUpdateCheck.addListener(this::somethingChanged);
checkForUpdates.addListener(this::somethingChanged);
startHidden.addListener(this::somethingChanged); startHidden.addListener(this::somethingChanged);
autoCloseVaults.addListener(this::somethingChanged); autoCloseVaults.addListener(this::somethingChanged);
useKeychain.addListener(this::somethingChanged); useKeychain.addListener(this::somethingChanged);
useQuickAccess.addListener(this::somethingChanged);
port.addListener(this::somethingChanged); port.addListener(this::somethingChanged);
numTrayNotifications.addListener(this::somethingChanged); numTrayNotifications.addListener(this::somethingChanged);
debugMode.addListener(this::somethingChanged); debugMode.addListener(this::somethingChanged);
@@ -123,15 +131,18 @@ public class Settings {
keychainProvider.addListener(this::somethingChanged); keychainProvider.addListener(this::somethingChanged);
userInterfaceOrientation.addListener(this::somethingChanged); userInterfaceOrientation.addListener(this::somethingChanged);
licenseKey.addListener(this::somethingChanged); licenseKey.addListener(this::somethingChanged);
showMinimizeButton.addListener(this::somethingChanged);
showTrayIcon.addListener(this::somethingChanged); showTrayIcon.addListener(this::somethingChanged);
compactMode.addListener(this::somethingChanged);
windowXPosition.addListener(this::somethingChanged); windowXPosition.addListener(this::somethingChanged);
windowYPosition.addListener(this::somethingChanged); windowYPosition.addListener(this::somethingChanged);
windowWidth.addListener(this::somethingChanged); windowWidth.addListener(this::somethingChanged);
windowHeight.addListener(this::somethingChanged); windowHeight.addListener(this::somethingChanged);
language.addListener(this::somethingChanged); language.addListener(this::somethingChanged);
mountService.addListener(this::somethingChanged); mountService.addListener(this::somethingChanged);
lastUpdateCheck.addListener(this::somethingChanged); quickAccessService.addListener(this::somethingChanged);
checkForUpdates.addListener(this::somethingChanged);
lastUpdateCheckReminder.addListener(this::somethingChanged);
lastSuccessfulUpdateCheck.addListener(this::somethingChanged);
} }
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
@@ -165,11 +176,10 @@ public class Settings {
SettingsJson serialized() { SettingsJson serialized() {
var json = new SettingsJson(); var json = new SettingsJson();
json.directories = directories.stream().map(VaultSettings::serialized).toList(); json.directories = directories.stream().map(VaultSettings::serialized).toList();
json.askedForUpdateCheck = askedForUpdateCheck.get();
json.checkForUpdatesEnabled = checkForUpdates.get();
json.startHidden = startHidden.get(); json.startHidden = startHidden.get();
json.autoCloseVaults = autoCloseVaults.get(); json.autoCloseVaults = autoCloseVaults.get();
json.useKeychain = useKeychain.get(); json.useKeychain = useKeychain.get();
json.useQuickAccess = useQuickAccess.get();
json.port = port.get(); json.port = port.get();
json.numTrayNotifications = numTrayNotifications.get(); json.numTrayNotifications = numTrayNotifications.get();
json.debugMode = debugMode.get(); json.debugMode = debugMode.get();
@@ -177,15 +187,18 @@ public class Settings {
json.keychainProvider = keychainProvider.get(); json.keychainProvider = keychainProvider.get();
json.uiOrientation = userInterfaceOrientation.get().name(); json.uiOrientation = userInterfaceOrientation.get().name();
json.licenseKey = licenseKey.get(); json.licenseKey = licenseKey.get();
json.showMinimizeButton = showMinimizeButton.get();
json.showTrayIcon = showTrayIcon.get(); json.showTrayIcon = showTrayIcon.get();
json.compactMode = compactMode.get();
json.windowXPosition = windowXPosition.get(); json.windowXPosition = windowXPosition.get();
json.windowYPosition = windowYPosition.get(); json.windowYPosition = windowYPosition.get();
json.windowWidth = windowWidth.get(); json.windowWidth = windowWidth.get();
json.windowHeight = windowHeight.get(); json.windowHeight = windowHeight.get();
json.language = language.get(); json.language = language.get();
json.mountService = mountService.get(); json.mountService = mountService.get();
json.lastUpdateCheck = lastUpdateCheck.get(); json.quickAccessService = quickAccessService.get();
json.checkForUpdatesEnabled = checkForUpdates.get();
json.lastReminderForUpdateCheck = lastUpdateCheckReminder.get();
json.lastSuccessfulUpdateCheck = lastSuccessfulUpdateCheck.get();
return json; return json;
} }
@@ -1,9 +1,11 @@
package org.cryptomator.common.settings; package org.cryptomator.common.settings;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import java.time.Instant;
import java.util.List; import java.util.List;
@JsonIgnoreProperties(ignoreUnknown = true) @JsonIgnoreProperties(ignoreUnknown = true)
@@ -16,15 +18,9 @@ class SettingsJson {
@JsonProperty("writtenByVersion") @JsonProperty("writtenByVersion")
String writtenByVersion; String writtenByVersion;
@JsonProperty("askedForUpdateCheck")
boolean askedForUpdateCheck = Settings.DEFAULT_ASKED_FOR_UPDATE_CHECK;
@JsonProperty("autoCloseVaults") @JsonProperty("autoCloseVaults")
boolean autoCloseVaults = Settings.DEFAULT_AUTO_CLOSE_VAULTS; boolean autoCloseVaults = Settings.DEFAULT_AUTO_CLOSE_VAULTS;
@JsonProperty("checkForUpdatesEnabled")
boolean checkForUpdatesEnabled = Settings.DEFAULT_CHECK_FOR_UPDATES;
@JsonProperty("debugMode") @JsonProperty("debugMode")
boolean debugMode = Settings.DEFAULT_DEBUG_MODE; boolean debugMode = Settings.DEFAULT_DEBUG_MODE;
@@ -49,12 +45,12 @@ class SettingsJson {
@JsonProperty("port") @JsonProperty("port")
int port = Settings.DEFAULT_PORT; int port = Settings.DEFAULT_PORT;
@JsonProperty("showMinimizeButton")
boolean showMinimizeButton = Settings.DEFAULT_SHOW_MINIMIZE_BUTTON;
@JsonProperty("showTrayIcon") @JsonProperty("showTrayIcon")
boolean showTrayIcon; boolean showTrayIcon;
@JsonProperty("compactMode")
boolean compactMode;
@JsonProperty("startHidden") @JsonProperty("startHidden")
boolean startHidden = Settings.DEFAULT_START_HIDDEN; boolean startHidden = Settings.DEFAULT_START_HIDDEN;
@@ -80,7 +76,20 @@ class SettingsJson {
@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 @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; String preferredVolumeImpl;
@JsonProperty("lastUpdateCheck") @JsonProperty("checkForUpdatesEnabled")
String lastUpdateCheck = Settings.DEFAULT_LAST_UPDATE_CHECK; boolean checkForUpdatesEnabled = Settings.DEFAULT_CHECK_FOR_UPDATES;
@JsonProperty("lastReminderForUpdateCheck")
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss'Z'", timezone = "UTC")
Instant lastReminderForUpdateCheck = Settings.DEFAULT_TIMESTAMP;
@JsonProperty("lastSuccessfulUpdateCheck")
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss'Z'", timezone = "UTC")
Instant lastSuccessfulUpdateCheck = Settings.DEFAULT_TIMESTAMP;
@JsonProperty("useQuickAccess")
boolean useQuickAccess = Settings.DEFAULT_USE_QUICKACCESS;
@JsonProperty("quickAccessService")
String quickAccessService = Settings.DEFAULT_QUICKACCESS_SERVICE;
} }
@@ -10,6 +10,7 @@ package org.cryptomator.common.settings;
import com.fasterxml.jackson.core.JacksonException; import com.fasterxml.jackson.core.JacksonException;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.google.common.base.Suppliers; import com.google.common.base.Suppliers;
import org.cryptomator.common.Environment; import org.cryptomator.common.Environment;
import org.slf4j.Logger; import org.slf4j.Logger;
@@ -36,7 +37,7 @@ import java.util.stream.Stream;
@Singleton @Singleton
public class SettingsProvider implements Supplier<Settings> { public class SettingsProvider implements Supplier<Settings> {
private static final ObjectMapper JSON = new ObjectMapper().setDefaultLeniency(true); private static final ObjectMapper JSON = new ObjectMapper().setDefaultLeniency(true).registerModule(new JavaTimeModule());
private static final Logger LOG = LoggerFactory.getLogger(SettingsProvider.class); private static final Logger LOG = LoggerFactory.getLogger(SettingsProvider.class);
private static final long SAVE_DELAY_MS = 1000; private static final long SAVE_DELAY_MS = 1000;
@@ -57,7 +58,10 @@ public class SettingsProvider implements Supplier<Settings> {
} }
private Settings load() { private Settings load() {
Settings settings = env.getSettingsPath().flatMap(this::tryLoad).findFirst().orElseGet(() -> Settings.create(env)); Settings settings = env.getSettingsPath() //
.flatMap(this::tryLoad) //
.findFirst() //
.orElseGet(() -> Settings.create(env));
settings.setSaveCmd(this::scheduleSave); settings.setSaveCmd(this::scheduleSave);
return settings; return settings;
} }
@@ -8,7 +8,7 @@ package org.cryptomator.common.settings;
import com.google.common.base.CharMatcher; import com.google.common.base.CharMatcher;
import com.google.common.base.Strings; import com.google.common.base.Strings;
import com.google.common.io.BaseEncoding; import com.google.common.io.BaseEncoding;
import org.apache.commons.lang3.SystemUtils; import org.jetbrains.annotations.VisibleForTesting;
import javafx.beans.Observable; import javafx.beans.Observable;
import javafx.beans.binding.Bindings; import javafx.beans.binding.Bindings;
@@ -39,6 +39,7 @@ public class VaultSettings {
static final WhenUnlocked DEFAULT_ACTION_AFTER_UNLOCK = WhenUnlocked.ASK; static final WhenUnlocked DEFAULT_ACTION_AFTER_UNLOCK = WhenUnlocked.ASK;
static final boolean DEFAULT_AUTOLOCK_WHEN_IDLE = false; static final boolean DEFAULT_AUTOLOCK_WHEN_IDLE = false;
static final int DEFAULT_AUTOLOCK_IDLE_SECONDS = 30 * 60; static final int DEFAULT_AUTOLOCK_IDLE_SECONDS = 30 * 60;
static final int DEFAULT_PORT = 42427;
private static final Random RNG = new Random(); private static final Random RNG = new Random();
@@ -55,6 +56,8 @@ public class VaultSettings {
public final IntegerProperty autoLockIdleSeconds; public final IntegerProperty autoLockIdleSeconds;
public final ObjectProperty<Path> mountPoint; public final ObjectProperty<Path> mountPoint;
public final StringExpression mountName; public final StringExpression mountName;
public final StringProperty mountService;
public final IntegerProperty port;
VaultSettings(VaultSettingsJson json) { VaultSettings(VaultSettingsJson json) {
this.id = json.id; this.id = json.id;
@@ -69,6 +72,8 @@ public class VaultSettings {
this.autoLockWhenIdle = new SimpleBooleanProperty(this, "autoLockWhenIdle", json.autoLockWhenIdle); this.autoLockWhenIdle = new SimpleBooleanProperty(this, "autoLockWhenIdle", json.autoLockWhenIdle);
this.autoLockIdleSeconds = new SimpleIntegerProperty(this, "autoLockIdleSeconds", json.autoLockIdleSeconds); this.autoLockIdleSeconds = new SimpleIntegerProperty(this, "autoLockIdleSeconds", json.autoLockIdleSeconds);
this.mountPoint = new SimpleObjectProperty<>(this, "mountPoint", json.mountPoint == null ? null : Path.of(json.mountPoint)); this.mountPoint = new SimpleObjectProperty<>(this, "mountPoint", json.mountPoint == null ? null : Path.of(json.mountPoint));
this.mountService = new SimpleStringProperty(this, "mountService", json.mountService);
this.port = new SimpleIntegerProperty(this, "port", json.port);
// mount name is no longer an explicit setting, see https://github.com/cryptomator/cryptomator/pull/1318 // mount name is no longer an explicit setting, see https://github.com/cryptomator/cryptomator/pull/1318
this.mountName = StringExpression.stringExpression(Bindings.createStringBinding(() -> { this.mountName = StringExpression.stringExpression(Bindings.createStringBinding(() -> {
final String name; final String name;
@@ -94,7 +99,7 @@ public class VaultSettings {
} }
Observable[] observables() { Observable[] observables() {
return new Observable[]{actionAfterUnlock, autoLockIdleSeconds, autoLockWhenIdle, displayName, maxCleartextFilenameLength, mountFlags, mountPoint, path, revealAfterMount, unlockAfterStartup, usesReadOnlyMode}; return new Observable[]{actionAfterUnlock, autoLockIdleSeconds, autoLockWhenIdle, displayName, maxCleartextFilenameLength, mountFlags, mountPoint, path, revealAfterMount, unlockAfterStartup, usesReadOnlyMode, port, mountService};
} }
public static VaultSettings withRandomId() { public static VaultSettings withRandomId() {
@@ -123,10 +128,12 @@ public class VaultSettings {
json.autoLockWhenIdle = autoLockWhenIdle.get(); json.autoLockWhenIdle = autoLockWhenIdle.get();
json.autoLockIdleSeconds = autoLockIdleSeconds.get(); json.autoLockIdleSeconds = autoLockIdleSeconds.get();
json.mountPoint = mountPoint.map(Path::toString).getValue(); json.mountPoint = mountPoint.map(Path::toString).getValue();
json.mountService = mountService.get();
json.port = port.get();
return json; return json;
} }
//visible for testing @VisibleForTesting
static String normalizeDisplayName(String original) { static String normalizeDisplayName(String original) {
if (original.isBlank() || ".".equals(original) || "..".equals(original)) { if (original.isBlank() || ".".equals(original) || "..".equals(original)) {
return "_"; return "_";
@@ -45,6 +45,12 @@ class VaultSettingsJson {
@JsonProperty("autoLockIdleSeconds") @JsonProperty("autoLockIdleSeconds")
int autoLockIdleSeconds = VaultSettings.DEFAULT_AUTOLOCK_IDLE_SECONDS; int autoLockIdleSeconds = VaultSettings.DEFAULT_AUTOLOCK_IDLE_SECONDS;
@JsonProperty("mountService")
String mountService;
@JsonProperty("port")
int port = VaultSettings.DEFAULT_PORT;
@Deprecated(since = "1.7.0") @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 @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; String winDriveLetter;
@@ -11,7 +11,7 @@ package org.cryptomator.common.vaults;
import org.apache.commons.lang3.SystemUtils; import org.apache.commons.lang3.SystemUtils;
import org.cryptomator.common.Constants; import org.cryptomator.common.Constants;
import org.cryptomator.common.mount.Mounter; import org.cryptomator.common.mount.Mounter;
import org.cryptomator.common.mount.WindowsDriveLetters; import org.cryptomator.common.settings.Settings;
import org.cryptomator.common.settings.VaultSettings; import org.cryptomator.common.settings.VaultSettings;
import org.cryptomator.cryptofs.CryptoFileSystem; import org.cryptomator.cryptofs.CryptoFileSystem;
import org.cryptomator.cryptofs.CryptoFileSystemProperties; import org.cryptomator.cryptofs.CryptoFileSystemProperties;
@@ -24,6 +24,9 @@ import org.cryptomator.cryptolib.api.MasterkeyLoadingFailedException;
import org.cryptomator.integrations.mount.MountFailedException; import org.cryptomator.integrations.mount.MountFailedException;
import org.cryptomator.integrations.mount.Mountpoint; import org.cryptomator.integrations.mount.Mountpoint;
import org.cryptomator.integrations.mount.UnmountFailedException; import org.cryptomator.integrations.mount.UnmountFailedException;
import org.cryptomator.integrations.quickaccess.QuickAccessService;
import org.cryptomator.integrations.quickaccess.QuickAccessServiceException;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -55,6 +58,7 @@ public class Vault {
private final VaultSettings vaultSettings; private final VaultSettings vaultSettings;
private final AtomicReference<CryptoFileSystem> cryptoFileSystem; private final AtomicReference<CryptoFileSystem> cryptoFileSystem;
private final AtomicReference<QuickAccessService.QuickAccessEntry> quickAccessEntry;
private final VaultState state; private final VaultState state;
private final ObjectProperty<Exception> lastKnownException; private final ObjectProperty<Exception> lastKnownException;
private final VaultConfigCache configCache; private final VaultConfigCache configCache;
@@ -68,12 +72,19 @@ public class Vault {
private final BooleanBinding unknownError; private final BooleanBinding unknownError;
private final ObjectBinding<Mountpoint> mountPoint; private final ObjectBinding<Mountpoint> mountPoint;
private final Mounter mounter; private final Mounter mounter;
private final Settings settings;
private final BooleanProperty showingStats; private final BooleanProperty showingStats;
private final AtomicReference<Mounter.MountHandle> mountHandle = new AtomicReference<>(null); private final AtomicReference<Mounter.MountHandle> mountHandle = new AtomicReference<>(null);
@Inject @Inject
Vault(VaultSettings vaultSettings, VaultConfigCache configCache, AtomicReference<CryptoFileSystem> cryptoFileSystem, VaultState state, @Named("lastKnownException") ObjectProperty<Exception> lastKnownException, VaultStats stats, WindowsDriveLetters windowsDriveLetters, Mounter mounter) { Vault(VaultSettings vaultSettings, //
VaultConfigCache configCache, //
AtomicReference<CryptoFileSystem> cryptoFileSystem, //
VaultState state, //
@Named("lastKnownException") ObjectProperty<Exception> lastKnownException, //
VaultStats stats, //
Mounter mounter, Settings settings) {
this.vaultSettings = vaultSettings; this.vaultSettings = vaultSettings;
this.configCache = configCache; this.configCache = configCache;
this.cryptoFileSystem = cryptoFileSystem; this.cryptoFileSystem = cryptoFileSystem;
@@ -89,7 +100,9 @@ public class Vault {
this.unknownError = Bindings.createBooleanBinding(this::isUnknownError, state); this.unknownError = Bindings.createBooleanBinding(this::isUnknownError, state);
this.mountPoint = Bindings.createObjectBinding(this::getMountPoint, state); this.mountPoint = Bindings.createObjectBinding(this::getMountPoint, state);
this.mounter = mounter; this.mounter = mounter;
this.settings = settings;
this.showingStats = new SimpleBooleanProperty(false); this.showingStats = new SimpleBooleanProperty(false);
this.quickAccessEntry = new AtomicReference<>(null);
} }
// ****************************************************************************** // ******************************************************************************
@@ -149,6 +162,9 @@ public class Vault {
var rootPath = fs.getRootDirectories().iterator().next(); var rootPath = fs.getRootDirectories().iterator().next();
var mountHandle = mounter.mount(vaultSettings, rootPath); var mountHandle = mounter.mount(vaultSettings, rootPath);
success = this.mountHandle.compareAndSet(null, mountHandle); success = this.mountHandle.compareAndSet(null, mountHandle);
if (settings.useQuickAccess.getValue()) {
addToQuickAccess();
}
} finally { } finally {
if (!success) { if (!success) {
destroyCryptoFileSystem(); destroyCryptoFileSystem();
@@ -173,6 +189,7 @@ public class Vault {
mountHandle.mountObj().close(); mountHandle.mountObj().close();
mountHandle.specialCleanup().run(); mountHandle.specialCleanup().run();
} finally { } finally {
removeFromQuickAccess();
destroyCryptoFileSystem(); destroyCryptoFileSystem();
} }
@@ -180,6 +197,52 @@ public class Vault {
LOG.info("Locked vault '{}'", getDisplayName()); LOG.info("Locked vault '{}'", getDisplayName());
} }
private synchronized void addToQuickAccess() {
if (quickAccessEntry.get() != null) {
//we don't throw an exception since we don't wanna block unlocking
LOG.warn("Vault already added to quick access area. Will be removed on next lock operation.");
return;
}
QuickAccessService.get() //
.filter(s -> s.getClass().getName().equals(settings.quickAccessService.getValue())) //
.findFirst() //
.ifPresentOrElse( //
this::addToQuickAccessInternal, //
() -> LOG.warn("Unable to add Vault to quick access area: Desired implementation not available.") //
);
}
private void addToQuickAccessInternal(@NotNull QuickAccessService s) {
if (getMountPoint() instanceof Mountpoint.WithPath mp) {
try {
var entry = s.add(mp.path(), getDisplayName());
quickAccessEntry.set(entry);
} catch (QuickAccessServiceException e) {
LOG.error("Adding vault to quick access area failed", e);
}
} else {
LOG.warn("Unable to add vault to quick access area: Vault is not mounted to local system path.");
}
}
private synchronized void removeFromQuickAccess() {
if (quickAccessEntry.get() == null) {
LOG.debug("Removing vault from quick access area: Entry not found, nothing to do.");
return;
}
removeFromQuickAccessInternal();
}
private void removeFromQuickAccessInternal() {
try {
quickAccessEntry.get().remove();
quickAccessEntry.set(null);
} catch (QuickAccessServiceException e) {
LOG.error("Removing vault from quick access area failed", e);
}
}
// ****************************************************************************** // ******************************************************************************
// Observable Properties // Observable Properties
// ******************************************************************************* // *******************************************************************************
@@ -8,11 +8,13 @@
*******************************************************************************/ *******************************************************************************/
package org.cryptomator.common.vaults; package org.cryptomator.common.vaults;
import org.apache.commons.lang3.SystemUtils;
import org.cryptomator.common.settings.Settings; import org.cryptomator.common.settings.Settings;
import org.cryptomator.common.settings.VaultSettings; import org.cryptomator.common.settings.VaultSettings;
import org.cryptomator.cryptofs.CryptoFileSystemProvider; import org.cryptomator.cryptofs.CryptoFileSystemProvider;
import org.cryptomator.cryptofs.DirStructure; import org.cryptomator.cryptofs.DirStructure;
import org.cryptomator.cryptofs.migration.Migrators; import org.cryptomator.cryptofs.migration.Migrators;
import org.cryptomator.integrations.mount.MountService;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -24,6 +26,7 @@ import java.nio.file.Files;
import java.nio.file.NoSuchFileException; import java.nio.file.NoSuchFileException;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.Collection; import java.util.Collection;
import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.ResourceBundle; import java.util.ResourceBundle;
@@ -38,14 +41,21 @@ public class VaultListManager {
private static final Logger LOG = LoggerFactory.getLogger(VaultListManager.class); private static final Logger LOG = LoggerFactory.getLogger(VaultListManager.class);
private final AutoLocker autoLocker; private final AutoLocker autoLocker;
private final List<MountService> mountServices;
private final VaultComponent.Factory vaultComponentFactory; private final VaultComponent.Factory vaultComponentFactory;
private final ObservableList<Vault> vaultList; private final ObservableList<Vault> vaultList;
private final String defaultVaultName; private final String defaultVaultName;
@Inject @Inject
public VaultListManager(ObservableList<Vault> vaultList, AutoLocker autoLocker, VaultComponent.Factory vaultComponentFactory, ResourceBundle resourceBundle, Settings settings) { public VaultListManager(ObservableList<Vault> vaultList, //
AutoLocker autoLocker, //
List<MountService> mountServices,
VaultComponent.Factory vaultComponentFactory,
ResourceBundle resourceBundle,
Settings settings) {
this.vaultList = vaultList; this.vaultList = vaultList;
this.autoLocker = autoLocker; this.autoLocker = autoLocker;
this.mountServices = mountServices;
this.vaultComponentFactory = vaultComponentFactory; this.vaultComponentFactory = vaultComponentFactory;
this.defaultVaultName = resourceBundle.getString("defaults.vault.vaultName"); this.defaultVaultName = resourceBundle.getString("defaults.vault.vaultName");
@@ -76,6 +86,15 @@ public class VaultListManager {
} else { } else {
vaultSettings.displayName.set(defaultVaultName); vaultSettings.displayName.set(defaultVaultName);
} }
//due to https://github.com/cryptomator/cryptomator/issues/2880#issuecomment-1680313498
var nameOfWinfspLocalMounter = "org.cryptomator.frontend.fuse.mount.WinFspMountProvider";
if (SystemUtils.IS_OS_WINDOWS //
&& vaultSettings.path.get().toString().contains("Dropbox") //
&& mountServices.stream().anyMatch(s -> s.getClass().getName().equals(nameOfWinfspLocalMounter))) {
vaultSettings.mountService.setValue(nameOfWinfspLocalMounter);
}
return vaultSettings; return vaultSettings;
} }
@@ -6,6 +6,7 @@
*******************************************************************************/ *******************************************************************************/
package org.cryptomator.launcher; package org.cryptomator.launcher;
import org.jetbrains.annotations.VisibleForTesting;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -48,7 +49,7 @@ class FileOpenRequestHandler {
handleLaunchArgs(FileSystems.getDefault(), args); handleLaunchArgs(FileSystems.getDefault(), args);
} }
// visible for testing @VisibleForTesting
void handleLaunchArgs(FileSystem fs, List<String> args) { void handleLaunchArgs(FileSystem fs, List<String> args) {
Collection<Path> pathsToOpen = args.stream().map(str -> { Collection<Path> pathsToOpen = args.stream().map(str -> {
try { try {
@@ -20,7 +20,7 @@ public class SupportedLanguages {
// "en" is not part of this list - it is always inserted at the top. // "en" is not part of this list - it is always inserted at the top.
public static final List<String> LANGUAGE_TAGS = List.of("ar", "be", "bn", "bs", "ca", "cs", "da", "de", "el", "es", "fr", "gl", "he", // public static final List<String> LANGUAGE_TAGS = List.of("ar", "be", "bn", "bs", "ca", "cs", "da", "de", "el", "es", "fr", "gl", "he", //
"hi", "hr", "hu", "id", "it", "ja", "ko", "lv", "nb", "nl", "nn", "pa", "pl", "pt", "pt-BR", "ro", "ru", "sk", "sr", "sr-Latn", "sv", "sw", // "hi", "hr", "hu", "id", "it", "ja", "ko", "lv", "nb", "nl", "nn", "pa", "pl", "pt", "pt-BR", "ro", "ru", "sk", "sr", "sr-Latn", "sv", "sw", //
"ta", "th", "tr", "uk", "vi", "zh", "zh-HK", "zh-TW"); "ta", "th", "tr", "ug", "uk", "vi", "zh", "zh-HK", "zh-TW");
public static final String ENGLISH = "en"; public static final String ENGLISH = "en";
private final List<String> sortedLanguageTags; private final List<String> sortedLanguageTags;
@@ -5,6 +5,7 @@ import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.LoggerContext; import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.encoder.PatternLayoutEncoder; import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
import ch.qos.logback.classic.spi.Configurator; import ch.qos.logback.classic.spi.Configurator;
import ch.qos.logback.classic.spi.ConfiguratorRank;
import ch.qos.logback.classic.spi.ILoggingEvent; import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.Appender; import ch.qos.logback.core.Appender;
import ch.qos.logback.core.ConsoleAppender; import ch.qos.logback.core.ConsoleAppender;
@@ -19,6 +20,7 @@ import org.cryptomator.common.Environment;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.Map; import java.util.Map;
@ConfiguratorRank(ConfiguratorRank.CUSTOM_NORMAL_PRIORITY)
public class LogbackConfigurator extends ContextAwareBase implements Configurator { public class LogbackConfigurator extends ContextAwareBase implements Configurator {
private static final String LOG_PATTERN = "%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n"; private static final String LOG_PATTERN = "%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n";
@@ -13,31 +13,37 @@ import org.slf4j.LoggerFactory;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Named; import javax.inject.Named;
import javafx.application.Platform;
import javafx.beans.binding.Bindings;
import javafx.beans.binding.BooleanBinding; import javafx.beans.binding.BooleanBinding;
import javafx.beans.property.BooleanProperty; import javafx.beans.property.BooleanProperty;
import javafx.beans.property.ObjectProperty; import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleBooleanProperty; import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.StringProperty; import javafx.beans.property.StringProperty;
import javafx.beans.value.ObservableValue; import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML; import javafx.fxml.FXML;
import javafx.scene.Node;
import javafx.scene.Scene; import javafx.scene.Scene;
import javafx.scene.control.Label; import javafx.scene.control.Label;
import javafx.scene.control.RadioButton; import javafx.scene.control.RadioButton;
import javafx.scene.control.Toggle; import javafx.scene.control.Toggle;
import javafx.scene.control.ToggleGroup; import javafx.scene.control.ToggleGroup;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox; import javafx.scene.layout.VBox;
import javafx.stage.DirectoryChooser; import javafx.stage.DirectoryChooser;
import javafx.stage.Stage; import javafx.stage.Stage;
import javafx.stage.WindowEvent;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.nio.file.StandardOpenOption; import java.nio.file.StandardOpenOption;
import java.util.Comparator;
import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.ResourceBundle; import java.util.ResourceBundle;
import java.util.concurrent.ExecutorService;
@AddVaultWizardScoped @AddVaultWizardScoped
public class CreateNewVaultLocationController implements FxController { public class CreateNewVaultLocationController implements FxController {
@@ -49,19 +55,23 @@ public class CreateNewVaultLocationController implements FxController {
private final Stage window; private final Stage window;
private final Lazy<Scene> chooseNameScene; private final Lazy<Scene> chooseNameScene;
private final Lazy<Scene> chooseExpertSettingsScene; private final Lazy<Scene> chooseExpertSettingsScene;
private final List<RadioButton> locationPresetBtns;
private final ObjectProperty<Path> vaultPath; private final ObjectProperty<Path> vaultPath;
private final StringProperty vaultName; private final StringProperty vaultName;
private final ExecutorService backgroundExecutor;
private final ResourceBundle resourceBundle; private final ResourceBundle resourceBundle;
private final ObservableValue<VaultPathStatus> vaultPathStatus; private final ObservableValue<VaultPathStatus> vaultPathStatus;
private final ObservableValue<Boolean> validVaultPath; private final ObservableValue<Boolean> validVaultPath;
private final BooleanProperty usePresetPath; private final BooleanProperty usePresetPath;
private final BooleanProperty loadingPresetLocations = new SimpleBooleanProperty(false);
private final ObservableList<Node> radioButtons;
private final ObservableList<Node> sortedRadioButtons;
private Path customVaultPath = DEFAULT_CUSTOM_VAULT_PATH; private Path customVaultPath = DEFAULT_CUSTOM_VAULT_PATH;
//FXML //FXML
public ToggleGroup locationPresetsToggler; public ToggleGroup locationPresetsToggler;
public VBox radioButtonVBox; public VBox radioButtonVBox;
public HBox customLocationRadioBtn;
public RadioButton customRadioButton; public RadioButton customRadioButton;
public Label locationStatusLabel; public Label locationStatusLabel;
public FontAwesome5IconView goodLocation; public FontAwesome5IconView goodLocation;
@@ -73,25 +83,20 @@ public class CreateNewVaultLocationController implements FxController {
@FxmlScene(FxmlFile.ADDVAULT_NEW_EXPERT_SETTINGS) Lazy<Scene> chooseExpertSettingsScene, // @FxmlScene(FxmlFile.ADDVAULT_NEW_EXPERT_SETTINGS) Lazy<Scene> chooseExpertSettingsScene, //
ObjectProperty<Path> vaultPath, // ObjectProperty<Path> vaultPath, //
@Named("vaultName") StringProperty vaultName, // @Named("vaultName") StringProperty vaultName, //
ResourceBundle resourceBundle) { ExecutorService backgroundExecutor, ResourceBundle resourceBundle) {
this.window = window; this.window = window;
this.chooseNameScene = chooseNameScene; this.chooseNameScene = chooseNameScene;
this.chooseExpertSettingsScene = chooseExpertSettingsScene; this.chooseExpertSettingsScene = chooseExpertSettingsScene;
this.vaultPath = vaultPath; this.vaultPath = vaultPath;
this.vaultName = vaultName; this.vaultName = vaultName;
this.backgroundExecutor = backgroundExecutor;
this.resourceBundle = resourceBundle; this.resourceBundle = resourceBundle;
this.vaultPathStatus = ObservableUtil.mapWithDefault(vaultPath, this::validatePath, new VaultPathStatus(false, "error.message")); this.vaultPathStatus = ObservableUtil.mapWithDefault(vaultPath, this::validatePath, new VaultPathStatus(false, "error.message"));
this.validVaultPath = ObservableUtil.mapWithDefault(vaultPathStatus, VaultPathStatus::valid, false); this.validVaultPath = ObservableUtil.mapWithDefault(vaultPathStatus, VaultPathStatus::valid, false);
this.vaultPathStatus.addListener(this::updateStatusLabel); this.vaultPathStatus.addListener(this::updateStatusLabel);
this.usePresetPath = new SimpleBooleanProperty(); this.usePresetPath = new SimpleBooleanProperty();
this.locationPresetBtns = LocationPresetsProvider.loadAll(LocationPresetsProvider.class) // this.radioButtons = FXCollections.observableArrayList();
.flatMap(LocationPresetsProvider::getLocations) // this.sortedRadioButtons = radioButtons.sorted(this::compareLocationPresets);
.sorted(Comparator.comparing(LocationPreset::name)) //
.map(preset -> { //
var btn = new RadioButton(preset.name());
btn.setUserData(preset.path());
return btn;
}).toList();
} }
private VaultPathStatus validatePath(Path p) throws NullPointerException { private VaultPathStatus validatePath(Path p) throws NullPointerException {
@@ -137,12 +142,45 @@ public class CreateNewVaultLocationController implements FxController {
@FXML @FXML
public void initialize() { public void initialize() {
radioButtonVBox.getChildren().addAll(1, locationPresetBtns); //first item is the list header var task = backgroundExecutor.submit(this::loadLocationPresets);
locationPresetsToggler.getToggles().addAll(locationPresetBtns); window.addEventHandler(WindowEvent.WINDOW_HIDING, _ -> task.cancel(true));
locationPresetsToggler.selectedToggleProperty().addListener(this::togglePredefinedLocation); locationPresetsToggler.selectedToggleProperty().addListener(this::togglePredefinedLocation);
usePresetPath.bind(locationPresetsToggler.selectedToggleProperty().isNotEqualTo(customRadioButton)); usePresetPath.bind(locationPresetsToggler.selectedToggleProperty().isNotEqualTo(customRadioButton));
radioButtons.add(customLocationRadioBtn);
Bindings.bindContent(radioButtonVBox.getChildren(), sortedRadioButtons); //to prevent garbage collection of the binding, we bind explicitly to the sorted list
} }
private void loadLocationPresets() {
Platform.runLater(() -> loadingPresetLocations.set(true));
try {
LocationPresetsProvider.loadAll(LocationPresetsProvider.class) //
.flatMap(LocationPresetsProvider::getLocations) //we do not use sorted(), because it evaluates the stream elements, blocking until all elements are gathered
.forEach(this::createRadioButtonFor);
} finally {
Platform.runLater(() -> loadingPresetLocations.set(false));
}
}
private void createRadioButtonFor(LocationPreset preset) {
Platform.runLater(() -> {
var btn = new RadioButton(preset.name());
btn.setUserData(preset.path());
radioButtons.add(btn);
locationPresetsToggler.getToggles().add(btn);
});
}
private int compareLocationPresets(Node left, Node right) {
if (customLocationRadioBtn.getId().equals(left.getId())) {
return 1;
} else if (customLocationRadioBtn.getId().equals(right.getId())) {
return -1;
} else {
return ((RadioButton) left).getText().compareToIgnoreCase(((RadioButton) right).getText());
}
}
private void togglePredefinedLocation(@SuppressWarnings("unused") ObservableValue<? extends Toggle> observable, @SuppressWarnings("unused") Toggle oldValue, Toggle newValue) { private void togglePredefinedLocation(@SuppressWarnings("unused") ObservableValue<? extends Toggle> observable, @SuppressWarnings("unused") Toggle oldValue, Toggle newValue) {
var storagePath = Optional.ofNullable((Path) newValue.getUserData()).orElse(customVaultPath); var storagePath = Optional.ofNullable((Path) newValue.getUserData()).orElse(customVaultPath);
vaultPath.set(storagePath.resolve(vaultName.get())); vaultPath.set(storagePath.resolve(vaultName.get()));
@@ -197,7 +235,15 @@ public class CreateNewVaultLocationController implements FxController {
} }
public boolean isValidVaultPath() { public boolean isValidVaultPath() {
return validVaultPath.getValue(); return Boolean.TRUE.equals(validVaultPath.getValue());
}
public boolean isLoadingPresetLocations() {
return loadingPresetLocations.getValue();
}
public BooleanProperty loadingPresetLocationsProperty() {
return loadingPresetLocations;
} }
public BooleanProperty usePresetPathProperty() { public BooleanProperty usePresetPathProperty() {
@@ -1,5 +1,7 @@
package org.cryptomator.ui.addvaultwizard; package org.cryptomator.ui.addvaultwizard;
import org.jetbrains.annotations.VisibleForTesting;
import javax.inject.Inject; import javax.inject.Inject;
import java.util.List; import java.util.List;
import java.util.ResourceBundle; import java.util.ResourceBundle;
@@ -51,7 +53,7 @@ public class ReadmeGenerator {
resourceBundle.getString("addvault.new.readme.accessLocation.4"))); resourceBundle.getString("addvault.new.readme.accessLocation.4")));
} }
// visible for testing @VisibleForTesting
String createDocument(Iterable<String> paragraphs) { String createDocument(Iterable<String> paragraphs) {
StringBuilder sb = new StringBuilder(RTF_HEADER); StringBuilder sb = new StringBuilder(RTF_HEADER);
for (String p : paragraphs) { for (String p : paragraphs) {
@@ -63,7 +65,7 @@ public class ReadmeGenerator {
return sb.toString(); return sb.toString();
} }
// visible for testing @VisibleForTesting
String escapeNonAsciiChars(CharSequence input) { String escapeNonAsciiChars(CharSequence input) {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
appendEscaped(sb, input); appendEscaped(sb, input);
@@ -20,10 +20,14 @@ public enum FxmlFile {
HUB_AUTH_FLOW("/fxml/hub_auth_flow.fxml"), // HUB_AUTH_FLOW("/fxml/hub_auth_flow.fxml"), //
HUB_INVALID_LICENSE("/fxml/hub_invalid_license.fxml"), // HUB_INVALID_LICENSE("/fxml/hub_invalid_license.fxml"), //
HUB_RECEIVE_KEY("/fxml/hub_receive_key.fxml"), // HUB_RECEIVE_KEY("/fxml/hub_receive_key.fxml"), //
HUB_REGISTER_DEVICE("/fxml/hub_register_device.fxml"), // HUB_LEGACY_REGISTER_DEVICE("/fxml/hub_legacy_register_device.fxml"), //
HUB_LEGACY_REGISTER_SUCCESS("/fxml/hub_legacy_register_success.fxml"), //
HUB_REGISTER_SUCCESS("/fxml/hub_register_success.fxml"), // HUB_REGISTER_SUCCESS("/fxml/hub_register_success.fxml"), //
HUB_REGISTER_FAILED("/fxml/hub_register_failed.fxml"), HUB_REGISTER_DEVICE_ALREADY_EXISTS("/fxml/hub_register_device_already_exists.fxml"), //
HUB_REGISTER_FAILED("/fxml/hub_register_failed.fxml"), //
HUB_REGISTER_DEVICE("/fxml/hub_register_device.fxml"), //
HUB_UNAUTHORIZED_DEVICE("/fxml/hub_unauthorized_device.fxml"), // HUB_UNAUTHORIZED_DEVICE("/fxml/hub_unauthorized_device.fxml"), //
HUB_REQUIRE_ACCOUNT_INIT("/fxml/hub_require_account_init.fxml"), //
LOCK_FORCED("/fxml/lock_forced.fxml"), // LOCK_FORCED("/fxml/lock_forced.fxml"), //
LOCK_FAILED("/fxml/lock_failed.fxml"), // LOCK_FAILED("/fxml/lock_failed.fxml"), //
MAIN_WINDOW("/fxml/main_window.fxml"), // MAIN_WINDOW("/fxml/main_window.fxml"), //
@@ -40,9 +44,11 @@ public enum FxmlFile {
RECOVERYKEY_RESET_PASSWORD("/fxml/recoverykey_reset_password.fxml"), // RECOVERYKEY_RESET_PASSWORD("/fxml/recoverykey_reset_password.fxml"), //
RECOVERYKEY_RESET_PASSWORD_SUCCESS("/fxml/recoverykey_reset_password_success.fxml"), // RECOVERYKEY_RESET_PASSWORD_SUCCESS("/fxml/recoverykey_reset_password_success.fxml"), //
RECOVERYKEY_SUCCESS("/fxml/recoverykey_success.fxml"), // RECOVERYKEY_SUCCESS("/fxml/recoverykey_success.fxml"), //
REMOVE_VAULT("/fxml/remove_vault.fxml"), // SHARE_VAULT("/fxml/share_vault.fxml"), //
SIMPLE_DIALOG("/fxml/simple_dialog.fxml"), //
UPDATE_REMINDER("/fxml/update_reminder.fxml"), // UPDATE_REMINDER("/fxml/update_reminder.fxml"), //
UNLOCK_ENTER_PASSWORD("/fxml/unlock_enter_password.fxml"), UNLOCK_ENTER_PASSWORD("/fxml/unlock_enter_password.fxml"),
UNLOCK_REQUIRES_RESTART("/fxml/unlock_requires_restart.fxml"), //
UNLOCK_INVALID_MOUNT_POINT("/fxml/unlock_invalid_mount_point.fxml"), // UNLOCK_INVALID_MOUNT_POINT("/fxml/unlock_invalid_mount_point.fxml"), //
UNLOCK_SELECT_MASTERKEYFILE("/fxml/unlock_select_masterkeyfile.fxml"), // UNLOCK_SELECT_MASTERKEYFILE("/fxml/unlock_select_masterkeyfile.fxml"), //
UNLOCK_SUCCESS("/fxml/unlock_success.fxml"), // UNLOCK_SUCCESS("/fxml/unlock_success.fxml"), //
@@ -17,6 +17,7 @@ public enum FontAwesome5Icon {
COGS("\uF085"), // COGS("\uF085"), //
COPY("\uF0C5"), // COPY("\uF0C5"), //
CROWN("\uF521"), // CROWN("\uF521"), //
DONATE("\uF4B9"), //
EDIT("\uF044"), // EDIT("\uF044"), //
EXCHANGE_ALT("\uF362"), // EXCHANGE_ALT("\uF362"), //
EXCLAMATION("\uF12A"), // EXCLAMATION("\uF12A"), //
@@ -47,12 +48,15 @@ public enum FontAwesome5Icon {
QUESTION_CIRCLE("\uf059"), // QUESTION_CIRCLE("\uf059"), //
REDO("\uF01E"), // REDO("\uF01E"), //
SEARCH("\uF002"), // SEARCH("\uF002"), //
SHARE("\uF064"), //
SPINNER("\uF110"), // SPINNER("\uF110"), //
SPONSORS("\uF2B5"), //
STETHOSCOPE("\uF0f1"), // STETHOSCOPE("\uF0f1"), //
SYNC("\uF021"), // SYNC("\uF021"), //
TIMES("\uF00D"), // TIMES("\uF00D"), //
TRASH("\uF1F8"), // TRASH("\uF1F8"), //
UNLINK("\uf127"), // UNLINK("\uf127"), //
USER_COG("\uf4fe"), //
WRENCH("\uF0AD"), // WRENCH("\uF0AD"), //
WINDOW_MINIMIZE("\uF2D1"), // WINDOW_MINIMIZE("\uF2D1"), //
; ;
@@ -0,0 +1,96 @@
package org.cryptomator.ui.controls;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.fxml.FXML;
import javafx.geometry.Pos;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Region;
import javafx.scene.layout.VBox;
public class NotificationBar extends HBox {
@FXML
private Label notificationLabel;
private final BooleanProperty dismissable = new SimpleBooleanProperty();
private final BooleanProperty notify = new SimpleBooleanProperty();
public NotificationBar() {
setAlignment(Pos.CENTER);
setStyle("-fx-alignment: center;");
Region spacer = new Region();
spacer.setMinWidth(40);
Region leftRegion = new Region();
HBox.setHgrow(leftRegion, javafx.scene.layout.Priority.ALWAYS);
Region rightRegion = new Region();
HBox.setHgrow(rightRegion, javafx.scene.layout.Priority.ALWAYS);
VBox vbox = new VBox();
vbox.setAlignment(Pos.CENTER);
HBox.setHgrow(vbox, javafx.scene.layout.Priority.ALWAYS);
notificationLabel = new Label();
notificationLabel.getStyleClass().add("notification-label");
notificationLabel.setStyle("-fx-alignment: center;");
vbox.getChildren().add(notificationLabel);
Button closeButton = new Button("X");
closeButton.setMinWidth(40);
closeButton.setStyle("-fx-background-color: transparent; -fx-text-fill: white; -fx-font-weight: bold;");
closeButton.visibleProperty().bind(dismissable);
closeButton.setOnAction(_ -> {
visibleProperty().unbind();
managedProperty().unbind();
visibleProperty().set(false);
managedProperty().set(false);
});
closeButton.visibleProperty().bind(dismissable);
getChildren().addAll(spacer, leftRegion, vbox, rightRegion, closeButton);
visibleProperty().bind(notifyProperty());
managedProperty().bind(notifyProperty());
}
public String getText() {
return notificationLabel.getText();
}
public void setText(String text) {
notificationLabel.setText(text);
}
public void setStyleClass(String styleClass) {
getStyleClass().clear();
getStyleClass().add(styleClass);
}
public boolean isDismissable() {
return dismissable.get();
}
public void setDismissable(boolean value) {
dismissable.set(value);
}
public boolean getNotify() {
return notify.get();
}
public void setNotify(boolean value) {
notify.set(value);
}
public BooleanProperty notifyProperty() {
return notify;
}
}
@@ -16,6 +16,7 @@ import org.cryptomator.ui.common.FxmlFile;
import org.cryptomator.ui.common.FxmlScene; import org.cryptomator.ui.common.FxmlScene;
import org.cryptomator.ui.fxapp.FxApplicationWindows; import org.cryptomator.ui.fxapp.FxApplicationWindows;
import org.cryptomator.ui.recoverykey.RecoveryKeyFactory; import org.cryptomator.ui.recoverykey.RecoveryKeyFactory;
import org.jetbrains.annotations.VisibleForTesting;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -116,7 +117,7 @@ public class HubToPasswordConvertController implements FxController {
}, Platform::runLater); // }, Platform::runLater); //
} }
//visible for testing @VisibleForTesting
void convertInternal() throws CompletionException, IllegalArgumentException { void convertInternal() throws CompletionException, IllegalArgumentException {
var passphrase = newPasswordController.getNewPassword(); var passphrase = newPasswordController.getNewPassword();
var vaultPath = vault.getPath(); var vaultPath = vault.getPath();
@@ -141,7 +142,7 @@ public class HubToPasswordConvertController implements FxController {
} }
} }
//visible for testing @VisibleForTesting
void backupHubConfig(Path hubConfigPath) throws IOException { void backupHubConfig(Path hubConfigPath) throws IOException {
byte[] hubConfigBytes = Files.readAllBytes(hubConfigPath); byte[] hubConfigBytes = Files.readAllBytes(hubConfigPath);
Path backupPath = hubConfigPath.resolveSibling(VAULTCONFIG_FILENAME + BackupHelper.generateFileIdSuffix(hubConfigBytes) + MASTERKEY_BACKUP_SUFFIX); Path backupPath = hubConfigPath.resolveSibling(VAULTCONFIG_FILENAME + BackupHelper.generateFileIdSuffix(hubConfigBytes) + MASTERKEY_BACKUP_SUFFIX);
@@ -149,7 +150,7 @@ public class HubToPasswordConvertController implements FxController {
LOG.debug("Successfully created hub config backup {}", backupPath.getFileName()); LOG.debug("Successfully created hub config backup {}", backupPath.getFileName());
} }
//visible for testing @VisibleForTesting
Path createPasswordConfig(Path passwordConfigPath, Path masterkeyFile, Passphrase passphrase) throws IOException, MasterkeyLoadingFailedException { Path createPasswordConfig(Path passwordConfigPath, Path masterkeyFile, Passphrase passphrase) throws IOException, MasterkeyLoadingFailedException {
var unverifiedVaultConfig = vault.getVaultConfigCache().get(); var unverifiedVaultConfig = vault.getVaultConfigCache().get();
try (var masterkey = masterkeyFileAccess.load(masterkeyFile, passphrase)) { try (var masterkey = masterkeyFileAccess.load(masterkeyFile, passphrase)) {
@@ -0,0 +1,75 @@
package org.cryptomator.ui.dialogs;
import org.cryptomator.common.settings.Settings;
import org.cryptomator.common.vaults.Vault;
import org.cryptomator.ui.controls.FontAwesome5Icon;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.inject.Inject;
import javax.inject.Singleton;
import javafx.collections.ObservableList;
import javafx.stage.Stage;
import java.util.ResourceBundle;
import java.util.function.Consumer;
@Singleton
public class Dialogs {
private final ResourceBundle resourceBundle;
@Inject
public Dialogs(ResourceBundle resourceBundle) {
this.resourceBundle = resourceBundle;
}
private static final Logger LOG = LoggerFactory.getLogger(Dialogs.class);
private SimpleDialog.Builder createDialogBuilder() {
return new SimpleDialog.Builder(resourceBundle);
}
public SimpleDialog.Builder prepareRemoveVaultDialog(Stage window, Vault vault, ObservableList<Vault> vaults) {
return createDialogBuilder().setOwner(window) //
.setTitleKey("removeVault.title", vault.getDisplayName()) //
.setMessageKey("removeVault.message") //
.setDescriptionKey("removeVault.description") //
.setIcon(FontAwesome5Icon.QUESTION) //
.setOkButtonKey("removeVault.confirmBtn") //
.setCancelButtonKey("generic.button.cancel") //
.setOkAction(stage -> {
LOG.debug("Removing vault {}.", vault.getDisplayName());
vaults.remove(vault);
stage.close();
});
}
public SimpleDialog.Builder prepareRemoveCertDialog(Stage window, Settings settings) {
return createDialogBuilder() //
.setOwner(window) //
.setTitleKey("removeCert.title") //
.setMessageKey("removeCert.message") //
.setDescriptionKey("removeCert.description") //
.setIcon(FontAwesome5Icon.QUESTION) //
.setOkButtonKey("removeCert.confirmBtn") //
.setCancelButtonKey("generic.button.cancel") //
.setOkAction(stage -> {
settings.licenseKey.set(null);
stage.close();
});
}
public SimpleDialog.Builder prepareDokanySupportEndDialog(Stage window, Consumer<Stage> cancelAction) {
return createDialogBuilder() //
.setOwner(window) //
.setTitleKey("dokanySupportEnd.title") //
.setMessageKey("dokanySupportEnd.message") //
.setDescriptionKey("dokanySupportEnd.description") //
.setIcon(FontAwesome5Icon.QUESTION) //
.setOkButtonKey("generic.button.close") //
.setCancelButtonKey("dokanySupportEnd.preferencesBtn") //
.setOkAction(Stage::close) //
.setCancelAction(cancelAction);
}
}
@@ -0,0 +1,138 @@
package org.cryptomator.ui.dialogs;
import org.cryptomator.ui.common.FxmlFile;
import org.cryptomator.ui.common.FxmlLoaderFactory;
import org.cryptomator.ui.controls.FontAwesome5Icon;
import javafx.scene.Scene;
import javafx.stage.Modality;
import javafx.stage.Stage;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.util.IllegalFormatException;
import java.util.Objects;
import java.util.ResourceBundle;
import java.util.function.Consumer;
public class SimpleDialog {
private final ResourceBundle resourceBundle;
private final Stage dialogStage;
SimpleDialog(Builder builder) throws IOException {
this.resourceBundle = builder.resourceBundle;
dialogStage = new Stage();
dialogStage.initOwner(builder.owner);
dialogStage.initModality(Modality.WINDOW_MODAL);
dialogStage.setTitle(resolveText(builder.titleKey, builder.titleArgs));
dialogStage.setResizable(false);
FxmlLoaderFactory loaderFactory = FxmlLoaderFactory.forController(
new SimpleDialogController(resolveText(builder.messageKey, null),
resolveText(builder.descriptionKey, null),
builder.icon,resolveText(builder.okButtonKey, null),
resolveText(builder.cancelButtonKey, null),
() -> builder.okAction.accept(dialogStage),
() -> builder.cancelAction.accept(dialogStage)),
Scene::new, builder.resourceBundle);
dialogStage.setScene(new Scene(loaderFactory.load(FxmlFile.SIMPLE_DIALOG.getRessourcePathString()).getRoot()));
}
public void showAndWait() {
dialogStage.showAndWait();
}
private String resolveText(String key, String[] args) {
if (key == null || key.isEmpty() || !resourceBundle.containsKey(key)) {
throw new IllegalArgumentException(String.format("Invalid key: '%s'. Key not found in ResourceBundle.", key));
}
String text = resourceBundle.getString(key);
try {
return args != null && args.length > 0 ? String.format(text, (Object[]) args) : text;
} catch (IllegalFormatException e) {
throw new IllegalArgumentException("Formatting error: Check if arguments match placeholders in the text.", e);
}
}
public static class Builder {
private Stage owner;
private final ResourceBundle resourceBundle;
private String titleKey;
private String[] titleArgs;
private String messageKey;
private String descriptionKey;
private String okButtonKey;
private String cancelButtonKey;
private FontAwesome5Icon icon;
private Consumer<Stage> okAction = Stage::close;
private Consumer<Stage> cancelAction = Stage::close;
public Builder(ResourceBundle resourceBundle) {
this.resourceBundle = resourceBundle;
}
public Builder setOwner(Stage owner) {
this.owner = owner;
return this;
}
public Builder setTitleKey(String titleKey, String... args) {
this.titleKey = titleKey;
this.titleArgs = args;
return this;
}
public Builder setMessageKey(String messageKey) {
this.messageKey = messageKey;
return this;
}
public Builder setDescriptionKey(String descriptionKey) {
this.descriptionKey = descriptionKey;
return this;
}
public Builder setIcon(FontAwesome5Icon icon) {
this.icon = icon;
return this;
}
public Builder setOkButtonKey(String okButtonKey) {
this.okButtonKey = okButtonKey;
return this;
}
public Builder setCancelButtonKey(String cancelButtonKey) {
this.cancelButtonKey = cancelButtonKey;
return this;
}
public Builder setOkAction(Consumer<Stage> okAction) {
this.okAction = okAction;
return this;
}
public Builder setCancelAction(Consumer<Stage> cancelAction) {
this.cancelAction = cancelAction;
return this;
}
public SimpleDialog build() {
Objects.requireNonNull(titleKey,"SimpleDialog titleKey must be set.");
Objects.requireNonNull(messageKey,"SimpleDialog messageKey must be set.");
Objects.requireNonNull(descriptionKey,"SimpleDialog descriptionKey must be set.");
Objects.requireNonNull(okButtonKey,"SimpleDialog okButtonKey must be set.");
Objects.requireNonNull(cancelButtonKey,"SimpleDialog cancelButtonKey must be set.");
try {
return new SimpleDialog(this);
} catch (IOException e) {
throw new UncheckedIOException("Failed to create SimpleDialog.", e);
}
}
}
}
@@ -0,0 +1,61 @@
package org.cryptomator.ui.dialogs;
import org.cryptomator.ui.common.FxController;
import org.cryptomator.ui.controls.FontAwesome5Icon;
import javafx.fxml.FXML;
public class SimpleDialogController implements FxController {
private final String message;
private final String description;
private final FontAwesome5Icon icon;
private final String okButtonText;
private final String cancelButtonText;
private final Runnable okAction;
private final Runnable cancelAction;
public SimpleDialogController(String message, String description, FontAwesome5Icon icon, String okButtonText, String cancelButtonText, Runnable okAction, Runnable cancelAction) {
this.message = message;
this.description = description;
this.icon = icon;
this.okButtonText = okButtonText;
this.cancelButtonText = cancelButtonText;
this.okAction = okAction;
this.cancelAction = cancelAction;
}
public String getMessage() {
return message;
}
public String getDescription() {
return description;
}
public FontAwesome5Icon getIcon() {
return icon;
}
public String getOkButtonText() {
return okButtonText;
}
public String getCancelButtonText() {
return cancelButtonText;
}
@FXML
private void handleOk() {
if (okAction != null) {
okAction.run();
}
}
@FXML
private void handleCancel() {
if (cancelAction != null) {
cancelAction.run();
}
}
}
@@ -20,6 +20,8 @@ public interface ErrorComponent {
default Stage show() { default Stage show() {
Stage stage = window(); Stage stage = window();
stage.setScene(scene()); stage.setScene(scene());
stage.setMinWidth(420);
stage.setMinHeight(300);
stage.show(); stage.show();
return stage; return stage;
} }
@@ -31,6 +31,7 @@ import java.net.http.HttpClient;
import java.net.http.HttpRequest; import java.net.http.HttpRequest;
import java.net.http.HttpResponse; import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.Comparator; import java.util.Comparator;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
@@ -42,7 +43,8 @@ public class ErrorController implements FxController {
private static final ObjectMapper JSON = new ObjectMapper(); private static final ObjectMapper JSON = new ObjectMapper();
private static final Logger LOG = LoggerFactory.getLogger(ErrorController.class); private static final Logger LOG = LoggerFactory.getLogger(ErrorController.class);
private static final String ERROR_CODES_URL = "https://api.cryptomator.org/desktop/error-codes.json"; private static final String USER_AGENT_FORMAT = "Cryptomator/%s (Build %s) (%s %s %s)";
private static final String ERROR_CODES_URL_FORMAT = "https://api.cryptomator.org/desktop/error-codes.json?error-code=%s";
private static final String SEARCH_URL_FORMAT = "https://github.com/cryptomator/cryptomator/discussions/categories/errors?discussions_q=category:Errors+%s"; private static final String SEARCH_URL_FORMAT = "https://github.com/cryptomator/cryptomator/discussions/categories/errors?discussions_q=category:Errors+%s";
private static final String REPORT_URL_FORMAT = "https://github.com/cryptomator/cryptomator/discussions/new?category=Errors&title=Error+%s&body=%s"; private static final String REPORT_URL_FORMAT = "https://github.com/cryptomator/cryptomator/discussions/new?category=Errors&title=Error+%s&body=%s";
private static final String SEARCH_ERRORCODE_DELIM = " OR "; private static final String SEARCH_ERRORCODE_DELIM = " OR ";
@@ -73,6 +75,7 @@ public class ErrorController implements FxController {
private final BooleanExpression errorSolutionFound = matchingErrorDiscussion.isNotNull(); private final BooleanExpression errorSolutionFound = matchingErrorDiscussion.isNotNull();
private final BooleanProperty isLoadingHttpResponse = new SimpleBooleanProperty(); private final BooleanProperty isLoadingHttpResponse = new SimpleBooleanProperty();
private final BooleanProperty askedForLookupDatabasePermission = new SimpleBooleanProperty(); private final BooleanProperty askedForLookupDatabasePermission = new SimpleBooleanProperty();
private final boolean formerSceneWasResizable;
@Inject @Inject
ErrorController(Application application, @Named("stackTrace") String stackTrace, ErrorCode errorCode, @Nullable Scene previousScene, Stage window, Environment environment, ExecutorService executorService) { ErrorController(Application application, @Named("stackTrace") String stackTrace, ErrorCode errorCode, @Nullable Scene previousScene, Stage window, Environment environment, ExecutorService executorService) {
@@ -83,12 +86,14 @@ public class ErrorController implements FxController {
this.window = window; this.window = window;
this.environment = environment; this.environment = environment;
this.executorService = executorService; this.executorService = executorService;
this.formerSceneWasResizable = window.isResizable();
} }
@FXML @FXML
public void back() { public void back() {
if (previousScene != null) { if (previousScene != null) {
window.setScene(previousScene); window.setScene(previousScene);
window.setResizable(formerSceneWasResizable);
} }
} }
@@ -142,11 +147,19 @@ public class ErrorController implements FxController {
@FXML @FXML
public void lookUpSolution() { public void lookUpSolution() {
String userAgent = USER_AGENT_FORMAT.formatted( //
environment.getAppVersion(), //
environment.getBuildNumber().orElse("undefined"), //
System.getProperty("os.name"), //
System.getProperty("os.version"), //
System.getProperty("os.arch"));
isLoadingHttpResponse.set(true); isLoadingHttpResponse.set(true);
askedForLookupDatabasePermission.set(true); askedForLookupDatabasePermission.set(true);
HttpClient httpClient = HttpClient.newBuilder().version(HttpClient.Version.HTTP_1_1).build(); HttpClient httpClient = HttpClient.newBuilder().version(HttpClient.Version.HTTP_1_1).build();
HttpRequest httpRequest = HttpRequest.newBuilder()// HttpRequest httpRequest = HttpRequest.newBuilder()//
.uri(URI.create(ERROR_CODES_URL))// .header("User-Agent", userAgent)
.timeout(Duration.ofSeconds(10))
.uri(URI.create(ERROR_CODES_URL_FORMAT.formatted(URLEncoder.encode(errorCode.toString(),StandardCharsets.UTF_8))))//
.build(); .build();
httpClient.sendAsync(httpRequest, HttpResponse.BodyHandlers.ofInputStream())// httpClient.sendAsync(httpRequest, HttpResponse.BodyHandlers.ofInputStream())//
.thenAcceptAsync(this::loadHttpResponse, executorService)// .thenAcceptAsync(this::loadHttpResponse, executorService)//
@@ -1,7 +1,9 @@
package org.cryptomator.ui.fxapp; package org.cryptomator.ui.fxapp;
import dagger.Lazy; import dagger.Lazy;
import org.cryptomator.common.Environment;
import org.cryptomator.common.settings.Settings; import org.cryptomator.common.settings.Settings;
import org.cryptomator.common.settings.VaultSettings;
import org.cryptomator.ui.traymenu.TrayMenuComponent; import org.cryptomator.ui.traymenu.TrayMenuComponent;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -9,6 +11,8 @@ import org.slf4j.LoggerFactory;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Named; import javax.inject.Named;
import javafx.application.Platform; import javafx.application.Platform;
import java.time.Duration;
import java.time.Instant;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@FxApplicationScoped @FxApplicationScoped
@@ -17,6 +21,7 @@ public class FxApplication {
private static final Logger LOG = LoggerFactory.getLogger(FxApplication.class); private static final Logger LOG = LoggerFactory.getLogger(FxApplication.class);
private final long startupTime; private final long startupTime;
private final Environment environment;
private final Settings settings; private final Settings settings;
private final AppLaunchEventHandler launchEventHandler; private final AppLaunchEventHandler launchEventHandler;
private final Lazy<TrayMenuComponent> trayMenu; private final Lazy<TrayMenuComponent> trayMenu;
@@ -26,8 +31,9 @@ public class FxApplication {
private final AutoUnlocker autoUnlocker; private final AutoUnlocker autoUnlocker;
@Inject @Inject
FxApplication(@Named("startupTime") long startupTime, Settings settings, AppLaunchEventHandler launchEventHandler, Lazy<TrayMenuComponent> trayMenu, FxApplicationWindows appWindows, FxApplicationStyle applicationStyle, FxApplicationTerminator applicationTerminator, AutoUnlocker autoUnlocker) { FxApplication(@Named("startupTime") long startupTime, Environment environment, Settings settings, AppLaunchEventHandler launchEventHandler, Lazy<TrayMenuComponent> trayMenu, FxApplicationWindows appWindows, FxApplicationStyle applicationStyle, FxApplicationTerminator applicationTerminator, AutoUnlocker autoUnlocker) {
this.startupTime = startupTime; this.startupTime = startupTime;
this.environment = environment;
this.settings = settings; this.settings = settings;
this.launchEventHandler = launchEventHandler; this.launchEventHandler = launchEventHandler;
this.trayMenu = trayMenu; this.trayMenu = trayMenu;
@@ -68,9 +74,35 @@ public class FxApplication {
return null; return null;
}); });
appWindows.checkAndShowUpdateReminderWindow(); var time14DaysAgo = Instant.now().minus(Duration.ofDays(14));
if (!environment.disableUpdateCheck() //
&& !settings.checkForUpdates.getValue() //
&& settings.lastSuccessfulUpdateCheck.get().isBefore(time14DaysAgo) //
&& settings.lastUpdateCheckReminder.get().isBefore(time14DaysAgo)) {
appWindows.showUpdateReminderWindow();
}
migrateAndInformDokanyRemoval();
launchEventHandler.startHandlingLaunchEvents(); launchEventHandler.startHandlingLaunchEvents();
autoUnlocker.tryUnlockForTimespan(2, TimeUnit.MINUTES); autoUnlocker.tryUnlockForTimespan(2, TimeUnit.MINUTES);
} }
private void migrateAndInformDokanyRemoval() {
var dokanyProviderId = "org.cryptomator.frontend.dokany.mount.DokanyMountProvider";
boolean dokanyFound = false;
if (settings.mountService.getValueSafe().equals(dokanyProviderId)) {
dokanyFound = true;
settings.mountService.set(null);
}
for (VaultSettings vaultSettings : settings.directories) {
if (vaultSettings.mountService.getValueSafe().equals(dokanyProviderId)) {
dokanyFound = true;
vaultSettings.mountService.set(null);
}
}
if (dokanyFound) {
appWindows.showDokanySupportEndWindow();
}
}
} }
@@ -13,6 +13,7 @@ import org.cryptomator.ui.lock.LockComponent;
import org.cryptomator.ui.mainwindow.MainWindowComponent; import org.cryptomator.ui.mainwindow.MainWindowComponent;
import org.cryptomator.ui.preferences.PreferencesComponent; import org.cryptomator.ui.preferences.PreferencesComponent;
import org.cryptomator.ui.quit.QuitComponent; import org.cryptomator.ui.quit.QuitComponent;
import org.cryptomator.ui.sharevault.ShareVaultComponent;
import org.cryptomator.ui.traymenu.TrayMenuComponent; import org.cryptomator.ui.traymenu.TrayMenuComponent;
import org.cryptomator.ui.unlock.UnlockComponent; import org.cryptomator.ui.unlock.UnlockComponent;
import org.cryptomator.ui.updatereminder.UpdateReminderComponent; import org.cryptomator.ui.updatereminder.UpdateReminderComponent;
@@ -22,7 +23,17 @@ import javafx.scene.image.Image;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
@Module(includes = {UpdateCheckerModule.class}, subcomponents = {TrayMenuComponent.class, MainWindowComponent.class, PreferencesComponent.class, VaultOptionsComponent.class, UnlockComponent.class, LockComponent.class, QuitComponent.class, ErrorComponent.class, HealthCheckComponent.class, UpdateReminderComponent.class}) @Module(includes = {UpdateCheckerModule.class}, subcomponents = {TrayMenuComponent.class, //
MainWindowComponent.class, //
PreferencesComponent.class, //
VaultOptionsComponent.class, //
UnlockComponent.class, //
LockComponent.class, //
QuitComponent.class, //
ErrorComponent.class, //
HealthCheckComponent.class, //
UpdateReminderComponent.class, //
ShareVaultComponent.class})
abstract class FxApplicationModule { abstract class FxApplicationModule {
private static Image createImageFromResource(String resourceName) throws IOException { private static Image createImageFromResource(String resourceName) throws IOException {
@@ -5,12 +5,14 @@ import dagger.Lazy;
import org.cryptomator.common.vaults.Vault; import org.cryptomator.common.vaults.Vault;
import org.cryptomator.common.vaults.VaultState; import org.cryptomator.common.vaults.VaultState;
import org.cryptomator.integrations.tray.TrayIntegrationProvider; import org.cryptomator.integrations.tray.TrayIntegrationProvider;
import org.cryptomator.ui.dialogs.Dialogs;
import org.cryptomator.ui.error.ErrorComponent; import org.cryptomator.ui.error.ErrorComponent;
import org.cryptomator.ui.lock.LockComponent; import org.cryptomator.ui.lock.LockComponent;
import org.cryptomator.ui.mainwindow.MainWindowComponent; import org.cryptomator.ui.mainwindow.MainWindowComponent;
import org.cryptomator.ui.preferences.PreferencesComponent; import org.cryptomator.ui.preferences.PreferencesComponent;
import org.cryptomator.ui.preferences.SelectedPreferencesTab; import org.cryptomator.ui.preferences.SelectedPreferencesTab;
import org.cryptomator.ui.quit.QuitComponent; import org.cryptomator.ui.quit.QuitComponent;
import org.cryptomator.ui.sharevault.ShareVaultComponent;
import org.cryptomator.ui.unlock.UnlockComponent; import org.cryptomator.ui.unlock.UnlockComponent;
import org.cryptomator.ui.unlock.UnlockWorkflow; import org.cryptomator.ui.unlock.UnlockWorkflow;
import org.cryptomator.ui.updatereminder.UpdateReminderComponent; import org.cryptomator.ui.updatereminder.UpdateReminderComponent;
@@ -46,37 +48,43 @@ public class FxApplicationWindows {
private final Lazy<PreferencesComponent> preferencesWindow; private final Lazy<PreferencesComponent> preferencesWindow;
private final QuitComponent.Builder quitWindowBuilder; private final QuitComponent.Builder quitWindowBuilder;
private final UnlockComponent.Factory unlockWorkflowFactory; private final UnlockComponent.Factory unlockWorkflowFactory;
private final UpdateReminderComponent.Factory updateReminderWindowBuilder; private final UpdateReminderComponent.Factory updateReminderWindowFactory;
private final LockComponent.Factory lockWorkflowFactory; private final LockComponent.Factory lockWorkflowFactory;
private final ErrorComponent.Factory errorWindowFactory; private final ErrorComponent.Factory errorWindowFactory;
private final ExecutorService executor; private final ExecutorService executor;
private final VaultOptionsComponent.Factory vaultOptionsWindow; private final VaultOptionsComponent.Factory vaultOptionsWindow;
private final ShareVaultComponent.Factory shareVaultWindow;
private final FilteredList<Window> visibleWindows; private final FilteredList<Window> visibleWindows;
private final Dialogs dialogs;
@Inject @Inject
public FxApplicationWindows(@PrimaryStage Stage primaryStage, public FxApplicationWindows(@PrimaryStage Stage primaryStage, //
Optional<TrayIntegrationProvider> trayIntegration, // Optional<TrayIntegrationProvider> trayIntegration, //
Lazy<MainWindowComponent> mainWindow, // Lazy<MainWindowComponent> mainWindow, //
Lazy<PreferencesComponent> preferencesWindow, // Lazy<PreferencesComponent> preferencesWindow, //
QuitComponent.Builder quitWindowBuilder, // QuitComponent.Builder quitWindowBuilder, //
UnlockComponent.Factory unlockWorkflowFactory, // UnlockComponent.Factory unlockWorkflowFactory, //
UpdateReminderComponent.Factory updateReminderWindowBuilder, // UpdateReminderComponent.Factory updateReminderWindowFactory, //
LockComponent.Factory lockWorkflowFactory, // LockComponent.Factory lockWorkflowFactory, //
ErrorComponent.Factory errorWindowFactory, // ErrorComponent.Factory errorWindowFactory, //
VaultOptionsComponent.Factory vaultOptionsWindow, // VaultOptionsComponent.Factory vaultOptionsWindow, //
ExecutorService executor) { ShareVaultComponent.Factory shareVaultWindow, //
ExecutorService executor, //
Dialogs dialogs) {
this.primaryStage = primaryStage; this.primaryStage = primaryStage;
this.trayIntegration = trayIntegration; this.trayIntegration = trayIntegration;
this.mainWindow = mainWindow; this.mainWindow = mainWindow;
this.preferencesWindow = preferencesWindow; this.preferencesWindow = preferencesWindow;
this.quitWindowBuilder = quitWindowBuilder; this.quitWindowBuilder = quitWindowBuilder;
this.unlockWorkflowFactory = unlockWorkflowFactory; this.unlockWorkflowFactory = unlockWorkflowFactory;
this.updateReminderWindowBuilder = updateReminderWindowBuilder; this.updateReminderWindowFactory = updateReminderWindowFactory;
this.lockWorkflowFactory = lockWorkflowFactory; this.lockWorkflowFactory = lockWorkflowFactory;
this.errorWindowFactory = errorWindowFactory; this.errorWindowFactory = errorWindowFactory;
this.executor = executor; this.executor = executor;
this.vaultOptionsWindow = vaultOptionsWindow; this.vaultOptionsWindow = vaultOptionsWindow;
this.shareVaultWindow = shareVaultWindow;
this.visibleWindows = Window.getWindows().filtered(Window::isShowing); this.visibleWindows = Window.getWindows().filtered(Window::isShowing);
this.dialogs = dialogs;
} }
public void initialize() { public void initialize() {
@@ -122,6 +130,10 @@ public class FxApplicationWindows {
return CompletableFuture.supplyAsync(() -> preferencesWindow.get().showPreferencesWindow(selectedTab), Platform::runLater).whenComplete(this::reportErrors); return CompletableFuture.supplyAsync(() -> preferencesWindow.get().showPreferencesWindow(selectedTab), Platform::runLater).whenComplete(this::reportErrors);
} }
public void showShareVaultWindow(Vault vault) {
CompletableFuture.runAsync(() -> shareVaultWindow.create(vault).showShareVaultWindow(), Platform::runLater);
}
public CompletionStage<Stage> showVaultOptionsWindow(Vault vault, SelectedVaultOptionsTab tab) { public CompletionStage<Stage> showVaultOptionsWindow(Vault vault, SelectedVaultOptionsTab tab) {
return showMainWindow().thenApplyAsync((window) -> vaultOptionsWindow.create(vault).showVaultOptionsWindow(tab), Platform::runLater).whenComplete(this::reportErrors); return showMainWindow().thenApplyAsync((window) -> vaultOptionsWindow.create(vault).showVaultOptionsWindow(tab), Platform::runLater).whenComplete(this::reportErrors);
} }
@@ -130,8 +142,18 @@ public class FxApplicationWindows {
CompletableFuture.runAsync(() -> quitWindowBuilder.build().showQuitWindow(response,forced), Platform::runLater); CompletableFuture.runAsync(() -> quitWindowBuilder.build().showQuitWindow(response,forced), Platform::runLater);
} }
public void checkAndShowUpdateReminderWindow() { public void showUpdateReminderWindow() {
CompletableFuture.runAsync(() -> updateReminderWindowBuilder.create().checkAndShowUpdateReminderWindow(), Platform::runLater); CompletableFuture.runAsync(() -> updateReminderWindowFactory.create().showUpdateReminderWindow(), Platform::runLater);
}
public void showDokanySupportEndWindow() {
CompletableFuture.runAsync(() -> dialogs.prepareDokanySupportEndDialog(
mainWindow.get().window(),
stage -> {
showPreferencesWindow(SelectedPreferencesTab.VOLUME);
stage.close();
}
).build().showAndWait(), Platform::runLater);
} }
public CompletionStage<Void> startUnlockWorkflow(Vault vault, @Nullable Stage owner) { public CompletionStage<Void> startUnlockWorkflow(Vault vault, @Nullable Stage owner) {
@@ -1,45 +1,57 @@
package org.cryptomator.ui.fxapp; package org.cryptomator.ui.fxapp;
import org.cryptomator.common.Environment; import org.cryptomator.common.Environment;
import org.cryptomator.common.SemVerComparator;
import org.cryptomator.common.settings.Settings; import org.cryptomator.common.settings.Settings;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Named; import javafx.beans.binding.Bindings;
import javafx.beans.binding.BooleanBinding; import javafx.beans.binding.BooleanBinding;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.ReadOnlyStringProperty; import javafx.beans.property.ReadOnlyStringProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty; import javafx.beans.property.StringProperty;
import javafx.concurrent.ScheduledService; import javafx.concurrent.ScheduledService;
import javafx.concurrent.Worker; import javafx.concurrent.Worker;
import javafx.concurrent.WorkerStateEvent; import javafx.concurrent.WorkerStateEvent;
import javafx.util.Duration; import javafx.util.Duration;
import java.time.Instant;
import java.util.Comparator; import java.util.Comparator;
@FxApplicationScoped @FxApplicationScoped
public class UpdateChecker { public class UpdateChecker {
private static final Logger LOG = LoggerFactory.getLogger(UpdateChecker.class); private static final Logger LOG = LoggerFactory.getLogger(UpdateChecker.class);
private static final Duration AUTOCHECK_DELAY = Duration.seconds(5); private static final Duration AUTO_CHECK_DELAY = Duration.seconds(5);
private final Environment env;
private final Settings settings; private final Settings settings;
private final String currentVersion; private final StringProperty latestVersion = new SimpleStringProperty();
private final StringProperty latestVersionProperty;
private final Comparator<String> semVerComparator;
private final ScheduledService<String> updateCheckerService; private final ScheduledService<String> updateCheckerService;
private final ObjectProperty<UpdateCheckState> state = new SimpleObjectProperty<>(UpdateCheckState.NOT_CHECKED);
private final ObjectProperty<Instant> lastSuccessfulUpdateCheck;
private final Comparator<String> versionComparator = new SemVerComparator();
private final BooleanBinding updateAvailable;
private final BooleanBinding checkFailed;
@Inject @Inject
UpdateChecker(Settings settings, Environment env, @Named("latestVersion") StringProperty latestVersionProperty, @Named("SemVer") Comparator<String> semVerComparator, ScheduledService<String> updateCheckerService) { UpdateChecker(Settings settings, //
Environment env, //
ScheduledService<String> updateCheckerService) {
this.env = env;
this.settings = settings; this.settings = settings;
this.latestVersionProperty = latestVersionProperty;
this.semVerComparator = semVerComparator;
this.updateCheckerService = updateCheckerService; this.updateCheckerService = updateCheckerService;
this.currentVersion = env.getAppVersion(); this.lastSuccessfulUpdateCheck = settings.lastSuccessfulUpdateCheck;
this.updateAvailable = Bindings.createBooleanBinding(this::isUpdateAvailable, latestVersion);
this.checkFailed = Bindings.equal(UpdateCheckState.CHECK_FAILED, state);
} }
public void automaticallyCheckForUpdatesIfEnabled() { public void automaticallyCheckForUpdatesIfEnabled() {
if (settings.checkForUpdates.get()) { if (!env.disableUpdateCheck() && settings.checkForUpdates.get()) {
startCheckingForUpdates(AUTOCHECK_DELAY); startCheckingForUpdates(AUTO_CHECK_DELAY);
} }
} }
@@ -59,36 +71,65 @@ public class UpdateChecker {
private void checkStarted(WorkerStateEvent event) { private void checkStarted(WorkerStateEvent event) {
LOG.debug("Checking for updates..."); LOG.debug("Checking for updates...");
state.set(UpdateCheckState.IS_CHECKING);
} }
private void checkSucceeded(WorkerStateEvent event) { private void checkSucceeded(WorkerStateEvent event) {
String latestVersion = updateCheckerService.getValue(); var latestVersionString = updateCheckerService.getValue();
LOG.info("Current version: {}, lastest version: {}", currentVersion, latestVersion); LOG.info("Current version: {}, latest version: {}", getCurrentVersion(), latestVersionString);
lastSuccessfulUpdateCheck.set(Instant.now());
if (semVerComparator.compare(currentVersion, latestVersion) < 0) { latestVersion.set(latestVersionString);
// update is available state.set(UpdateCheckState.CHECK_SUCCESSFUL);
latestVersionProperty.set(latestVersion);
} else {
latestVersionProperty.set(null);
}
} }
private void checkFailed(WorkerStateEvent event) { private void checkFailed(WorkerStateEvent event) {
LOG.warn("Error checking for updates", event.getSource().getException()); state.set(UpdateCheckState.CHECK_FAILED);
}
public enum UpdateCheckState {
NOT_CHECKED,
IS_CHECKING,
CHECK_SUCCESSFUL,
CHECK_FAILED;
} }
/* Observable Properties */ /* Observable Properties */
public BooleanBinding checkingForUpdatesProperty() { public BooleanBinding checkingForUpdatesProperty() {
return updateCheckerService.stateProperty().isEqualTo(Worker.State.RUNNING); return updateCheckerService.stateProperty().isEqualTo(Worker.State.RUNNING);
} }
public ReadOnlyStringProperty latestVersionProperty() { public ReadOnlyStringProperty latestVersionProperty() {
return latestVersionProperty; return latestVersion;
}
public BooleanBinding updateAvailableProperty() {
return updateAvailable;
}
public BooleanBinding checkFailedProperty() {
return checkFailed;
}
public boolean isUpdateAvailable() {
String currentVersion = getCurrentVersion();
String latestVersionString = latestVersion.get();
if (currentVersion == null || latestVersionString == null) {
return false;
} else {
return versionComparator.compare(currentVersion, latestVersionString) < 0;
}
}
public ObjectProperty<Instant> lastSuccessfulUpdateCheckProperty() {
return lastSuccessfulUpdateCheck;
}
public ObjectProperty<UpdateCheckState> updateCheckStateProperty() {
return state;
} }
public String getCurrentVersion() { public String getCurrentVersion() {
return currentVersion; return env.getAppVersion();
} }
} }
@@ -11,8 +11,6 @@ import org.slf4j.LoggerFactory;
import javax.inject.Named; import javax.inject.Named;
import javafx.beans.binding.Bindings; import javafx.beans.binding.Bindings;
import javafx.beans.binding.ObjectBinding; import javafx.beans.binding.ObjectBinding;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.concurrent.ScheduledService; import javafx.concurrent.ScheduledService;
import javafx.concurrent.Task; import javafx.concurrent.Task;
import javafx.util.Duration; import javafx.util.Duration;
@@ -32,13 +30,6 @@ public abstract class UpdateCheckerModule {
private static final Duration UPDATE_CHECK_INTERVAL = Duration.hours(3); private static final Duration UPDATE_CHECK_INTERVAL = Duration.hours(3);
private static final Duration DISABLED_UPDATE_CHECK_INTERVAL = Duration.hours(100000); // Duration.INDEFINITE leads to overflows... private static final Duration DISABLED_UPDATE_CHECK_INTERVAL = Duration.hours(100000); // Duration.INDEFINITE leads to overflows...
@Provides
@Named("latestVersion")
@FxApplicationScoped
static StringProperty provideLatestVersion() {
return new SimpleStringProperty();
}
@Provides @Provides
@FxApplicationScoped @FxApplicationScoped
static Optional<HttpClient> provideHttpClient() { static Optional<HttpClient> provideHttpClient() {
@@ -63,6 +54,7 @@ public abstract class UpdateCheckerModule {
return HttpRequest.newBuilder() // return HttpRequest.newBuilder() //
.uri(LATEST_VERSION_URI) // .uri(LATEST_VERSION_URI) //
.header("User-Agent", userAgent) // .header("User-Agent", userAgent) //
.timeout(java.time.Duration.ofSeconds(10))
.build(); .build();
} }
@@ -25,6 +25,8 @@ public interface HealthCheckComponent {
default Stage showHealthCheckWindow() { default Stage showHealthCheckWindow() {
Stage stage = window(); Stage stage = window();
stage.setScene(startScene().get()); stage.setScene(startScene().get());
stage.setMinWidth(420);
stage.setMinHeight(300);
stage.show(); stage.show();
return stage; return stage;
} }
@@ -101,16 +101,16 @@ public class StartController implements FxController {
} }
} }
private void loadingKeyFailed(Throwable e) { private void loadingKeyFailed(Throwable t) {
switch (e) { switch (t) {
case UnlockCancelledException uce -> {} //ok case UnlockCancelledException e -> {} // ok // TODO: rename to _ with JEP 443
case VaultKeyInvalidException vkie -> { case VaultKeyInvalidException e -> { // TODO: rename to _ with JEP 443
LOG.error("Invalid key"); //TODO: specific error screen LOG.error("Invalid key"); // TODO: specific error screen
appWindows.showErrorWindow(e, window, null); appWindows.showErrorWindow(e, window, null);
} }
default -> { default -> {
LOG.error("Failed to load key.", e); LOG.error("Failed to load key.", t);
appWindows.showErrorWindow(e, window, null); appWindows.showErrorWindow(t, window, null);
} }
} }
} }
@@ -35,13 +35,13 @@ public class AuthFlowController implements FxController {
private final String deviceId; private final String deviceId;
private final HubConfig hubConfig; private final HubConfig hubConfig;
private final AtomicReference<String> tokenRef; private final AtomicReference<String> tokenRef;
private final CompletableFuture<JWEObject> result; private final CompletableFuture<ReceivedKey> result;
private final Lazy<Scene> receiveKeyScene; private final Lazy<Scene> receiveKeyScene;
private final ObjectProperty<URI> authUri; private final ObjectProperty<URI> authUri;
private AuthFlowTask task; private AuthFlowTask task;
@Inject @Inject
public AuthFlowController(Application application, @KeyLoading Stage window, ExecutorService executor, @Named("deviceId") String deviceId, HubConfig hubConfig, @Named("bearerToken") AtomicReference<String> tokenRef, CompletableFuture<JWEObject> result, @FxmlScene(FxmlFile.HUB_RECEIVE_KEY) Lazy<Scene> receiveKeyScene) { public AuthFlowController(Application application, @KeyLoading Stage window, ExecutorService executor, @Named("deviceId") String deviceId, HubConfig hubConfig, @Named("bearerToken") AtomicReference<String> tokenRef, CompletableFuture<ReceivedKey> result, @FxmlScene(FxmlFile.HUB_RECEIVE_KEY) Lazy<Scene> receiveKeyScene) {
this.application = application; this.application = application;
this.window = window; this.window = window;
this.executor = executor; this.executor = executor;
@@ -1,13 +1,14 @@
package org.cryptomator.ui.keyloading.hub; package org.cryptomator.ui.keyloading.hub;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import io.github.coffeelibs.tinyoauth2client.AuthFlow;
import io.github.coffeelibs.tinyoauth2client.TinyOAuth2; import io.github.coffeelibs.tinyoauth2client.TinyOAuth2;
import io.github.coffeelibs.tinyoauth2client.http.response.Response; import io.github.coffeelibs.tinyoauth2client.http.response.Response;
import javafx.concurrent.Task; import javafx.concurrent.Task;
import java.io.IOException; import java.io.IOException;
import java.net.URI; import java.net.URI;
import java.net.http.HttpClient;
import java.time.Duration;
import java.util.function.Consumer; import java.util.function.Consumer;
class AuthFlowTask extends Task<String> { class AuthFlowTask extends Task<String> {
@@ -21,7 +22,7 @@ class AuthFlowTask extends Task<String> {
/** /**
* Spawns a server and waits for the redirectUri to be called. * Spawns a server and waits for the redirectUri to be called.
* *
* @param hubConfig Configuration object holding parameters required by {@link AuthFlow} * @param hubConfig Configuration object holding parameters required by {@link io.github.coffeelibs.tinyoauth2client.AuthorizationCodeGrant}
* @param redirectUriConsumer A callback invoked with the redirectUri, as soon as the server has started * @param redirectUriConsumer A callback invoked with the redirectUri, as soon as the server has started
*/ */
public AuthFlowTask(HubConfig hubConfig, AuthFlowContext authFlowContext, Consumer<URI> redirectUriConsumer) { public AuthFlowTask(HubConfig hubConfig, AuthFlowContext authFlowContext, Consumer<URI> redirectUriConsumer) {
@@ -34,10 +35,11 @@ class AuthFlowTask extends Task<String> {
protected String call() throws IOException, InterruptedException { protected String call() throws IOException, InterruptedException {
var response = TinyOAuth2.client(hubConfig.clientId) // var response = TinyOAuth2.client(hubConfig.clientId) //
.withTokenEndpoint(URI.create(hubConfig.tokenEndpoint)) // .withTokenEndpoint(URI.create(hubConfig.tokenEndpoint)) //
.authFlow(URI.create(hubConfig.authEndpoint)) // .withRequestTimeout(Duration.ofSeconds(10)) //
.authorizationCodeGrant(URI.create(hubConfig.authEndpoint)) //
.setSuccessResponse(Response.redirect(URI.create(hubConfig.authSuccessUrl + "&device=" + authFlowContext.deviceId()))) // .setSuccessResponse(Response.redirect(URI.create(hubConfig.authSuccessUrl + "&device=" + authFlowContext.deviceId()))) //
.setErrorResponse(Response.redirect(URI.create(hubConfig.authErrorUrl + "&device=" + authFlowContext.deviceId()))) // .setErrorResponse(Response.redirect(URI.create(hubConfig.authErrorUrl + "&device=" + authFlowContext.deviceId()))) //
.authorize(redirectUriConsumer); .authorize(HttpClient.newHttpClient(), redirectUriConsumer);
if (response.statusCode() != 200) { if (response.statusCode() != 200) {
throw new NotOkResponseException("Authorization returned status code " + response.statusCode()); throw new NotOkResponseException("Authorization returned status code " + response.statusCode());
} }
@@ -1,5 +0,0 @@
package org.cryptomator.ui.keyloading.hub;
record CreateDeviceDto(String id, String name, String publicKey) {
}
@@ -0,0 +1,12 @@
package org.cryptomator.ui.keyloading.hub;
import org.cryptomator.cryptolib.api.MasterkeyLoadingFailedException;
/**
* Thrown, when Hub registerDevice-Request returns with 409
*/
class DeviceAlreadyExistsException extends MasterkeyLoadingFailedException {
public DeviceAlreadyExistsException() {
super("Device already registered on this Hub instance");
}
}
@@ -1,19 +0,0 @@
package org.cryptomator.ui.keyloading.hub;
import com.google.common.io.CharStreams;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
class HttpHelper {
public static String readBody(HttpResponse<InputStream> response) throws IOException {
try (var in = response.body(); var reader = new InputStreamReader(in, StandardCharsets.UTF_8)) {
return CharStreams.toString(reader);
}
}
}
@@ -1,6 +1,10 @@
package org.cryptomator.ui.keyloading.hub; package org.cryptomator.ui.keyloading.hub;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import org.jetbrains.annotations.Nullable;
import java.net.URI;
// needs to be accessible by JSON decoder // needs to be accessible by JSON decoder
@JsonIgnoreProperties(ignoreUnknown = true) @JsonIgnoreProperties(ignoreUnknown = true)
@@ -9,8 +13,56 @@ public class HubConfig {
public String clientId; public String clientId;
public String authEndpoint; public String authEndpoint;
public String tokenEndpoint; public String tokenEndpoint;
public String devicesResourceUrl;
public String authSuccessUrl; public String authSuccessUrl;
public String authErrorUrl; public String authErrorUrl;
public @Nullable String apiBaseUrl;
@Deprecated // use apiBaseUrl + "/devices/"
public String devicesResourceUrl;
/**
* A collection of functions to construct URIs related to this Hub instance.
*/
@JsonIgnore
public final URIProcessors URIs = new URIProcessors();
/**
* Get the URI pointing to the <code>/api/</code> base resource.
*
* @return <code>/api/</code> URI
* @apiNote URI is guaranteed to end on <code>/</code>
* @see #URIs
*/
public URI getApiBaseUrl() {
if (apiBaseUrl != null) {
// make sure to end on "/":
return URI.create(apiBaseUrl + "/").normalize();
} else { // legacy approach
assert devicesResourceUrl != null;
// make sure to end on "/":
return URI.create(devicesResourceUrl + "/..").normalize();
}
}
public URI getWebappBaseUrl() {
return getApiBaseUrl().resolve("../app/");
}
public class URIProcessors {
public final URIProcessor API = this::fromApiEndpoint;
/**
* Resolves paths relative to the <code>/api/</code> endpoint of this Hub instance.
*/
public URI fromApiEndpoint(String path) {
var relPath = path.startsWith("/") ? path.substring(1) : path;
return getApiBaseUrl().resolve(relPath);
}
}
@FunctionalInterface
public interface URIProcessor {
URI resolve(String path);
}
} }

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