mirror of
https://github.com/cryptomator/cryptomator.git
synced 2026-09-22 07:54:19 +00:00
Compare commits
639
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3f06460667 | ||
|
|
617f1bf2c9 | ||
|
|
02ad38f871 | ||
|
|
7a2944cbea | ||
|
|
4c47204f92 | ||
|
|
f052395a7f | ||
|
|
57be83b38d | ||
|
|
c2cd4f5bbf | ||
|
|
d3d57312ba | ||
|
|
593a64c9bd | ||
|
|
19dc4fb6ff | ||
|
|
81f45012f3 | ||
|
|
c59554f7bb | ||
|
|
11c66e8df7 | ||
|
|
c49bf0f146 | ||
|
|
e74bd91879 | ||
|
|
89d9249a08 | ||
|
|
013fff1223 | ||
|
|
fd9d27215e | ||
|
|
f91cc2374c | ||
|
|
48298bb161 | ||
|
|
7a1cd9026c | ||
|
|
754e53d8db | ||
|
|
c36f1bc8d0 | ||
|
|
7315b59a6d | ||
|
|
8a243a01aa | ||
|
|
9e4006cc89 | ||
|
|
26b69beb87 | ||
|
|
f95bf87a4b | ||
|
|
e854c7d189 | ||
|
|
8a434dcd96 | ||
|
|
6b7324723e | ||
|
|
0bdcb2b3be | ||
|
|
c3931d9d29 | ||
|
|
307825a339 | ||
|
|
093f0e8c94 | ||
|
|
c938c42c00 | ||
|
|
884c6f6bdd | ||
|
|
c5367db971 | ||
|
|
59560193ee | ||
|
|
a6b31e19b9 | ||
|
|
8a44115234 | ||
|
|
43a1f00bea | ||
|
|
3e458060bc | ||
|
|
4bb5a3f10d | ||
|
|
8bb451261e | ||
|
|
de4c7d47e5 | ||
|
|
b4fe63c966 | ||
|
|
ed45182b6c | ||
|
|
afd2d74c90 | ||
|
|
4bcf01270a | ||
|
|
64466df6b8 | ||
|
|
db9bd49dd9 | ||
|
|
4ed4a3e3e5 | ||
|
|
ad73b2f31d | ||
|
|
227b322b8a | ||
|
|
ccf2e60390 | ||
|
|
1104c1067a | ||
|
|
83d2c39080 | ||
|
|
446caff901 | ||
|
|
90537caee7 | ||
|
|
25dea8ebe6 | ||
|
|
4a7d2907c8 | ||
|
|
7f3af0c7f6 | ||
|
|
e6e04078fa | ||
|
|
e3f6b5f812 | ||
|
|
f3461f7da4 | ||
|
|
94518ede99 | ||
|
|
0fa041da85 | ||
|
|
daa4f3a568 | ||
|
|
fc6f7d184c | ||
|
|
e50c949b62 | ||
|
|
349349e057 | ||
|
|
4b36a1219f | ||
|
|
6533ba7367 | ||
|
|
7f9c9a7df6 | ||
|
|
afda8a4981 | ||
|
|
153f9b485c | ||
|
|
b9e91115b4 | ||
|
|
cdcd43a805 | ||
|
|
2d29b1a76f | ||
|
|
f62a5ed74b | ||
|
|
7fe7e1f5bf | ||
|
|
a4d9703cf4 | ||
|
|
c9a3a775cc | ||
|
|
e7cac42d5d | ||
|
|
983e7d973b | ||
|
|
a84ac94701 | ||
|
|
4761c58265 | ||
|
|
682e762a5a | ||
|
|
c3ada43abb | ||
|
|
9a71782fff | ||
|
|
2f4c12a89e | ||
|
|
2b79c58577 | ||
|
|
1d3c62e2c7 | ||
|
|
17166c45ac | ||
|
|
f758388063 | ||
|
|
8767564977 | ||
|
|
59f47116f0 | ||
|
|
8fac541024 | ||
|
|
1ba21b531a | ||
|
|
daad48d5af | ||
|
|
8eedc62fbe | ||
|
|
d65442f042 | ||
|
|
216513405a | ||
|
|
f4c0bc29ed | ||
|
|
d1ce0362b4 | ||
|
|
4497fb160e | ||
|
|
5bffa28cdb | ||
|
|
14c5693594 | ||
|
|
53c6045cca | ||
|
|
16d441ec44 | ||
|
|
fa053ac3df | ||
|
|
e78a064af6 | ||
|
|
d5245009f4 | ||
|
|
8f4392711e | ||
|
|
644e38f49e | ||
|
|
3b38049d71 | ||
|
|
79bb4a5215 | ||
|
|
c199d1cb3b | ||
|
|
164a4de6de | ||
|
|
2ce7fee06d | ||
|
|
99e9e92f10 | ||
|
|
8e6500d93f | ||
|
|
89ce99deaf | ||
|
|
510e134605 | ||
|
|
62b434f549 | ||
|
|
1f1e336d57 | ||
|
|
f64455d8fb | ||
|
|
8b1d2101db | ||
|
|
22a37699ea | ||
|
|
44f92cfb26 | ||
|
|
27c10080d6 | ||
|
|
2067c5a33b | ||
|
|
fc5ed9ecc0 | ||
|
|
5e956c50c2 | ||
|
|
5110b35690 | ||
|
|
499960b3ec | ||
|
|
f6479ddf24 | ||
|
|
5d8b016e5f | ||
|
|
2bf2f2b616 | ||
|
|
1089e90ebf | ||
|
|
9fee4afd2a | ||
|
|
7ad9b10138 | ||
|
|
fb6e4f0c15 | ||
|
|
6c5f3cb72c | ||
|
|
581b16e354 | ||
|
|
d74248ff63 | ||
|
|
698ac639e9 | ||
|
|
5a086f52b5 | ||
|
|
54b7f3c842 | ||
|
|
94b9813c50 | ||
|
|
b00ee4740a | ||
|
|
78cffe2f60 | ||
|
|
9d15a7664d | ||
|
|
02186ca17a | ||
|
|
b0ed133e05 | ||
|
|
f5ecf846f2 | ||
|
|
a9444182bb | ||
|
|
191d9473c0 | ||
|
|
8089bcd0d0 | ||
|
|
5d8457cbdd | ||
|
|
f623b1ee7e | ||
|
|
c546f3363b | ||
|
|
8a1ec1d073 | ||
|
|
81307b6d75 | ||
|
|
50fa8e0608 | ||
|
|
626a692d63 | ||
|
|
c9b9eee564 | ||
|
|
edc308ccd1 | ||
|
|
ad214691f9 | ||
|
|
acf11da202 | ||
|
|
94eb1e365b | ||
|
|
414ccad8fb | ||
|
|
e57e5358c4 | ||
|
|
e24719ed19 | ||
|
|
e21525ce2e | ||
|
|
9a14cfc674 | ||
|
|
9af9362a7b | ||
|
|
4d4a93746d | ||
|
|
4280112eab | ||
|
|
638e1e562d | ||
|
|
321bd2ff8c | ||
|
|
323a884718 | ||
|
|
5bdfffd151 | ||
|
|
cb6b77318d | ||
|
|
6fcec26eea | ||
|
|
feb9fb689e | ||
|
|
0178ca4080 | ||
|
|
4ddb6b73bd | ||
|
|
da845c6941 | ||
|
|
c30a28aae0 | ||
|
|
5305c5a631 | ||
|
|
b0d2dcbff3 | ||
|
|
5c1364792e | ||
|
|
abf8392baa | ||
|
|
034a70d473 | ||
|
|
79f2863f24 | ||
|
|
f1ef506e2b | ||
|
|
8c9d75fe57 | ||
|
|
d00d77b747 | ||
|
|
fbeeaa4c93 | ||
|
|
00f5d433da | ||
|
|
115a4216ee | ||
|
|
403d469dff | ||
|
|
ddf112bdfa | ||
|
|
2ade07da75 | ||
|
|
e6a0339878 | ||
|
|
2b0c2cf90a | ||
|
|
2afd8d0988 | ||
|
|
f2bda6b5f9 | ||
|
|
0bb1bf81ec | ||
|
|
bf8d5ed09f | ||
|
|
e9f6854df8 | ||
|
|
6d47f28634 | ||
|
|
225332bd4f | ||
|
|
354225bf1e | ||
|
|
8c84720e24 | ||
|
|
0d4f373311 | ||
|
|
1da535e89c | ||
|
|
941b4e3652 | ||
|
|
dd1af8cd78 | ||
|
|
27ea29ab9d | ||
|
|
a699a794a9 | ||
|
|
cd6b1cf129 | ||
|
|
7d2c4992af | ||
|
|
968e8f51e4 | ||
|
|
6a21d24687 | ||
|
|
cba6ed9875 | ||
|
|
72fdc8f536 | ||
|
|
41336cca13 | ||
|
|
322907bbcd | ||
|
|
1f8df6fead | ||
|
|
6e085b783d | ||
|
|
59dddd3f4c | ||
|
|
d6bbcfbbc1 | ||
|
|
4de6b83e2f | ||
|
|
90cbb0c5f6 | ||
|
|
7260d7f9f8 | ||
|
|
c39c4be1cd | ||
|
|
565ab4a09b | ||
|
|
f797491a17 | ||
|
|
cff83b6ac6 | ||
|
|
6f9b3e31e7 | ||
|
|
0a0dde3f47 | ||
|
|
e27e303c01 | ||
|
|
ef54b685f6 | ||
|
|
0370fd5848 | ||
|
|
119d18d699 | ||
|
|
8322633b14 | ||
|
|
2f32fc5c16 | ||
|
|
7c44c4f194 | ||
|
|
bbb663f9d2 | ||
|
|
fdb4a2fb5c | ||
|
|
0a4684133d | ||
|
|
0d5e518af3 | ||
|
|
d47ab43fcf | ||
|
|
19a711d12b | ||
|
|
bf2db55d00 | ||
|
|
885975e099 | ||
|
|
85c2901484 | ||
|
|
434030b139 | ||
|
|
e43bb37758 | ||
|
|
2eb9f0fca8 | ||
|
|
9503feb9c4 | ||
|
|
08e9f130e4 | ||
|
|
4e39eaa1f1 | ||
|
|
eaca95e8dc | ||
|
|
cf32e794c8 | ||
|
|
b5b221a5c7 | ||
|
|
d7cb99a12d | ||
|
|
b1893c63d4 | ||
|
|
79b3274074 | ||
|
|
7c86e5e39a | ||
|
|
b50cc703b6 | ||
|
|
9dc4a1dc5a | ||
|
|
f1a63a1679 | ||
|
|
d53d4e3452 | ||
|
|
b7fa1ae6d8 | ||
|
|
3f192a587c | ||
|
|
3a1b0b17d6 | ||
|
|
5d2a243c55 | ||
|
|
008a2a3301 | ||
|
|
0680437004 | ||
|
|
db6cf5459e | ||
|
|
1d8466a9e3 | ||
|
|
dcbcd692e7 | ||
|
|
87fd6c712a | ||
|
|
958505559f | ||
|
|
4736e5e7e7 | ||
|
|
55d217887a | ||
|
|
34ccd3ff73 | ||
|
|
989c349331 | ||
|
|
b9df56a6de | ||
|
|
38dbefff0b | ||
|
|
4cbe45919b | ||
|
|
b7ccf7986d | ||
|
|
40d632a489 | ||
|
|
800aca5207 | ||
|
|
6a26d95c15 | ||
|
|
439d3d7529 | ||
|
|
7476e192a3 | ||
|
|
c6193bc259 | ||
|
|
7446c69cd8 | ||
|
|
e1cc61037e | ||
|
|
1ae951126a | ||
|
|
6bb8c0d4e7 | ||
|
|
087b6162ed | ||
|
|
f9e8031acb | ||
|
|
43c352e0d2 | ||
|
|
61ec3bc465 | ||
|
|
36dd98127d | ||
|
|
30862146b0 | ||
|
|
c19734da6f | ||
|
|
ba8fb273c7 | ||
|
|
5204a8e356 | ||
|
|
43b341860b | ||
|
|
ad02e43daf | ||
|
|
ebd767595b | ||
|
|
4942bcb52b | ||
|
|
6b2e718e04 | ||
|
|
a1323b5e81 | ||
|
|
ab4f487de1 | ||
|
|
d506e7472d | ||
|
|
2d33d02b46 | ||
|
|
06ddec4b70 | ||
|
|
6231c5b8b3 | ||
|
|
24e31553fd | ||
|
|
eaa6b31de8 | ||
|
|
a3b8297e23 | ||
|
|
060ae588a2 | ||
|
|
262f84e8db | ||
|
|
6d55331ef2 | ||
|
|
42269a6057 | ||
|
|
181e45a596 | ||
|
|
3c8e506805 | ||
|
|
401b0afe9f | ||
|
|
42ec41b991 | ||
|
|
7ec3c5d04f | ||
|
|
f0a7379575 | ||
|
|
0d12b11c48 | ||
|
|
14a025f769 | ||
|
|
598fc9bbc8 | ||
|
|
fbab2df00f | ||
|
|
fb56b61a75 | ||
|
|
c5c3d55658 | ||
|
|
48c2d49c86 | ||
|
|
00d68393f6 | ||
|
|
7a50ba0b43 | ||
|
|
b2bee99286 | ||
|
|
88d384afdf | ||
|
|
7af82b831f | ||
|
|
a86f42fa44 | ||
|
|
70b0413777 | ||
|
|
577a77af38 | ||
|
|
3ba7e9ba00 | ||
|
|
b2250e8ce0 | ||
|
|
f2a480c7a0 | ||
|
|
6715ff9f5f | ||
|
|
bda38096e1 | ||
|
|
7e66a61294 | ||
|
|
3aa627a467 | ||
|
|
ae1b5fc925 | ||
|
|
b1076f9c86 | ||
|
|
ede1c72595 | ||
|
|
8c5325511c | ||
|
|
d2fcd5b64f | ||
|
|
6d9704ffa2 | ||
|
|
40df3d015a | ||
|
|
4e22706d92 | ||
|
|
341710f724 | ||
|
|
8386183f7a | ||
|
|
b76a7d6895 | ||
|
|
4a397a8151 | ||
|
|
2239a3e6a3 | ||
|
|
5318368879 | ||
|
|
41a279da9d | ||
|
|
478c69f82c | ||
|
|
eb0e630a44 | ||
|
|
0bcbf9a13a | ||
|
|
e3073a3613 | ||
|
|
3333dc7f22 | ||
|
|
895614353e | ||
|
|
676c507a50 | ||
|
|
5f4fd92b1d | ||
|
|
12ec6fbec8 | ||
|
|
43fc976ad7 | ||
|
|
034278c0a0 | ||
|
|
92b3a9e1bd | ||
|
|
fc7169f2a0 | ||
|
|
c39710ede0 | ||
|
|
cc0b6aed15 | ||
|
|
f8a83c9cc8 | ||
|
|
43ce64f01e | ||
|
|
d585a03f76 | ||
|
|
f953be6237 | ||
|
|
e81bbe197b | ||
|
|
738fa4da12 | ||
|
|
9a08dcc46d | ||
|
|
74ef8d915d | ||
|
|
025a7a5582 | ||
|
|
3b2ddcf98d | ||
|
|
c10fc0ee5b | ||
|
|
aaa37e2c7a | ||
|
|
7af7c920e3 | ||
|
|
a4f79fb98a | ||
|
|
f429f2d3e7 | ||
|
|
4f6e091c13 | ||
|
|
2df779f7ab | ||
|
|
5b9d9150c5 | ||
|
|
f0aaec2058 | ||
|
|
4adc4a9175 | ||
|
|
5a97060fac | ||
|
|
db96074119 | ||
|
|
7ecc10bc79 | ||
|
|
44fe4a6f8a | ||
|
|
76a4ef50cb | ||
|
|
ca2f80024a | ||
|
|
dcd7077b08 | ||
|
|
31482d7d18 | ||
|
|
5ef666154e | ||
|
|
a810eff797 | ||
|
|
664158eb84 | ||
|
|
6b43881909 | ||
|
|
126004b1f8 | ||
|
|
ba34cfa9d5 | ||
|
|
03b4ad85ef | ||
|
|
1abfcd495f | ||
|
|
69964a80f1 | ||
|
|
aa8306ea4a | ||
|
|
3fecde37f4 | ||
|
|
2fc5fd99fb | ||
|
|
7edacfea70 | ||
|
|
7020fa49d9 | ||
|
|
7cea0bb33c | ||
|
|
3d622b18dc | ||
|
|
62cd506588 | ||
|
|
cd830f27a0 | ||
|
|
3f75018369 | ||
|
|
270a4c594d | ||
|
|
a5fdc5755b | ||
|
|
0a5a554714 | ||
|
|
976f22c27a | ||
|
|
8267574697 | ||
|
|
9077c964b3 | ||
|
|
f80467a3a4 | ||
|
|
8c462c4cb7 | ||
|
|
b25b5bd5a3 | ||
|
|
6365c22297 | ||
|
|
d7dd24b94e | ||
|
|
aee8844558 | ||
|
|
c536149c62 | ||
|
|
ca1ae8181b | ||
|
|
2b19c9757b | ||
|
|
d6871e3d82 | ||
|
|
0432a64537 | ||
|
|
06988b06c7 | ||
|
|
9b72eb8219 | ||
|
|
ea188f6176 | ||
|
|
cf67d022c8 | ||
|
|
7ba6e12799 | ||
|
|
b512518ccc | ||
|
|
93dfd35627 | ||
|
|
50b92f9510 | ||
|
|
7cca8922d8 | ||
|
|
c00889b1c4 | ||
|
|
b6224f355d | ||
|
|
9a8f96d432 | ||
|
|
3cc199227b | ||
|
|
3d0647bce3 | ||
|
|
192f35a9dd | ||
|
|
f2b4c9a35b | ||
|
|
3b8fec4c5a | ||
|
|
60b74a018d | ||
|
|
be69e04f51 | ||
|
|
194f6009df | ||
|
|
910a2eace8 | ||
|
|
8191a7dae6 | ||
|
|
3c95618eec | ||
|
|
fc709eb700 | ||
|
|
a6c60ac5d0 | ||
|
|
756672258d | ||
|
|
fb6f7072d4 | ||
|
|
aa95ad40c0 | ||
|
|
b88b9c8f92 | ||
|
|
2b8cd36b7b | ||
|
|
3d23deb744 | ||
|
|
de3b2715c7 | ||
|
|
f3d8bd359d | ||
|
|
d7d6e46b2a | ||
|
|
501f682d68 | ||
|
|
7cbf1e10e5 | ||
|
|
fb00972bc1 | ||
|
|
387fb28c65 | ||
|
|
40fbfd10d1 | ||
|
|
e5e4695cd6 | ||
|
|
4a0c8ae80e | ||
|
|
384ca8eb2a | ||
|
|
59f360bde7 | ||
|
|
8830e0f5fb | ||
|
|
7a391a2825 | ||
|
|
a1941911ef | ||
|
|
a0667ff361 | ||
|
|
ba3667ab51 | ||
|
|
cbc41d535d | ||
|
|
f51780dcb5 | ||
|
|
c055488df7 | ||
|
|
b15c376e59 | ||
|
|
fdf03d2fdc | ||
|
|
437350af9f | ||
|
|
5114e2ad22 | ||
|
|
b3b4f61c42 | ||
|
|
fa16556af1 | ||
|
|
de766c2653 | ||
|
|
dcc27efe5c | ||
|
|
78ceb604f9 | ||
|
|
7bdcdcba3d | ||
|
|
e929d41d67 | ||
|
|
600aca083c | ||
|
|
02c20c01ee | ||
|
|
50cfdbbc0b | ||
|
|
38c556af0b | ||
|
|
0b9d777109 | ||
|
|
eb3c1f3c7a | ||
|
|
311c490377 | ||
|
|
39ed00ff6f | ||
|
|
28338d2dcf | ||
|
|
bba5d11bdc | ||
|
|
36ef191874 | ||
|
|
3e4c6c1b61 | ||
|
|
c9d0224814 | ||
|
|
8aed6045a0 | ||
|
|
8440705436 | ||
|
|
af667b10cf | ||
|
|
1b522fe9a0 | ||
|
|
cb3c46744e | ||
|
|
c471289fb5 | ||
|
|
18ca563865 | ||
|
|
2430526ee7 | ||
|
|
c9bb0235e2 | ||
|
|
2f8236e9db | ||
|
|
e4e757606d | ||
|
|
6fcb796177 | ||
|
|
4d6b035c29 | ||
|
|
68c206a4fa | ||
|
|
d258171131 | ||
|
|
adaf9ef5ce | ||
|
|
22f299f67c | ||
|
|
0fb0bc8e1d | ||
|
|
da666410fc | ||
|
|
ea007f3cfe | ||
|
|
1c868a644f | ||
|
|
5ff6a8c258 | ||
|
|
62d7b7a0c0 | ||
|
|
7fcbb57ab1 | ||
|
|
8e25dcd396 | ||
|
|
a9f1e5b761 | ||
|
|
f642149723 | ||
|
|
4b359d98cb | ||
|
|
764fccf0b5 | ||
|
|
81d1059489 | ||
|
|
a2574a5883 | ||
|
|
118a1411d8 | ||
|
|
44310cbd0e | ||
|
|
2dce7b6f71 | ||
|
|
98db82d137 | ||
|
|
fd55656261 | ||
|
|
978dec64ee | ||
|
|
8d7bf3a370 | ||
|
|
1cea7bcffc | ||
|
|
16e77d4b9b | ||
|
|
f22111e36f | ||
|
|
c5d4c9a9c1 | ||
|
|
4bc9b1d60c | ||
|
|
7a40a3cb0c | ||
|
|
ad555ece8e | ||
|
|
2d96d2e5c6 | ||
|
|
0a968b60aa | ||
|
|
3b4f82092d | ||
|
|
de16647d00 | ||
|
|
03403e53bc | ||
|
|
2939702842 | ||
|
|
b3d09a4cae | ||
|
|
73c0af9749 | ||
|
|
53c7e031a3 | ||
|
|
1e280f2c97 | ||
|
|
ce82593fc6 | ||
|
|
c2c3d778d1 | ||
|
|
7771181e15 | ||
|
|
1a39333b4c | ||
|
|
85472db00a | ||
|
|
d6a020994e | ||
|
|
518f75be32 | ||
|
|
28c7dbad69 | ||
|
|
31e9f3a025 | ||
|
|
a03d5af144 | ||
|
|
50a654d5af | ||
|
|
1954f31910 | ||
|
|
68bf441fdd | ||
|
|
a606bcb81e | ||
|
|
fe93e51ffa | ||
|
|
f2949aae63 | ||
|
|
80e101456b | ||
|
|
2f311c1dfe | ||
|
|
c5cfe4d1b3 | ||
|
|
a09b55c81b | ||
|
|
32f266c721 | ||
|
|
3adffad087 | ||
|
|
84e3cf0762 | ||
|
|
1292936904 | ||
|
|
7a913c89c9 | ||
|
|
4c4816bdab | ||
|
|
f9bfd5d1b1 | ||
|
|
00e1e3654e | ||
|
|
8aaee3710a | ||
|
|
1946fc6c0e | ||
|
|
8fb95b67d9 | ||
|
|
e6890e8fa5 | ||
|
|
7cdb2025dc | ||
|
|
414d81dc06 | ||
|
|
b450ab028d | ||
|
|
958c22bed8 | ||
|
|
6ff640648f | ||
|
|
7b132adfe2 | ||
|
|
3497144034 | ||
|
|
edbeea5502 | ||
|
|
a88e08147d | ||
|
|
8ff06a3efd | ||
|
|
902c66cf1e | ||
|
|
d58307d1d6 | ||
|
|
3e6204a657 | ||
|
|
e677a0beaa | ||
|
|
d379ada100 | ||
|
|
cb7d0ade47 | ||
|
|
4d9dc4312d | ||
|
|
92fad41b96 | ||
|
|
e038348dca | ||
|
|
d85c6c8f41 | ||
|
|
17057e8f8d |
@@ -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).
|
||||||
|
|
||||||
@@ -16,6 +16,14 @@
|
|||||||
|
|
||||||
- Suggest your change by [submitting a new issue](https://github.com/cryptomator/cryptomator/issues/new/choose) and start writing code.
|
- Suggest your change by [submitting a new issue](https://github.com/cryptomator/cryptomator/issues/new/choose) and start writing code.
|
||||||
|
|
||||||
|
## Do you intend to add a new translation or change an existing one?
|
||||||
|
|
||||||
|
Translations are not managed directly in this repository. Instead, we use [Crowdin](https://translate.cryptomator.org/), which automatically synchronizes translations with this repository. If you want to help us with translations, please visit our translation project on Crowdin.
|
||||||
|
|
||||||
|
## Use of Generative AI
|
||||||
|
|
||||||
|
AI tools may assist your work, but every contribution must be fully understood, reviewed, and tested by you. Only submit changes you can clearly explain and justify. Unverified or low-quality AI output that wastes our time and resources will be closed without further review.
|
||||||
|
|
||||||
## Code of Conduct
|
## Code of Conduct
|
||||||
|
|
||||||
Help us keep Cryptomator open and inclusive. Please read and follow our [Code of Conduct](https://github.com/cryptomator/cryptomator/blob/develop/.github/CODE_OF_CONDUCT.md).
|
Help us keep Cryptomator open and inclusive. Please read and follow our [Code of Conduct](https://github.com/cryptomator/cryptomator/blob/develop/.github/CODE_OF_CONDUCT.md).
|
||||||
|
|||||||
@@ -1,7 +1,14 @@
|
|||||||
name: Bug Report
|
name: Bug Report
|
||||||
description: Create a report to help us improve
|
description: Create a report to help us improve
|
||||||
labels: ["type:bug"]
|
type: "Bug"
|
||||||
body:
|
body:
|
||||||
|
- type: input
|
||||||
|
id: summary
|
||||||
|
attributes:
|
||||||
|
label: Summary
|
||||||
|
placeholder: Please summarize your problem.
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
- type: checkboxes
|
- type: checkboxes
|
||||||
id: terms
|
id: terms
|
||||||
attributes:
|
attributes:
|
||||||
@@ -11,13 +18,6 @@ body:
|
|||||||
required: true
|
required: true
|
||||||
- label: I agree to follow this project's [Code of Conduct](https://github.com/cryptomator/cryptomator/blob/develop/.github/CODE_OF_CONDUCT.md)
|
- label: I agree to follow this project's [Code of Conduct](https://github.com/cryptomator/cryptomator/blob/develop/.github/CODE_OF_CONDUCT.md)
|
||||||
required: true
|
required: true
|
||||||
- type: input
|
|
||||||
id: summary
|
|
||||||
attributes:
|
|
||||||
label: Summary
|
|
||||||
placeholder: Please summarize your problem.
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
- type: textarea
|
- type: textarea
|
||||||
id: software-versions
|
id: software-versions
|
||||||
attributes:
|
attributes:
|
||||||
@@ -97,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?
|
||||||
@@ -1,7 +1,14 @@
|
|||||||
name: Feature Request
|
name: Feature Request
|
||||||
description: Suggest an idea for this project
|
description: Suggest an idea for this project
|
||||||
labels: ["type:feature-request"]
|
type: "Feature"
|
||||||
body:
|
body:
|
||||||
|
- type: input
|
||||||
|
id: summary
|
||||||
|
attributes:
|
||||||
|
label: Summary
|
||||||
|
placeholder: Please summarize your feature request.
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
- type: checkboxes
|
- type: checkboxes
|
||||||
id: terms
|
id: terms
|
||||||
attributes:
|
attributes:
|
||||||
@@ -11,13 +18,6 @@ body:
|
|||||||
required: true
|
required: true
|
||||||
- label: I agree to follow this project's [Code of Conduct](https://github.com/cryptomator/cryptomator/blob/develop/.github/CODE_OF_CONDUCT.md)
|
- label: I agree to follow this project's [Code of Conduct](https://github.com/cryptomator/cryptomator/blob/develop/.github/CODE_OF_CONDUCT.md)
|
||||||
required: true
|
required: true
|
||||||
- type: input
|
|
||||||
id: summary
|
|
||||||
attributes:
|
|
||||||
label: Summary
|
|
||||||
placeholder: Please summarize your feature request.
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
- type: textarea
|
- type: textarea
|
||||||
id: motivation
|
id: motivation
|
||||||
attributes:
|
attributes:
|
||||||
|
|||||||
@@ -0,0 +1,76 @@
|
|||||||
|
name: 'Windows Code Signing'
|
||||||
|
description: 'Sign files on Windows with the Azure Trusted Signing'
|
||||||
|
inputs:
|
||||||
|
base-dir:
|
||||||
|
description: 'Absolute path to the base directory to search for files'
|
||||||
|
required: true
|
||||||
|
recursive:
|
||||||
|
description: 'Whether to search recursively in subdirectories'
|
||||||
|
required: false
|
||||||
|
default: 'false'
|
||||||
|
file-extensions:
|
||||||
|
description: 'List of file extensions to sign, separated by comma'
|
||||||
|
required: true
|
||||||
|
default: 'exe,dll,ps1'
|
||||||
|
description:
|
||||||
|
description: 'Signature description'
|
||||||
|
required: true
|
||||||
|
default: 'Cryptomator'
|
||||||
|
url:
|
||||||
|
description: 'Signature URL'
|
||||||
|
required: false
|
||||||
|
default: 'https://cryptomator.org'
|
||||||
|
append-signature:
|
||||||
|
description: 'Whether to append the signature to existing signatures'
|
||||||
|
required: false
|
||||||
|
default: 'false'
|
||||||
|
tenant-id:
|
||||||
|
description: 'Azure Tenant ID'
|
||||||
|
required: true
|
||||||
|
client-id:
|
||||||
|
description: 'Azure Client ID'
|
||||||
|
required: true
|
||||||
|
client-secret:
|
||||||
|
description: 'Azure Client Secret'
|
||||||
|
required: true
|
||||||
|
|
||||||
|
runs:
|
||||||
|
using: 'composite'
|
||||||
|
steps:
|
||||||
|
- name: Generate, mask, and output the input secrets
|
||||||
|
id: set-secrets
|
||||||
|
run: |
|
||||||
|
echo "::add-mask::${{ inputs.tenant-id }}"
|
||||||
|
echo "::add-mask::${{ inputs.client-id }}"
|
||||||
|
echo "::add-mask::${{ inputs.client-secret }}"
|
||||||
|
echo "tenant-id=${{ inputs.tenant-id }}" >> "$GITHUB_OUTPUT"
|
||||||
|
echo "client-id=${{ inputs.client-id }}" >> "$GITHUB_OUTPUT"
|
||||||
|
echo "client-secret=${{ inputs.client-secret }}" >> "$GITHUB_OUTPUT"
|
||||||
|
shell: bash
|
||||||
|
- name: Sign DLLs with Azure Trusted Signing
|
||||||
|
uses: azure/trusted-signing-action@fc390cf8ed0f14e248a542af1d838388a47c7a7c # v0.5.10
|
||||||
|
with:
|
||||||
|
files-folder: ${{ inputs.base-dir }}
|
||||||
|
files-folder-filter: ${{ inputs.file-extensions }}
|
||||||
|
files-folder-recurse: ${{ inputs.recursive }}
|
||||||
|
append-signature: ${{ inputs.append-signature }}
|
||||||
|
description: ${{ inputs.description }}
|
||||||
|
description-url: ${{ inputs.url }}
|
||||||
|
azure-tenant-id: ${{ steps.set-secrets.outputs.tenant-id }}
|
||||||
|
azure-client-id: ${{ steps.set-secrets.outputs.client-id }}
|
||||||
|
azure-client-secret: ${{ steps.set-secrets.outputs.client-secret }}
|
||||||
|
trusted-signing-account-name: cryptomatorSigning
|
||||||
|
certificate-profile-name: production
|
||||||
|
endpoint: https://weu.codesigning.azure.net/
|
||||||
|
timestamp-rfc3161: http://timestamp.acs.microsoft.com
|
||||||
|
timestamp-digest: SHA256
|
||||||
|
exclude-environment-credential: false
|
||||||
|
exclude-workload-identity-credential: true
|
||||||
|
exclude-managed-identity-credential: true
|
||||||
|
exclude-shared-token-cache-credential: true
|
||||||
|
exclude-visual-studio-credential: true
|
||||||
|
exclude-visual-studio-code-credential: true
|
||||||
|
exclude-azure-cli-credential: true
|
||||||
|
exclude-azure-powershell-credential: true
|
||||||
|
exclude-azure-developer-cli-credential: true
|
||||||
|
exclude-interactive-browser-credential: true
|
||||||
@@ -10,6 +10,10 @@ updates:
|
|||||||
ignore:
|
ignore:
|
||||||
- dependency-name: "org.cryptomator:integrations-api"
|
- dependency-name: "org.cryptomator:integrations-api"
|
||||||
versions: ["2.0.0-alpha1"]
|
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:
|
||||||
java-test-dependencies:
|
java-test-dependencies:
|
||||||
patterns:
|
patterns:
|
||||||
@@ -49,6 +53,4 @@ updates:
|
|||||||
groups:
|
groups:
|
||||||
github-actions:
|
github-actions:
|
||||||
patterns:
|
patterns:
|
||||||
- "*"
|
- "*"
|
||||||
labels:
|
|
||||||
- "misc:ci"
|
|
||||||
+107
-26
@@ -8,16 +8,24 @@ on:
|
|||||||
version:
|
version:
|
||||||
description: 'Version'
|
description: 'Version'
|
||||||
required: false
|
required: false
|
||||||
|
push:
|
||||||
|
branches-ignore:
|
||||||
|
- 'dependabot/**'
|
||||||
|
paths:
|
||||||
|
- '.github/workflows/appimage.yml'
|
||||||
|
- 'dist/linux/appimage/**'
|
||||||
|
- 'dist/linux/common/**'
|
||||||
|
- 'dist/linux/resources/**'
|
||||||
|
|
||||||
env:
|
env:
|
||||||
JAVA_DIST: 'zulu'
|
JAVA_DIST: 'temurin'
|
||||||
JAVA_VERSION: '22.0.2+9'
|
JAVA_VERSION: '25.0.1+8.0.LTS'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
get-version:
|
get-version:
|
||||||
uses: ./.github/workflows/get-version.yml
|
uses: ./.github/workflows/get-version.yml
|
||||||
with:
|
with:
|
||||||
version: ${{ inputs.version }}
|
version: ${{ inputs.version }} #okay if not defined
|
||||||
|
|
||||||
build:
|
build:
|
||||||
name: Build AppImage
|
name: Build AppImage
|
||||||
@@ -29,22 +37,21 @@ jobs:
|
|||||||
include:
|
include:
|
||||||
- os: ubuntu-latest
|
- os: ubuntu-latest
|
||||||
appimage-suffix: x86_64
|
appimage-suffix: x86_64
|
||||||
openjfx-url: 'https://download2.gluonhq.com/openjfx/22.0.2/openjfx-22.0.2_linux-x64_bin-jmods.zip'
|
openjfx-url: 'https://download2.gluonhq.com/openjfx/25/openjfx-25_linux-x64_bin-jmods.zip'
|
||||||
openjfx-sha: 'd44bff3b94d5668fdee18a938d7b1269026d663d44765f02d29a9bdfd3fa1eb0'
|
openjfx-sha: '96e520f48610d8ffb94ca30face1f11ffe8a977ddc1c4ff80b1a9e9f048bd94e'
|
||||||
- os: [self-hosted, Linux, ARM64]
|
- os: ubuntu-24.04-arm
|
||||||
appimage-suffix: aarch64
|
appimage-suffix: aarch64
|
||||||
openjfx-url: 'https://download2.gluonhq.com/openjfx/22.0.2/openjfx-22.0.2_linux-aarch64_bin-jmods.zip'
|
openjfx-url: 'https://download2.gluonhq.com/openjfx/25/openjfx-25_linux-aarch64_bin-jmods.zip'
|
||||||
openjfx-sha: '3d5457136690c4f5bb9522d38b45218e045bdac13c24aa4c808c7c8d17d039c7'
|
openjfx-sha: '9ad4ca7b769ca4ee6419f1e99143dd6ff812f8be4fddb46a7d7cacbeea148af4'
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||||
- name: Setup Java
|
- name: Setup Java
|
||||||
uses: actions/setup-java@v4
|
uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0
|
||||||
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: 'maven'
|
cache: 'maven'
|
||||||
|
|
||||||
- name: Download OpenJFX jmods
|
- name: Download OpenJFX jmods
|
||||||
id: download-jmods
|
id: download-jmods
|
||||||
run: |
|
run: |
|
||||||
@@ -61,26 +68,34 @@ 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_AMD64 ]; then
|
if [ $POM_JFX_VERSION -ne $JMOD_VERSION ]; then
|
||||||
>&2 echo "Major JavaFX version in pom.xml (${POM_JFX_VERSION}) != amd64 jmod version (${JMOD_VERSION})"
|
>&2 echo "Major JavaFX version in pom.xml (${POM_JFX_VERSION}) != amd64 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 -Plinux -DskipTests -Djavafx.platform=linux
|
run: mvn -B clean package -Plinux -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 with help option
|
||||||
|
id: jep-493-check
|
||||||
|
run: |
|
||||||
|
JMOD_PATHS="openjfx-jmods"
|
||||||
|
if ! ${JAVA_HOME}/bin/jlink --help | grep -q "Linking from run-time image enabled"; then
|
||||||
|
JMOD_PATHS="${JAVA_HOME}/jmods:${JMOD_PATHS}"
|
||||||
|
fi
|
||||||
|
echo "jmod_paths=${JMOD_PATHS}" >> "$GITHUB_OUTPUT"
|
||||||
- name: Run jlink
|
- name: Run jlink
|
||||||
#Remark: no compression is applied for improved build compression later (here appimage)
|
#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:openjfx-jmods"
|
--module-path "${{ steps.jep-493-check.outputs.jmod_paths }}"
|
||||||
--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
|
--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.crypto.cryptoki,jdk.crypto.ec,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
|
||||||
@@ -98,10 +113,10 @@ jobs:
|
|||||||
--dest appdir
|
--dest appdir
|
||||||
--name Cryptomator
|
--name Cryptomator
|
||||||
--vendor "Skymatic GmbH"
|
--vendor "Skymatic GmbH"
|
||||||
--copyright "(C) 2016 - 2024 Skymatic GmbH"
|
--copyright "(C) 2016 - 2025 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=javafx.graphics,org.cryptomator.jfuse.linux.amd64,org.cryptomator.jfuse.linux.aarch64,org.purejava.appindicator"
|
||||||
--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 }}\""
|
||||||
@@ -116,7 +131,8 @@ 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
|
--java-options "-Dcryptomator.networking.truststore.p12Path=\"/etc/cryptomator/certs.p12\""
|
||||||
|
--java-options "-XX:ErrorFile=/cryptomator/cryptomator_crash.log"
|
||||||
--resource-dir dist/linux/resources
|
--resource-dir dist/linux/resources
|
||||||
- name: Patch Cryptomator.AppDir
|
- name: Patch Cryptomator.AppDir
|
||||||
run: |
|
run: |
|
||||||
@@ -133,13 +149,13 @@ jobs:
|
|||||||
cp dist/linux/common/org.cryptomator.Cryptomator.desktop Cryptomator.AppDir/usr/share/applications/org.cryptomator.Cryptomator.desktop
|
cp dist/linux/common/org.cryptomator.Cryptomator.desktop Cryptomator.AppDir/usr/share/applications/org.cryptomator.Cryptomator.desktop
|
||||||
cp dist/linux/common/application-vnd.cryptomator.vault.xml Cryptomator.AppDir/usr/share/mime/packages/application-vnd.cryptomator.vault.xml
|
cp dist/linux/common/application-vnd.cryptomator.vault.xml Cryptomator.AppDir/usr/share/mime/packages/application-vnd.cryptomator.vault.xml
|
||||||
ln -s usr/share/icons/hicolor/scalable/apps/org.cryptomator.Cryptomator.svg Cryptomator.AppDir/org.cryptomator.Cryptomator.svg
|
ln -s usr/share/icons/hicolor/scalable/apps/org.cryptomator.Cryptomator.svg Cryptomator.AppDir/org.cryptomator.Cryptomator.svg
|
||||||
ln -s usr/share/icons/hicolor/scalable/apps/org.cryptomator.Cryptomator.svg Cryptomator.AppDir/Cryptomator.svg
|
|
||||||
ln -s usr/share/icons/hicolor/scalable/apps/org.cryptomator.Cryptomator.svg Cryptomator.AppDir/.DirIcon
|
ln -s usr/share/icons/hicolor/scalable/apps/org.cryptomator.Cryptomator.svg Cryptomator.AppDir/.DirIcon
|
||||||
ln -s usr/share/applications/org.cryptomator.Cryptomator.desktop Cryptomator.AppDir/Cryptomator.desktop
|
ln -s usr/share/applications/org.cryptomator.Cryptomator.desktop Cryptomator.AppDir/org.cryptomator.Cryptomator.desktop
|
||||||
|
ln -s org.cryptomator.Cryptomator.metainfo.xml Cryptomator.AppDir/usr/share/metainfo/org.cryptomator.Cryptomator.appdata.xml
|
||||||
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-${{ matrix.appimage-suffix }}.AppImage -o appimagetool.AppImage
|
curl -L https://github.com/AppImage/appimagetool/releases/download/continuous/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
|
||||||
@@ -152,14 +168,14 @@ jobs:
|
|||||||
- name: Build AppImage
|
- name: Build AppImage
|
||||||
run: >
|
run: >
|
||||||
./squashfs-root/AppRun Cryptomator.AppDir cryptomator-${{ needs.get-version.outputs.semVerStr }}-${{ matrix.appimage-suffix }}.AppImage
|
./squashfs-root/AppRun Cryptomator.AppDir cryptomator-${{ needs.get-version.outputs.semVerStr }}-${{ matrix.appimage-suffix }}.AppImage
|
||||||
-u 'gh-releases-zsync|cryptomator|cryptomator|latest|cryptomator-*-${{ matrix.appimage-suffix }}.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
|
||||||
- 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@v4
|
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
||||||
with:
|
with:
|
||||||
name: appimage-${{ matrix.appimage-suffix }}
|
name: appimage-${{ matrix.appimage-suffix }}
|
||||||
path: |
|
path: |
|
||||||
@@ -169,11 +185,76 @@ jobs:
|
|||||||
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/') && github.event.action == 'published'
|
if: startsWith(github.ref, 'refs/tags/') && github.event.action == 'published'
|
||||||
uses: softprops/action-gh-release@v2
|
uses: softprops/action-gh-release@6da8fa9354ddfdc4aeace5fc48d7f679b5214090 # v2.4.1
|
||||||
with:
|
with:
|
||||||
fail_on_unmatched_files: true
|
fail_on_unmatched_files: true
|
||||||
token: ${{ secrets.CRYPTOBOT_RELEASE_TOKEN }}
|
token: ${{ secrets.CRYPTOBOT_RELEASE_TOKEN }}
|
||||||
files: |
|
files: |
|
||||||
cryptomator-*.AppImage
|
cryptomator-*.AppImage
|
||||||
cryptomator-*.zsync
|
cryptomator-*.zsync
|
||||||
cryptomator-*.asc
|
cryptomator-*.asc
|
||||||
|
|
||||||
|
create-aur-bin-pr:
|
||||||
|
name: Create PR for aur-bin repo
|
||||||
|
needs: [build, get-version]
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
if: github.event_name == 'release' && needs.get-version.outputs.versionType == 'stable'
|
||||||
|
steps:
|
||||||
|
- name: Download AppImages
|
||||||
|
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0
|
||||||
|
with:
|
||||||
|
path: downloads/
|
||||||
|
merge-multiple: true
|
||||||
|
- name: Compute sha256 hash of AppImages
|
||||||
|
id: checksums
|
||||||
|
run: |
|
||||||
|
X64_SHA256=$(sha256sum downloads/cryptomator-*-x86_64.AppImage | cut -d ' ' -f1)
|
||||||
|
echo "x64-sha256sum=${X64_SHA256}" >> "$GITHUB_OUTPUT"
|
||||||
|
AARCH64_SHA256=$(sha256sum downloads/cryptomator-*-aarch64.AppImage | cut -d ' ' -f1)
|
||||||
|
echo "aarch64-sha256sum=${AARCH64_SHA256}" >> "$GITHUB_OUTPUT"
|
||||||
|
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||||
|
with:
|
||||||
|
repository: 'cryptomator/aur-bin'
|
||||||
|
token: ${{ secrets.CRYPTOBOT_PR_TOKEN }}
|
||||||
|
- name: Install dependencies
|
||||||
|
run: |
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get -y install makepkg pacman-package-manager
|
||||||
|
- name: Checkout release branch
|
||||||
|
run: |
|
||||||
|
git checkout -b release/${{ needs.get-version.outputs.semVerStr }}
|
||||||
|
- name: Update build file
|
||||||
|
run: |
|
||||||
|
sed -i -e 's|^pkgver=.*$|pkgver=${{ needs.get-version.outputs.semVerStr }}|' PKGBUILD
|
||||||
|
sed -i -e 's|^pkgrel=.*$|pkgrel=1|' PKGBUILD
|
||||||
|
sed -i -e "s|^sha256sums_x86_64=.*$|sha256sums_x86_64=('${{ steps.checksums.outputs.x64-sha256sum }}'|" PKGBUILD
|
||||||
|
sed -i -e "s|^sha256sums_aarch64=.*$|sha256sums_aarch64=('${{ steps.checksums.outputs.aarch64-sha256sum}}'|" PKGBUILD
|
||||||
|
makepkg --printsrcinfo > .SRCINFO
|
||||||
|
- 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
|
||||||
|
id: create-pr
|
||||||
|
run: |
|
||||||
|
printf "> [!IMPORTANT]\n> Todos:\n> - [ ] Update build instructions\n> - [ ] Check for JDK update\n> - [ ] Check for JFX update" > pr_body.md
|
||||||
|
URL=$(gh pr create --title "Release ${{ needs.get-version.outputs.semVerStr }}" --body-file pr_body.md)
|
||||||
|
echo "PR_URL=$URL" >> "$GITHUB_OUTPUT"
|
||||||
|
env:
|
||||||
|
GH_TOKEN: ${{ secrets.CRYPTOBOT_PR_TOKEN }}
|
||||||
|
- name: Slack Notification
|
||||||
|
uses: rtCamp/action-slack-notify@e31e87e03dd19038e411e38ae27cbad084a90661 # v2.3.3
|
||||||
|
env:
|
||||||
|
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }}
|
||||||
|
SLACK_USERNAME: 'Cryptobot'
|
||||||
|
SLACK_ICON: false
|
||||||
|
SLACK_ICON_EMOJI: ':bot:'
|
||||||
|
SLACK_CHANNEL: 'cryptomator-desktop'
|
||||||
|
SLACK_TITLE: "AUR-bin release PR for ${{ github.event.repository.name }} ${{ github.event.release.tag_name }} created."
|
||||||
|
SLACK_MESSAGE: "See <${{ steps.create-pr.outputs.PR_URL }}|PR> on how to proceed."
|
||||||
|
SLACK_FOOTER: false
|
||||||
|
MSG_MINIMAL: true
|
||||||
|
|||||||
@@ -0,0 +1,95 @@
|
|||||||
|
name: Create PR for AUR
|
||||||
|
|
||||||
|
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'
|
||||||
|
env:
|
||||||
|
INPUT_TAG: ${{ inputs.tag }}
|
||||||
|
outputs:
|
||||||
|
url: ${{ steps.url.outputs.url}}
|
||||||
|
sha256: ${{ steps.sha256.outputs.sha256}}
|
||||||
|
steps:
|
||||||
|
- name: Determine tarball url
|
||||||
|
id: url
|
||||||
|
run: |
|
||||||
|
URL="";
|
||||||
|
if [[ -n "${INPUT_TAG}" ]]; then
|
||||||
|
URL="https://github.com/cryptomator/cryptomator/archive/refs/tags/${INPUT_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: sha256
|
||||||
|
run: |
|
||||||
|
curl --silent --fail-with-body -L -H "Accept: application/vnd.github+json" ${{ steps.url.outputs.url }} --output cryptomator.tar.gz
|
||||||
|
TARBALL_SHA256=$(sha256sum cryptomator.tar.gz | cut -d ' ' -f1)
|
||||||
|
echo "sha256=${TARBALL_SHA256}" >> "$GITHUB_OUTPUT"
|
||||||
|
aur:
|
||||||
|
name: Create PR for AUR
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: [tarball, get-version]
|
||||||
|
env:
|
||||||
|
AUR_PR_URL: tbd
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||||
|
with:
|
||||||
|
repository: 'cryptomator/aur'
|
||||||
|
token: ${{ secrets.CRYPTOBOT_PR_TOKEN }}
|
||||||
|
- name: Install dependencies
|
||||||
|
run: |
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install makepkg pacman-package-manager
|
||||||
|
- name: Checkout release branch
|
||||||
|
run: |
|
||||||
|
git checkout -b release/${{ needs.get-version.outputs.semVerStr }}
|
||||||
|
- name: Update build file
|
||||||
|
run: |
|
||||||
|
sed -i -e 's|^pkgver=.*$|pkgver=${{ needs.get-version.outputs.semVerStr }}|' PKGBUILD
|
||||||
|
sed -i -e 's|^pkgrel=.*$|pkgrel=1|' PKGBUILD
|
||||||
|
sed -i -e "s|^sha256sums=.*$|sha256sums=('${{ needs.tarball.outputs.sha256 }}'|" PKGBUILD
|
||||||
|
makepkg --printsrcinfo > .SRCINFO
|
||||||
|
- 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 build instructions\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 "AUR_PR_URL=$PR_URL" >> "$GITHUB_ENV"
|
||||||
|
env:
|
||||||
|
GH_TOKEN: ${{ secrets.CRYPTOBOT_PR_TOKEN }}
|
||||||
|
- name: Slack Notification
|
||||||
|
if: github.event_name == 'release'
|
||||||
|
uses: rtCamp/action-slack-notify@e31e87e03dd19038e411e38ae27cbad084a90661 # v2.3.3
|
||||||
|
env:
|
||||||
|
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }}
|
||||||
|
SLACK_USERNAME: 'Cryptobot'
|
||||||
|
SLACK_ICON: false
|
||||||
|
SLACK_ICON_EMOJI: ':bot:'
|
||||||
|
SLACK_CHANNEL: 'cryptomator-desktop'
|
||||||
|
SLACK_TITLE: "AUR release PR created for ${{ github.event.repository.name }} ${{ github.event.release.tag_name }} created."
|
||||||
|
SLACK_MESSAGE: "See <${{ env.AUR_PR_URL }}|PR> on how to proceed."
|
||||||
|
SLACK_FOOTER: false
|
||||||
|
MSG_MINIMAL: true
|
||||||
@@ -13,28 +13,78 @@ on:
|
|||||||
description: "Url to the file to upload"
|
description: "Url to the file to upload"
|
||||||
required: true
|
required: true
|
||||||
type: string
|
type: string
|
||||||
|
avast:
|
||||||
|
description: "Upload to Avast"
|
||||||
|
required: false
|
||||||
|
type: boolean
|
||||||
|
default: false
|
||||||
|
kaspersky:
|
||||||
|
description: "Upload to Kaspersky"
|
||||||
|
required: false
|
||||||
|
type: boolean
|
||||||
|
default: false
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
allowlist:
|
download-file:
|
||||||
name: Anti Virus Allowlisting
|
name: Downloads the file into the VM
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
outputs:
|
||||||
|
fileName: ${{ steps.extractName.outputs.fileName}}
|
||||||
|
env:
|
||||||
|
INPUT_URL: ${{ inputs.url }}
|
||||||
steps:
|
steps:
|
||||||
- name: Download file
|
- name: Extract file name
|
||||||
|
id: extractName
|
||||||
run: |
|
run: |
|
||||||
curl --remote-name ${{ inputs.url }} -L
|
url="${INPUT_URL}"
|
||||||
|
echo "fileName=${url##*/}" >> $GITHUB_OUTPUT
|
||||||
|
- name: Download file
|
||||||
|
run: curl --remote-name ${INPUT_URL} -L -o ${{steps.extractName.outputs.fileName}}
|
||||||
|
- name: Upload artifact
|
||||||
|
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
||||||
|
with:
|
||||||
|
name: ${{ steps.extractName.outputs.fileName }}
|
||||||
|
path: ${{ steps.extractName.outputs.fileName }}
|
||||||
|
if-no-files-found: error
|
||||||
|
allowlist-kaspersky:
|
||||||
|
name: Anti Virus Allowlisting Kaspersky
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: download-file
|
||||||
|
if: github.event_name == 'workflow_call' || inputs.kaspersky
|
||||||
|
steps:
|
||||||
|
- name: Download artifact
|
||||||
|
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0
|
||||||
|
with:
|
||||||
|
name: ${{ needs.download-file.outputs.fileName }}
|
||||||
|
path: upload
|
||||||
- name: Upload to Kaspersky
|
- name: Upload to Kaspersky
|
||||||
uses: SamKirkland/FTP-Deploy-Action@v4.3.5
|
uses: SamKirkland/FTP-Deploy-Action@a51268f67f6605236975928ae28b0f7e9971d50a # v4.6.3
|
||||||
with:
|
with:
|
||||||
protocol: ftps
|
protocol: ftps
|
||||||
server: allowlist.kaspersky-labs.com
|
server: allowlist.kaspersky-labs.com
|
||||||
port: 990
|
port: 990
|
||||||
username: ${{ secrets.ALLOWLIST_KASPERSKY_USERNAME }}
|
username: ${{ secrets.ALLOWLIST_KASPERSKY_USERNAME }}
|
||||||
password: ${{ secrets.ALLOWLIST_KASPERSKY_PASSWORD }}
|
password: ${{ secrets.ALLOWLIST_KASPERSKY_PASSWORD }}
|
||||||
|
local-dir: ./upload/
|
||||||
|
allowlist-avast:
|
||||||
|
name: Anti Virus Allowlisting Avast
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: download-file
|
||||||
|
if: github.event_name == 'workflow_call' || inputs.avast
|
||||||
|
steps:
|
||||||
|
- name: Download artifact
|
||||||
|
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0
|
||||||
|
with:
|
||||||
|
name: ${{ needs.download-file.outputs.fileName }}
|
||||||
|
path: upload
|
||||||
- name: Upload to Avast
|
- name: Upload to Avast
|
||||||
uses: SamKirkland/FTP-Deploy-Action@v4.3.5
|
uses: wlixcc/SFTP-Deploy-Action@a5ccb9c6211a94cc59404f0fdb2a9936a6dfee64 # v1.2.6
|
||||||
with:
|
with:
|
||||||
protocol: ftp
|
|
||||||
server: whitelisting.avast.com
|
server: whitelisting.avast.com
|
||||||
port: 21
|
port: 22
|
||||||
username: ${{ secrets.ALLOWLIST_AVAST_USERNAME }}
|
username: ${{ secrets.ALLOWLIST_AVAST_USERNAME }}
|
||||||
password: ${{ secrets.ALLOWLIST_AVAST_PASSWORD }}
|
password: ${{ secrets.ALLOWLIST_AVAST_PASSWORD }}
|
||||||
|
ssh_private_key: ''
|
||||||
|
sftp_only: true
|
||||||
|
local_path: './upload/*'
|
||||||
|
remote_path: '/data'
|
||||||
+30
-10
@@ -2,12 +2,16 @@ name: Build
|
|||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
|
paths:
|
||||||
|
- '.github/workflows/build.yml'
|
||||||
|
- 'pom.xml'
|
||||||
|
- 'src/**'
|
||||||
pull_request_target:
|
pull_request_target:
|
||||||
types: [labeled]
|
types: [labeled]
|
||||||
|
|
||||||
env:
|
env:
|
||||||
JAVA_DIST: 'zulu'
|
JAVA_DIST: 'temurin'
|
||||||
JAVA_VERSION: 22
|
JAVA_VERSION: 25
|
||||||
|
|
||||||
defaults:
|
defaults:
|
||||||
run:
|
run:
|
||||||
@@ -18,14 +22,14 @@ jobs:
|
|||||||
name: Compile and Test
|
name: Compile and Test
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||||
- uses: actions/setup-java@v4
|
- uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0
|
||||||
with:
|
with:
|
||||||
distribution: ${{ env.JAVA_DIST }}
|
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@v4
|
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
|
||||||
with:
|
with:
|
||||||
path: ~/.sonar/cache
|
path: ~/.sonar/cache
|
||||||
key: ${{ runner.os }}-sonar
|
key: ${{ runner.os }}-sonar
|
||||||
@@ -33,7 +37,7 @@ jobs:
|
|||||||
- name: Build and Test
|
- name: Build and Test
|
||||||
run: >
|
run: >
|
||||||
xvfb-run
|
xvfb-run
|
||||||
mvn -B verify -Djavafx.platform=linux
|
mvn -B verify
|
||||||
jacoco:report
|
jacoco:report
|
||||||
org.sonarsource.scanner.maven:sonar-maven-plugin:sonar
|
org.sonarsource.scanner.maven:sonar-maven-plugin:sonar
|
||||||
-Pcoverage
|
-Pcoverage
|
||||||
@@ -45,7 +49,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@v2
|
uses: softprops/action-gh-release@6da8fa9354ddfdc4aeace5fc48d7f679b5214090 # v2.4.1
|
||||||
with:
|
with:
|
||||||
draft: true
|
draft: true
|
||||||
discussion_category_name: releases
|
discussion_category_name: releases
|
||||||
@@ -53,10 +57,26 @@ 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: -->
|
|
||||||
|
### Full Changelog
|
||||||
|
See [CHANGELOG.md](https://github.com/cryptomator/cryptomator/blob/develop/CHANGELOG.md).
|
||||||
|
|
||||||
|
📜 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).
|
||||||
|
|||||||
@@ -1,57 +1,76 @@
|
|||||||
name: Checks JDK version for minor updates
|
name: Check JDK for non-major updates
|
||||||
|
|
||||||
on:
|
on:
|
||||||
schedule:
|
schedule:
|
||||||
- cron: '0 0 1 * *' # run once a month at the first day of month
|
- cron: '0 0 1 * *' # run once a month at the first day of month
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
env:
|
env:
|
||||||
JDK_VERSION: '22.0.1+8'
|
JDK_VERSION: '25.0.1+8.0.LTS'
|
||||||
JDK_VENDOR: zulu
|
JDK_VENDOR: temurin
|
||||||
|
RUNTIME_VERSION_HELPER: >
|
||||||
|
public class Test {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
System.out.println(Runtime.version());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
jdk-current:
|
check-version:
|
||||||
name: Check out current version
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
outputs:
|
|
||||||
jdk-date: ${{ steps.get-data.outputs.jdk-date}}
|
|
||||||
steps:
|
|
||||||
- uses: actions/setup-java@v4
|
|
||||||
with:
|
|
||||||
java-version: ${{ env.JDK_VERSION }}
|
|
||||||
distribution: ${{ env.JDK_VENDOR }}
|
|
||||||
check-latest: false
|
|
||||||
- name: Read JAVA_VERSION_DATE and store in env variable
|
|
||||||
id: get-data
|
|
||||||
run: |
|
|
||||||
date=$(cat ${JAVA_HOME}/release | grep "JAVA_VERSION_DATE=\"" | awk -F'=' '{print $2}' | tr -d '"')
|
|
||||||
echo "jdk-date=${date}" >> "$GITHUB_OUTPUT"
|
|
||||||
jdk-latest:
|
|
||||||
name: Checkout latest jdk version
|
name: Checkout latest jdk version
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
outputs:
|
env:
|
||||||
jdk-date: ${{ steps.get-data.outputs.jdk-date}}
|
JDK_MAJOR_VERSION: 'toBeFilled'
|
||||||
jdk-version: ${{ steps.get-data.outputs.jdk-version}}
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/setup-java@v4
|
- name: Determine current major version
|
||||||
|
run: echo 'JDK_MAJOR_VERSION=${{ env.JDK_VERSION }}'.substring(0,2) >> "$env:GITHUB_ENV"
|
||||||
|
shell: pwsh
|
||||||
|
- name: Checkout latest JDK ${{ env.JDK_MAJOR_VERSION }}
|
||||||
|
uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0
|
||||||
with:
|
with:
|
||||||
java-version: 21
|
java-version: ${{ env.JDK_MAJOR_VERSION}}
|
||||||
distribution: ${{ env.JDK_VENDOR }}
|
distribution: ${{ env.JDK_VENDOR }}
|
||||||
check-latest: true
|
check-latest: true
|
||||||
- name: Read JAVA_VERSION_DATE and store in env variable
|
- name: Determine if update is available
|
||||||
id: get-data
|
id: determine
|
||||||
|
shell: pwsh
|
||||||
run: |
|
run: |
|
||||||
date=$(cat ${JAVA_HOME}/release | grep "JAVA_VERSION_DATE=\"" | awk -F'=' '{print $2}' | tr -d '"')
|
$latestVersion = 0,0,0,0 #INTERIM, UPDATE, PATCH and BUILD
|
||||||
echo "jdk-date=${date}" >> "$GITHUB_OUTPUT"
|
$currentVersion = 0,0,0,0
|
||||||
version=$(cat ${JAVA_HOME}/release | grep "JAVA_RUNTIME_VERSION=\"" | awk -F'=' '{print $2}' | tr -d '"')
|
|
||||||
echo "jdk-version=${version}" >> "$GITHUB_OUTPUT"
|
# Get the latest JDK runtime version
|
||||||
notify:
|
"${env:RUNTIME_VERSION_HELPER}" | Set-Content -Path "GetRuntimeVersion.java"
|
||||||
name: Notifies for jdk update
|
$latestVersionString = & java GetRuntimeVersion.java
|
||||||
runs-on: ubuntu-latest
|
$runtimeVersionAndBuild = $latestVersionString.Split('+')
|
||||||
needs: [jdk-current, jdk-latest]
|
if($runtimeVersionAndBuild.Length -eq 2) {
|
||||||
if: ${{ needs.jdk-latest.outputs.jdk-date }} > ${{ needs.jdk-current.outputs.jdk-date }}
|
$latestVersion[3]=$runtimeVersionAndBuild[1];
|
||||||
steps:
|
}
|
||||||
- name: Slack Notification
|
$tmp=$runtimeVersionAndBuild[0].Split('.')
|
||||||
uses: rtCamp/action-slack-notify@v2
|
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@e31e87e03dd19038e411e38ae27cbad084a90661 # v2.3.3
|
||||||
env:
|
env:
|
||||||
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }}
|
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }}
|
||||||
SLACK_USERNAME: 'Cryptobot'
|
SLACK_USERNAME: 'Cryptobot'
|
||||||
@@ -59,6 +78,6 @@ jobs:
|
|||||||
SLACK_ICON_EMOJI: ':bot:'
|
SLACK_ICON_EMOJI: ':bot:'
|
||||||
SLACK_CHANNEL: 'cryptomator-desktop'
|
SLACK_CHANNEL: 'cryptomator-desktop'
|
||||||
SLACK_TITLE: "JDK update available"
|
SLACK_TITLE: "JDK update available"
|
||||||
SLACK_MESSAGE: "Cryptomator-CI JDK can be upgraded to ${{ needs.jdk-latest.outputs.jdk-version }}. See https://github.com/cryptomator/cryptomator/wiki/How-to-update-the-build-JDK for instructions."
|
SLACK_MESSAGE: "Cryptomator-CI JDK can be upgraded to ${{ steps.determine.outputs.LATEST_JDK_VERSION }}. Check the Nextcloud collective for instructions."
|
||||||
SLACK_FOOTER: false
|
SLACK_FOOTER: false
|
||||||
MSG_MINIMAL: true
|
MSG_MINIMAL: true
|
||||||
@@ -5,55 +5,69 @@ on:
|
|||||||
inputs:
|
inputs:
|
||||||
semver:
|
semver:
|
||||||
description: 'SemVer String (e.g. 1.7.0-beta1)'
|
description: 'SemVer String (e.g. 1.7.0-beta1)'
|
||||||
required: true
|
|
||||||
ppaver:
|
ppaver:
|
||||||
description: 'Base PPA Version String (e.g. 1.6.16+1.7.0~beta1) without -0ppa1'
|
description: 'Base PPA Version String (e.g. 1.6.16+1.7.0~beta1) without -0ppa1'
|
||||||
required: true
|
|
||||||
dput:
|
dput:
|
||||||
description: 'Upload to PPA'
|
description: 'Upload to PPA'
|
||||||
required: true
|
required: true
|
||||||
default: false
|
default: false
|
||||||
type: boolean
|
type: boolean
|
||||||
|
push:
|
||||||
|
branches-ignore:
|
||||||
|
- 'dependabot/**'
|
||||||
|
paths:
|
||||||
|
- '.github/workflows/debian.yml'
|
||||||
|
- 'dist/linux/debian/**'
|
||||||
|
- 'dist/linux/common/**'
|
||||||
|
- 'dist/linux/resources/**'
|
||||||
|
|
||||||
env:
|
env:
|
||||||
JAVA_DIST: 'zulu'
|
JAVA_DIST: 'temurin'
|
||||||
JAVA_VERSION: '22.0.2+9'
|
JAVA_VERSION: '25.0.1+8.0.LTS'
|
||||||
COFFEELIBS_JDK: 22
|
DEB_BUILD_DEPENDS: 'debhelper (>=10), openjdk-25-jdk (>= 25+36), libgtk-3-0 (>= 3.20.0), libxxf86vm1, libgl1'
|
||||||
COFFEELIBS_JDK_VERSION: '22.0.2+9-0ppa1'
|
OPENJFX_JMODS_AMD64: 'https://download2.gluonhq.com/openjfx/25/openjfx-25_linux-x64_bin-jmods.zip'
|
||||||
OPENJFX_JMODS_AMD64: 'https://download2.gluonhq.com/openjfx/22.0.2/openjfx-22.0.2_linux-x64_bin-jmods.zip'
|
OPENJFX_JMODS_AMD64_HASH: '96e520f48610d8ffb94ca30face1f11ffe8a977ddc1c4ff80b1a9e9f048bd94e'
|
||||||
OPENJFX_JMODS_AMD64_HASH: 'd44bff3b94d5668fdee18a938d7b1269026d663d44765f02d29a9bdfd3fa1eb0'
|
OPENJFX_JMODS_AARCH64: 'https://download2.gluonhq.com/openjfx/25/openjfx-25_linux-aarch64_bin-jmods.zip'
|
||||||
OPENJFX_JMODS_AARCH64: 'https://download2.gluonhq.com/openjfx/22.0.2/openjfx-22.0.2_linux-aarch64_bin-jmods.zip'
|
OPENJFX_JMODS_AARCH64_HASH: '9ad4ca7b769ca4ee6419f1e99143dd6ff812f8be4fddb46a7d7cacbeea148af4'
|
||||||
OPENJFX_JMODS_AARCH64_HASH: '3d5457136690c4f5bb9522d38b45218e045bdac13c24aa4c808c7c8d17d039c7'
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
get-version:
|
||||||
|
uses: ./.github/workflows/get-version.yml
|
||||||
|
with:
|
||||||
|
version: ${{ inputs.semver }} #okay if not defined
|
||||||
|
|
||||||
build:
|
build:
|
||||||
name: Build Debian Package
|
name: Build Debian Package
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-22.04
|
||||||
|
needs: [get-version]
|
||||||
|
env:
|
||||||
|
INPUT_PPAVER: ${{ inputs.ppaver }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||||
- id: versions
|
- id: deb-version
|
||||||
name: Get version information
|
name: Determine deb-version
|
||||||
run: |
|
run: |
|
||||||
SEM_VER_STR="${{ inputs.semver }}"
|
if [ -n "${INPUT_PPAVER}" ]; then
|
||||||
SEM_VER_NUM=`echo ${SEM_VER_STR} | sed -E 's/([0-9]+\.[0-9]+\.[0-9]+).*/\1/'`
|
echo "debVersion=${INPUT_PPAVER}" >> "$GITHUB_OUTPUT"
|
||||||
REVCOUNT=`git rev-list --count HEAD`
|
else
|
||||||
echo "semVerStr=${SEM_VER_STR}" >> $GITHUB_OUTPUT
|
echo "debVersion=${{needs.get-version.outputs.semVerStr}}" >> "$GITHUB_OUTPUT"
|
||||||
echo "semVerNum=${SEM_VER_NUM}" >> $GITHUB_OUTPUT
|
fi
|
||||||
echo "revNum=${REVCOUNT}" >> $GITHUB_OUTPUT
|
|
||||||
- name: Install build tools
|
- name: Install build tools
|
||||||
run: |
|
run: |
|
||||||
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.COFFEELIBS_JDK }}=${{ env.COFFEELIBS_JDK_VERSION }}
|
sudo apt-get install devscripts dput
|
||||||
|
sudo apt-get satisfy "${DEB_BUILD_DEPENDS}"
|
||||||
|
env:
|
||||||
|
DEB_BUILD_DEPENDS: ${{ env.DEB_BUILD_DEPENDS }}
|
||||||
- name: Setup Java
|
- name: Setup Java
|
||||||
uses: actions/setup-java@v4
|
uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0
|
||||||
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: 'maven'
|
cache: 'maven'
|
||||||
- name: Run maven
|
- name: Run maven
|
||||||
run: mvn -B clean package -Plinux -Djavafx.platform=linux -DskipTests
|
run: mvn -B clean package -Plinux -DskipTests
|
||||||
- name: Download OpenJFX jmods
|
- name: Download OpenJFX jmods
|
||||||
id: download-jmods
|
id: download-jmods
|
||||||
run: |
|
run: |
|
||||||
@@ -94,7 +108,7 @@ jobs:
|
|||||||
cp -r jmods pkgdir
|
cp -r jmods pkgdir
|
||||||
cp -r dist/linux/common/ pkgdir
|
cp -r dist/linux/common/ pkgdir
|
||||||
cp target/cryptomator-*.jar pkgdir/mods
|
cp target/cryptomator-*.jar pkgdir/mods
|
||||||
tar -cJf cryptomator_${{ inputs.ppaver }}.orig.tar.xz -C pkgdir .
|
tar -cJf cryptomator_${{ steps.deb-version.outputs.debVersion }}.orig.tar.xz -C pkgdir .
|
||||||
- name: Patch and rename pkgdir
|
- name: Patch and rename pkgdir
|
||||||
run: |
|
run: |
|
||||||
cp -r dist/linux/debian/ pkgdir
|
cp -r dist/linux/debian/ pkgdir
|
||||||
@@ -103,12 +117,12 @@ jobs:
|
|||||||
envsubst '${SEMVER_STR} ${VERSION_NUM} ${REVISION_NUM} ${DISABLE_UPDATE_CHECK}' < dist/linux/debian/rules > pkgdir/debian/rules
|
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_${{ steps.deb-version.outputs.debVersion }}
|
||||||
env:
|
env:
|
||||||
SEMVER_STR: ${{ steps.versions.outputs.semVerStr }}
|
SEMVER_STR: ${{ needs.get-version.outputs.semVerStr }}
|
||||||
VERSION_NUM: ${{ steps.versions.outputs.semVerNum }}
|
VERSION_NUM: ${{ needs.get-version.outputs.semVerNum }}
|
||||||
REVISION_NUM: ${{ steps.versions.outputs.revNum }}
|
REVISION_NUM: ${{ needs.get-version.outputs.revNum }}
|
||||||
PPA_VERSION: ${{ inputs.ppaver }}-0ppa1
|
PPA_VERSION: ${{ steps.deb-version.outputs.debVersion }}-0ppa1
|
||||||
- name: Prepare GPG-Agent for signing with key 615D449FE6E6A235
|
- name: Prepare GPG-Agent for signing with key 615D449FE6E6A235
|
||||||
run: |
|
run: |
|
||||||
echo "${GPG_PRIVATE_KEY}" | gpg --batch --quiet --import
|
echo "${GPG_PRIVATE_KEY}" | gpg --batch --quiet --import
|
||||||
@@ -118,17 +132,18 @@ jobs:
|
|||||||
GPG_PASSPHRASE: ${{ secrets.RELEASES_GPG_PASSPHRASE }}
|
GPG_PASSPHRASE: ${{ secrets.RELEASES_GPG_PASSPHRASE }}
|
||||||
- name: debuild
|
- name: debuild
|
||||||
run: |
|
run: |
|
||||||
|
(sleep 8m; gpg --batch --quiet --pinentry-mode loopback -u 615D449FE6E6A235 --dry-run --sign README.md) &
|
||||||
debuild -S -sa -d
|
debuild -S -sa -d
|
||||||
debuild -b -sa -d
|
debuild -b -sa -d
|
||||||
env:
|
env:
|
||||||
DEBSIGN_PROGRAM: gpg --batch --pinentry-mode loopback
|
DEBSIGN_PROGRAM: gpg --batch --pinentry-mode loopback
|
||||||
DEBSIGN_KEYID: 615D449FE6E6A235
|
DEBSIGN_KEYID: 615D449FE6E6A235
|
||||||
working-directory: cryptomator_${{ inputs.ppaver }}
|
working-directory: cryptomator_${{ steps.deb-version.outputs.debVersion }}
|
||||||
- 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_*_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@v4
|
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
||||||
with:
|
with:
|
||||||
name: linux-deb-package
|
name: linux-deb-package
|
||||||
path: |
|
path: |
|
||||||
@@ -140,7 +155,7 @@ jobs:
|
|||||||
cryptomator_*_amd64.deb
|
cryptomator_*_amd64.deb
|
||||||
cryptomator_*.asc
|
cryptomator_*.asc
|
||||||
- name: Publish on PPA
|
- name: Publish on PPA
|
||||||
if: inputs.dput
|
if: inputs.dput && inputs.ppaver != ''
|
||||||
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
|
||||||
|
|||||||
@@ -7,12 +7,13 @@ on:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
check-dependencies:
|
check-dependencies:
|
||||||
uses: skymatic/workflows/.github/workflows/run-dependency-check.yml@v1
|
uses: skymatic/workflows/.github/workflows/run-dependency-check.yml@1074588008ae3326a2221ea451783280518f0366 # v3.0.1
|
||||||
with:
|
with:
|
||||||
runner-os: 'ubuntu-latest'
|
runner-os: 'ubuntu-latest'
|
||||||
java-distribution: 'temurin'
|
java-distribution: 'temurin'
|
||||||
java-version: 22
|
java-version: 25
|
||||||
check-command: 'mvn -B validate -Pdependency-check -Djavafx.platform=linux'
|
|
||||||
secrets:
|
secrets:
|
||||||
nvd-api-key: ${{ secrets.NVD_API_KEY }}
|
nvd-api-key: ${{ secrets.NVD_API_KEY }}
|
||||||
|
ossindex-username: ${{ secrets.OSSINDEX_USERNAME }}
|
||||||
|
ossindex-token: ${{ secrets.OSSINDEX_API_TOKEN }}
|
||||||
slack-webhook-url: ${{ secrets.SLACK_WEBHOOK_URL }}
|
slack-webhook-url: ${{ secrets.SLACK_WEBHOOK_URL }}
|
||||||
|
|||||||
@@ -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@v7
|
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
|
||||||
with:
|
with:
|
||||||
script: |
|
script: |
|
||||||
const query = `query($owner:String!, $name:String!) {
|
const query = `query($owner:String!, $name:String!) {
|
||||||
@@ -53,7 +53,7 @@ jobs:
|
|||||||
INTERVAL: 900
|
INTERVAL: 900
|
||||||
JSON_DATA: ${{ steps.get-stats.outputs.result }}
|
JSON_DATA: ${{ steps.get-stats.outputs.result }}
|
||||||
- name: Upload Results
|
- name: Upload Results
|
||||||
uses: fjogeleit/http-request-action@v1
|
uses: fjogeleit/http-request-action@1297c6fc63a79b147d1676540a3fd9d2e37817c5 # v1.16.5
|
||||||
with:
|
with:
|
||||||
url: 'https://graphite-us-central1.grafana.net/metrics'
|
url: 'https://graphite-us-central1.grafana.net/metrics'
|
||||||
method: 'POST'
|
method: 'POST'
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ jobs:
|
|||||||
- name: Query Discussion Data
|
- name: Query Discussion Data
|
||||||
if: github.event_name == 'discussion_comment' || github.event_name == 'discussion' && github.event.action != 'deleted'
|
if: github.event_name == 'discussion_comment' || github.event_name == 'discussion' && github.event.action != 'deleted'
|
||||||
id: query-data
|
id: query-data
|
||||||
uses: actions/github-script@v7
|
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
|
||||||
with:
|
with:
|
||||||
script: |
|
script: |
|
||||||
const query = `query ($owner: String!, $name: String!, $discussionNumber: Int!) {
|
const query = `query ($owner: String!, $name: String!, $discussionNumber: Int!) {
|
||||||
@@ -42,7 +42,7 @@ jobs:
|
|||||||
return await github.graphql(query, variables)
|
return await github.graphql(query, variables)
|
||||||
- name: Get Gist
|
- name: Get Gist
|
||||||
id: get-gist
|
id: get-gist
|
||||||
uses: andymckay/get-gist-action@master
|
uses: andymckay/get-gist-action@cf3bc8164af24126f7e5979eb6d3dc0c12309bd1 # not_tagged
|
||||||
with:
|
with:
|
||||||
gistURL: https://gist.github.com/cryptobot/accba9fb9555e7192271b85606f97230
|
gistURL: https://gist.github.com/cryptobot/accba9fb9555e7192271b85606f97230
|
||||||
- name: Merge Error Code Data
|
- name: Merge Error Code Data
|
||||||
@@ -58,7 +58,7 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
DISCUSSION: ${{ steps.query-data.outputs.result }}
|
DISCUSSION: ${{ steps.query-data.outputs.result }}
|
||||||
- name: Patch Gist
|
- name: Patch Gist
|
||||||
uses: exuanbo/actions-deploy-gist@v1
|
uses: exuanbo/actions-deploy-gist@47697fceaeea2006a90594ee24eb9cd0a1121ef8 # v1.1.4
|
||||||
with:
|
with:
|
||||||
token: ${{ secrets.CRYPTOBOT_GIST_TOKEN }}
|
token: ${{ secrets.CRYPTOBOT_GIST_TOKEN }}
|
||||||
gist_id: accba9fb9555e7192271b85606f97230
|
gist_id: accba9fb9555e7192271b85606f97230
|
||||||
|
|||||||
@@ -26,13 +26,10 @@ jobs:
|
|||||||
- name: Determine tarball url
|
- name: Determine tarball url
|
||||||
id: url
|
id: url
|
||||||
run: |
|
run: |
|
||||||
URL="";
|
URL="https://github.com/cryptomator/cryptomator/archive/refs/tags/${TAG}.tar.gz"
|
||||||
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"
|
echo "url=${URL}" >> "$GITHUB_OUTPUT"
|
||||||
|
env:
|
||||||
|
TAG: ${{ inputs.tag || github.event.release.tag_name}}
|
||||||
- name: Download source tarball and compute checksum
|
- name: Download source tarball and compute checksum
|
||||||
id: sha512
|
id: sha512
|
||||||
run: |
|
run: |
|
||||||
@@ -46,10 +43,10 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
FLATHUB_PR_URL: tbd
|
FLATHUB_PR_URL: tbd
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||||
with:
|
with:
|
||||||
repository: 'flathub/org.cryptomator.Cryptomator'
|
repository: 'flathub/org.cryptomator.Cryptomator'
|
||||||
token: ${{ secrets.CRYPTOBOT_WINGET_TOKEN }}
|
token: ${{ secrets.CRYPTOBOT_PR_TOKEN }}
|
||||||
- name: Checkout release branch
|
- name: Checkout release branch
|
||||||
run: |
|
run: |
|
||||||
git checkout -b release/${{ needs.get-version.outputs.semVerStr }}
|
git checkout -b release/${{ needs.get-version.outputs.semVerStr }}
|
||||||
@@ -72,9 +69,9 @@ jobs:
|
|||||||
PR_URL=$(gh pr create --title "Release ${{ needs.get-version.outputs.semVerStr }}" --body-file 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"
|
echo "FLATHUB_PR_URL=$PR_URL" >> "$GITHUB_ENV"
|
||||||
env:
|
env:
|
||||||
GH_TOKEN: ${{ secrets.CRYPTOBOT_WINGET_TOKEN }}
|
GH_TOKEN: ${{ secrets.CRYPTOBOT_PR_TOKEN }}
|
||||||
- name: Slack Notification
|
- name: Slack Notification
|
||||||
uses: rtCamp/action-slack-notify@v2
|
uses: rtCamp/action-slack-notify@e31e87e03dd19038e411e38ae27cbad084a90661 # v2.3.3
|
||||||
if: github.event_name == 'release'
|
if: github.event_name == 'release'
|
||||||
env:
|
env:
|
||||||
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }}
|
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }}
|
||||||
|
|||||||
@@ -22,8 +22,8 @@ on:
|
|||||||
value: ${{ jobs.determine-version.outputs.type }}
|
value: ${{ jobs.determine-version.outputs.type }}
|
||||||
|
|
||||||
env:
|
env:
|
||||||
JAVA_DIST: 'zulu'
|
JAVA_DIST: 'temurin'
|
||||||
JAVA_VERSION: 22
|
JAVA_VERSION: 25
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
determine-version:
|
determine-version:
|
||||||
@@ -35,11 +35,11 @@ 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@v4
|
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- name: Setup Java
|
- name: Setup Java
|
||||||
uses: actions/setup-java@v4
|
uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0
|
||||||
with:
|
with:
|
||||||
distribution: ${{ env.JAVA_DIST }}
|
distribution: ${{ env.JAVA_DIST }}
|
||||||
java-version: ${{ env.JAVA_VERSION }}
|
java-version: ${{ env.JAVA_VERSION }}
|
||||||
@@ -49,8 +49,8 @@ jobs:
|
|||||||
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 [[ "${VERSION_STRING}" =~ [0-9]+\.[0-9]+\.[0-9]+.* ]]; then
|
||||||
SEM_VER_STR="${{ inputs.version }}"
|
SEM_VER_STR="${VERSION_STRING}"
|
||||||
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
|
||||||
@@ -70,7 +70,9 @@ jobs:
|
|||||||
echo "semVerNum=${SEM_VER_NUM}" >> $GITHUB_OUTPUT
|
echo "semVerNum=${SEM_VER_NUM}" >> $GITHUB_OUTPUT
|
||||||
echo "revNum=${REVCOUNT}" >> $GITHUB_OUTPUT
|
echo "revNum=${REVCOUNT}" >> $GITHUB_OUTPUT
|
||||||
echo "type=${TYPE}" >> $GITHUB_OUTPUT
|
echo "type=${TYPE}" >> $GITHUB_OUTPUT
|
||||||
|
env:
|
||||||
|
VERSION_STRING: ${{ inputs.version }}
|
||||||
- name: Validate Version
|
- name: Validate Version
|
||||||
uses: skymatic/semver-validation-action@v3
|
uses: skymatic/semver-validation-action@7a6ae1c9e121540d11c9c7e4e667c83d583aa153 # v3.0.0
|
||||||
with:
|
with:
|
||||||
version: ${{ steps.versions.outputs.semVerStr }}
|
version: ${{ steps.versions.outputs.semVerStr }}
|
||||||
@@ -0,0 +1,301 @@
|
|||||||
|
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.
|
||||||
|
#
|
||||||
|
#######################################
|
||||||
|
|
||||||
|
on:
|
||||||
|
release:
|
||||||
|
types: [published]
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
version:
|
||||||
|
description: 'Version'
|
||||||
|
required: false
|
||||||
|
notarize:
|
||||||
|
description: 'Notarize'
|
||||||
|
required: true
|
||||||
|
default: false
|
||||||
|
type: boolean
|
||||||
|
|
||||||
|
env:
|
||||||
|
JAVA_DIST: 'temurin'
|
||||||
|
JAVA_VERSION: '25.0.1+8.0.LTS'
|
||||||
|
|
||||||
|
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/25/openjfx-25_osx-x64_bin-jmods.zip'
|
||||||
|
openjfx-sha: '0eba73fb28a24c845175d16fa2f8c081c936ce6de1be9b79eb6119fa32e53d52'
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||||
|
- name: Setup Java
|
||||||
|
uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0
|
||||||
|
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 clean package -Pmac -DskipTests
|
||||||
|
- name: Patch target dir
|
||||||
|
run: |
|
||||||
|
cp LICENSE.txt target
|
||||||
|
cp target/cryptomator-*.jar target/mods
|
||||||
|
- name: Run jlink with help option
|
||||||
|
id: jep-493-check
|
||||||
|
run: |
|
||||||
|
JMOD_PATHS="openjfx-jmods"
|
||||||
|
if ! ${JAVA_HOME}/bin/jlink --help | grep -q "Linking from run-time image enabled"; then
|
||||||
|
JMOD_PATHS="${JAVA_HOME}/jmods:${JMOD_PATHS}"
|
||||||
|
fi
|
||||||
|
echo "jmod_paths=${JMOD_PATHS}" >> "$GITHUB_OUTPUT"
|
||||||
|
- 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 "${{ steps.jep-493-check.outputs.jmod_paths }}"
|
||||||
|
--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.crypto.cryptoki,jdk.crypto.ec,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 - 2025 Skymatic GmbH"
|
||||||
|
--app-version "${{ needs.get-version.outputs.semVerNum }}"
|
||||||
|
--java-options "--enable-preview"
|
||||||
|
--java-options "--enable-native-access=javafx.graphics,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.updateMechanism=org.cryptomator.macos.update.DmgUpdateMechanism"
|
||||||
|
--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: Build and install DockTilePlugin
|
||||||
|
env:
|
||||||
|
DERIVED_DATA_PATH: dist/mac/DockTilePlugin/build
|
||||||
|
run: |
|
||||||
|
xcodebuild -project dist/mac/DockTilePlugin/DockTilePlugin.xcodeproj \
|
||||||
|
-scheme DockTilePlugin \
|
||||||
|
-configuration Release \
|
||||||
|
-destination "platform=macOS,arch=x86_64" \
|
||||||
|
-derivedDataPath ${DERIVED_DATA_PATH} \
|
||||||
|
-quiet \
|
||||||
|
clean build
|
||||||
|
mkdir -p Cryptomator.app/Contents/PlugIns
|
||||||
|
cp -R ${DERIVED_DATA_PATH}/Build/Products/Release/Cryptomator.docktileplugin Cryptomator.app/Contents/PlugIns/
|
||||||
|
rm -rf ${DERIVED_DATA_PATH}
|
||||||
|
- name: Generate license for dmg
|
||||||
|
run: >
|
||||||
|
mvn -B 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: Codesign .dmg
|
||||||
|
run: |
|
||||||
|
codesign -s ${CODESIGN_IDENTITY} --timestamp Cryptomator-*.dmg
|
||||||
|
env:
|
||||||
|
CODESIGN_IDENTITY: ${{ secrets.MACOS_CODESIGN_IDENTITY }}
|
||||||
|
- name: Notarize .dmg
|
||||||
|
if: startsWith(github.ref, 'refs/tags/') || inputs.notarize
|
||||||
|
uses: cocoalibs/xcode-notarization-action@5cf433d494b6fa26504b574c591f4dd120388846 # v1.0.3
|
||||||
|
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@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
||||||
|
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@6da8fa9354ddfdc4aeace5fc48d7f679b5214090 # v2.4.1
|
||||||
|
with:
|
||||||
|
fail_on_unmatched_files: true
|
||||||
|
token: ${{ secrets.CRYPTOBOT_RELEASE_TOKEN }}
|
||||||
|
files: |
|
||||||
|
Cryptomator-*.dmg
|
||||||
|
Cryptomator-*.asc
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
name: Build macOS .dmg
|
name: Build macOS .dmg for arm64
|
||||||
|
|
||||||
on:
|
on:
|
||||||
release:
|
release:
|
||||||
@@ -13,10 +13,16 @@ on:
|
|||||||
required: true
|
required: true
|
||||||
default: false
|
default: false
|
||||||
type: boolean
|
type: boolean
|
||||||
|
push:
|
||||||
|
branches-ignore:
|
||||||
|
- 'dependabot/**'
|
||||||
|
paths:
|
||||||
|
- '.github/workflows/mac-dmg.yml'
|
||||||
|
- 'dist/mac/**'
|
||||||
|
|
||||||
env:
|
env:
|
||||||
JAVA_DIST: 'zulu'
|
JAVA_DIST: 'temurin'
|
||||||
JAVA_VERSION: '22.0.2+9'
|
JAVA_VERSION: '25.0.1+8.0.LTS'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
get-version:
|
get-version:
|
||||||
@@ -32,24 +38,16 @@ 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/22.0.2/openjfx-22.0.2_osx-x64_bin-jmods.zip'
|
|
||||||
openjfx-sha: '115cb08bb59d880cfff6e51e0bf0dcc45785ed9d456b8b8425597b04da6ab3d4'
|
|
||||||
- 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/22.0.2/openjfx-22.0.2_osx-aarch64_bin-jmods.zip'
|
openjfx-url: 'https://download2.gluonhq.com/openjfx/25/openjfx-25_osx-aarch64_bin-jmods.zip'
|
||||||
openjfx-sha: '813c6748f7c99cb7a579d48b48a087b4682b1fad1fc1a4fe5f9b21cf872b15a7'
|
openjfx-sha: '13f8c0513c40c95881479fbcf0465a29a60217393fb0656f5e4eab78a9442fba'
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||||
- name: Setup Java
|
- name: Setup Java
|
||||||
uses: actions/setup-java@v4
|
uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0
|
||||||
with:
|
with:
|
||||||
distribution: ${{ env.JAVA_DIST }}
|
distribution: ${{ env.JAVA_DIST }}
|
||||||
java-version: ${{ env.JAVA_VERSION }}
|
java-version: ${{ env.JAVA_VERSION }}
|
||||||
@@ -79,19 +77,27 @@ 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 -Djavafx.platform=mac clean package -Pmac -DskipTests
|
run: mvn -B 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 with help option
|
||||||
|
id: jep-493-check
|
||||||
|
run: |
|
||||||
|
JMOD_PATHS="openjfx-jmods"
|
||||||
|
if ! ${JAVA_HOME}/bin/jlink --help | grep -q "Linking from run-time image enabled"; then
|
||||||
|
JMOD_PATHS="${JAVA_HOME}/jmods:${JMOD_PATHS}"
|
||||||
|
fi
|
||||||
|
echo "jmod_paths=${JMOD_PATHS}" >> "$GITHUB_OUTPUT"
|
||||||
- name: Run jlink
|
- name: Run jlink
|
||||||
#Remark: no compression is applied for improved build compression later (here dmg)
|
#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 "${{ steps.jep-493-check.outputs.jmod_paths }}"
|
||||||
--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
|
--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.crypto.cryptoki,jdk.crypto.ec,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
|
||||||
@@ -109,10 +115,10 @@ jobs:
|
|||||||
--dest appdir
|
--dest appdir
|
||||||
--name Cryptomator
|
--name Cryptomator
|
||||||
--vendor "Skymatic GmbH"
|
--vendor "Skymatic GmbH"
|
||||||
--copyright "(C) 2016 - 2024 Skymatic GmbH"
|
--copyright "(C) 2016 - 2025 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=javafx.graphics,org.cryptomator.jfuse.mac"
|
||||||
--java-options "-Xss5m"
|
--java-options "-Xss5m"
|
||||||
--java-options "-Xmx256m"
|
--java-options "-Xmx256m"
|
||||||
--java-options "-Dfile.encoding=\"utf-8\""
|
--java-options "-Dfile.encoding=\"utf-8\""
|
||||||
@@ -128,7 +134,9 @@ jobs:
|
|||||||
--java-options "-Dcryptomator.integrationsMac.keychainServiceName=\"Cryptomator\""
|
--java-options "-Dcryptomator.integrationsMac.keychainServiceName=\"Cryptomator\""
|
||||||
--java-options "-Dcryptomator.mountPointsDir=\"@{userhome}/Library/Application Support/Cryptomator/mnt\""
|
--java-options "-Dcryptomator.mountPointsDir=\"@{userhome}/Library/Application Support/Cryptomator/mnt\""
|
||||||
--java-options "-Dcryptomator.showTrayIcon=true"
|
--java-options "-Dcryptomator.showTrayIcon=true"
|
||||||
|
--java-options "-Dcryptomator.updateMechanism=org.cryptomator.macos.update.DmgUpdateMechanism"
|
||||||
--java-options "-Dcryptomator.buildNumber=\"dmg-${{ needs.get-version.outputs.revNum }}\""
|
--java-options "-Dcryptomator.buildNumber=\"dmg-${{ needs.get-version.outputs.revNum }}\""
|
||||||
|
--java-options "-XX:ErrorFile=/cryptomator/cryptomator_crash.log"
|
||||||
--mac-package-identifier org.cryptomator
|
--mac-package-identifier org.cryptomator
|
||||||
--resource-dir dist/mac/resources
|
--resource-dir dist/mac/resources
|
||||||
- name: Patch Cryptomator.app
|
- name: Patch Cryptomator.app
|
||||||
@@ -142,9 +150,23 @@ jobs:
|
|||||||
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 }}
|
PROVISIONING_PROFILE_BASE64: ${{ secrets.MACOS_PROVISIONING_PROFILE_BASE64 }}
|
||||||
|
- name: Build and install DockTilePlugin
|
||||||
|
env:
|
||||||
|
DERIVED_DATA_PATH: dist/mac/DockTilePlugin/build
|
||||||
|
run: |
|
||||||
|
xcodebuild -project dist/mac/DockTilePlugin/DockTilePlugin.xcodeproj \
|
||||||
|
-scheme DockTilePlugin \
|
||||||
|
-configuration Release \
|
||||||
|
-destination "platform=macOS,arch=arm64" \
|
||||||
|
-derivedDataPath ${DERIVED_DATA_PATH} \
|
||||||
|
-quiet \
|
||||||
|
clean build
|
||||||
|
mkdir -p Cryptomator.app/Contents/PlugIns
|
||||||
|
cp -R ${DERIVED_DATA_PATH}/Build/Products/Release/Cryptomator.docktileplugin Cryptomator.app/Contents/PlugIns/
|
||||||
|
rm -rf ${DERIVED_DATA_PATH}
|
||||||
- name: Generate license for dmg
|
- name: Generate license for dmg
|
||||||
run: >
|
run: >
|
||||||
mvn -B -Djavafx.platform=mac license:add-third-party
|
mvn -B 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
|
||||||
@@ -232,15 +254,20 @@ jobs:
|
|||||||
Cryptomator-${VERSION_NO}-${{ matrix.output-suffix }}.dmg dmg
|
Cryptomator-${VERSION_NO}-${{ matrix.output-suffix }}.dmg dmg
|
||||||
env:
|
env:
|
||||||
VERSION_NO: ${{ needs.get-version.outputs.semVerNum }}
|
VERSION_NO: ${{ needs.get-version.outputs.semVerNum }}
|
||||||
|
- name: Codesign .dmg
|
||||||
|
run: |
|
||||||
|
codesign -s ${CODESIGN_IDENTITY} --timestamp Cryptomator-*.dmg
|
||||||
|
env:
|
||||||
|
CODESIGN_IDENTITY: ${{ secrets.MACOS_CODESIGN_IDENTITY }}
|
||||||
- name: Notarize .dmg
|
- name: Notarize .dmg
|
||||||
if: startsWith(github.ref, 'refs/tags/') || inputs.notarize
|
if: startsWith(github.ref, 'refs/tags/') || inputs.notarize
|
||||||
uses: cocoalibs/xcode-notarization-action@v1
|
uses: cocoalibs/xcode-notarization-action@5cf433d494b6fa26504b574c591f4dd120388846 # v1.0.3
|
||||||
with:
|
with:
|
||||||
app-path: 'Cryptomator-*.dmg'
|
app-path: 'Cryptomator-*.dmg'
|
||||||
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
|
||||||
@@ -255,7 +282,7 @@ 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@v4
|
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
||||||
with:
|
with:
|
||||||
name: dmg-${{ matrix.output-suffix }}
|
name: dmg-${{ matrix.output-suffix }}
|
||||||
path: |
|
path: |
|
||||||
@@ -264,7 +291,7 @@ jobs:
|
|||||||
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/') && github.event.action == 'published'
|
if: startsWith(github.ref, 'refs/tags/') && github.event.action == 'published'
|
||||||
uses: softprops/action-gh-release@v2
|
uses: softprops/action-gh-release@6da8fa9354ddfdc4aeace5fc48d7f679b5214090 # v2.4.1
|
||||||
with:
|
with:
|
||||||
fail_on_unmatched_files: true
|
fail_on_unmatched_files: true
|
||||||
token: ${{ secrets.CRYPTOBOT_RELEASE_TOKEN }}
|
token: ${{ secrets.CRYPTOBOT_RELEASE_TOKEN }}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ jobs:
|
|||||||
issues: write
|
issues: write
|
||||||
pull-requests: write
|
pull-requests: write
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/stale@v9
|
- uses: actions/stale@5f858e3efba33a5ca4407a664cc011ad407f2008 # v10.1.0
|
||||||
with:
|
with:
|
||||||
days-before-stale: 14
|
days-before-stale: 14
|
||||||
days-before-close: 0
|
days-before-close: 0
|
||||||
|
|||||||
@@ -19,14 +19,14 @@ 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@v2
|
uses: softprops/action-gh-release@6da8fa9354ddfdc4aeace5fc48d7f679b5214090 # v2.4.1
|
||||||
with:
|
with:
|
||||||
fail_on_unmatched_files: true
|
fail_on_unmatched_files: true
|
||||||
token: ${{ secrets.CRYPTOBOT_RELEASE_TOKEN }}
|
token: ${{ secrets.CRYPTOBOT_RELEASE_TOKEN }}
|
||||||
files: |
|
files: |
|
||||||
cryptomator-*.tar.gz.asc
|
cryptomator-*.tar.gz.asc
|
||||||
- name: Slack Notification
|
- name: Slack Notification
|
||||||
uses: rtCamp/action-slack-notify@v2
|
uses: rtCamp/action-slack-notify@e31e87e03dd19038e411e38ae27cbad084a90661 # v2.3.3
|
||||||
env:
|
env:
|
||||||
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }}
|
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }}
|
||||||
SLACK_USERNAME: 'Cryptobot'
|
SLACK_USERNAME: 'Cryptobot'
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ on:
|
|||||||
pull_request:
|
pull_request:
|
||||||
|
|
||||||
env:
|
env:
|
||||||
JAVA_DIST: 'zulu'
|
JAVA_DIST: 'temurin'
|
||||||
JAVA_VERSION: 22
|
JAVA_VERSION: 25
|
||||||
|
|
||||||
defaults:
|
defaults:
|
||||||
run:
|
run:
|
||||||
@@ -15,13 +15,12 @@ jobs:
|
|||||||
test:
|
test:
|
||||||
name: Compile and Test
|
name: Compile and Test
|
||||||
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]')"
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||||
- uses: actions/setup-java@v4
|
- uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0
|
||||||
with:
|
with:
|
||||||
distribution: ${{ env.JAVA_DIST }}
|
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 -Djavafx.platform=linux
|
run: xvfb-run mvn -B clean install jacoco:report -Pcoverage
|
||||||
@@ -11,17 +11,17 @@ defaults:
|
|||||||
shell: bash
|
shell: bash
|
||||||
|
|
||||||
env:
|
env:
|
||||||
JAVA_DIST: 'zulu'
|
JAVA_DIST: 'temurin'
|
||||||
JAVA_VERSION: 22
|
JAVA_VERSION: 25
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
check-preconditions:
|
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@v4
|
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||||
- name: Setup Java
|
- name: Setup Java
|
||||||
uses: actions/setup-java@v4
|
uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0
|
||||||
with:
|
with:
|
||||||
distribution: ${{ env.JAVA_DIST }}
|
distribution: ${{ env.JAVA_DIST }}
|
||||||
java-version: ${{ env.JAVA_VERSION }}
|
java-version: ${{ env.JAVA_VERSION }}
|
||||||
@@ -49,7 +49,7 @@ jobs:
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
- name: Cache NVD DB
|
- name: Cache NVD DB
|
||||||
uses: actions/cache@v4
|
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
|
||||||
with:
|
with:
|
||||||
path: ~/.m2/repository/org/owasp/dependency-check-data/
|
path: ~/.m2/repository/org/owasp/dependency-check-data/
|
||||||
key: dependency-check-${{ github.run_id }}
|
key: dependency-check-${{ github.run_id }}
|
||||||
@@ -60,6 +60,6 @@ jobs:
|
|||||||
- name: Run org.owasp:dependency-check plugin
|
- name: Run org.owasp:dependency-check plugin
|
||||||
id: dependency-check
|
id: dependency-check
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
run: mvn -B verify -Pdependency-check -DskipTests -Djavafx.platform=linux
|
run: mvn -B verify -Pdependency-check -DskipTests
|
||||||
env:
|
env:
|
||||||
NVD_API_KEY: ${{ secrets.NVD_API_KEY }}
|
NVD_API_KEY: ${{ secrets.NVD_API_KEY }}
|
||||||
@@ -12,7 +12,7 @@ jobs:
|
|||||||
issues: write
|
issues: write
|
||||||
pull-requests: write
|
pull-requests: write
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/stale@v9
|
- uses: actions/stale@5f858e3efba33a5ca4407a664cc011ad407f2008 # v10.1.0
|
||||||
with:
|
with:
|
||||||
days-before-stale: 365
|
days-before-stale: 365
|
||||||
days-before-close: 90
|
days-before-close: 90
|
||||||
|
|||||||
+207
-141
@@ -8,18 +8,24 @@ on:
|
|||||||
version:
|
version:
|
||||||
description: 'Version'
|
description: 'Version'
|
||||||
required: false
|
required: false
|
||||||
isDebug:
|
sign:
|
||||||
description: 'Build debug version with console output'
|
description: 'Sign binaries'
|
||||||
|
required: false
|
||||||
type: boolean
|
type: boolean
|
||||||
default: false
|
default: false
|
||||||
|
push:
|
||||||
|
branches-ignore:
|
||||||
|
- 'dependabot/**'
|
||||||
|
paths:
|
||||||
|
- '.github/workflows/win-exe.yml'
|
||||||
|
- 'dist/win/**'
|
||||||
|
|
||||||
|
|
||||||
env:
|
env:
|
||||||
JAVA_DIST: 'zulu'
|
OPENJFX_JMODS_AMD64: 'https://download2.gluonhq.com/openjfx/25/openjfx-25_windows-x64_bin-jmods.zip'
|
||||||
JAVA_VERSION: '22.0.2+9'
|
OPENJFX_JMODS_AMD64_HASH: 'c8eb9fd039b00e0020cf6c3db8ed7876bf3ee4d27860aa697a247b83b8296ae7'
|
||||||
OPENJFX_JMODS_AMD64: 'https://download2.gluonhq.com/openjfx/22.0.2/openjfx-22.0.2_windows-x64_bin-jmods.zip'
|
WINFSP_MSI: 'https://github.com/winfsp/winfsp/releases/download/v2.1/winfsp-2.1.25156.msi'
|
||||||
OPENJFX_JMODS_AMD64_HASH: 'f9376d200f5c5b85327d575c1ec1482e6455f19916577f7e2fc9be2f48bb29b6'
|
WINFSP_MSI_HASH: '073a70e00f77423e34bed98b86e600def93393ba5822204fac57a29324db9f7a'
|
||||||
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'
|
WINFSP_UNINSTALLER: 'https://github.com/cryptomator/winfsp-uninstaller/releases/latest/download/winfsp-uninstaller.exe'
|
||||||
|
|
||||||
defaults:
|
defaults:
|
||||||
@@ -34,36 +40,46 @@ jobs:
|
|||||||
|
|
||||||
build-msi:
|
build-msi:
|
||||||
name: Build .msi Installer
|
name: Build .msi Installer
|
||||||
runs-on: windows-latest
|
runs-on: ${{ matrix.os }}
|
||||||
needs: [get-version]
|
needs: [ get-version ]
|
||||||
env:
|
strategy:
|
||||||
LOOPBACK_ALIAS: 'cryptomator-vault'
|
matrix:
|
||||||
WIN_CONSOLE_FLAG: ''
|
include:
|
||||||
|
- arch: x64
|
||||||
|
os: windows-latest
|
||||||
|
java-dist: 'zulu' #cannot use temurin, see https://github.com/cryptomator/cryptomator/issues/3824#issuecomment-2829827427
|
||||||
|
java-version: '25.0.1+8'
|
||||||
|
java-package: 'jdk'
|
||||||
steps:
|
steps:
|
||||||
- name: Upgrade WIX to latest version
|
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||||
run: choco install wixtoolset --version 3.14.1
|
|
||||||
shell: pwsh
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- name: Setup Java
|
- name: Setup Java
|
||||||
uses: actions/setup-java@v4
|
uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0
|
||||||
with:
|
with:
|
||||||
distribution: ${{ env.JAVA_DIST }}
|
distribution: ${{ matrix.java-dist }}
|
||||||
java-version: ${{ env.JAVA_VERSION }}
|
java-version: ${{ matrix.java-version }}
|
||||||
|
java-package: ${{ matrix.java-package }}
|
||||||
check-latest: true
|
check-latest: true
|
||||||
cache: 'maven'
|
cache: 'maven'
|
||||||
|
- name: Install wix and extensions
|
||||||
|
run: |
|
||||||
|
dotnet tool install --global wix --version 6.0.0
|
||||||
|
wix.exe extension add WixToolset.UI.wixext/6.0.0 --global
|
||||||
|
wix.exe extension add WixToolset.Util.wixext/6.0.0 --global
|
||||||
- name: Download and extract JavaFX jmods from Gluon
|
- name: Download and extract JavaFX jmods from Gluon
|
||||||
|
if: matrix.arch == 'x64'
|
||||||
#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.OPENJFX_JMODS_AMD64 }}"
|
curl --output openjfx-jmods.zip -L "${{ env.OPENJFX_JMODS_AMD64 }}"
|
||||||
if(!(Get-FileHash -Path jfxjmods.zip -Algorithm SHA256).Hash.ToLower().equals("${{ env.OPENJFX_JMODS_AMD64_HASH }}")) {
|
if(!(Get-FileHash -Path openjfx-jmods.zip -Algorithm SHA256).Hash.ToLower().equals("${{ env.OPENJFX_JMODS_AMD64_HASH }}")) {
|
||||||
throw "Wrong checksum of JMOD archive downloaded from ${{ env.OPENJFX_JMODS_AMD64 }}.";
|
throw "Wrong checksum of JMOD archive downloaded from ${{ env.OPENJFX_JMODS_AMD64 }}.";
|
||||||
}
|
}
|
||||||
Expand-Archive -Path jfxjmods.zip -DestinationPath jfxjmods
|
Expand-Archive -Path openjfx-jmods.zip -DestinationPath openjfx-jmods
|
||||||
Get-ChildItem -Path jfxjmods -Recurse -Filter "*.jmod" | ForEach-Object { Move-Item -Path $_ -Destination $_.Directory.Parent}
|
Get-ChildItem -Path openjfx-jmods -Recurse -Filter "*.jmod" | ForEach-Object { Move-Item -Path $_ -Destination $_.Directory.Parent}
|
||||||
shell: pwsh
|
shell: pwsh
|
||||||
- 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
|
||||||
|
if: matrix.arch == 'x64'
|
||||||
run: |
|
run: |
|
||||||
JMOD_VERSION_AMD64=$(jmod describe jfxjmods/javafx.base.jmod | head -1)
|
JMOD_VERSION_AMD64=$(jmod describe openjfx-jmods/javafx.base.jmod | head -1)
|
||||||
JMOD_VERSION_AMD64=${JMOD_VERSION_AMD64#*@}
|
JMOD_VERSION_AMD64=${JMOD_VERSION_AMD64#*@}
|
||||||
JMOD_VERSION_AMD64=${JMOD_VERSION_AMD64%%.*}
|
JMOD_VERSION_AMD64=${JMOD_VERSION_AMD64%%.*}
|
||||||
POM_JFX_VERSION=$(mvn help:evaluate "-Dexpression=javafx.version" -q -DforceStdout)
|
POM_JFX_VERSION=$(mvn help:evaluate "-Dexpression=javafx.version" -q -DforceStdout)
|
||||||
@@ -75,29 +91,34 @@ jobs:
|
|||||||
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 -Pwin -DskipTests -Djavafx.platform=win
|
run: mvn -B clean package -Pwin -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 with help option
|
||||||
|
id: jep-493-check
|
||||||
|
run: |
|
||||||
|
JMOD_PATHS="openjfx-jmods"
|
||||||
|
if ! $(${JAVA_HOME}/bin/jlink --help | grep -q "Linking from run-time image enabled"); then
|
||||||
|
JMOD_PATHS="${JAVA_HOME}/jmods;${JMOD_PATHS}"
|
||||||
|
fi
|
||||||
|
echo "jmod_paths=${JMOD_PATHS}" >> "$GITHUB_OUTPUT"
|
||||||
- name: Run jlink
|
- name: Run jlink
|
||||||
#Remark: no compression is applied for improved build compression later (here msi)
|
# 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 "${{ steps.jep-493-check.outputs.jmod_paths }}"
|
||||||
--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
|
--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.crypto.cryptoki,jdk.crypto.ec,jdk.crypto.mscapi,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 zip-0
|
--compress zip-0
|
||||||
- name: Change win-console flag if debug is active
|
|
||||||
if: ${{ inputs.isDebug }}
|
|
||||||
run: echo "WIN_CONSOLE_FLAG=--win-console" >> $GITHUB_ENV
|
|
||||||
- name: Run jpackage
|
- name: Run jpackage
|
||||||
run: >
|
run: >
|
||||||
${JAVA_HOME}/bin/jpackage
|
${JAVA_HOME}/bin/jpackage
|
||||||
@@ -110,10 +131,10 @@ jobs:
|
|||||||
--dest appdir
|
--dest appdir
|
||||||
--name Cryptomator
|
--name Cryptomator
|
||||||
--vendor "Skymatic GmbH"
|
--vendor "Skymatic GmbH"
|
||||||
--copyright "(C) 2016 - 2024 Skymatic GmbH"
|
--copyright "(C) 2016 - 2025 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,org.cryptomator.integrations.win"
|
--java-options "--enable-native-access=javafx.graphics,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,30 +146,24 @@ jobs:
|
|||||||
--java-options "-Dcryptomator.p12Path=\"@{appdata}/Cryptomator/key.p12;@{userhome}/AppData/Roaming/Cryptomator/key.p12\""
|
--java-options "-Dcryptomator.p12Path=\"@{appdata}/Cryptomator/key.p12;@{userhome}/AppData/Roaming/Cryptomator/key.p12\""
|
||||||
--java-options "-Dcryptomator.ipcSocketPath=\"@{localappdata}/Cryptomator/ipc.socket\""
|
--java-options "-Dcryptomator.ipcSocketPath=\"@{localappdata}/Cryptomator/ipc.socket\""
|
||||||
--java-options "-Dcryptomator.mountPointsDir=\"@{userhome}/Cryptomator\""
|
--java-options "-Dcryptomator.mountPointsDir=\"@{userhome}/Cryptomator\""
|
||||||
--java-options "-Dcryptomator.loopbackAlias=\"${{ env.LOOPBACK_ALIAS }}\""
|
--java-options "-Dcryptomator.loopbackAlias=\"cryptomator-vault\""
|
||||||
--java-options "-Dcryptomator.showTrayIcon=true"
|
--java-options "-Dcryptomator.showTrayIcon=true"
|
||||||
--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 "-Djavafx.verbose=${{ inputs.isDebug }}"
|
--java-options "-Dcryptomator.integrationsWin.windowsHelloKeychainPaths=\"@{appdata}/Cryptomator/windowsHelloKeychain.json\""
|
||||||
|
--java-options "-Dcryptomator.disableUpdateCheck=false"
|
||||||
|
--java-options "-XX:ErrorFile=C:/cryptomator/cryptomator_crash.log"
|
||||||
--resource-dir dist/win/resources
|
--resource-dir dist/win/resources
|
||||||
--icon dist/win/resources/Cryptomator.ico
|
--icon dist/win/resources/Cryptomator.ico
|
||||||
${WIN_CONSOLE_FLAG}
|
--add-launcher "Cryptomator (Debug)=dist/win/debug-launcher.properties"
|
||||||
- name: Patch Application Directory
|
- name: Patch Application Directory
|
||||||
run: |
|
run: |
|
||||||
cp dist/win/contrib/* appdir/Cryptomator
|
cp dist/win/contrib/* appdir/Cryptomator
|
||||||
- name: Set LOOPBACK_ALIAS in patchWebDAV.bat
|
|
||||||
shell: pwsh
|
|
||||||
run: |
|
|
||||||
$patchScript = "appdir\Cryptomator\patchWebDAV.bat"
|
|
||||||
try {
|
|
||||||
(Get-Content $patchScript ) -replace '::REPLACE ME', "SET LOOPBACK_ALIAS=`"${{ env.LOOPBACK_ALIAS}}`"" | Set-Content $patchScript
|
|
||||||
} catch {
|
|
||||||
Write-Host "Failed to set LOOPBACK_ALIAS for patchWebDAV.bat"
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
- name: Fix permissions
|
- name: Fix permissions
|
||||||
run: attrib -r appdir/Cryptomator/Cryptomator.exe
|
run: |
|
||||||
|
attrib -r appdir/Cryptomator/Cryptomator.exe
|
||||||
|
attrib -r "appdir/Cryptomator/Cryptomator (Debug).exe"
|
||||||
shell: pwsh
|
shell: pwsh
|
||||||
- name: Extract jars with DLLs for Codesigning
|
- name: Extract jars with DLLs for Codesigning
|
||||||
shell: pwsh
|
shell: pwsh
|
||||||
@@ -173,16 +188,27 @@ jobs:
|
|||||||
New-Item -Path appdir/jpackage-jmod -ItemType Directory
|
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"
|
& $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"
|
Get-ChildItem -Recurse -Path "jpackage-jmod" -File wixhelper.dll | Select-Object -Last 1 | Copy-Item -Destination "appdir"
|
||||||
- name: Codesign
|
- name: Sign DLLs with Azure Trusted Signing
|
||||||
uses: skymatic/code-sign-action@v3
|
if: inputs.sign || github.event_name == 'release'
|
||||||
|
uses: ./.github/actions/win-sign-action
|
||||||
with:
|
with:
|
||||||
certificate: ${{ secrets.WIN_CODESIGN_P12_BASE64 }}
|
base-dir: ${{ github.workspace }}\appdir
|
||||||
password: ${{ secrets.WIN_CODESIGN_P12_PW }}
|
|
||||||
certificatesha1: 5FC94CE149E5B511E621F53A060AC67CBD446B3A
|
|
||||||
description: Cryptomator
|
|
||||||
timestampUrl: 'http://timestamp.digicert.com'
|
|
||||||
folder: appdir
|
|
||||||
recursive: true
|
recursive: true
|
||||||
|
append-signature: true
|
||||||
|
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
|
||||||
|
client-id: ${{ secrets.AZURE_CLIENT_ID }}
|
||||||
|
client-secret: ${{ secrets.AZURE_CLIENT_SECRET }}
|
||||||
|
- name: Sign DLLs with Actalis CodeSigner
|
||||||
|
if: inputs.sign || github.event_name == 'release'
|
||||||
|
uses: skymatic/workflows/.github/actions/win-sign-action@450e322ff2214d0be0b079b63343c894f3ef735f # no specific version
|
||||||
|
with:
|
||||||
|
base-dir: 'appdir'
|
||||||
|
file-extensions: 'dll,exe,ps1'
|
||||||
|
recursive: true
|
||||||
|
sign-description: 'Cryptomator'
|
||||||
|
sign-url: 'https://cryptomator.org'
|
||||||
|
username: ${{ secrets.WIN_CODESIGN_USERNAME }}
|
||||||
|
password: ${{ secrets.WIN_CODESIGN_PW }}
|
||||||
- name: Replace DLLs inside jars with signed ones
|
- name: Replace DLLs inside jars with signed ones
|
||||||
shell: pwsh
|
shell: pwsh
|
||||||
run: |
|
run: |
|
||||||
@@ -199,7 +225,7 @@ jobs:
|
|||||||
}
|
}
|
||||||
- name: Generate license for MSI
|
- name: Generate license for MSI
|
||||||
run: >
|
run: >
|
||||||
mvn -B license:add-third-party "-Djavafx.platform=win"
|
mvn -B license:add-third-party
|
||||||
"-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"
|
||||||
@@ -218,7 +244,7 @@ jobs:
|
|||||||
--dest installer
|
--dest installer
|
||||||
--name Cryptomator
|
--name Cryptomator
|
||||||
--vendor "Skymatic GmbH"
|
--vendor "Skymatic GmbH"
|
||||||
--copyright "(C) 2016 - 2024 Skymatic GmbH"
|
--copyright "(C) 2016 - 2025 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
|
||||||
@@ -231,17 +257,18 @@ jobs:
|
|||||||
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
|
JP_WIXHELPER_DIR: ${{ github.workspace }}\appdir
|
||||||
- name: Codesign MSI
|
- name: Sign MSI with Azure Trusted Signing
|
||||||
uses: skymatic/code-sign-action@v3
|
if: inputs.sign || github.event_name == 'release'
|
||||||
|
uses: ./.github/actions/win-sign-action
|
||||||
with:
|
with:
|
||||||
certificate: ${{ secrets.WIN_CODESIGN_P12_BASE64 }}
|
base-dir: ${{ github.workspace }}\installer
|
||||||
password: ${{ secrets.WIN_CODESIGN_P12_PW }}
|
file-extensions: msi
|
||||||
certificatesha1: 5FC94CE149E5B511E621F53A060AC67CBD446B3A
|
description: 'Cryptomator Installer'
|
||||||
description: Cryptomator Installer
|
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
|
||||||
timestampUrl: 'http://timestamp.digicert.com'
|
client-id: ${{ secrets.AZURE_CLIENT_ID }}
|
||||||
folder: installer
|
client-secret: ${{ secrets.AZURE_CLIENT_SECRET }}
|
||||||
- name: Add possible alpha/beta tags to installer name
|
- name: Add possible alpha/beta tags and architecture to installer name
|
||||||
run: mv installer/Cryptomator-*.msi Cryptomator-${{ needs.get-version.outputs.semVerStr }}-x64.msi
|
run: mv installer/Cryptomator-*.msi Cryptomator-${{ needs.get-version.outputs.semVerStr }}-${{ matrix.arch }}.msi
|
||||||
- name: Create detached GPG signature with key 615D449FE6E6A235
|
- name: Create detached GPG signature with key 615D449FE6E6A235
|
||||||
run: |
|
run: |
|
||||||
echo "${GPG_PRIVATE_KEY}" | gpg --batch --quiet --import
|
echo "${GPG_PRIVATE_KEY}" | gpg --batch --quiet --import
|
||||||
@@ -250,9 +277,9 @@ 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@v4
|
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
||||||
with:
|
with:
|
||||||
name: msi
|
name: msi-${{ matrix.arch }}
|
||||||
path: |
|
path: |
|
||||||
Cryptomator-*.msi
|
Cryptomator-*.msi
|
||||||
Cryptomator-*.asc
|
Cryptomator-*.asc
|
||||||
@@ -260,26 +287,42 @@ jobs:
|
|||||||
|
|
||||||
build-exe:
|
build-exe:
|
||||||
name: Build .exe installer
|
name: Build .exe installer
|
||||||
runs-on: windows-latest
|
runs-on: ${{ matrix.os }}
|
||||||
needs: [get-version, build-msi]
|
needs: [ get-version, build-msi ]
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- arch: x64
|
||||||
|
os: windows-latest
|
||||||
|
executable-suffix: x64
|
||||||
|
java-dist: 'zulu'
|
||||||
|
java-version: '24.0.1+9'
|
||||||
|
java-package: 'jdk'
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||||
|
- name: Install wix and extensions
|
||||||
|
run: |
|
||||||
|
dotnet tool install --global wix --version 6.0.0
|
||||||
|
wix.exe extension add WixToolset.BootstrapperApplications.wixext/6.0.0 --global
|
||||||
|
wix.exe extension add WixToolset.Util.wixext/6.0.0 --global
|
||||||
- name: Download .msi
|
- name: Download .msi
|
||||||
uses: actions/download-artifact@v4
|
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0
|
||||||
with:
|
with:
|
||||||
name: msi
|
name: msi-${{ matrix.arch }}
|
||||||
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@v4
|
- name: Setup Java
|
||||||
|
uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0
|
||||||
with:
|
with:
|
||||||
distribution: ${{ env.JAVA_DIST }}
|
distribution: ${{ matrix.java-dist }}
|
||||||
java-version: ${{ env.JAVA_VERSION }}
|
java-version: ${{ matrix.java-version }}
|
||||||
|
java-package: ${{ matrix.java-package }}
|
||||||
check-latest: true
|
check-latest: true
|
||||||
cache: 'maven'
|
cache: 'maven'
|
||||||
- name: Generate license for exe
|
- name: Generate license for exe
|
||||||
run: >
|
run: >
|
||||||
mvn -B license:add-third-party "-Djavafx.platform=win"
|
mvn -B license:add-third-party
|
||||||
"-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"
|
||||||
@@ -290,60 +333,83 @@ jobs:
|
|||||||
shell: pwsh
|
shell: pwsh
|
||||||
- name: Download WinFsp
|
- name: Download WinFsp
|
||||||
run: |
|
run: |
|
||||||
curl --output dist/win/bundle/resources/winfsp.msi -L ${{ env.WINFSP_MSI }}
|
curl --output $env:WINFSP_PATH -L ${{ env.WINFSP_MSI }}
|
||||||
|
$computedHash = (Get-FileHash -Path $env:WINFSP_PATH -Algorithm SHA256).Hash.ToLower()
|
||||||
|
if ($computedHash -ne "${{ env.WINFSP_MSI_HASH }}") {
|
||||||
|
throw "Checksum mismatch for $env:WINFSP_PATH (expected ${{ env.WINFSP_MSI_HASH }}, got $computedHash)."
|
||||||
|
}
|
||||||
|
env:
|
||||||
|
WINFSP_PATH: 'dist/win/bundle/resources/winfsp.msi'
|
||||||
shell: pwsh
|
shell: pwsh
|
||||||
- name: Download Legacy-WinFsp uninstaller
|
- name: Download Legacy-WinFsp uninstaller
|
||||||
run: |
|
run: |
|
||||||
curl --output dist/win/bundle/resources/winfsp-uninstaller.exe -L ${{ env.WINFSP_UNINSTALLER }}
|
curl --output dist/win/bundle/resources/winfsp-uninstaller.exe -L ${{ env.WINFSP_UNINSTALLER }}
|
||||||
shell: pwsh
|
shell: pwsh
|
||||||
- name: Compile to wixObj file
|
- name: Create Wix Burn bundle
|
||||||
|
working-directory: dist/win
|
||||||
run: >
|
run: >
|
||||||
"${WIX}/bin/candle.exe" dist/win/bundle/bundleWithWinfsp.wxs
|
wix build
|
||||||
-ext WixBalExtension
|
-define BundleName="Cryptomator"
|
||||||
-ext WixUtilExtension
|
-define BundleVersion="${{ needs.get-version.outputs.semVerNum }}.${{ needs.get-version.outputs.revNum}}"
|
||||||
-out dist/win/bundle/
|
-define BundleVendor="Skymatic GmbH"
|
||||||
-dBundleVersion="${{ needs.get-version.outputs.semVerNum }}.${{ needs.get-version.outputs.revNum }}"
|
-define BundleCopyright="(C) 2016 - 2025 Skymatic GmbH"
|
||||||
-dBundleVendor="Skymatic GmbH"
|
-define AboutUrl="https://cryptomator.org"
|
||||||
-dBundleCopyright="(C) 2016 - 2024 Skymatic GmbH"
|
-define HelpUrl="https://cryptomator.org/contact"
|
||||||
-dAboutUrl="https://cryptomator.org"
|
-define UpdateUrl="https://cryptomator.org/downloads/"
|
||||||
-dHelpUrl="https://cryptomator.org/contact"
|
-ext "WixToolset.Util.wixext"
|
||||||
-dUpdateUrl="https://cryptomator.org/downloads/"
|
-ext "WixToolset.BootstrapperApplications.wixext"
|
||||||
- name: Create executable with linker
|
./bundle/bundleWithWinfsp.wxs
|
||||||
run: >
|
-out "../../installer/unsigned/Cryptomator-Installer.exe"
|
||||||
"${WIX}/bin/light.exe" -b dist/win/ dist/win/bundle/bundleWithWinfsp.wixobj
|
|
||||||
-ext WixBalExtension
|
|
||||||
-ext WixUtilExtension
|
|
||||||
-out installer/unsigned/Cryptomator-Installer.exe
|
|
||||||
- name: Detach burn engine in preparation to sign
|
- name: Detach burn engine in preparation to sign
|
||||||
run: >
|
run: >
|
||||||
"${WIX}/bin/insignia.exe"
|
wix burn detach installer/unsigned/Cryptomator-Installer.exe -engine tmp/engine.exe
|
||||||
-ib installer/unsigned/Cryptomator-Installer.exe
|
- name: Sign WiX burn engine with Azure Trusted Signing
|
||||||
-o tmp/engine.exe
|
if: inputs.sign || github.event_name == 'release'
|
||||||
- name: Codesign burn engine
|
uses: ./.github/actions/win-sign-action
|
||||||
uses: skymatic/code-sign-action@v3
|
|
||||||
with:
|
with:
|
||||||
certificate: ${{ secrets.WIN_CODESIGN_P12_BASE64 }}
|
base-dir: ${{ github.workspace }}\tmp
|
||||||
password: ${{ secrets.WIN_CODESIGN_P12_PW }}
|
file-extensions: exe
|
||||||
certificatesha1: 5FC94CE149E5B511E621F53A060AC67CBD446B3A
|
append-signature: true
|
||||||
description: Cryptomator Installer
|
description: 'Cryptomator Bundle Installer'
|
||||||
timestampUrl: 'http://timestamp.digicert.com'
|
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
|
||||||
folder: tmp
|
client-id: ${{ secrets.AZURE_CLIENT_ID }}
|
||||||
|
client-secret: ${{ secrets.AZURE_CLIENT_SECRET }}
|
||||||
|
- name: Sign burn engine with Actalis CodeSigner
|
||||||
|
if: inputs.sign || github.event_name == 'release'
|
||||||
|
uses: skymatic/workflows/.github/actions/win-sign-action@450e322ff2214d0be0b079b63343c894f3ef735f # no specific version
|
||||||
|
with:
|
||||||
|
base-dir: 'tmp'
|
||||||
|
file-extensions: 'exe'
|
||||||
|
sign-description: 'Cryptomator Bundle Installer'
|
||||||
|
sign-url: 'https://cryptomator.org'
|
||||||
|
username: ${{ secrets.WIN_CODESIGN_USERNAME }}
|
||||||
|
password: ${{ secrets.WIN_CODESIGN_PW }}
|
||||||
- name: Reattach signed burn engine to installer
|
- name: Reattach signed burn engine to installer
|
||||||
run : >
|
run: >
|
||||||
"${WIX}/bin/insignia.exe"
|
wix burn reattach installer/unsigned/Cryptomator-Installer.exe -engine tmp/engine.exe -o installer/Cryptomator-Installer.exe
|
||||||
-ab tmp/engine.exe installer/unsigned/Cryptomator-Installer.exe
|
- name: Sign EXE installer with Azure Trusted Signing
|
||||||
-o installer/Cryptomator-Installer.exe
|
if: inputs.sign || github.event_name == 'release'
|
||||||
- name: Codesign EXE
|
uses: ./.github/actions/win-sign-action
|
||||||
uses: skymatic/code-sign-action@v3
|
|
||||||
with:
|
with:
|
||||||
certificate: ${{ secrets.WIN_CODESIGN_P12_BASE64 }}
|
base-dir: ${{ github.workspace }}\installer
|
||||||
password: ${{ secrets.WIN_CODESIGN_P12_PW }}
|
file-extensions: exe
|
||||||
certificatesha1: 5FC94CE149E5B511E621F53A060AC67CBD446B3A
|
append-signature: true
|
||||||
description: Cryptomator Installer
|
description: 'Cryptomator Bundle Installer'
|
||||||
timestampUrl: 'http://timestamp.digicert.com'
|
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
|
||||||
folder: installer
|
client-id: ${{ secrets.AZURE_CLIENT_ID }}
|
||||||
|
client-secret: ${{ secrets.AZURE_CLIENT_SECRET }}
|
||||||
|
- name: Sign installer with Actalis CodeSigner
|
||||||
|
if: inputs.sign || github.event_name == 'release'
|
||||||
|
uses: skymatic/workflows/.github/actions/win-sign-action@450e322ff2214d0be0b079b63343c894f3ef735f # no specific version
|
||||||
|
with:
|
||||||
|
base-dir: 'installer'
|
||||||
|
file-extensions: 'exe'
|
||||||
|
sign-description: 'Cryptomator Bundle Installer'
|
||||||
|
sign-url: 'https://cryptomator.org'
|
||||||
|
username: ${{ secrets.WIN_CODESIGN_USERNAME }}
|
||||||
|
password: ${{ secrets.WIN_CODESIGN_PW }}
|
||||||
- name: Add possible alpha/beta tags to installer name
|
- name: Add possible alpha/beta tags to installer name
|
||||||
run: mv installer/Cryptomator-Installer.exe Cryptomator-${{ needs.get-version.outputs.semVerStr }}-x64.exe
|
run: mv installer/Cryptomator-Installer.exe Cryptomator-${{ needs.get-version.outputs.semVerStr }}-${{ matrix.executable-suffix }}.exe
|
||||||
- name: Create detached GPG signature with key 615D449FE6E6A235
|
- name: Create detached GPG signature with key 615D449FE6E6A235
|
||||||
run: |
|
run: |
|
||||||
echo "${GPG_PRIVATE_KEY}" | gpg --batch --quiet --import
|
echo "${GPG_PRIVATE_KEY}" | gpg --batch --quiet --import
|
||||||
@@ -352,9 +418,9 @@ 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@v4
|
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
||||||
with:
|
with:
|
||||||
name: exe
|
name: exe-${{ matrix.executable-suffix }}
|
||||||
path: |
|
path: |
|
||||||
Cryptomator-*.exe
|
Cryptomator-*.exe
|
||||||
Cryptomator-*.asc
|
Cryptomator-*.asc
|
||||||
@@ -364,39 +430,39 @@ jobs:
|
|||||||
name: Publish installers to the github release
|
name: Publish installers to the github release
|
||||||
if: startsWith(github.ref, 'refs/tags/') && github.event.action == 'published'
|
if: startsWith(github.ref, 'refs/tags/') && github.event.action == 'published'
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
needs: [build-msi, build-exe]
|
needs: [ build-msi, build-exe ]
|
||||||
outputs:
|
outputs:
|
||||||
download-url-msi: ${{ fromJSON(steps.publish.outputs.assets)[0].browser_download_url }}
|
download-url-msi-x64: ${{ fromJSON(steps.publish.outputs.assets)[0].browser_download_url }}
|
||||||
download-url-exe: ${{ fromJSON(steps.publish.outputs.assets)[1].browser_download_url }}
|
download-url-exe-x64: ${{ fromJSON(steps.publish.outputs.assets)[2].browser_download_url }}
|
||||||
steps:
|
steps:
|
||||||
- name: Download installers
|
- name: Download installers
|
||||||
uses: actions/download-artifact@v4
|
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0
|
||||||
with:
|
with:
|
||||||
merge-multiple: true
|
merge-multiple: true
|
||||||
- name: Publish .msi on GitHub Releases
|
- name: Publish installers on GitHub Releases
|
||||||
id: publish
|
id: publish
|
||||||
uses: softprops/action-gh-release@v2
|
uses: softprops/action-gh-release@6da8fa9354ddfdc4aeace5fc48d7f679b5214090 # v2.4.1
|
||||||
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
|
# do not change ordering of filelist, required for correct job output
|
||||||
files: |
|
files: |
|
||||||
*.msi
|
*x64.msi
|
||||||
*.exe
|
*x64.exe
|
||||||
*.asc
|
*.asc
|
||||||
|
|
||||||
allowlist-msi:
|
allowlist-msi-x64:
|
||||||
uses: ./.github/workflows/av-whitelist.yml
|
uses: ./.github/workflows/av-whitelist.yml
|
||||||
needs: [publish]
|
needs: [ publish ]
|
||||||
with:
|
with:
|
||||||
url: ${{ needs.publish.outputs.download-url-msi }}
|
url: ${{ needs.publish.outputs.download-url-msi-x64 }}
|
||||||
secrets: inherit
|
secrets: inherit
|
||||||
|
|
||||||
allowlist-exe:
|
allowlist-exe-x64:
|
||||||
uses: ./.github/workflows/av-whitelist.yml
|
uses: ./.github/workflows/av-whitelist.yml
|
||||||
needs: [publish]
|
needs: [ publish, allowlist-msi-x64 ]
|
||||||
with:
|
with:
|
||||||
url: ${{ needs.publish.outputs.download-url-exe }}
|
url: ${{ needs.publish.outputs.download-url-exe-x64 }}
|
||||||
secrets: inherit
|
secrets: inherit
|
||||||
|
|
||||||
notify-winget:
|
notify-winget:
|
||||||
@@ -406,14 +472,14 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Slack Notification
|
- name: Slack Notification
|
||||||
uses: rtCamp/action-slack-notify@v2
|
uses: rtCamp/action-slack-notify@e31e87e03dd19038e411e38ae27cbad084a90661 # v2.3.3
|
||||||
env:
|
env:
|
||||||
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }}
|
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }}
|
||||||
SLACK_USERNAME: 'Cryptobot'
|
SLACK_USERNAME: 'Cryptobot'
|
||||||
SLACK_ICON: false
|
SLACK_ICON: false
|
||||||
SLACK_ICON_EMOJI: ':bot:'
|
SLACK_ICON_EMOJI: ':bot:'
|
||||||
SLACK_CHANNEL: 'cryptomator-desktop'
|
SLACK_CHANNEL: 'cryptomator-desktop'
|
||||||
SLACK_TITLE: "MSI of ${{ github.event.repository.name }} ${{ github.event.release.tag_name }} published."
|
SLACK_TITLE: "MSI packages of ${{ github.event.repository.name }} ${{ github.event.release.tag_name }} published."
|
||||||
SLACK_MESSAGE: "Ready to <https://github.com/${{ github.repository }}/actions/workflows/winget.yml| release to winget>."
|
SLACK_MESSAGE: "Ready to <https://github.com/${{ github.repository }}/actions/workflows/winget.yml| release them to winget>."
|
||||||
SLACK_FOOTER: false
|
SLACK_FOOTER: false
|
||||||
MSG_MINIMAL: true
|
MSG_MINIMAL: true
|
||||||
|
|||||||
@@ -16,12 +16,12 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
gh repo sync cryptomator/winget-pkgs -b master --force
|
gh repo sync cryptomator/winget-pkgs -b master --force
|
||||||
env:
|
env:
|
||||||
GH_TOKEN: ${{ secrets.CRYPTOBOT_WINGET_TOKEN }}
|
GH_TOKEN: ${{ secrets.CRYPTOBOT_PR_TOKEN }}
|
||||||
- name: Submit package
|
- name: Submit package
|
||||||
uses: vedantmgoyal2009/winget-releaser@v2
|
uses: vedantmgoyal2009/winget-releaser@19e706d4c9121098010096f9c495a70a7518b30f # no_specific_version
|
||||||
with:
|
with:
|
||||||
identifier: Cryptomator.Cryptomator
|
identifier: Cryptomator.Cryptomator
|
||||||
version: ${{ inputs.tag }}
|
version: ${{ inputs.tag }}
|
||||||
release-tag: ${{ inputs.tag }}
|
release-tag: ${{ inputs.tag }}
|
||||||
installers-regex: '\.msi$'
|
installers-regex: '-x64\.msi$'
|
||||||
token: ${{ secrets.CRYPTOBOT_WINGET_TOKEN }}
|
token: ${{ secrets.CRYPTOBOT_PR_TOKEN }}
|
||||||
Generated
+21
-18
@@ -14,29 +14,32 @@
|
|||||||
<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.49/dagger-compiler-2.49.jar" />
|
<entry name="$MAVEN_REPOSITORY$/com/google/dagger/dagger-compiler/2.57.2/dagger-compiler-2.57.2.jar" />
|
||||||
<entry name="$MAVEN_REPOSITORY$/com/google/dagger/dagger/2.49/dagger-2.49.jar" />
|
<entry name="$MAVEN_REPOSITORY$/com/google/dagger/dagger/2.57.2/dagger-2.57.2.jar" />
|
||||||
<entry name="$MAVEN_REPOSITORY$/javax/inject/javax.inject/1/javax.inject-1.jar" />
|
<entry name="$MAVEN_REPOSITORY$/jakarta/inject/jakarta.inject-api/2.0.1/jakarta.inject-api-2.0.1.jar" />
|
||||||
<entry name="$MAVEN_REPOSITORY$/com/google/dagger/dagger-spi/2.49/dagger-spi-2.49.jar" />
|
<entry name="$MAVEN_REPOSITORY$/org/jspecify/jspecify/1.0.0/jspecify-1.0.0.jar" />
|
||||||
|
<entry name="$MAVEN_REPOSITORY$/com/google/dagger/dagger-spi/2.57.2/dagger-spi-2.57.2.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$/com/google/devtools/ksp/symbol-processing-api/1.9.20-1.0.14/symbol-processing-api-1.9.20-1.0.14.jar" />
|
<entry name="$MAVEN_REPOSITORY$/com/google/devtools/ksp/symbol-processing-api/2.1.21-2.0.2/symbol-processing-api-2.1.21-2.0.2.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$/org/jetbrains/kotlin/kotlin-stdlib/1.9.20/kotlin-stdlib-1.9.20.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.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$/org/checkerframework/checker-qual/3.12.0/checker-qual-3.12.0.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$/com/google/j2objc/j2objc-annotations/1.3/j2objc-annotations-1.3.jar" />
|
|
||||||
<entry name="$MAVEN_REPOSITORY$/com/squareup/javapoet/1.13.0/javapoet-1.13.0.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/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/kotlinpoet/1.11.0/kotlinpoet-1.11.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.6.10/kotlin-stdlib-jdk8-1.6.10.jar" />
|
||||||
|
<entry name="$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib-jdk7/1.6.10/kotlin-stdlib-jdk7-1.6.10.jar" />
|
||||||
<entry name="$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-reflect/1.6.10/kotlin-reflect-1.6.10.jar" />
|
<entry name="$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-reflect/1.6.10/kotlin-reflect-1.6.10.jar" />
|
||||||
|
<entry name="$MAVEN_REPOSITORY$/javax/inject/javax.inject/1/javax.inject-1.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/checkerframework/checker-compat-qual/2.5.5/checker-compat-qual-2.5.5.jar" />
|
<entry name="$MAVEN_REPOSITORY$/org/checkerframework/checker-compat-qual/2.5.3/checker-compat-qual-2.5.3.jar" />
|
||||||
|
<entry name="$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-metadata-jvm/2.1.21/kotlin-metadata-jvm-2.1.21.jar" />
|
||||||
|
<entry name="$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib/2.1.21/kotlin-stdlib-2.1.21.jar" />
|
||||||
|
<entry name="$MAVEN_REPOSITORY$/org/jetbrains/annotations/13.0/annotations-13.0.jar" />
|
||||||
</processorPath>
|
</processorPath>
|
||||||
<module name="cryptomator" />
|
<module name="cryptomator" />
|
||||||
</profile>
|
</profile>
|
||||||
@@ -44,7 +47,7 @@
|
|||||||
</component>
|
</component>
|
||||||
<component name="JavacSettings">
|
<component name="JavacSettings">
|
||||||
<option name="ADDITIONAL_OPTIONS_OVERRIDE">
|
<option name="ADDITIONAL_OPTIONS_OVERRIDE">
|
||||||
<module name="cryptomator" options="-Adagger.fastInit=enabled -Adagger.formatGeneratedSource=enabled --enable-preview" />
|
<module name="cryptomator" options="-Adagger.fastInit=enabled -Adagger.formatGeneratedSource=enabled" />
|
||||||
</option>
|
</option>
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
||||||
+3
-5
@@ -1,10 +1,8 @@
|
|||||||
<component name="InspectionProjectProfileManager">
|
<component name="InspectionProjectProfileManager">
|
||||||
<profile version="1.0">
|
<profile version="1.0">
|
||||||
<option name="myName" value="Project Default" />
|
<option name="myName" value="Project Default" />
|
||||||
<inspection_tool class="SpellCheckingInspection" enabled="true" level="TYPO" enabled_by_default="true">
|
<inspection_tool class="Deprecation" enabled="true" level="WARNING" enabled_by_default="true" editorAttributes="DEPRECATED_ATTRIBUTES" />
|
||||||
<option name="processCode" value="true" />
|
<inspection_tool class="MarkedForRemoval" enabled="true" level="WARNING" enabled_by_default="true" editorAttributes="MARKED_FOR_REMOVAL_ATTRIBUTES" />
|
||||||
<option name="processLiterals" value="true" />
|
<inspection_tool class="RedundantScheduledForRemovalAnnotation" enabled="true" level="WARNING" enabled_by_default="true" editorAttributes="MARKED_FOR_REMOVAL_ATTRIBUTES" />
|
||||||
<option name="processComments" value="true" />
|
|
||||||
</inspection_tool>
|
|
||||||
</profile>
|
</profile>
|
||||||
</component>
|
</component>
|
||||||
Generated
+1
-1
@@ -8,7 +8,7 @@
|
|||||||
</list>
|
</list>
|
||||||
</option>
|
</option>
|
||||||
</component>
|
</component>
|
||||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_22" project-jdk-name="22" project-jdk-type="JavaSDK">
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_25" project-jdk-name="25" project-jdk-type="JavaSDK">
|
||||||
<output url="file://$PROJECT_DIR$/out" />
|
<output url="file://$PROJECT_DIR$/out" />
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
<configuration default="false" name="Cryptomator Linux" type="Application" factoryName="Application">
|
<configuration default="false" name="Cryptomator Linux" 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="@{userhome}/.config/Cryptomator/settings.json" -Dcryptomator.p12Path="@{userhome}/.config/Cryptomator/key.p12" -Dcryptomator.ipcSocketPath="@{userhome}/.config/Cryptomator/ipc.socket" -Dcryptomator.logDir="@{userhome}/.local/share/Cryptomator/logs" -Dcryptomator.pluginDir="@{userhome}/.local/share/Cryptomator/plugins" -Dcryptomator.mountPointsDir="@{userhome}/.local/share/Cryptomator/mnt" -Dcryptomator.showTrayIcon=true -Xss20m -Xmx512m --enable-preview --enable-native-access=org.cryptomator.jfuse.linux.amd64,org.cryptomator.jfuse.linux.aarch64,org.purejava.appindicator" />
|
<option name="VM_PARAMETERS" value="-Dcryptomator.settingsPath="@{userhome}/.config/Cryptomator/settings.json" -Dcryptomator.p12Path="@{userhome}/.config/Cryptomator/key.p12" -Dcryptomator.ipcSocketPath="@{userhome}/.config/Cryptomator/ipc.socket" -Dcryptomator.logDir="@{userhome}/.local/share/Cryptomator/logs" -Dcryptomator.pluginDir="@{userhome}/.local/share/Cryptomator/plugins" -Dcryptomator.mountPointsDir="@{userhome}/.local/share/Cryptomator/mnt" -Dcryptomator.showTrayIcon=true -Xss20m -Xmx512m --enable-preview --enable-native-access=org.cryptomator.jfuse.linux.amd64,org.cryptomator.jfuse.linux.aarch64,org.purejava.appindicator,javafx.graphics" />
|
||||||
<method v="2">
|
<method v="2">
|
||||||
<option name="Make" enabled="true" />
|
<option name="Make" enabled="true" />
|
||||||
</method>
|
</method>
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
<configuration default="false" name="Cryptomator Linux Dev" type="Application" factoryName="Application">
|
<configuration default="false" name="Cryptomator Linux 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="@{userhome}/.config/Cryptomator-Dev/settings.json" -Dcryptomator.p12Path="@{userhome}/.config/Cryptomator-Dev/key.p12" -Dcryptomator.ipcSocketPath="@{userhome}/.config/Cryptomator-Dev/ipc.socket" -Dcryptomator.logDir="@{userhome}/.local/share/Cryptomator-Dev/logs" -Dcryptomator.pluginDir="@{userhome}/.local/share/Cryptomator-Dev/plugins" -Dcryptomator.mountPointsDir="@{userhome}/.local/share/Cryptomator-Dev/mnt" -Dcryptomator.showTrayIcon=true -Dfuse.experimental="true" -Xss20m -Xmx512m --enable-preview --enable-native-access=org.cryptomator.jfuse.linux.amd64,org.cryptomator.jfuse.linux.aarch64,org.purejava.appindicator" />
|
<option name="VM_PARAMETERS" value="-Dcryptomator.settingsPath="@{userhome}/.config/Cryptomator-Dev/settings.json" -Dcryptomator.p12Path="@{userhome}/.config/Cryptomator-Dev/key.p12" -Dcryptomator.ipcSocketPath="@{userhome}/.config/Cryptomator-Dev/ipc.socket" -Dcryptomator.logDir="@{userhome}/.local/share/Cryptomator-Dev/logs" -Dcryptomator.pluginDir="@{userhome}/.local/share/Cryptomator-Dev/plugins" -Dcryptomator.mountPointsDir="@{userhome}/.local/share/Cryptomator-Dev/mnt" -Dcryptomator.showTrayIcon=true -Dfuse.experimental="true" -Xss20m -Xmx512m --enable-preview --enable-native-access=org.cryptomator.jfuse.linux.amd64,org.cryptomator.jfuse.linux.aarch64,org.purejava.appindicator,javafx.graphics" />
|
||||||
<method v="2">
|
<method v="2">
|
||||||
<option name="Make" enabled="true" />
|
<option name="Make" enabled="true" />
|
||||||
</method>
|
</method>
|
||||||
|
|||||||
+1
-1
@@ -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="@{appdata}/Cryptomator/settings.json;@{userhome}/AppData/Roaming/Cryptomator/settings.json" -Dcryptomator.ipcSocketPath="@{localappdata}/Cryptomator/ipc.socket" -Dcryptomator.logDir="@{localappdata}/Cryptomator" -Dcryptomator.pluginDir="@{appdata}/Cryptomator/Plugins" -Dcryptomator.integrationsWin.keychainPaths="@{appdata}/Cryptomator/keychain.json;@{userhome}/AppData/Roaming/Cryptomator/keychain.json" -Dcryptomator.p12Path="@{appdata}/Cryptomator/key.p12;@{userhome}/AppData/Roaming/Cryptomator/key.p12" -Dcryptomator.mountPointsDir="@{userhome}/Cryptomator" -Dcryptomator.showTrayIcon=true -Xss2m -Xmx512m --enable-preview --enable-native-access=org.cryptomator.jfuse.win,org.cryptomator.integrations.win" />
|
<option name="VM_PARAMETERS" value="-Dcryptomator.settingsPath="@{appdata}/Cryptomator/settings.json;@{userhome}/AppData/Roaming/Cryptomator/settings.json" -Dcryptomator.ipcSocketPath="@{localappdata}/Cryptomator/ipc.socket" -Dcryptomator.logDir="@{localappdata}/Cryptomator" -Dcryptomator.pluginDir="@{appdata}/Cryptomator/Plugins" -Dcryptomator.integrationsWin.keychainPaths="@{appdata}/Cryptomator/keychain.json;@{userhome}/AppData/Roaming/Cryptomator/keychain.json" -Dcryptomator.integrationsWin.windowsHelloKeychainPaths="@{appdata}/Cryptomator/windowsHelloKeychain.json;@{userhome}/AppData/Roaming/Cryptomator/windowsHelloKeychain.json" -Dcryptomator.p12Path="@{appdata}/Cryptomator/key.p12;@{userhome}/AppData/Roaming/Cryptomator/key.p12" -Dcryptomator.mountPointsDir="@{userhome}/Cryptomator" -Dcryptomator.showTrayIcon=true -Xss2m -Xmx512m --enable-preview --enable-native-access=org.cryptomator.jfuse.win,org.cryptomator.integrations.win,javafx.graphics" />
|
||||||
<method v="2">
|
<method v="2">
|
||||||
<option name="Make" enabled="true" />
|
<option name="Make" enabled="true" />
|
||||||
</method>
|
</method>
|
||||||
|
|||||||
+1
-1
@@ -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="@{appdata}/Cryptomator-Dev/settings.json;@{userhome}/AppData/Roaming/Cryptomator-Dev/settings.json" -Dcryptomator.ipcSocketPath="@{localappdata}/Cryptomator-Dev/ipc.socket" -Dcryptomator.logDir="@{localappdata}/Cryptomator-Dev" -Dcryptomator.pluginDir="@{appdata}/Cryptomator-Dev/Plugins" -Dcryptomator.integrationsWin.keychainPaths="@{appdata}/Cryptomator-Dev/keychain.json;@{userhome}/AppData/Roaming/Cryptomator-Dev/keychain.json" -Dcryptomator.p12Path="@{appdata}/Cryptomator-Dev/key.p12;@{userhome}/AppData/Roaming/Cryptomator-Dev/key.p12" -Dcryptomator.mountPointsDir="@{userhome}/Cryptomator-Dev" -Dcryptomator.showTrayIcon=true -Xss2m -Xmx512m --enable-preview --enable-native-access=org.cryptomator.jfuse.win,org.cryptomator.integrations.win" />
|
<option name="VM_PARAMETERS" value="-Dcryptomator.settingsPath="@{appdata}/Cryptomator-Dev/settings.json;@{userhome}/AppData/Roaming/Cryptomator-Dev/settings.json" -Dcryptomator.ipcSocketPath="@{localappdata}/Cryptomator-Dev/ipc.socket" -Dcryptomator.logDir="@{localappdata}/Cryptomator-Dev" -Dcryptomator.pluginDir="@{appdata}/Cryptomator-Dev/Plugins" -Dcryptomator.integrationsWin.keychainPaths="@{appdata}/Cryptomator-Dev/keychain.json;@{userhome}/AppData/Roaming/Cryptomator-Dev/keychain.json" -Dcryptomator.integrationsWin.windowsHelloKeychainPaths="@{appdata}/Cryptomator-Dev/windowsHelloKeychain.json;@{userhome}/AppData/Roaming/Cryptomator-Dev/windowsHelloKeychain.json" -Dcryptomator.p12Path="@{appdata}/Cryptomator-Dev/key.p12;@{userhome}/AppData/Roaming/Cryptomator-Dev/key.p12" -Dcryptomator.mountPointsDir="@{userhome}/Cryptomator-Dev" -Dcryptomator.showTrayIcon=true -Xss2m -Xmx512m --enable-preview --enable-native-access=org.cryptomator.jfuse.win,org.cryptomator.integrations.win,javafx.graphics" />
|
||||||
<method v="2">
|
<method v="2">
|
||||||
<option name="Make" enabled="true" />
|
<option name="Make" enabled="true" />
|
||||||
</method>
|
</method>
|
||||||
|
|||||||
+1
-1
@@ -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="@{userhome}/Library/Application Support/Cryptomator/settings.json" -Dcryptomator.p12Path="@{userhome}/Library/Application Support/Cryptomator/key.p12" -Dcryptomator.ipcSocketPath="@{userhome}/Library/Application Support/Cryptomator/ipc.socket" -Dcryptomator.logDir="@{userhome}/Library/Logs/Cryptomator" -Dcryptomator.pluginDir="@{userhome}/Library/Application Support/Cryptomator/Plugins" -Dcryptomator.mountPointsDir="@{userhome}/Cryptomator" -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="@{userhome}/Library/Application Support/Cryptomator/settings.json" -Dcryptomator.p12Path="@{userhome}/Library/Application Support/Cryptomator/key.p12" -Dcryptomator.ipcSocketPath="@{userhome}/Library/Application Support/Cryptomator/ipc.socket" -Dcryptomator.logDir="@{userhome}/Library/Logs/Cryptomator" -Dcryptomator.pluginDir="@{userhome}/Library/Application Support/Cryptomator/Plugins" -Dcryptomator.mountPointsDir="@{userhome}/Cryptomator" -Dcryptomator.showTrayIcon=true -Dcryptomator.integrationsMac.keychainServiceName=Cryptomator -Dcryptomator.updateMechanism=org.cryptomator.macos.update.DmgUpdateMechanism -Xss2m -Xmx512m -ea --enable-preview --enable-native-access=org.cryptomator.jfuse.mac,javafx.graphics" />
|
||||||
<method v="2">
|
<method v="2">
|
||||||
<option name="Make" enabled="true" />
|
<option name="Make" enabled="true" />
|
||||||
</method>
|
</method>
|
||||||
|
|||||||
+1
-1
@@ -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="@{userhome}/Library/Application Support/Cryptomator-Dev/settings.json" -Dcryptomator.p12Path="@{userhome}/Library/Application Support/Cryptomator-Dev/key.p12" -Dcryptomator.ipcSocketPath="@{userhome}/Library/Application Support/Cryptomator-Dev/ipc.socket" -Dcryptomator.logDir="@{userhome}/Library/Logs/Cryptomator-Dev" -Dcryptomator.pluginDir="@{userhome}/Library/Application Support/Cryptomator-Dev/Plugins" -Dcryptomator.mountPointsDir="@{userhome}/Library/Application Support/Cryptomator-Dev/mnt" -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="@{userhome}/Library/Application Support/Cryptomator-Dev/settings.json" -Dcryptomator.p12Path="@{userhome}/Library/Application Support/Cryptomator-Dev/key.p12" -Dcryptomator.ipcSocketPath="@{userhome}/Library/Application Support/Cryptomator-Dev/ipc.socket" -Dcryptomator.logDir="@{userhome}/Library/Logs/Cryptomator-Dev" -Dcryptomator.pluginDir="@{userhome}/Library/Application Support/Cryptomator-Dev/Plugins" -Dcryptomator.mountPointsDir="@{userhome}/Library/Application Support/Cryptomator-Dev/mnt" -Dcryptomator.showTrayIcon=true -Dcryptomator.integrationsMac.keychainServiceName=Cryptomator -Xss2m -Xmx512m -ea --enable-preview --enable-native-access=org.cryptomator.jfuse.mac,javafx.graphics" />
|
||||||
<method v="2">
|
<method v="2">
|
||||||
<option name="Make" enabled="true" />
|
<option name="Make" enabled="true" />
|
||||||
</method>
|
</method>
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
# Changelog
|
||||||
|
|
||||||
|
All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
||||||
|
|
||||||
|
The changelog starts with version 1.19.0.
|
||||||
|
Changes to prior versions can be found on the [Github release page](https://github.com/cryptomator/cryptomator/releases).
|
||||||
|
|
||||||
|
## [Unreleased](https://github.com/cryptomator/cryptomator/compare/1.18.0...HEAD)
|
||||||
|
|
||||||
|
### Added
|
||||||
|
* New Self-Update Mechanism (initially for .dmg and Flatpak packages) (#3948)
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
* Built using JDK 25 (#4031)
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
[](https://cryptomator.org/)
|
[](https://cryptomator.org/)
|
||||||
|
|
||||||
[](https://github.com/cryptomator/cryptomator/actions?query=workflow%3ABuild)
|
[](https://github.com/cryptomator/cryptomator/actions/workflows/build.yml?query=branch%3Adevelop)
|
||||||
[](https://snyk.io/test/github/cryptomator/cryptomator)
|
[](https://snyk.io/test/github/cryptomator/cryptomator)
|
||||||
[](https://sonarcloud.io/dashboard?id=cryptomator_cryptomator)
|
[](https://sonarcloud.io/dashboard?id=cryptomator_cryptomator)
|
||||||
[](http://twitter.com/Cryptomator)
|
[](https://mastodon.online/@cryptomator)
|
||||||
[](https://translate.cryptomator.org/)
|
[](https://translate.cryptomator.org/)
|
||||||
[](https://github.com/cryptomator/cryptomator/releases/latest)
|
[](https://github.com/cryptomator/cryptomator/releases/latest)
|
||||||
[](https://community.cryptomator.org)
|
[](https://community.cryptomator.org)
|
||||||
@@ -17,21 +17,14 @@ 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="28"></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.hassmann-it-forensik.de/"><img src="https://cryptomator.org/img/sponsors/hassmannitforensik.png" alt="Hassmann IT-Forensik" height="56"></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.route4me.com/"><img src="https://cryptomator.org/img/sponsors/route4me.svg" alt="Route4Me" height="56"></a></td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
@@ -39,9 +32,9 @@ Cryptomator is provided free of charge as an open-source project despite the hig
|
|||||||
|
|
||||||
### Special Shoutout
|
### Special Shoutout
|
||||||
|
|
||||||
Continuous integration hosting for ARM64 builds is provided by [MacStadium](https://www.macstadium.com/opensource).
|
Continuous integration hosting for ARM64 builds is provided by [MacStadium](https://www.macstadium.com/company/opensource).
|
||||||
|
|
||||||
<a href="https://www.macstadium.com/opensource"><img src="https://uploads-ssl.webflow.com/5ac3c046c82724970fc60918/5c019d917bba312af7553b49_MacStadium-developerlogo.png" alt="MacStadium" height="100"></a>
|
<a href="https://www.macstadium.com/company/opensource"><img src="https://uploads-ssl.webflow.com/5ac3c046c82724970fc60918/5c019d917bba312af7553b49_MacStadium-developerlogo.png" alt="MacStadium" height="100"></a>
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -61,7 +54,7 @@ Download native binaries of Cryptomator on [cryptomator.org](https://cryptomator
|
|||||||
- File names get encrypted
|
- File names get encrypted
|
||||||
- Folder structure gets obfuscated
|
- Folder structure gets obfuscated
|
||||||
- Use as many vaults in your Dropbox as you want, each having individual passwords
|
- Use as many vaults in your Dropbox as you want, each having individual passwords
|
||||||
- Four thousand commits for the security of your data!! :tada:
|
- More than Five thousand commits for the security of your data!! :tada:
|
||||||
|
|
||||||
### Privacy
|
### Privacy
|
||||||
|
|
||||||
@@ -79,13 +72,13 @@ Download native binaries of Cryptomator on [cryptomator.org](https://cryptomator
|
|||||||
|
|
||||||
### Security Architecture
|
### Security Architecture
|
||||||
|
|
||||||
For more information on the security details visit [cryptomator.org](https://docs.cryptomator.org/en/latest/security/architecture/).
|
For more information on the security details visit [cryptomator.org](https://docs.cryptomator.org/security/architecture/).
|
||||||
|
|
||||||
## Building
|
## Building
|
||||||
|
|
||||||
### Dependencies
|
### Dependencies
|
||||||
|
|
||||||
* JDK 22 (e.g. temurin, zulu)
|
* JDK 24 (e.g. temurin, zulu)
|
||||||
* Maven 3
|
* Maven 3
|
||||||
|
|
||||||
### Run Maven
|
### Run Maven
|
||||||
|
|||||||
Vendored
+22
-14
@@ -12,23 +12,23 @@ 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)
|
CPU_ARCH=$(uname -m)
|
||||||
|
|
||||||
if [[ ! "${CPU_ARCH}" =~ x86_64|aarch64 ]]; then echo "Platform ${CPU_ARCH} not supported"; exit 1; fi
|
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 -Djavafx.platform=linux
|
mvn -B -f ../../../pom.xml clean package -Plinux -DskipTests
|
||||||
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_VERSION=25
|
||||||
JAVAFX_ARCH="x64"
|
JAVAFX_ARCH="x64"
|
||||||
JAVAFX_JMODS_SHA256='d44bff3b94d5668fdee18a938d7b1269026d663d44765f02d29a9bdfd3fa1eb0'
|
JAVAFX_JMODS_SHA256='96e520f48610d8ffb94ca30face1f11ffe8a977ddc1c4ff80b1a9e9f048bd94e'
|
||||||
if [ "${CPU_ARCH}" = "aarch64" ]; then
|
if [ "${CPU_ARCH}" = "aarch64" ]; then
|
||||||
JAVAFX_ARCH="aarch64"
|
JAVAFX_ARCH="aarch64"
|
||||||
JAVAFX_JMODS_SHA256='3d5457136690c4f5bb9522d38b45218e045bdac13c24aa4c808c7c8d17d039c7'
|
JAVAFX_JMODS_SHA256='951c52481af0ec5885b06f1ebaa8a10da7e8ea23c5e1ef3e2f6f11fa1b3a7ce1'
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# download javaFX jmods
|
# download javaFX jmods
|
||||||
@@ -51,12 +51,18 @@ if [ $POM_JFX_VERSION -ne $JMOD_VERSION ]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
# add runtime
|
# create runtime
|
||||||
|
## check for JEP 493
|
||||||
|
JMOD_PATHS="openjfx-jmods"
|
||||||
|
if ! ${JAVA_HOME}/bin/jlink --help | grep -q "Linking from run-time image enabled"; then
|
||||||
|
JMOD_PATHS="${JAVA_HOME}/jmods:${JMOD_PATHS}"
|
||||||
|
fi
|
||||||
|
## create runtime image
|
||||||
${JAVA_HOME}/bin/jlink \
|
${JAVA_HOME}/bin/jlink \
|
||||||
--verbose \
|
--verbose \
|
||||||
--output runtime \
|
--output runtime \
|
||||||
--module-path "${JAVA_HOME}/jmods:openjfx-jmods" \
|
--module-path "${JMOD_PATHS}" \
|
||||||
--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 \
|
--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.crypto.cryptoki,jdk.crypto.ec,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 \
|
||||||
@@ -75,8 +81,8 @@ ${JAVA_HOME}/bin/jpackage \
|
|||||||
--name Cryptomator \
|
--name Cryptomator \
|
||||||
--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=javafx.graphics,org.cryptomator.jfuse.linux.amd64,org.cryptomator.jfuse.linux.aarch64,org.purejava.appindicator" \
|
||||||
--copyright "(C) 2016 - 2024 Skymatic GmbH" \
|
--copyright "(C) 2016 - 2025 Skymatic GmbH" \
|
||||||
--java-options "-Xss5m" \
|
--java-options "-Xss5m" \
|
||||||
--java-options "-Xmx256m" \
|
--java-options "-Xmx256m" \
|
||||||
--app-version "${VERSION}.${REVISION_NO}" \
|
--app-version "${VERSION}.${REVISION_NO}" \
|
||||||
@@ -91,6 +97,8 @@ ${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}\"" \
|
||||||
|
--java-options "-Dcryptomator.networking.truststore.p12Path=\"/etc/cryptomator/certs.p12\"" \
|
||||||
|
--java-options "-XX:ErrorFile=/cryptomator/cryptomator_crash.log" \
|
||||||
--resource-dir ../resources
|
--resource-dir ../resources
|
||||||
|
|
||||||
# transform AppDir
|
# transform AppDir
|
||||||
@@ -108,20 +116,20 @@ cp ../common/org.cryptomator.Cryptomator.desktop Cryptomator.AppDir/usr/share/ap
|
|||||||
cp ../common/org.cryptomator.Cryptomator.metainfo.xml Cryptomator.AppDir/usr/share/metainfo/org.cryptomator.Cryptomator.metainfo.xml
|
cp ../common/org.cryptomator.Cryptomator.metainfo.xml Cryptomator.AppDir/usr/share/metainfo/org.cryptomator.Cryptomator.metainfo.xml
|
||||||
cp ../common/application-vnd.cryptomator.vault.xml Cryptomator.AppDir/usr/share/mime/packages/application-vnd.cryptomator.vault.xml
|
cp ../common/application-vnd.cryptomator.vault.xml Cryptomator.AppDir/usr/share/mime/packages/application-vnd.cryptomator.vault.xml
|
||||||
ln -s usr/share/icons/hicolor/scalable/apps/org.cryptomator.Cryptomator.svg Cryptomator.AppDir/org.cryptomator.Cryptomator.svg
|
ln -s usr/share/icons/hicolor/scalable/apps/org.cryptomator.Cryptomator.svg Cryptomator.AppDir/org.cryptomator.Cryptomator.svg
|
||||||
ln -s usr/share/icons/hicolor/scalable/apps/org.cryptomator.Cryptomator.svg Cryptomator.AppDir/Cryptomator.svg
|
|
||||||
ln -s usr/share/icons/hicolor/scalable/apps/org.cryptomator.Cryptomator.svg Cryptomator.AppDir/.DirIcon
|
ln -s usr/share/icons/hicolor/scalable/apps/org.cryptomator.Cryptomator.svg Cryptomator.AppDir/.DirIcon
|
||||||
ln -s usr/share/applications/org.cryptomator.Cryptomator.desktop Cryptomator.AppDir/Cryptomator.desktop
|
ln -s usr/share/applications/org.cryptomator.Cryptomator.desktop Cryptomator.AppDir/org.cryptomator.Cryptomator.desktop
|
||||||
|
ln -s org.cryptomator.Cryptomator.metainfo.xml Cryptomator.AppDir/usr/share/metainfo/org.cryptomator.Cryptomator.appdata.xml
|
||||||
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-${CPU_ARCH}.AppImage -o /tmp/appimagetool.AppImage
|
curl -L https://github.com/AppImage/appimagetool/releases/download/continuous/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}-${CPU_ARCH}.AppImage \
|
cryptomator-${SEMVER_STR}-${CPU_ARCH}.AppImage \
|
||||||
-u 'gh-releases-zsync|cryptomator|cryptomator|latest|cryptomator-*-${CPU_ARCH}.AppImage.zsync'
|
-u "gh-releases-zsync|cryptomator|cryptomator|latest|cryptomator-*-${CPU_ARCH}.AppImage.zsync"
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
echo "Done. AppImage successfully created: cryptomator-${SEMVER_STR}-${CPU_ARCH}.AppImage"
|
echo "Done. AppImage successfully created: cryptomator-${SEMVER_STR}-${CPU_ARCH}.AppImage"
|
||||||
|
|||||||
+51
-6
@@ -1,11 +1,16 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!-- Copyright 2018 Armin Schrenk <armin.schrenk@zoho.eu> -->
|
|
||||||
<component type="desktop-application">
|
<component type="desktop-application">
|
||||||
<id>org.cryptomator.Cryptomator</id>
|
<id>org.cryptomator.Cryptomator</id>
|
||||||
<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>Encryption made easy and optimized for the cloud</summary>
|
<summary>Encryption for your cloud made easy</summary>
|
||||||
|
|
||||||
|
<keywords>
|
||||||
|
<keyword>encryption</keyword>
|
||||||
|
<keyword>security</keyword>
|
||||||
|
<keyword>privacy</keyword>
|
||||||
|
</keywords>
|
||||||
|
|
||||||
<description>
|
<description>
|
||||||
<p>
|
<p>
|
||||||
@@ -44,12 +49,16 @@
|
|||||||
|
|
||||||
<screenshots>
|
<screenshots>
|
||||||
<screenshot type="default">
|
<screenshot type="default">
|
||||||
<caption>Light theme</caption>
|
<caption>Encrypts your data, protects your privacy</caption>
|
||||||
<image>https://user-images.githubusercontent.com/11858409/156986109-6e58f59c-8b8c-4501-b33b-bb1e33007cea.png</image>
|
<image>https://static.cryptomator.org/desktop/flathubScreenshots/MainWindowUnlockDialog_light.png</image>
|
||||||
</screenshot>
|
</screenshot>
|
||||||
<screenshot>
|
<screenshot>
|
||||||
<caption>Dark theme</caption>
|
<caption>Dark theme available</caption>
|
||||||
<image>https://user-images.githubusercontent.com/11858409/156986113-6c5d7801-86e0-4643-bc2f-aff9d95d3ce0.png</image>
|
<image>https://static.cryptomator.org/desktop/flathubScreenshots/MainWindowUnlocked_dark.png</image>
|
||||||
|
</screenshot>
|
||||||
|
<screenshot>
|
||||||
|
<caption>Easy to use - work on encrypted files as if they were not</caption>
|
||||||
|
<image>https://static.cryptomator.org/desktop/flathubScreenshots/MainWindowUnlocked_light.png</image>
|
||||||
</screenshot>
|
</screenshot>
|
||||||
</screenshots>
|
</screenshots>
|
||||||
|
|
||||||
@@ -74,6 +83,42 @@
|
|||||||
</content_rating>
|
</content_rating>
|
||||||
|
|
||||||
<releases>
|
<releases>
|
||||||
|
<release date="2025-11-12" version="1.18.0">
|
||||||
|
<url type="details">https://github.com/cryptomator/cryptomator/releases/1.18.0</url>
|
||||||
|
</release>
|
||||||
|
<release date="2025-07-08" version="1.17.1">
|
||||||
|
<url type="details">https://github.com/cryptomator/cryptomator/releases/1.17.1</url>
|
||||||
|
</release>
|
||||||
|
<release date="2025-06-24" version="1.17.0">
|
||||||
|
<url type="details">https://github.com/cryptomator/cryptomator/releases/1.17.0</url>
|
||||||
|
</release>
|
||||||
|
<release date="2025-05-15" version="1.16.2">
|
||||||
|
<url type="details">https://github.com/cryptomator/cryptomator/releases/1.16.2</url>
|
||||||
|
</release>
|
||||||
|
<release date="2025-04-30" version="1.16.1">
|
||||||
|
<url type="details">https://github.com/cryptomator/cryptomator/releases/1.16.1</url>
|
||||||
|
</release>
|
||||||
|
<release date="2025-04-29" version="1.16.0">
|
||||||
|
<url type="details">https://github.com/cryptomator/cryptomator/releases/1.16.0</url>
|
||||||
|
</release>
|
||||||
|
<release date="2025-04-09" version="1.15.3">
|
||||||
|
<url type="details">https://github.com/cryptomator/cryptomator/releases/1.15.3</url>
|
||||||
|
</release>
|
||||||
|
<release date="2025-04-04" version="1.15.2">
|
||||||
|
<url type="details">https://github.com/cryptomator/cryptomator/releases/1.15.2</url>
|
||||||
|
</release>
|
||||||
|
<release date="2025-02-05" version="1.15.1">
|
||||||
|
<url type="details">https://github.com/cryptomator/cryptomator/releases/1.15.1</url>
|
||||||
|
</release>
|
||||||
|
<release date="2025-02-03" version="1.15.0">
|
||||||
|
<url type="details">https://github.com/cryptomator/cryptomator/releases/1.15.0</url>
|
||||||
|
</release>
|
||||||
|
<release date="2024-11-19" version="1.14.2">
|
||||||
|
<url type="details">https://github.com/cryptomator/cryptomator/releases/1.14.2</url>
|
||||||
|
</release>
|
||||||
|
<release date="2024-09-17" version="1.14.0">
|
||||||
|
<url type="details">https://github.com/cryptomator/cryptomator/releases/1.14.0</url>
|
||||||
|
</release>
|
||||||
<release date="2024-06-26" version="1.13.0">
|
<release date="2024-06-26" version="1.13.0">
|
||||||
<url type="details">https://github.com/cryptomator/cryptomator/releases/1.13.0</url>
|
<url type="details">https://github.com/cryptomator/cryptomator/releases/1.13.0</url>
|
||||||
</release>
|
</release>
|
||||||
|
|||||||
@@ -1,12 +1,16 @@
|
|||||||
<svg height="16" viewBox="0 0 42 42" width="16" xmlns="http://www.w3.org/2000/svg">
|
<svg height="16" viewBox="0 0 42 42" width="16" xmlns="http://www.w3.org/2000/svg">
|
||||||
<style
|
<defs>
|
||||||
id="current-color-scheme" type="text/css">
|
<style id="current-color-scheme" type="text/css">
|
||||||
.ColorScheme-Text {
|
.ColorScheme-Text {
|
||||||
color:#232629;
|
color:#222222;
|
||||||
}
|
}
|
||||||
</style>
|
.ColorScheme-Highlight {
|
||||||
<g fill-rule="evenodd" style="fill:#f2f2f2;fill-opacity:1" class="ColorScheme-Text" fill="currentColor">
|
color:#49B04A;
|
||||||
<path d="m15.591 35.824c-.019.009-.936.775-1.458 1.208a.418.418 0 0 1 -.627-.111 9.322 9.322 0 0 1 -.3-5.974 15.843 15.843 0 0 0 2.894 2.043c.051 1.03-.161 2.644-.509 2.834zm6.409-6.824h-2l.5-5a2 2 0 1 1 1 0zm-14.544-3.241.744-1.366a1.579 1.579 0 0 0 -.019-1.557l.653-1.2c.2.014-.03-.113.165-.14.051-.217-.051-.336 0-.5a3.269 3.269 0 0 0 0-1.5 7.151 7.151 0 0 1 0-3 2.366 2.366 0 0 0 -2.378 1.448 2.409 2.409 0 0 0 .229 2.661l-.7 1.278a1.779 1.779 0 0 0 -1.317.891l-.741 1.372a1.577 1.577 0 0 0 -.019 1.487 3.028 3.028 0 0 0 -2.746 1.525 2.648 2.648 0 0 0 .044 2.631.748.748 0 0 0 .981.266.656.656 0 0 0 .284-.92 1.37 1.37 0 0 1 -.023-1.361 1.6 1.6 0 0 1 2.079-.63 1.408 1.408 0 0 1 .672 1.95 1.546 1.546 0 0 1 -1.2.78.688.688 0 0 0 -.636.749.707.707 0 0 0 .717.6.789.789 0 0 0 .082 0 2.989 2.989 0 0 0 2.322-1.513 2.669 2.669 0 0 0 -.377-3.084 1.767 1.767 0 0 0 1.184-.867zm13.544-10.759a13.013 13.013 0 0 1 5-1 21.6 21.6 0 0 1 4.5.5 9.312 9.312 0 0 0 -9.5-8.5c-5.794 0-9.176 4-9.5 8.5a21.858 21.858 0 0 1 4.5-.5 12.819 12.819 0 0 1 5 1zm3.5-5c1.209 0 2.5.866 2.5 2h-5c0-1.134 1.291-2 2.5-2zm-7 0c1.209 0 2.5.866 2.5 2h-5c0-1.134 1.291-2 2.5-2zm14.473 6a8.067 8.067 0 0 0 -8.08 8v2.141a3.891 3.891 0 0 0 -2.893 3.734v5.125a23.166 23.166 0 0 1 -4.174-1.623 7.857 7.857 0 0 1 -.027.878 3.263 3.263 0 0 1 -.729 2.074l-1.794 1.483a.379.379 0 0 1 -.276.188h-4c-1.324 0-2.346-1.336-2.653-3.343a7.058 7.058 0 0 1 .234-3.18 3.477 3.477 0 0 1 1.636-2.157 1.868 1.868 0 0 1 .783-.32h1.5a8.035 8.035 0 0 1 -1.5-5 11.1 11.1 0 0 1 .5-3 2.519 2.519 0 0 0 0-1.5 13.272 13.272 0 0 1 -.5-3.5c6.687-1.936 11 0 11 0s4.319-1.955 11 0"/>
|
}
|
||||||
<path d="m39 28h-10v-4a3.13 3.13 0 0 1 3-3 3.087 3.087 0 0 1 3 3v1a1.034 1.034 0 0 0 1 1h1a1.034 1.034 0 0 0 1-1v-1a6 6 0 0 0 -12 0v4h-1a2.073 2.073 0 0 0 -2 2v6a2.073 2.073 0 0 0 2 2h14a2.073 2.073 0 0 0 2-2v-6a2.073 2.073 0 0 0 -2-2zm-5.391 5.94a1.609 1.609 0 0 1 -3.217 0v-1.876a1.609 1.609 0 0 1 3.217 0z"/>
|
</style>
|
||||||
|
</defs>
|
||||||
|
<g fill-rule="evenodd">
|
||||||
|
<path d="m15.591 35.824c-.019.009-.936.775-1.458 1.208a.418.418 0 0 1 -.627-.111 9.322 9.322 0 0 1 -.3-5.974 15.843 15.843 0 0 0 2.894 2.043c.051 1.03-.161 2.644-.509 2.834zm6.409-6.824h-2l.5-5a2 2 0 1 1 1 0zm-14.544-3.241.744-1.366a1.579 1.579 0 0 0 -.019-1.557l.653-1.2c.2.014-.03-.113.165-.14.051-.217-.051-.336 0-.5a3.269 3.269 0 0 0 0-1.5 7.151 7.151 0 0 1 0-3 2.366 2.366 0 0 0 -2.378 1.448 2.409 2.409 0 0 0 .229 2.661l-.7 1.278a1.779 1.779 0 0 0 -1.317.891l-.741 1.372a1.577 1.577 0 0 0 -.019 1.487 3.028 3.028 0 0 0 -2.746 1.525 2.648 2.648 0 0 0 .044 2.631.748.748 0 0 0 .981.266.656.656 0 0 0 .284-.92 1.37 1.37 0 0 1 -.023-1.361 1.6 1.6 0 0 1 2.079-.63 1.408 1.408 0 0 1 .672 1.95 1.546 1.546 0 0 1 -1.2.78.688.688 0 0 0 -.636.749.707.707 0 0 0 .717.6.789.789 0 0 0 .082 0 2.989 2.989 0 0 0 2.322-1.513 2.669 2.669 0 0 0 -.377-3.084 1.767 1.767 0 0 0 1.184-.867zm13.544-10.759a13.013 13.013 0 0 1 5-1 21.6 21.6 0 0 1 4.5.5 9.312 9.312 0 0 0 -9.5-8.5c-5.794 0-9.176 4-9.5 8.5a21.858 21.858 0 0 1 4.5-.5 12.819 12.819 0 0 1 5 1zm3.5-5c1.209 0 2.5.866 2.5 2h-5c0-1.134 1.291-2 2.5-2zm-7 0c1.209 0 2.5.866 2.5 2h-5c0-1.134 1.291-2 2.5-2zm14.473 6a8.067 8.067 0 0 0 -8.08 8v2.141a3.891 3.891 0 0 0 -2.893 3.734v5.125a23.166 23.166 0 0 1 -4.174-1.623 7.857 7.857 0 0 1 -.027.878 3.263 3.263 0 0 1 -.729 2.074l-1.794 1.483a.379.379 0 0 1 -.276.188h-4c-1.324 0-2.346-1.336-2.653-3.343a7.058 7.058 0 0 1 .234-3.18 3.477 3.477 0 0 1 1.636-2.157 1.868 1.868 0 0 1 .783-.32h1.5a8.035 8.035 0 0 1 -1.5-5 11.1 11.1 0 0 1 .5-3 2.519 2.519 0 0 0 0-1.5 13.272 13.272 0 0 1 -.5-3.5c6.687-1.936 11 0 11 0s4.319-1.955 11 0" class="ColorScheme-Text" fill="currentColor"/>
|
||||||
|
<path d="m39 28h-10v-4a3.13 3.13 0 0 1 3-3 3.087 3.087 0 0 1 3 3v1a1.034 1.034 0 0 0 1 1h1a1.034 1.034 0 0 0 1-1v-1a6 6 0 0 0 -12 0v4h-1a2.073 2.073 0 0 0 -2 2v6a2.073 2.073 0 0 0 2 2h14a2.073 2.073 0 0 0 2-2v-6a2.073 2.073 0 0 0 -2-2zm-5.391 5.94a1.609 1.609 0 0 1 -3.217 0v-1.876a1.609 1.609 0 0 1 3.217 0z" class="ColorScheme-Highlight" fill="currentColor"/>
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.3 KiB |
+8
-6
@@ -1,8 +1,10 @@
|
|||||||
<svg height="16" viewBox="0 0 42 42" width="16" xmlns="http://www.w3.org/2000/svg">
|
<svg height="16" viewBox="0 0 42 42" width="16" xmlns="http://www.w3.org/2000/svg">
|
||||||
<style id="current-color-scheme" type="text/css">
|
<defs>
|
||||||
.ColorScheme-Text {
|
<style id="current-color-scheme" type="text/css">
|
||||||
color:#232629;
|
.ColorScheme-Text {
|
||||||
}
|
color:#222222;
|
||||||
</style>
|
}
|
||||||
<path d="m32.66 29.319a1.432 1.432 0 0 0 -.66-.319h-1.5a8.125 8.125 0 0 0 1.5-5 11.027 11.027 0 0 0 -.5-3 2.519 2.519 0 0 1 0-1.5 12.987 12.987 0 0 0 .5-3.5c-6.681-1.955-11 0-11 0s-4.313-1.936-11 0a13.272 13.272 0 0 0 .5 3.5 2.519 2.519 0 0 1 0 1.5 11.1 11.1 0 0 0 -.5 3 8.035 8.035 0 0 0 1.5 5h-1.5a1.868 1.868 0 0 0 -.783.319 3.477 3.477 0 0 0 -1.636 2.157 7.058 7.058 0 0 0 -.234 3.18c.307 2.008 1.329 3.344 2.653 3.344h4a.379.379 0 0 0 .277-.187l1.793-1.483a3.263 3.263 0 0 0 .729-2.074 7.857 7.857 0 0 0 .027-.878 23.166 23.166 0 0 0 4.174 1.622 24.4 24.4 0 0 0 4.051-1.614 7.848 7.848 0 0 0 .027.869 3.263 3.263 0 0 0 .729 2.074l1.793 1.484a.61.61 0 0 0 .4.187h4c1.324 0 2.223-1.336 2.529-3.343a7.057 7.057 0 0 0 -.234-3.18 3.477 3.477 0 0 0 -1.635-2.158zm-17.069 6.5c-.019.009-.936.775-1.458 1.208a.418.418 0 0 1 -.627-.111 9.322 9.322 0 0 1 -.3-5.974 15.843 15.843 0 0 0 2.894 2.048c.051 1.03-.161 2.644-.509 2.834zm6.409-6.819h-2l.5-5a2 2 0 1 1 1 0zm6.38 7.921a.418.418 0 0 1 -.627.111c-.522-.433-1.439-1.2-1.458-1.208-.348-.189-.56-1.8-.505-2.828a15.84 15.84 0 0 0 2.9-2.037 9.322 9.322 0 0 1 -.31 5.962zm-20.924-11.162.744-1.366a1.579 1.579 0 0 0 -.019-1.557l.653-1.2c.2.014-.03-.113.165-.14.051-.217-.051-.336 0-.5a3.269 3.269 0 0 0 0-1.5 7.151 7.151 0 0 1 0-3 2.366 2.366 0 0 0 -2.378 1.448 2.409 2.409 0 0 0 .229 2.661l-.7 1.278a1.779 1.779 0 0 0 -1.317.891l-.741 1.372a1.577 1.577 0 0 0 -.019 1.487 3.028 3.028 0 0 0 -2.746 1.525 2.648 2.648 0 0 0 .044 2.631.748.748 0 0 0 .981.266.656.656 0 0 0 .284-.92 1.37 1.37 0 0 1 -.023-1.361 1.6 1.6 0 0 1 2.079-.63 1.408 1.408 0 0 1 .672 1.95 1.546 1.546 0 0 1 -1.2.78.688.688 0 0 0 -.636.749.707.707 0 0 0 .717.6.789.789 0 0 0 .082 0 2.989 2.989 0 0 0 2.322-1.513 2.669 2.669 0 0 0 -.377-3.084 1.767 1.767 0 0 0 1.184-.867zm33.217 1.2a3.021 3.021 0 0 0 -2.658-1.525 1.574 1.574 0 0 0 -.107-1.283l-.745-1.367a1.779 1.779 0 0 0 -1.317-.891l-.7-1.278a2.409 2.409 0 0 0 .229-2.661 2.283 2.283 0 0 0 -2.375-1.454 7.039 7.039 0 0 1 0 3 3.272 3.272 0 0 0 0 1.5c.047.152-.047.3 0 .5.227.04-.069.156.165.14l.653 1.2a1.579 1.579 0 0 0 -.019 1.557l.745 1.367a1.753 1.753 0 0 0 1.045.832 2.66 2.66 0 0 0 -.238 2.916 2.989 2.989 0 0 0 2.326 1.509.79.79 0 0 0 .082 0 .707.707 0 0 0 .717-.6.688.688 0 0 0 -.636-.749 1.546 1.546 0 0 1 -1.2-.78 1.408 1.408 0 0 1 .672-1.95 1.628 1.628 0 0 1 1.179-.089 1.512 1.512 0 0 1 .9.719 1.37 1.37 0 0 1 -.023 1.361.656.656 0 0 0 .284.92.748.748 0 0 0 .981-.266 2.648 2.648 0 0 0 .04-2.633zm-19.673-11.959a13.013 13.013 0 0 1 5-1 21.6 21.6 0 0 1 4.5.5 9.312 9.312 0 0 0 -9.5-8.5c-5.794 0-9.176 4-9.5 8.5a21.858 21.858 0 0 1 4.5-.5 12.819 12.819 0 0 1 5 1zm3.5-5c1.209 0 2.5.866 2.5 2h-5c0-1.134 1.291-2 2.5-2zm-7 0c1.209 0 2.5.866 2.5 2h-5c0-1.134 1.291-2 2.5-2z" fill-rule="evenodd" style="fill:#f2f2f2;fill-opacity:1" class="ColorScheme-Text" fill="currentColor"/>
|
</style>
|
||||||
|
</defs>
|
||||||
|
<path d="m32.66 29.319a1.432 1.432 0 0 0 -.66-.319h-1.5a8.125 8.125 0 0 0 1.5-5 11.027 11.027 0 0 0 -.5-3 2.519 2.519 0 0 1 0-1.5 12.987 12.987 0 0 0 .5-3.5c-6.681-1.955-11 0-11 0s-4.313-1.936-11 0a13.272 13.272 0 0 0 .5 3.5 2.519 2.519 0 0 1 0 1.5 11.1 11.1 0 0 0 -.5 3 8.035 8.035 0 0 0 1.5 5h-1.5a1.868 1.868 0 0 0 -.783.319 3.477 3.477 0 0 0 -1.636 2.157 7.058 7.058 0 0 0 -.234 3.18c.307 2.008 1.329 3.344 2.653 3.344h4a.379.379 0 0 0 .277-.187l1.793-1.483a3.263 3.263 0 0 0 .729-2.074 7.857 7.857 0 0 0 .027-.878 23.166 23.166 0 0 0 4.174 1.622 24.4 24.4 0 0 0 4.051-1.614 7.848 7.848 0 0 0 .027.869 3.263 3.263 0 0 0 .729 2.074l1.793 1.484a.61.61 0 0 0 .4.187h4c1.324 0 2.223-1.336 2.529-3.343a7.057 7.057 0 0 0 -.234-3.18 3.477 3.477 0 0 0 -1.635-2.158zm-17.069 6.5c-.019.009-.936.775-1.458 1.208a.418.418 0 0 1 -.627-.111 9.322 9.322 0 0 1 -.3-5.974 15.843 15.843 0 0 0 2.894 2.048c.051 1.03-.161 2.644-.509 2.834zm6.409-6.819h-2l.5-5a2 2 0 1 1 1 0zm6.38 7.921a.418.418 0 0 1 -.627.111c-.522-.433-1.439-1.2-1.458-1.208-.348-.189-.56-1.8-.505-2.828a15.84 15.84 0 0 0 2.9-2.037 9.322 9.322 0 0 1 -.31 5.962zm-20.924-11.162.744-1.366a1.579 1.579 0 0 0 -.019-1.557l.653-1.2c.2.014-.03-.113.165-.14.051-.217-.051-.336 0-.5a3.269 3.269 0 0 0 0-1.5 7.151 7.151 0 0 1 0-3 2.366 2.366 0 0 0 -2.378 1.448 2.409 2.409 0 0 0 .229 2.661l-.7 1.278a1.779 1.779 0 0 0 -1.317.891l-.741 1.372a1.577 1.577 0 0 0 -.019 1.487 3.028 3.028 0 0 0 -2.746 1.525 2.648 2.648 0 0 0 .044 2.631.748.748 0 0 0 .981.266.656.656 0 0 0 .284-.92 1.37 1.37 0 0 1 -.023-1.361 1.6 1.6 0 0 1 2.079-.63 1.408 1.408 0 0 1 .672 1.95 1.546 1.546 0 0 1 -1.2.78.688.688 0 0 0 -.636.749.707.707 0 0 0 .717.6.789.789 0 0 0 .082 0 2.989 2.989 0 0 0 2.322-1.513 2.669 2.669 0 0 0 -.377-3.084 1.767 1.767 0 0 0 1.184-.867zm33.217 1.2a3.021 3.021 0 0 0 -2.658-1.525 1.574 1.574 0 0 0 -.107-1.283l-.745-1.367a1.779 1.779 0 0 0 -1.317-.891l-.7-1.278a2.409 2.409 0 0 0 .229-2.661 2.283 2.283 0 0 0 -2.375-1.454 7.039 7.039 0 0 1 0 3 3.272 3.272 0 0 0 0 1.5c.047.152-.047.3 0 .5.227.04-.069.156.165.14l.653 1.2a1.579 1.579 0 0 0 -.019 1.557l.745 1.367a1.753 1.753 0 0 0 1.045.832 2.66 2.66 0 0 0 -.238 2.916 2.989 2.989 0 0 0 2.326 1.509.79.79 0 0 0 .082 0 .707.707 0 0 0 .717-.6.688.688 0 0 0 -.636-.749 1.546 1.546 0 0 1 -1.2-.78 1.408 1.408 0 0 1 .672-1.95 1.628 1.628 0 0 1 1.179-.089 1.512 1.512 0 0 1 .9.719 1.37 1.37 0 0 1 -.023 1.361.656.656 0 0 0 .284.92.748.748 0 0 0 .981-.266 2.648 2.648 0 0 0 .04-2.633zm-19.673-11.959a13.013 13.013 0 0 1 5-1 21.6 21.6 0 0 1 4.5.5 9.312 9.312 0 0 0 -9.5-8.5c-5.794 0-9.176 4-9.5 8.5a21.858 21.858 0 0 1 4.5-.5 12.819 12.819 0 0 1 5 1zm3.5-5c1.209 0 2.5.866 2.5 2h-5c0-1.134 1.291-2 2.5-2zm-7 0c1.209 0 2.5.866 2.5 2h-5c0-1.134 1.291-2 2.5-2z" fill-rule="evenodd" class="ColorScheme-Text" fill="currentColor"/>
|
||||||
</svg>
|
</svg>
|
||||||
|
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 3.0 KiB |
Vendored
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
cryptomator (${PPA_VERSION}) focal; urgency=low
|
cryptomator (${PPA_VERSION}) jammy; urgency=low
|
||||||
|
|
||||||
* Full changelog can be found on https://github.com/cryptomator/cryptomator/releases
|
* Full changelog can be found on https://github.com/cryptomator/cryptomator/releases
|
||||||
|
|
||||||
|
|||||||
Vendored
+2
-2
@@ -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-22 (>= 22.0.1+8-0ppa1), libgtk-3-0, libxxf86vm1, libgl1
|
Build-Depends: debhelper (>=10), openjdk-25-jdk (>= 25+36), libgtk-3-0 (>= 3.20.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
|
||||||
@@ -12,7 +12,7 @@ Package: cryptomator
|
|||||||
Architecture: any
|
Architecture: any
|
||||||
Section: utils
|
Section: utils
|
||||||
Priority: optional
|
Priority: optional
|
||||||
Depends: ${shlibs:Depends}, ${misc:Depends}, fuse3
|
Depends: ${shlibs:Depends}, ${misc:Depends}, fuse3, libgtk-3-0 (>= 3.20.0)
|
||||||
Recommends: gvfs-backends, gvfs-fuse, gnome-keyring
|
Recommends: gvfs-backends, gvfs-fuse, gnome-keyring
|
||||||
XB-AppName: Cryptomator
|
XB-AppName: Cryptomator
|
||||||
XB-Category: Utility;Security;FileTools;
|
XB-Category: Utility;Security;FileTools;
|
||||||
|
|||||||
Vendored
+2
-2
@@ -4,11 +4,11 @@ Upstream-Contact: Cryptomator <info@cryptomator.org>
|
|||||||
Source: https://cryptomator.org
|
Source: https://cryptomator.org
|
||||||
|
|
||||||
Files: *
|
Files: *
|
||||||
Copyright: 2016-2024 Skymatic GmbH
|
Copyright: 2016-2025 Skymatic GmbH
|
||||||
License: GPL-3+
|
License: GPL-3+
|
||||||
|
|
||||||
Files: debian/org.cryptomator.Cryptomator.appdata.xml
|
Files: debian/org.cryptomator.Cryptomator.appdata.xml
|
||||||
Copyright: 2016-2024 Skymatic GmbH
|
Copyright: 2016-2025 Skymatic GmbH
|
||||||
License: FSFAP
|
License: FSFAP
|
||||||
|
|
||||||
License: GPL-3+
|
License: GPL-3+
|
||||||
|
|||||||
Vendored
+6
-4
@@ -4,11 +4,12 @@
|
|||||||
# 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-22-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)
|
||||||
|
JAVA_HOME = /usr/lib/jvm/java-25-openjdk-amd64
|
||||||
JMODS_PATH = jmods/amd64:${JAVA_HOME}/jmods
|
JMODS_PATH = jmods/amd64:${JAVA_HOME}/jmods
|
||||||
else ifeq ($(DEB_BUILD_ARCH),arm64)
|
else ifeq ($(DEB_BUILD_ARCH),arm64)
|
||||||
|
JAVA_HOME = /usr/lib/jvm/java-25-openjdk-arm64
|
||||||
JMODS_PATH = jmods/aarch64:${JAVA_HOME}/jmods
|
JMODS_PATH = jmods/aarch64:${JAVA_HOME}/jmods
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@@ -28,7 +29,7 @@ override_dh_auto_build:
|
|||||||
$(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.security.auth,jdk.accessibility,jdk.management.jfr,jdk.net,java.compiler \
|
--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.crypto.cryptoki,jdk.crypto.ec,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 \
|
||||||
@@ -44,8 +45,8 @@ override_dh_auto_build:
|
|||||||
--name cryptomator \
|
--name cryptomator \
|
||||||
--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=javafx.graphics,org.cryptomator.jfuse.linux.amd64,org.cryptomator.jfuse.linux.aarch64,org.purejava.appindicator" \
|
||||||
--copyright "(C) 2016 - 2024 Skymatic GmbH" \
|
--copyright "(C) 2016 - 2025 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\"" \
|
||||||
@@ -62,6 +63,7 @@ override_dh_auto_build:
|
|||||||
--java-options "-Dcryptomator.appVersion=\"${SEMVER_STR}\"" \
|
--java-options "-Dcryptomator.appVersion=\"${SEMVER_STR}\"" \
|
||||||
--java-options "-Dcryptomator.disableUpdateCheck=\"${DISABLE_UPDATE_CHECK}\"" \
|
--java-options "-Dcryptomator.disableUpdateCheck=\"${DISABLE_UPDATE_CHECK}\"" \
|
||||||
--java-options "-Dcryptomator.integrationsLinux.autoStartCmd=\"cryptomator\"" \
|
--java-options "-Dcryptomator.integrationsLinux.autoStartCmd=\"cryptomator\"" \
|
||||||
|
--java-options "-Dcryptomator.networking.truststore.p12Path=\"/etc/cryptomator/certs.p12\"" \
|
||||||
--app-version "${VERSION_NUM}.${REVISION_NUM}" \
|
--app-version "${VERSION_NUM}.${REVISION_NUM}" \
|
||||||
--resource-dir resources \
|
--resource-dir resources \
|
||||||
--verbose
|
--verbose
|
||||||
|
|||||||
@@ -1 +1,2 @@
|
|||||||
embedded.provisionprofile
|
embedded.provisionprofile
|
||||||
|
xcuserdata/
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
//
|
||||||
|
// CryptomatorDockTilePlugin.swift
|
||||||
|
// Integrations
|
||||||
|
//
|
||||||
|
// Created by Tobias Hagemann on 22.09.25.
|
||||||
|
// Copyright © 2025 Cryptomator. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import AppKit
|
||||||
|
|
||||||
|
class CryptomatorDockTilePlugin: NSObject, NSDockTilePlugIn {
|
||||||
|
func setDockTile(_ dockTile: NSDockTile?) {
|
||||||
|
guard let dockTile = dockTile, let image = Bundle(for: Self.self).image(forResource: "Cryptomator") else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
dockTile.contentView = NSImageView(image: image)
|
||||||
|
dockTile.display()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,314 @@
|
|||||||
|
// !$*UTF8*$!
|
||||||
|
{
|
||||||
|
archiveVersion = 1;
|
||||||
|
classes = {
|
||||||
|
};
|
||||||
|
objectVersion = 77;
|
||||||
|
objects = {
|
||||||
|
|
||||||
|
/* Begin PBXBuildFile section */
|
||||||
|
74E08DE12E8584DE007E665C /* CryptomatorDockTilePlugin.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74E08DE02E85847E007E665C /* CryptomatorDockTilePlugin.swift */; };
|
||||||
|
74E08DED2E858532007E665C /* Cryptomator.icns in Resources */ = {isa = PBXBuildFile; fileRef = 74E08DEC2E858532007E665C /* Cryptomator.icns */; };
|
||||||
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
|
/* Begin PBXFileReference section */
|
||||||
|
74E08DD92E858467007E665C /* Cryptomator.docktileplugin */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Cryptomator.docktileplugin; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
|
74E08DE02E85847E007E665C /* CryptomatorDockTilePlugin.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CryptomatorDockTilePlugin.swift; sourceTree = "<group>"; };
|
||||||
|
74E08DEC2E858532007E665C /* Cryptomator.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = Cryptomator.icns; path = ../resources/Cryptomator.icns; sourceTree = SOURCE_ROOT; };
|
||||||
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
|
/* Begin PBXFrameworksBuildPhase section */
|
||||||
|
74E08DD62E858467007E665C /* Frameworks */ = {
|
||||||
|
isa = PBXFrameworksBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
|
/* End PBXFrameworksBuildPhase section */
|
||||||
|
|
||||||
|
/* Begin PBXGroup section */
|
||||||
|
74E08DD02E858467007E665C = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
74E08DE02E85847E007E665C /* CryptomatorDockTilePlugin.swift */,
|
||||||
|
74E08DEC2E858532007E665C /* Cryptomator.icns */,
|
||||||
|
74E08DDA2E858467007E665C /* Products */,
|
||||||
|
);
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
74E08DDA2E858467007E665C /* Products */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
74E08DD92E858467007E665C /* Cryptomator.docktileplugin */,
|
||||||
|
);
|
||||||
|
name = Products;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
/* End PBXGroup section */
|
||||||
|
|
||||||
|
/* Begin PBXNativeTarget section */
|
||||||
|
74E08DD82E858467007E665C /* DockTilePlugin */ = {
|
||||||
|
isa = PBXNativeTarget;
|
||||||
|
buildConfigurationList = 74E08DDD2E858467007E665C /* Build configuration list for PBXNativeTarget "DockTilePlugin" */;
|
||||||
|
buildPhases = (
|
||||||
|
74E08DD52E858467007E665C /* Sources */,
|
||||||
|
74E08DD62E858467007E665C /* Frameworks */,
|
||||||
|
74E08DD72E858467007E665C /* Resources */,
|
||||||
|
);
|
||||||
|
buildRules = (
|
||||||
|
);
|
||||||
|
dependencies = (
|
||||||
|
);
|
||||||
|
name = DockTilePlugin;
|
||||||
|
packageProductDependencies = (
|
||||||
|
);
|
||||||
|
productName = DockTilePlugin;
|
||||||
|
productReference = 74E08DD92E858467007E665C /* Cryptomator.docktileplugin */;
|
||||||
|
productType = "com.apple.product-type.bundle";
|
||||||
|
};
|
||||||
|
/* End PBXNativeTarget section */
|
||||||
|
|
||||||
|
/* Begin PBXProject section */
|
||||||
|
74E08DD12E858467007E665C /* Project object */ = {
|
||||||
|
isa = PBXProject;
|
||||||
|
attributes = {
|
||||||
|
BuildIndependentTargetsInParallel = 1;
|
||||||
|
LastUpgradeCheck = 2600;
|
||||||
|
ORGANIZATIONNAME = Cryptomator;
|
||||||
|
TargetAttributes = {
|
||||||
|
74E08DD82E858467007E665C = {
|
||||||
|
CreatedOnToolsVersion = 26.0.1;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
buildConfigurationList = 74E08DD42E858467007E665C /* Build configuration list for PBXProject "DockTilePlugin" */;
|
||||||
|
developmentRegion = en;
|
||||||
|
hasScannedForEncodings = 0;
|
||||||
|
knownRegions = (
|
||||||
|
en,
|
||||||
|
Base,
|
||||||
|
);
|
||||||
|
mainGroup = 74E08DD02E858467007E665C;
|
||||||
|
minimizedProjectReferenceProxies = 1;
|
||||||
|
preferredProjectObjectVersion = 77;
|
||||||
|
productRefGroup = 74E08DDA2E858467007E665C /* Products */;
|
||||||
|
projectDirPath = "";
|
||||||
|
projectRoot = "";
|
||||||
|
targets = (
|
||||||
|
74E08DD82E858467007E665C /* DockTilePlugin */,
|
||||||
|
);
|
||||||
|
};
|
||||||
|
/* End PBXProject section */
|
||||||
|
|
||||||
|
/* Begin PBXResourcesBuildPhase section */
|
||||||
|
74E08DD72E858467007E665C /* Resources */ = {
|
||||||
|
isa = PBXResourcesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
74E08DED2E858532007E665C /* Cryptomator.icns in Resources */,
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
|
/* End PBXResourcesBuildPhase section */
|
||||||
|
|
||||||
|
/* Begin PBXSourcesBuildPhase section */
|
||||||
|
74E08DD52E858467007E665C /* Sources */ = {
|
||||||
|
isa = PBXSourcesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
74E08DE12E8584DE007E665C /* CryptomatorDockTilePlugin.swift in Sources */,
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
|
/* End PBXSourcesBuildPhase section */
|
||||||
|
|
||||||
|
/* Begin XCBuildConfiguration section */
|
||||||
|
74E08DDB2E858467007E665C /* Debug */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||||
|
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
|
||||||
|
CLANG_ANALYZER_NONNULL = YES;
|
||||||
|
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||||
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
|
||||||
|
CLANG_ENABLE_MODULES = YES;
|
||||||
|
CLANG_ENABLE_OBJC_ARC = YES;
|
||||||
|
CLANG_ENABLE_OBJC_WEAK = YES;
|
||||||
|
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||||
|
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_COMMA = YES;
|
||||||
|
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||||
|
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||||
|
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||||
|
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||||
|
CLANG_WARN_EMPTY_BODY = YES;
|
||||||
|
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||||
|
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||||
|
CLANG_WARN_INT_CONVERSION = YES;
|
||||||
|
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||||
|
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||||
|
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||||
|
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||||
|
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||||
|
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||||
|
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||||
|
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||||
|
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||||
|
COPY_PHASE_STRIP = NO;
|
||||||
|
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||||
|
DEVELOPMENT_TEAM = YZQJQUHA3L;
|
||||||
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
|
ENABLE_TESTABILITY = YES;
|
||||||
|
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
||||||
|
GCC_C_LANGUAGE_STANDARD = gnu17;
|
||||||
|
GCC_DYNAMIC_NO_PIC = NO;
|
||||||
|
GCC_NO_COMMON_BLOCKS = YES;
|
||||||
|
GCC_OPTIMIZATION_LEVEL = 0;
|
||||||
|
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||||
|
"DEBUG=1",
|
||||||
|
"$(inherited)",
|
||||||
|
);
|
||||||
|
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||||
|
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||||
|
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||||
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||||
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||||
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
|
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
|
||||||
|
MACOSX_DEPLOYMENT_TARGET = 11.5;
|
||||||
|
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||||
|
MTL_FAST_MATH = YES;
|
||||||
|
ONLY_ACTIVE_ARCH = YES;
|
||||||
|
SDKROOT = macosx;
|
||||||
|
SWIFT_VERSION = 5.0;
|
||||||
|
};
|
||||||
|
name = Debug;
|
||||||
|
};
|
||||||
|
74E08DDC2E858467007E665C /* Release */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||||
|
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
|
||||||
|
CLANG_ANALYZER_NONNULL = YES;
|
||||||
|
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||||
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
|
||||||
|
CLANG_ENABLE_MODULES = YES;
|
||||||
|
CLANG_ENABLE_OBJC_ARC = YES;
|
||||||
|
CLANG_ENABLE_OBJC_WEAK = YES;
|
||||||
|
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||||
|
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_COMMA = YES;
|
||||||
|
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||||
|
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||||
|
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||||
|
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||||
|
CLANG_WARN_EMPTY_BODY = YES;
|
||||||
|
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||||
|
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||||
|
CLANG_WARN_INT_CONVERSION = YES;
|
||||||
|
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||||
|
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||||
|
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||||
|
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||||
|
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||||
|
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||||
|
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||||
|
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||||
|
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||||
|
COPY_PHASE_STRIP = NO;
|
||||||
|
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||||
|
DEVELOPMENT_TEAM = YZQJQUHA3L;
|
||||||
|
ENABLE_NS_ASSERTIONS = NO;
|
||||||
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
|
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
||||||
|
GCC_C_LANGUAGE_STANDARD = gnu17;
|
||||||
|
GCC_NO_COMMON_BLOCKS = YES;
|
||||||
|
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||||
|
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||||
|
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||||
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||||
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||||
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
|
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
|
||||||
|
MACOSX_DEPLOYMENT_TARGET = 11.5;
|
||||||
|
MTL_ENABLE_DEBUG_INFO = NO;
|
||||||
|
MTL_FAST_MATH = YES;
|
||||||
|
SDKROOT = macosx;
|
||||||
|
SWIFT_VERSION = 5.0;
|
||||||
|
};
|
||||||
|
name = Release;
|
||||||
|
};
|
||||||
|
74E08DDE2E858467007E665C /* Debug */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
CODE_SIGN_STYLE = Manual;
|
||||||
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
|
CURRENT_PROJECT_VERSION = 1;
|
||||||
|
DEVELOPMENT_TEAM = "";
|
||||||
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
|
INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2025 Cryptomator. All rights reserved.";
|
||||||
|
INFOPLIST_KEY_NSPrincipalClass = CryptomatorDockTilePlugin;
|
||||||
|
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Bundles";
|
||||||
|
MARKETING_VERSION = 1.0;
|
||||||
|
PRODUCT_BUNDLE_IDENTIFIER = org.cryptomator.DockTilePlugin;
|
||||||
|
PRODUCT_NAME = Cryptomator;
|
||||||
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
|
SKIP_INSTALL = YES;
|
||||||
|
STRING_CATALOG_GENERATE_SYMBOLS = YES;
|
||||||
|
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||||
|
WRAPPER_EXTENSION = docktileplugin;
|
||||||
|
};
|
||||||
|
name = Debug;
|
||||||
|
};
|
||||||
|
74E08DDF2E858467007E665C /* Release */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
CODE_SIGN_STYLE = Manual;
|
||||||
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
|
CURRENT_PROJECT_VERSION = 1;
|
||||||
|
DEVELOPMENT_TEAM = "";
|
||||||
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
|
INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2025 Cryptomator. All rights reserved.";
|
||||||
|
INFOPLIST_KEY_NSPrincipalClass = CryptomatorDockTilePlugin;
|
||||||
|
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Bundles";
|
||||||
|
MARKETING_VERSION = 1.0;
|
||||||
|
PRODUCT_BUNDLE_IDENTIFIER = org.cryptomator.DockTilePlugin;
|
||||||
|
PRODUCT_NAME = Cryptomator;
|
||||||
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
|
SKIP_INSTALL = YES;
|
||||||
|
STRING_CATALOG_GENERATE_SYMBOLS = YES;
|
||||||
|
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||||
|
WRAPPER_EXTENSION = docktileplugin;
|
||||||
|
};
|
||||||
|
name = Release;
|
||||||
|
};
|
||||||
|
/* End XCBuildConfiguration section */
|
||||||
|
|
||||||
|
/* Begin XCConfigurationList section */
|
||||||
|
74E08DD42E858467007E665C /* Build configuration list for PBXProject "DockTilePlugin" */ = {
|
||||||
|
isa = XCConfigurationList;
|
||||||
|
buildConfigurations = (
|
||||||
|
74E08DDB2E858467007E665C /* Debug */,
|
||||||
|
74E08DDC2E858467007E665C /* Release */,
|
||||||
|
);
|
||||||
|
defaultConfigurationIsVisible = 0;
|
||||||
|
defaultConfigurationName = Release;
|
||||||
|
};
|
||||||
|
74E08DDD2E858467007E665C /* Build configuration list for PBXNativeTarget "DockTilePlugin" */ = {
|
||||||
|
isa = XCConfigurationList;
|
||||||
|
buildConfigurations = (
|
||||||
|
74E08DDE2E858467007E665C /* Debug */,
|
||||||
|
74E08DDF2E858467007E665C /* Release */,
|
||||||
|
);
|
||||||
|
defaultConfigurationIsVisible = 0;
|
||||||
|
defaultConfigurationName = Release;
|
||||||
|
};
|
||||||
|
/* End XCConfigurationList section */
|
||||||
|
};
|
||||||
|
rootObject = 74E08DD12E858467007E665C /* Project object */;
|
||||||
|
}
|
||||||
Generated
Vendored
+7
@@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Workspace
|
||||||
|
version = "1.0">
|
||||||
|
<FileRef
|
||||||
|
location = "self:">
|
||||||
|
</FileRef>
|
||||||
|
</Workspace>
|
||||||
Vendored
+67
@@ -0,0 +1,67 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Scheme
|
||||||
|
LastUpgradeVersion = "2600"
|
||||||
|
version = "1.7">
|
||||||
|
<BuildAction
|
||||||
|
parallelizeBuildables = "YES"
|
||||||
|
buildImplicitDependencies = "YES"
|
||||||
|
buildArchitectures = "Automatic">
|
||||||
|
<BuildActionEntries>
|
||||||
|
<BuildActionEntry
|
||||||
|
buildForTesting = "YES"
|
||||||
|
buildForRunning = "YES"
|
||||||
|
buildForProfiling = "YES"
|
||||||
|
buildForArchiving = "YES"
|
||||||
|
buildForAnalyzing = "YES">
|
||||||
|
<BuildableReference
|
||||||
|
BuildableIdentifier = "primary"
|
||||||
|
BlueprintIdentifier = "74E08DD82E858467007E665C"
|
||||||
|
BuildableName = "Cryptomator.docktileplugin"
|
||||||
|
BlueprintName = "DockTilePlugin"
|
||||||
|
ReferencedContainer = "container:DockTilePlugin.xcodeproj">
|
||||||
|
</BuildableReference>
|
||||||
|
</BuildActionEntry>
|
||||||
|
</BuildActionEntries>
|
||||||
|
</BuildAction>
|
||||||
|
<TestAction
|
||||||
|
buildConfiguration = "Debug"
|
||||||
|
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||||
|
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||||
|
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||||
|
shouldAutocreateTestPlan = "YES">
|
||||||
|
</TestAction>
|
||||||
|
<LaunchAction
|
||||||
|
buildConfiguration = "Debug"
|
||||||
|
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||||
|
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||||
|
launchStyle = "0"
|
||||||
|
useCustomWorkingDirectory = "NO"
|
||||||
|
ignoresPersistentStateOnLaunch = "NO"
|
||||||
|
debugDocumentVersioning = "YES"
|
||||||
|
debugServiceExtension = "internal"
|
||||||
|
allowLocationSimulation = "YES">
|
||||||
|
</LaunchAction>
|
||||||
|
<ProfileAction
|
||||||
|
buildConfiguration = "Release"
|
||||||
|
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||||
|
savedToolIdentifier = ""
|
||||||
|
useCustomWorkingDirectory = "NO"
|
||||||
|
debugDocumentVersioning = "YES">
|
||||||
|
<MacroExpansion>
|
||||||
|
<BuildableReference
|
||||||
|
BuildableIdentifier = "primary"
|
||||||
|
BlueprintIdentifier = "74E08DD82E858467007E665C"
|
||||||
|
BuildableName = "Cryptomator.docktileplugin"
|
||||||
|
BlueprintName = "DockTilePlugin"
|
||||||
|
ReferencedContainer = "container:DockTilePlugin.xcodeproj">
|
||||||
|
</BuildableReference>
|
||||||
|
</MacroExpansion>
|
||||||
|
</ProfileAction>
|
||||||
|
<AnalyzeAction
|
||||||
|
buildConfiguration = "Debug">
|
||||||
|
</AnalyzeAction>
|
||||||
|
<ArchiveAction
|
||||||
|
buildConfiguration = "Release"
|
||||||
|
revealArchiveInOrganizer = "YES">
|
||||||
|
</ArchiveAction>
|
||||||
|
</Scheme>
|
||||||
Vendored
+31
-10
@@ -24,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 - 2024"
|
COPYRIGHT_YEARS="2016 - 2025"
|
||||||
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"
|
||||||
@@ -32,15 +32,15 @@ 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"
|
||||||
|
|
||||||
JAVAFX_VERSION=22.0.2
|
JAVAFX_VERSION=25
|
||||||
JAVAFX_ARCH="undefined"
|
JAVAFX_ARCH="undefined"
|
||||||
JAVAFX_JMODS_SHA256="undefined"
|
JAVAFX_JMODS_SHA256="undefined"
|
||||||
if [ "$(machine)" = "arm64e" ]; then
|
if [ "$(machine)" = "arm64e" ]; then
|
||||||
JAVAFX_ARCH="aarch64"
|
JAVAFX_ARCH="aarch64"
|
||||||
JAVAFX_JMODS_SHA256="813c6748f7c99cb7a579d48b48a087b4682b1fad1fc1a4fe5f9b21cf872b15a7"
|
JAVAFX_JMODS_SHA256="13f8c0513c40c95881479fbcf0465a29a60217393fb0656f5e4eab78a9442fba"
|
||||||
else
|
else
|
||||||
JAVAFX_ARCH="x64"
|
JAVAFX_ARCH="x64"
|
||||||
JAVAFX_JMODS_SHA256="115cb08bb59d880cfff6e51e0bf0dcc45785ed9d456b8b8425597b04da6ab3d4"
|
JAVAFX_JMODS_SHA256="0eba73fb28a24c845175d16fa2f8c081c936ce6de1be9b79eb6119fa32e53d52"
|
||||||
fi
|
fi
|
||||||
JAVAFX_JMODS_URL="https://download2.gluonhq.com/openjfx/${JAVAFX_VERSION}/openjfx-${JAVAFX_VERSION}_osx-${JAVAFX_ARCH}_bin-jmods.zip"
|
JAVAFX_JMODS_URL="https://download2.gluonhq.com/openjfx/${JAVAFX_VERSION}/openjfx-${JAVAFX_VERSION}_osx-${JAVAFX_ARCH}_bin-jmods.zip"
|
||||||
|
|
||||||
@@ -71,15 +71,21 @@ if [ "${POM_JFX_VERSION}" -ne "${JMOD_VERSION}" ]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# compile
|
# compile
|
||||||
mvn -B -Djavafx.platform=mac -f../../../pom.xml clean package -DskipTests -Pmac
|
mvn -B -f../../../pom.xml clean package -DskipTests -Pmac
|
||||||
cp ../../../LICENSE.txt ../../../target
|
cp ../../../LICENSE.txt ../../../target
|
||||||
cp ../../../target/${MAIN_JAR_GLOB} ../../../target/mods
|
cp ../../../target/${MAIN_JAR_GLOB} ../../../target/mods
|
||||||
|
|
||||||
# add runtime
|
# create runtime
|
||||||
|
## check for JEP 493
|
||||||
|
JMOD_PATHS="openjfx-jmods"
|
||||||
|
if ! ${JAVA_HOME}/bin/jlink --help | grep -q "Linking from run-time image enabled"; then
|
||||||
|
JMOD_PATHS="${JAVA_HOME}/jmods:${JMOD_PATHS}"
|
||||||
|
fi
|
||||||
|
## create custom runtime
|
||||||
${JAVA_HOME}/bin/jlink \
|
${JAVA_HOME}/bin/jlink \
|
||||||
--output runtime \
|
--output runtime \
|
||||||
--module-path "${JAVA_HOME}/jmods:openjfx-jmods" \
|
--module-path "${JMOD_PATHS}" \
|
||||||
--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 \
|
--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.crypto.cryptoki,jdk.crypto.ec,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 \
|
||||||
@@ -100,7 +106,7 @@ ${JAVA_HOME}/bin/jpackage \
|
|||||||
--copyright "(C) ${COPYRIGHT_YEARS} ${VENDOR}" \
|
--copyright "(C) ${COPYRIGHT_YEARS} ${VENDOR}" \
|
||||||
--app-version "${VERSION_NO}" \
|
--app-version "${VERSION_NO}" \
|
||||||
--java-options "--enable-preview" \
|
--java-options "--enable-preview" \
|
||||||
--java-options "--enable-native-access=org.cryptomator.jfuse.mac" \
|
--java-options "--enable-native-access=javafx.graphics,org.cryptomator.jfuse.mac" \
|
||||||
--java-options "-Xss5m" \
|
--java-options "-Xss5m" \
|
||||||
--java-options "-Xmx256m" \
|
--java-options "-Xmx256m" \
|
||||||
--java-options "-Dfile.encoding=\"utf-8\"" \
|
--java-options "-Dfile.encoding=\"utf-8\"" \
|
||||||
@@ -109,6 +115,7 @@ ${JAVA_HOME}/bin/jpackage \
|
|||||||
--java-options "-Dsun.java2d.metal=true" \
|
--java-options "-Dsun.java2d.metal=true" \
|
||||||
--java-options "-Dcryptomator.appVersion=\"${VERSION_NO}\"" \
|
--java-options "-Dcryptomator.appVersion=\"${VERSION_NO}\"" \
|
||||||
--java-options "-Dcryptomator.logDir=\"@{userhome}/Library/Logs/${APP_NAME}\"" \
|
--java-options "-Dcryptomator.logDir=\"@{userhome}/Library/Logs/${APP_NAME}\"" \
|
||||||
|
--java-options "-XX:ErrorFile=/cryptomator/cryptomator_crash.log" \
|
||||||
--java-options "-Dcryptomator.pluginDir=\"@{userhome}/Library/Application Support/${APP_NAME}/Plugins\"" \
|
--java-options "-Dcryptomator.pluginDir=\"@{userhome}/Library/Application Support/${APP_NAME}/Plugins\"" \
|
||||||
--java-options "-Dcryptomator.settingsPath=\"@{userhome}/Library/Application Support/${APP_NAME}/settings.json\"" \
|
--java-options "-Dcryptomator.settingsPath=\"@{userhome}/Library/Application Support/${APP_NAME}/settings.json\"" \
|
||||||
--java-options "-Dcryptomator.ipcSocketPath=\"@{userhome}/Library/Application Support/${APP_NAME}/ipc.socket\"" \
|
--java-options "-Dcryptomator.ipcSocketPath=\"@{userhome}/Library/Application Support/${APP_NAME}/ipc.socket\"" \
|
||||||
@@ -116,6 +123,7 @@ ${JAVA_HOME}/bin/jpackage \
|
|||||||
--java-options "-Dcryptomator.integrationsMac.keychainServiceName=\"${APP_NAME}\"" \
|
--java-options "-Dcryptomator.integrationsMac.keychainServiceName=\"${APP_NAME}\"" \
|
||||||
--java-options "-Dcryptomator.mountPointsDir=\"@{userhome}/Library/Application Support${APP_NAME}/mnt\"" \
|
--java-options "-Dcryptomator.mountPointsDir=\"@{userhome}/Library/Application Support${APP_NAME}/mnt\"" \
|
||||||
--java-options "-Dcryptomator.showTrayIcon=true" \
|
--java-options "-Dcryptomator.showTrayIcon=true" \
|
||||||
|
--java-options "-Dcryptomator.updateMechanism=org.cryptomator.macos.update.DmgUpdateMechanism" \
|
||||||
--java-options "-Dcryptomator.buildNumber=\"dmg-${REVISION_NO}\"" \
|
--java-options "-Dcryptomator.buildNumber=\"dmg-${REVISION_NO}\"" \
|
||||||
--mac-package-identifier ${PACKAGE_IDENTIFIER} \
|
--mac-package-identifier ${PACKAGE_IDENTIFIER} \
|
||||||
--resource-dir ../resources
|
--resource-dir ../resources
|
||||||
@@ -126,8 +134,21 @@ sed -i '' "s|###BUNDLE_SHORT_VERSION_STRING###|${VERSION_NO}|g" ${APP_NAME}.app/
|
|||||||
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/
|
cp ../embedded.provisionprofile ${APP_NAME}.app/Contents/
|
||||||
|
|
||||||
|
# build and install dock tile plugin
|
||||||
|
echo "Building and installing Cryptomator.docktileplugin..."
|
||||||
|
DERIVED_DATA_PATH=../DockTilePlugin/build
|
||||||
|
xcodebuild -project ../DockTilePlugin/DockTilePlugin.xcodeproj \
|
||||||
|
-scheme DockTilePlugin \
|
||||||
|
-configuration Release \
|
||||||
|
-derivedDataPath ${DERIVED_DATA_PATH} \
|
||||||
|
-quiet \
|
||||||
|
clean build
|
||||||
|
mkdir -p ${APP_NAME}.app/Contents/PlugIns
|
||||||
|
cp -R ${DERIVED_DATA_PATH}/Build/Products/Release/Cryptomator.docktileplugin ${APP_NAME}.app/Contents/PlugIns/
|
||||||
|
rm -rf ${DERIVED_DATA_PATH}
|
||||||
|
|
||||||
# generate license
|
# generate license
|
||||||
mvn -B -Djavafx.platform=mac -f../../../pom.xml license:add-third-party \
|
mvn -B -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 \
|
||||||
|
|||||||
+1
-1
@@ -17,7 +17,7 @@
|
|||||||
\f1\b0 \
|
\f1\b0 \
|
||||||
\
|
\
|
||||||
|
|
||||||
\f0\b \'a9 2016 \'96 2024 Skymatic GmbH
|
\f0\b \'a9 2016 \'96 2025 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.\
|
||||||
|
|||||||
Vendored
+3
@@ -116,5 +116,8 @@
|
|||||||
<!-- allow utilization of integrated GPU, see https://developer.apple.com/library/mac/qa/qa1734/_index.html -->
|
<!-- allow utilization of integrated GPU, see https://developer.apple.com/library/mac/qa/qa1734/_index.html -->
|
||||||
<key>NSSupportsAutomaticGraphicsSwitching</key>
|
<key>NSSupportsAutomaticGraphicsSwitching</key>
|
||||||
<true/>
|
<true/>
|
||||||
|
<!-- register dock tile plugin -->
|
||||||
|
<key>NSDockTilePlugIn</key>
|
||||||
|
<string>Cryptomator.docktileplugin</string>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
|||||||
+2
-1
@@ -4,7 +4,8 @@ installer
|
|||||||
*.wixobj
|
*.wixobj
|
||||||
*.pdb
|
*.pdb
|
||||||
*.msi
|
*.msi
|
||||||
|
*Debug.properties
|
||||||
*.exe
|
*.exe
|
||||||
*.jmod
|
*.jmod
|
||||||
resources/jfxJmods.zip
|
resources/jfxJmods.zip
|
||||||
license.rtf
|
license.rtf
|
||||||
|
|||||||
Vendored
+6
-2
@@ -11,7 +11,11 @@ SET HELP_URL="https://cryptomator.org/contact/"
|
|||||||
SET MODULE_AND_MAIN_CLASS="org.cryptomator.desktop/org.cryptomator.launcher.Cryptomator"
|
SET MODULE_AND_MAIN_CLASS="org.cryptomator.desktop/org.cryptomator.launcher.Cryptomator"
|
||||||
SET LOOPBACK_ALIAS="cryptomator-vault"
|
SET LOOPBACK_ALIAS="cryptomator-vault"
|
||||||
|
|
||||||
powershell -NoLogo -NoProfile -ExecutionPolicy Unrestricted -Command .\build.ps1^
|
:: read clean parameter from command line
|
||||||
|
SET CLEAN=0
|
||||||
|
IF "%~1"=="clean" SET CLEAN=1
|
||||||
|
|
||||||
|
pwsh -NoLogo -NoProfile -ExecutionPolicy Unrestricted -Command .\build.ps1^
|
||||||
-AppName %APPNAME%^
|
-AppName %APPNAME%^
|
||||||
-MainJarGlob "%MAIN_JAR_GLOB%"^
|
-MainJarGlob "%MAIN_JAR_GLOB%"^
|
||||||
-ModuleAndMainClass "%MODULE_AND_MAIN_CLASS%"^
|
-ModuleAndMainClass "%MODULE_AND_MAIN_CLASS%"^
|
||||||
@@ -22,4 +26,4 @@ powershell -NoLogo -NoProfile -ExecutionPolicy Unrestricted -Command .\build.ps1
|
|||||||
-HelpUrl "%HELP_URL%"^
|
-HelpUrl "%HELP_URL%"^
|
||||||
-UpdateUrl "%UPDATE_URL%"^
|
-UpdateUrl "%UPDATE_URL%"^
|
||||||
-LoopbackAlias "%LOOPBACK_ALIAS%"^
|
-LoopbackAlias "%LOOPBACK_ALIAS%"^
|
||||||
-Clean 1
|
-Clean %CLEAN%
|
||||||
Vendored
+169
-69
@@ -9,39 +9,63 @@ Param(
|
|||||||
[Parameter(Mandatory, HelpMessage="Please provide an update url")][string] $UpdateUrl,
|
[Parameter(Mandatory, HelpMessage="Please provide an update url")][string] $UpdateUrl,
|
||||||
[Parameter(Mandatory, HelpMessage="Please provide an about url")][string] $AboutUrl,
|
[Parameter(Mandatory, HelpMessage="Please provide an about url")][string] $AboutUrl,
|
||||||
[Parameter(Mandatory, HelpMessage="Please provide an alias for localhost")][string] $LoopbackAlias,
|
[Parameter(Mandatory, HelpMessage="Please provide an alias for localhost")][string] $LoopbackAlias,
|
||||||
[bool] $clean
|
[bool] $clean = $false # if true, cleans up previous build artifacts
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# ============================
|
||||||
|
# Function Definitions Section
|
||||||
|
# ============================
|
||||||
|
|
||||||
|
function Main {
|
||||||
|
|
||||||
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
|
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
|
||||||
$ProgressPreference = 'SilentlyContinue' # disables Invoke-WebRequest's progress bar, which slows down downloads to a few bytes/s
|
$ProgressPreference = 'SilentlyContinue' # disables Invoke-WebRequest's progress bar, which slows down downloads to a few bytes/s
|
||||||
|
|
||||||
# check preconditions
|
# check preconditions
|
||||||
if ((Get-Command "git" -ErrorAction SilentlyContinue) -eq $null)
|
if ((Get-Command "git" -ErrorAction SilentlyContinue) -eq $null)
|
||||||
{
|
{
|
||||||
Write-Host "Unable to find git.exe in your PATH (try: choco install git)"
|
Write-Error "Unable to find git.exe in your PATH (try: choco install git)"
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
if ((Get-Command "mvn" -ErrorAction SilentlyContinue) -eq $null)
|
if ((Get-Command "mvn" -ErrorAction SilentlyContinue) -eq $null)
|
||||||
{
|
{
|
||||||
Write-Host "Unable to find mvn.cmd in your PATH (try: choco install maven)"
|
Write-Error "Unable to find mvn.cmd in your PATH (try: choco install maven)"
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
|
if ((Get-Command 'wix' -ErrorAction SilentlyContinue) -eq $null)
|
||||||
|
{
|
||||||
|
Write-Error 'Unable to find wix in your PATH (try: dotnet tool install --global wix --version 6.0.0)'
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
$wixExtensions = & wix.exe extension list --global | Out-String
|
||||||
|
if ($wixExtensions -notmatch 'WixToolset.UI.wixext') {
|
||||||
|
Write-Error 'Wix UI extension missing. Please install it with: wix.exe extension add WixToolset.UI.wixext/6.0.0 --global)'
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
if ($wixExtensions -notmatch 'WixToolset.Util.wixext') {
|
||||||
|
Write-Error 'Wix Util extension missing. Please install it with: wix.exe extension add WixToolset.Util.wixext/6.0.0 --global)'
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
if ($wixExtensions -notmatch 'WixToolset.BootstrapperApplications.wixext') {
|
||||||
|
Write-Error 'Wix Bootstrapper extension missing. Please install it with: wix.exe extension add WixToolset.BootstrapperApplications.wixext/6.0.0 --global)'
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
$buildDir = Split-Path -Parent $PSCommandPath
|
$buildDir = Split-Path -Parent $PSCommandPath
|
||||||
$version = $(mvn -f $buildDir/../../pom.xml help:evaluate -Dexpression="project.version" -q -DforceStdout)
|
$version = $(mvn -f $buildDir/../../pom.xml help:evaluate -Dexpression="project.version" -q -DforceStdout)
|
||||||
$semVerNo = $version -replace '(\d+\.\d+\.\d+).*','$1'
|
$semVerNo = $version -replace '(\d+\.\d+\.\d+).*','$1'
|
||||||
$revisionNo = $(git rev-list --count HEAD)
|
$revisionNo = $(git rev-list --count HEAD)
|
||||||
|
|
||||||
Write-Output "`$version=$version"
|
Write-Host "`$version=$version"
|
||||||
Write-Output "`$semVerNo=$semVerNo"
|
Write-Host "`$semVerNo=$semVerNo"
|
||||||
Write-Output "`$revisionNo=$revisionNo"
|
Write-Host "`$revisionNo=$revisionNo"
|
||||||
Write-Output "`$buildDir=$buildDir"
|
Write-Host "`$buildDir=$buildDir"
|
||||||
Write-Output "`$Env:JAVA_HOME=$Env:JAVA_HOME"
|
Write-Host "`$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 "-Djavafx.platform=win"
|
&mvn -B -f $buildDir/../../pom.xml clean package -DskipTests -Pwin
|
||||||
Copy-Item "$buildDir\..\..\target\$MainJarGlob.jar" -Destination "$buildDir\..\..\target\mods"
|
Copy-Item "$buildDir\..\..\target\$MainJarGlob.jar" -Destination "$buildDir\..\..\target\mods"
|
||||||
|
|
||||||
# add runtime
|
# add runtime
|
||||||
@@ -50,43 +74,102 @@ if ($clean -and (Test-Path -Path $runtimeImagePath)) {
|
|||||||
Remove-Item -Path $runtimeImagePath -Force -Recurse
|
Remove-Item -Path $runtimeImagePath -Force -Recurse
|
||||||
}
|
}
|
||||||
|
|
||||||
## download jfx jmods
|
## download jfx jmods for X64, while they are part of the Arm64 JDK
|
||||||
$javaFxVersion='22.0.2'
|
$archCode = (Get-CimInstance Win32_Processor).Architecture
|
||||||
$javaFxJmodsUrl = "https://download2.gluonhq.com/openjfx/${javaFxVersion}/openjfx-${javaFxVersion}_windows-x64_bin-jmods.zip"
|
$archName = switch ($archCode) {
|
||||||
$javaFxJmodsSHA256 = 'f9376d200f5c5b85327d575c1ec1482e6455f19916577f7e2fc9be2f48bb29b6'
|
9 { "x64" }
|
||||||
$javaFxJmods = '.\resources\jfxJmods.zip'
|
12 { "ARM64" }
|
||||||
if( !(Test-Path -Path $javaFxJmods) ) {
|
default { "WMI Win32_Processor.Architecture code ($archCode)" }
|
||||||
Write-Output "Downloading ${javaFxJmodsUrl}..."
|
|
||||||
Invoke-WebRequest $javaFxJmodsUrl -OutFile $javaFxJmods # redirects are followed by default
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$jmodsChecksumActual = $(Get-FileHash -Path $javaFxJmods -Algorithm SHA256).Hash
|
switch ($archName) {
|
||||||
if( $jmodsChecksumActual -ne $javaFxJmodsSHA256 ) {
|
'ARM64' {
|
||||||
Write-Error "Checksum mismatch for jfxJmods.zip. Expected: $javaFxJmodsSHA256
|
$javafxBaseJmod = Join-Path $Env:JAVA_HOME "jmods\javafx.base.jmod"
|
||||||
, actual: $jmodsChecksumActual"
|
if (!(Test-Path $javafxBaseJmod)) {
|
||||||
exit 1;
|
Write-Error "JavaFX module not found in JDK. Please ensure a JDK with JavaFX (including jmods) is installed."
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
$jmodPaths = "$Env:JAVA_HOME/jmods"
|
||||||
|
}
|
||||||
|
'x64' {
|
||||||
|
$javaFxVersion='25'
|
||||||
|
$javaFxJmodsUrl = "https://download2.gluonhq.com/openjfx/${javaFxVersion}/openjfx-${javaFxVersion}_windows-x64_bin-jmods.zip"
|
||||||
|
$javaFxJmodsSHA256 = 'c8eb9fd039b00e0020cf6c3db8ed7876bf3ee4d27860aa697a247b83b8296ae7'
|
||||||
|
$javaFxJmods = '.\resources\jfxJmods.zip'
|
||||||
|
|
||||||
|
if( !(Test-Path -Path $javaFxJmods) ) {
|
||||||
|
Write-Host "Downloading ${javaFxJmodsUrl}..."
|
||||||
|
Invoke-WebRequest $javaFxJmodsUrl -OutFile $javaFxJmods # redirects are followed by default
|
||||||
|
}
|
||||||
|
|
||||||
|
$jmodsChecksumActual = $(Get-FileHash -Path $javaFxJmods -Algorithm SHA256).Hash.ToLower()
|
||||||
|
if( $jmodsChecksumActual -ne $javaFxJmodsSHA256 ) {
|
||||||
|
Write-Error "Checksum mismatch for jfxJmods.zip. Expected: $javaFxJmodsSHA256
|
||||||
|
, actual: $jmodsChecksumActual"
|
||||||
|
exit 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Expand-Archive -Path $javaFxJmods -Force -DestinationPath ".\resources\"
|
||||||
|
Remove-Item -Recurse -Force -Path ".\resources\javafx-jmods" -ErrorAction Ignore
|
||||||
|
Move-Item -Force -Path ".\resources\javafx-jmods-*" -Destination ".\resources\javafx-jmods" -ErrorAction Stop
|
||||||
|
|
||||||
|
$jmodPaths="$buildDir/resources/javafx-jmods";
|
||||||
|
}
|
||||||
|
default {
|
||||||
|
Write-Error "Unsupported architecture: $arch"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Expand-Archive -Path $javaFxJmods -Force -DestinationPath ".\resources\"
|
|
||||||
Remove-Item -Recurse -Force -Path ".\resources\javafx-jmods"
|
|
||||||
Move-Item -Force -Path ".\resources\javafx-jmods-*" -Destination ".\resources\javafx-jmods" -ErrorAction Stop
|
|
||||||
|
|
||||||
## create custom runtime
|
## create custom runtime
|
||||||
|
### check for JEP 493
|
||||||
|
if ((& "$Env:JAVA_HOME\bin\jlink" --help | Select-String -Pattern "Linking from run-time image enabled" -SimpleMatch | Measure-Object).Count -eq 0 ) {
|
||||||
|
$jmodPaths="$Env:JAVA_HOME/jmods;" + $jmodPaths;
|
||||||
|
}
|
||||||
|
|
||||||
|
### create 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 $jmodPaths `
|
||||||
--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 `
|
--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,jdk.crypto.cryptoki,jdk.crypto.ec,jdk.crypto.mscapi,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 "zip-0" #do not compress to have improved msi compression
|
--compress "zip-0" #do not compress and use msi compression
|
||||||
|
|
||||||
$appPath = ".\$AppName"
|
$appPath = ".\$AppName"
|
||||||
if ($clean -and (Test-Path -Path $appPath)) {
|
if ($clean -and (Test-Path -Path $appPath)) {
|
||||||
Remove-Item -Path $appPath -Force -Recurse
|
Remove-Item -Path $appPath -Force -Recurse
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$javaOptions = @(
|
||||||
|
"--java-options", "--enable-native-access=javafx.graphics,org.cryptomator.jfuse.win,org.cryptomator.integrations.win"
|
||||||
|
"--java-options", "-Xss5m"
|
||||||
|
"--java-options", "-Xmx256m"
|
||||||
|
"--java-options", "-Dcryptomator.appVersion=`"$semVerNo`""
|
||||||
|
"--java-options", "-Dfile.encoding=`"utf-8`""
|
||||||
|
"--java-options", "-Djava.net.useSystemProxies=true"
|
||||||
|
"--java-options", "-Dcryptomator.logDir=`"@{localappdata}/$AppName`""
|
||||||
|
"--java-options", "-XX:ErrorFile=`"C:/cryptomator/cryptomator_crash.log`""
|
||||||
|
"--java-options", "-Dcryptomator.pluginDir=`"@{appdata}/$AppName/Plugins`""
|
||||||
|
"--java-options", "-Dcryptomator.settingsPath=`"@{appdata}/$AppName/settings.json;@{userhome}/AppData/Roaming/$AppName/settings.json`""
|
||||||
|
"--java-options", "-Dcryptomator.ipcSocketPath=`"@{localappdata}/$AppName/ipc.socket`""
|
||||||
|
"--java-options", "-Dcryptomator.p12Path=`"@{appdata}/$AppName/key.p12;@{userhome}/AppData/Roaming/$AppName/key.p12`""
|
||||||
|
"--java-options", "-Dcryptomator.mountPointsDir=`"@{userhome}/$AppName`""
|
||||||
|
"--java-options", "-Dcryptomator.loopbackAlias=`"$LoopbackAlias`""
|
||||||
|
"--java-options", "-Dcryptomator.integrationsWin.autoStartShellLinkName=`"$AppName`""
|
||||||
|
"--java-options", "-Dcryptomator.integrationsWin.keychainPaths=`"@{appdata}/$AppName/keychain.json;@{userhome}/AppData/Roaming/$AppName/keychain.json`""
|
||||||
|
"--java-options", "-Dcryptomator.integrationsWin.windowsHelloKeychainPaths=`"@{appdata}/$AppName/windowsHelloKeychain.json`""
|
||||||
|
"--java-options", "-Dcryptomator.showTrayIcon=true"
|
||||||
|
"--java-options", "-Dcryptomator.buildNumber=`"msi-$revisionNo`""
|
||||||
|
"--java-options", "-Dcryptomator.disableUpdateCheck=false"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
# create app dir
|
# create app dir
|
||||||
& "$Env:JAVA_HOME\bin\jpackage" `
|
& "$Env:JAVA_HOME\bin\jpackage" `
|
||||||
--verbose `
|
--verbose `
|
||||||
@@ -99,30 +182,19 @@ if ($clean -and (Test-Path -Path $appPath)) {
|
|||||||
--name $AppName `
|
--name $AppName `
|
||||||
--vendor $Vendor `
|
--vendor $Vendor `
|
||||||
--copyright $copyright `
|
--copyright $copyright `
|
||||||
--java-options "--enable-preview" `
|
|
||||||
--java-options "--enable-native-access=org.cryptomator.jfuse.win,org.cryptomator.integrations.win" `
|
|
||||||
--java-options "-Xss5m" `
|
|
||||||
--java-options "-Xmx256m" `
|
|
||||||
--java-options "-Dcryptomator.appVersion=`"$semVerNo`"" `
|
|
||||||
--app-version "$semVerNo.$revisionNo" `
|
--app-version "$semVerNo.$revisionNo" `
|
||||||
--java-options "-Dfile.encoding=`"utf-8`"" `
|
|
||||||
--java-options "-Djava.net.useSystemProxies=true" `
|
|
||||||
--java-options "-Dcryptomator.logDir=`"@{localappdata}/$AppName`"" `
|
|
||||||
--java-options "-Dcryptomator.pluginDir=`"@{appdata}/$AppName/Plugins`"" `
|
|
||||||
--java-options "-Dcryptomator.settingsPath=`"@{appdata}/$AppName/settings.json;@{userhome}/AppData/Roaming/$AppName/settings.json`"" `
|
|
||||||
--java-options "-Dcryptomator.ipcSocketPath=`"@{localappdata}/$AppName/ipc.socket`"" `
|
|
||||||
--java-options "-Dcryptomator.p12Path=`"@{appdata}/$AppName/key.p12;@{userhome}/AppData/Roaming/$AppName/key.p12`"" `
|
|
||||||
--java-options "-Dcryptomator.mountPointsDir=`"@{userhome}/$AppName`"" `
|
|
||||||
--java-options "-Dcryptomator.loopbackAlias=`"$LoopbackAlias`"" `
|
|
||||||
--java-options "-Dcryptomator.integrationsWin.autoStartShellLinkName=`"$AppName`"" `
|
|
||||||
--java-options "-Dcryptomator.integrationsWin.keychainPaths=`"@{appdata}/$AppName/keychain.json;@{userhome}/AppData/Roaming/$AppName/keychain.json`"" `
|
|
||||||
--java-options "-Dcryptomator.showTrayIcon=true" `
|
|
||||||
--java-options "-Dcryptomator.buildNumber=`"msi-$revisionNo`"" `
|
|
||||||
--resource-dir resources `
|
--resource-dir resources `
|
||||||
--icon resources/$AppName.ico
|
--icon resources/$AppName.ico `
|
||||||
|
--add-launcher "${AppName} (Debug)=$buildDir\debug-launcher.properties" `
|
||||||
|
@javaOptions
|
||||||
|
|
||||||
|
if ($LASTEXITCODE -ne 0) {
|
||||||
|
Write-Error "jpackage Appimage failed with exit code $LASTEXITCODE"
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
#Create RTF license for msi
|
#Create RTF license for msi
|
||||||
&mvn -B -f $buildDir/../../pom.xml license:add-third-party "-Djavafx.platform=win" `
|
&mvn -B -f $buildDir/../../pom.xml license:add-third-party `
|
||||||
"-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\" `
|
||||||
@@ -134,14 +206,7 @@ if ($clean -and (Test-Path -Path $appPath)) {
|
|||||||
# patch app dir
|
# patch app dir
|
||||||
Copy-Item "contrib\*" -Destination "$AppName"
|
Copy-Item "contrib\*" -Destination "$AppName"
|
||||||
attrib -r "$AppName\$AppName.exe"
|
attrib -r "$AppName\$AppName.exe"
|
||||||
# patch batch script to set hostfile
|
attrib -r "$AppName\${AppName} (Debug).exe"
|
||||||
$webDAVPatcher = "$AppName\patchWebDAV.bat"
|
|
||||||
try {
|
|
||||||
(Get-Content $webDAVPatcher ) -replace '::REPLACE ME', "SET LOOPBACK_ALIAS=`"$LoopbackAlias`"" | Set-Content $webDAVPatcher
|
|
||||||
} catch {
|
|
||||||
Write-Host "Failed to set LOOPBACK_ALIAS for patchWebDAV.bat"
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
# create .msi
|
# create .msi
|
||||||
$Env:JP_WIXWIZARD_RESOURCES = "$buildDir\resources"
|
$Env:JP_WIXWIZARD_RESOURCES = "$buildDir\resources"
|
||||||
@@ -166,8 +231,13 @@ $Env:JP_WIXHELPER_DIR = "."
|
|||||||
--about-url $AboutUrl `
|
--about-url $AboutUrl `
|
||||||
--file-associations resources/FAvaultFile.properties
|
--file-associations resources/FAvaultFile.properties
|
||||||
|
|
||||||
|
if ($LASTEXITCODE -ne 0) {
|
||||||
|
Write-Error "jpackage MSI failed with exit code $LASTEXITCODE"
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
#Create RTF license for bundle
|
#Create RTF license for bundle
|
||||||
&mvn -B -f $buildDir/../../pom.xml license:add-third-party "-Djavafx.platform=win" `
|
&mvn -B -f $buildDir/../../pom.xml license:add-third-party `
|
||||||
"-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\" `
|
||||||
@@ -177,24 +247,54 @@ $Env:JP_WIXHELPER_DIR = "."
|
|||||||
"-Dlicense.licenseMergesUrl=file:///$buildDir/../../license/merges"
|
"-Dlicense.licenseMergesUrl=file:///$buildDir/../../license/merges"
|
||||||
|
|
||||||
# download Winfsp
|
# download Winfsp
|
||||||
$winfspMsiUrl= 'https://github.com/winfsp/winfsp/releases/download/v2.0/winfsp-2.0.23075.msi'
|
$winfspMsiUrl= 'https://github.com/winfsp/winfsp/releases/download/v2.1/winfsp-2.1.25156.msi'
|
||||||
Write-Output "Downloading ${winfspMsiUrl}..."
|
$winfspMsiHash = '073A70E00F77423E34BED98B86E600DEF93393BA5822204FAC57A29324DB9F7A'
|
||||||
|
Write-Host "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
|
||||||
|
$computedHash = $(Get-FileHash -Path '.\bundle\resources\winfsp.msi' -Algorithm SHA256).Hash
|
||||||
|
if (! $computedHash.Equals($winfspMsiHash)) {
|
||||||
|
Write-Error -Category InvalidData -CategoryActivity "Data integrity check failed" -Message @"
|
||||||
|
Downloaded Winfsp Installer does not match stored SHA256 checksum.
|
||||||
|
Expected: $winfspMsiHash
|
||||||
|
Actual: $computedHash
|
||||||
|
"@
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
# download legacy-winfsp uninstaller
|
# download legacy-winfsp uninstaller
|
||||||
$winfspUninstaller= 'https://github.com/cryptomator/winfsp-uninstaller/releases/latest/download/winfsp-uninstaller.exe'
|
$winfspUninstaller= 'https://github.com/cryptomator/winfsp-uninstaller/releases/latest/download/winfsp-uninstaller.exe'
|
||||||
Write-Output "Downloading ${winfspUninstaller}..."
|
Write-Host "Downloading ${winfspUninstaller}..."
|
||||||
Invoke-WebRequest $winfspUninstaller -OutFile ".\bundle\resources\winfsp-uninstaller.exe" # redirects are followed by default
|
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" -Force
|
||||||
|
|
||||||
# create bundle including winfsp
|
# create bundle including winfsp
|
||||||
& "$env:WIX\bin\candle.exe" .\bundle\bundleWithWinfsp.wxs -ext WixBalExtension -ext WixUtilextension -out bundle\ `
|
& wix build `
|
||||||
-dBundleVersion="$semVerNo.$revisionNo" `
|
-define BundleName="$AppName" `
|
||||||
-dBundleVendor="$Vendor" `
|
-define BundleVersion="$semVerNo.$revisionNo" `
|
||||||
-dBundleCopyright="$copyright" `
|
-define BundleVendor="$Vendor" `
|
||||||
-dAboutUrl="$AboutUrl" `
|
-define BundleCopyright="$copyright" `
|
||||||
-dHelpUrl="$HelpUrl" `
|
-define AboutUrl="$AboutUrl" `
|
||||||
-dUpdateUrl="$UpdateUrl"
|
-define HelpUrl="$HelpUrl" `
|
||||||
& "$env:WIX\bin\light.exe" -b . .\bundle\BundlewithWinfsp.wixobj -ext WixBalExtension -ext WixUtilextension -out installer\$AppName-Installer.exe
|
-define UpdateUrl="$UpdateUrl" `
|
||||||
|
-ext "WixToolset.Util.wixext" `
|
||||||
|
-ext "WixToolset.BootstrapperApplications.wixext" `
|
||||||
|
.\bundle\bundleWithWinfsp.wxs `
|
||||||
|
-out "installer\$AppName-Installer.exe"
|
||||||
|
|
||||||
|
Write-Host "Created EXE installer .\installer\$AppName-Installer.exe"
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
# ============================
|
||||||
|
# Script Execution Starts Here
|
||||||
|
# ============================
|
||||||
|
if ($clean) {
|
||||||
|
Write-Host "Cleaning up previous build artifacts..."
|
||||||
|
Remove-Item -Path ".\runtime" -Force -Recurse -ErrorAction Ignore -ProgressAction SilentlyContinue
|
||||||
|
Remove-Item -Path ".\$AppName" -Force -Recurse -ErrorAction Ignore -ProgressAction SilentlyContinue
|
||||||
|
Remove-Item -Path ".\installer" -Force -Recurse -ErrorAction Ignore -ProgressAction SilentlyContinue
|
||||||
|
}
|
||||||
|
return Main
|
||||||
|
|
||||||
|
|||||||
Vendored
+45
-59
@@ -1,66 +1,52 @@
|
|||||||
<?xml version="1.0"?>
|
<!-- For Built in variables, see https://wixtoolset.org/docs/tools/burn/builtin-variables/-->
|
||||||
|
<ns0:Wix xmlns:ns0="http://wixtoolset.org/schemas/v4/wxs" xmlns:bal="http://wixtoolset.org/schemas/v4/wxs/bal" xmlns:util="http://wixtoolset.org/schemas/v4/wxs/util">
|
||||||
<!-- For Built in variables, see https://wixtoolset.org/docs/tools/burn/builtin-variables/-->
|
<ns0:Bundle Name="$(var.BundleName)"
|
||||||
<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">
|
UpgradeCode="29eea626-2e5b-4449-b5f8-4602925ddf7b"
|
||||||
<!-- see https://wixtoolset.org/documentation/manual/v3/xsd/wix/bundle.html-->
|
Version="$(var.BundleVersion)"
|
||||||
<!-- Attributes explicitly not used:
|
Manufacturer="$(var.BundleVendor)"
|
||||||
Condition - the single msi files have their own install conditions, no need to copy them here
|
AboutUrl="$(var.AboutUrl)"
|
||||||
-->
|
HelpUrl="$(var.HelpUrl)"
|
||||||
|
UpdateUrl="$(var.UpdateUrl)"
|
||||||
<Bundle Name="Cryptomator" UpgradeCode="29eea626-2e5b-4449-b5f8-4602925ddf7b" Version="$(var.BundleVersion)" Manufacturer="$(var.BundleVendor)"
|
Copyright="$(var.BundleCopyright)"
|
||||||
AboutUrl="$(var.AboutUrl)" HelpUrl="$(var.HelpUrl)" UpdateUrl="$(var.UpdateUrl)" Copyright="$(var.BundleCopyright)" IconSourceFile="bundle\resources\Cryptomator.ico">
|
IconSourceFile="bundle\resources\Cryptomator.ico">
|
||||||
|
|
||||||
<!-- detect outdated WinFsp installations -->
|
<!-- detect outdated WinFsp installations -->
|
||||||
<util:ProductSearch
|
<util:ProductSearch Variable="InstalledLegacyWinFspVersion" Result="version" UpgradeCode="82F812D9-4083-4EF1-8BC8-0F1EDA05B46B" />
|
||||||
Variable="InstalledLegacyWinFspVersion"
|
|
||||||
Result="version"
|
|
||||||
UpgradeCode="82F812D9-4083-4EF1-8BC8-0F1EDA05B46B"/>
|
|
||||||
|
|
||||||
<!-- for definition of the standard themes, see https://github.com/wixtoolset/wix3/blob/master/src/ext/BalExtension/wixstdba/Resources/-->
|
<ns0:BootstrapperApplication>
|
||||||
<BootstrapperApplicationRef Id="WixStandardBootstrapperApplication.RtfLargeLicense">
|
<bal:WixStandardBootstrapperApplication LicenseFile="bundle\resources\license.rtf" ShowVersion="yes"
|
||||||
<!-- see https://wixtoolset.org/documentation/manual/v3/xsd/bal/wixstandardbootstrapperapplication.html -->
|
SuppressOptionsUI="yes"
|
||||||
<!-- Possible Attributes: LaunchTarget -->
|
Theme="rtfLargeLicense"
|
||||||
<bal:WixStandardBootstrapperApplication
|
ThemeFile="bundle\resources\customBootstrapperTheme.xml"
|
||||||
LicenseFile="bundle\resources\license.rtf"
|
LocalizationFile="bundle\resources\customBootstrapperTheme.wxl"
|
||||||
ShowVersion="yes"
|
LogoSideFile="bundle\resources\logoSide.png"
|
||||||
SuppressOptionsUI="yes"
|
LogoFile="bundle\resources\logo.png"
|
||||||
ThemeFile="bundle\customBootstrapperTheme.xml"
|
LaunchTarget="[ProgramFiles64Folder]\$(var.BundleName)\$(var.BundleName).exe" />
|
||||||
LocalizationFile="bundle\customBootstrapperTheme.wxl"
|
<ns0:Payload SourceFile="bundle\resources\logoSide.png"/>
|
||||||
LogoFile="bundle\resources\logo.png"/>
|
<!-- Required due to https://github.com/wixtoolset/issues/issues/8104 -->
|
||||||
<Payload SourceFile="bundle\resources\logoSide.png" />
|
<ns0:Payload Name="Cryptobot.ico" SourceFile="bundle\resources\Cryptomator.ico"/>
|
||||||
</BootstrapperApplicationRef>
|
</ns0:BootstrapperApplication>
|
||||||
|
|
||||||
<Chain>
|
<ns0:Variable Name="DISABLEUPDATECHECK" bal:Overridable="yes" Type="string" Value="false"/>
|
||||||
<ExePackage Cache="yes" PerMachine="yes" Permanent="no"
|
|
||||||
SourceFile="resources\winfsp-uninstaller.exe"
|
<ns0:Chain>
|
||||||
DisplayName="Removing outdated WinFsp Driver"
|
<ns0:ExePackage Cache="keep" PerMachine="yes" Permanent="no" SourceFile="bundle\resources\winfsp-uninstaller.exe" DisplayName="Removing outdated WinFsp Driver" Description="Executable to remove old winfsp" DetectCondition="false" InstallCondition="(InstalledLegacyWinFspVersion <> v0.0.0.0) AND ((WixBundleAction = 7) OR (WixBundleAction = 5))" UninstallArguments="">
|
||||||
Description="Executable to remove old winfsp"
|
<ns0:CommandLine Condition="WixBundleUILevel <= 3" InstallArgument="-q -l "[WixBundleLog].winfsp-uninstaller.log"" RepairArgument="-q" UninstallArgument="-s" />
|
||||||
DetectCondition="false"
|
|
||||||
InstallCondition="(InstalledLegacyWinFspVersion <> v0.0.0.0) AND ((WixBundleAction = 7) OR (WixBundleAction = 5))">
|
|
||||||
<CommandLine Condition="WixBundleUILevel <= 3" InstallArgument="-q -l "[WixBundleLog].winfsp-uninstaller.log"" RepairArgument="-q" UninstallArgument="-s" />
|
|
||||||
<!-- XML allows line breaks in attributes, hence keep the line breaks here -->
|
<!-- XML allows line breaks in attributes, hence keep the line breaks here -->
|
||||||
<CommandLine Condition="WixBundleUILevel > 3" InstallArgument="-l "[WixBundleLog].winfsp-uninstaller.log" -t "Cryptomator Installer" -m "Cryptomator requires a newer version of the WinFsp driver. The installer will now uninstall WinFsp, possibly reboot, and afterwards proceed with the installation.
|
<ns0:CommandLine Condition="WixBundleUILevel > 3" InstallArgument="-l "[WixBundleLog].winfsp-uninstaller.log" -t "Cryptomator Installer" -m "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?"" RepairArgument="-q" UninstallArgument="-s" />
|
Do you want to continue?"" RepairArgument="-q" UninstallArgument="-s" />
|
||||||
<ExitCode Behavior="success" Value="0"/>
|
<ns0:ExitCode Behavior="success" Value="0" />
|
||||||
<ExitCode Behavior="success" Value="1"/>
|
<ns0:ExitCode Behavior="success" Value="1" />
|
||||||
<ExitCode Behavior="error" Value="2"/>
|
<ns0:ExitCode Behavior="error" Value="2" />
|
||||||
<ExitCode Behavior="error" Value="3"/>
|
<ns0:ExitCode Behavior="error" Value="3" />
|
||||||
<ExitCode Behavior="forceReboot" Value="4"/>
|
<ns0:ExitCode Behavior="forceReboot" Value="4" />
|
||||||
<ExitCode Behavior="success" Value="5"/>
|
<ns0:ExitCode Behavior="success" Value="5" />
|
||||||
</ExePackage>
|
</ns0:ExePackage>
|
||||||
<!-- see https://wixtoolset.org/documentation/manual/v3/xsd/wix/msipackage.html-->
|
<ns0:MsiPackage SourceFile="bundle\resources\Cryptomator.msi" CacheId="cryptomator-bundle-cryptomator" Visible="no">
|
||||||
<MsiPackage
|
<ns0:MsiProperty Name="DISABLEUPDATECHECK" Value="[DISABLEUPDATECHECK]"/>
|
||||||
SourceFile="resources\Cryptomator.msi"
|
</ns0:MsiPackage>
|
||||||
CacheId="cryptomator-bundle-cryptomator"
|
<ns0:MsiPackage SourceFile="bundle\resources\winfsp.msi" CacheId="cryptomator-bundle-winfsp" Visible="yes" Permanent="yes" />
|
||||||
DisplayInternalUI="no"
|
</ns0:Chain>
|
||||||
Visible="no"/>
|
</ns0:Bundle>
|
||||||
<MsiPackage
|
</ns0:Wix>
|
||||||
SourceFile="resources\winfsp.msi"
|
|
||||||
CacheId="cryptomator-bundle-winfsp"
|
|
||||||
Visible="yes"
|
|
||||||
DisplayInternalUI="no"
|
|
||||||
Permanent="yes"/>
|
|
||||||
</Chain>
|
|
||||||
</Bundle>
|
|
||||||
</Wix>
|
|
||||||
-64
@@ -1,64 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. -->
|
|
||||||
|
|
||||||
|
|
||||||
<WixLocalization Culture="en-us" Language="1033" xmlns="http://schemas.microsoft.com/wix/2006/localization">
|
|
||||||
<String Id="Caption">[WixBundleName] Setup</String>
|
|
||||||
<String Id="Title">[WixBundleName]</String>
|
|
||||||
<String Id="InstallHeader">Welcome</String>
|
|
||||||
<String Id="InstallMessage">This Setup will install [WixBundleName] and additional dependencies on your computer.</String>
|
|
||||||
<String Id="InstallVersion">Version [WixBundleVersion]</String>
|
|
||||||
<String Id="ConfirmCancelMessage">Are you sure you want to cancel?</String>
|
|
||||||
<String Id="ExecuteUpgradeRelatedBundleMessage">Previous version</String>
|
|
||||||
<String Id="HelpHeader">Setup Help</String>
|
|
||||||
<String Id="HelpText">/install | /repair | /uninstall | /layout [directory] - installs, repairs, uninstalls or
|
|
||||||
creates a complete local copy of the bundle in directory. Install is the default.
|
|
||||||
|
|
||||||
/passive | /quiet - displays minimal UI with no prompts or displays no UI and
|
|
||||||
no prompts. By default UI and all prompts are displayed.
|
|
||||||
|
|
||||||
/norestart - suppress any attempts to restart. By default UI will prompt before restart.
|
|
||||||
/log log.txt - logs to a specific file. By default a log file is created in %TEMP%.</String>
|
|
||||||
<String Id="HelpCloseButton">&Close</String>
|
|
||||||
<String Id="InstallLicenseLinkText">[WixBundleName] <a href="#">license terms</a>.</String>
|
|
||||||
<String Id="InstallAcceptCheckbox">I &agree to the license terms and conditions</String>
|
|
||||||
<String Id="InstallOptionsButton">&Options</String>
|
|
||||||
<String Id="InstallInstallButton">&Install</String>
|
|
||||||
<String Id="InstallCloseButton">&Close</String>
|
|
||||||
<String Id="OptionsHeader">Setup Options</String>
|
|
||||||
<String Id="OptionsLocationLabel">Install location:</String>
|
|
||||||
<String Id="OptionsBrowseButton">&Browse</String>
|
|
||||||
<String Id="OptionsOkButton">&OK</String>
|
|
||||||
<String Id="OptionsCancelButton">&Cancel</String>
|
|
||||||
<String Id="ProgressHeader">Setup Progress</String>
|
|
||||||
<String Id="ProgressLabel">Processing:</String>
|
|
||||||
<String Id="OverallProgressPackageText">Initializing...</String>
|
|
||||||
<String Id="ProgressCancelButton">&Cancel</String>
|
|
||||||
<String Id="ModifyHeader">Modify Setup</String>
|
|
||||||
<String Id="ModifyRepairButton">&Repair</String>
|
|
||||||
<String Id="ModifyUninstallButton">&Uninstall</String>
|
|
||||||
<String Id="ModifyCloseButton">&Close</String>
|
|
||||||
<String Id="SuccessRepairHeader">Repair Successfully Completed</String>
|
|
||||||
<String Id="SuccessUninstallHeader">Uninstall Successfully Completed</String>
|
|
||||||
<String Id="SuccessInstallHeader">Installation Successfully Completed</String>
|
|
||||||
<String Id="SuccessHeader">Setup Successful</String>
|
|
||||||
<String Id="SuccessLaunchButton">&Launch</String>
|
|
||||||
<String Id="SuccessRestartText">You must restart your computer before you can use the software.</String>
|
|
||||||
<String Id="SuccessRestartButton">&Restart</String>
|
|
||||||
<String Id="SuccessCloseButton">&Close</String>
|
|
||||||
<String Id="FailureHeader">Setup Failed</String>
|
|
||||||
<String Id="FailureInstallHeader">Setup Failed</String>
|
|
||||||
<String Id="FailureUninstallHeader">Uninstall Failed</String>
|
|
||||||
<String Id="FailureRepairHeader">Repair Failed</String>
|
|
||||||
<String Id="FailureHyperlinkLogText">One or more issues caused the setup to fail. Please fix the issues and then retry setup. For more information see the <a href="#">log file</a>.</String>
|
|
||||||
<String Id="FailureRestartText">You must restart your computer to complete the rollback of the software.</String>
|
|
||||||
<String Id="FailureRestartButton">&Restart</String>
|
|
||||||
<String Id="FailureCloseButton">&Close</String>
|
|
||||||
<String Id="FilesInUseHeader">Files In Use</String>
|
|
||||||
<String Id="FilesInUseLabel">The following applications are using files that need to be updated:</String>
|
|
||||||
<String Id="FilesInUseCloseRadioButton">Close the &applications and attempt to restart them.</String>
|
|
||||||
<String Id="FilesInUseDontCloseRadioButton">&Do not close applications. A reboot will be required.</String>
|
|
||||||
<String Id="FilesInUseOkButton">&OK</String>
|
|
||||||
<String Id="FilesInUseCancelButton">&Cancel</String>
|
|
||||||
<String Id="ErrorFailNoActionReboot">No action was taken as a system reboot is required.</String>
|
|
||||||
</WixLocalization>
|
|
||||||
-91
@@ -1,91 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. -->
|
|
||||||
<!-- adjusted theme based on https://github.com/wixtoolset/wix3/blob/master/src/ext/BalExtension/wixstdba/Resources/HyperlinkSidebarTheme.xml -->
|
|
||||||
|
|
||||||
|
|
||||||
<Theme xmlns="http://wixtoolset.org/schemas/thmutil/2010">
|
|
||||||
<Window Width="600" Height="450" HexStyle="100a0000" FontId="0">#(loc.Caption)</Window>
|
|
||||||
<Font Id="0" Height="-12" Weight="500" Foreground="000000" Background="FFFFFF">Segoe UI</Font>
|
|
||||||
<Font Id="1" Height="-24" Weight="500" Foreground="000000">Segoe UI</Font>
|
|
||||||
<Font Id="2" Height="-22" Weight="500" Foreground="666666">Segoe UI</Font>
|
|
||||||
<Font Id="3" Height="-12" Weight="500" Foreground="000000" Background="FFFFFF">Segoe UI</Font>
|
|
||||||
<Font Id="4" Height="-12" Weight="500" Foreground="ff0000" Background="FFFFFF" Underline="yes">Segoe UI</Font>
|
|
||||||
<Font Id="5" Height="-12" Weight="700" Foreground="000000" Background="FFFFFF">Segoe UI</Font>
|
|
||||||
|
|
||||||
<Image X="11" Y="11" Width="64" Height="64" ImageFile="logo.png" />
|
|
||||||
<Text X="80" Y="11" Width="-11" Height="64" FontId="1" DisablePrefix="yes">#(loc.Title)</Text>
|
|
||||||
|
|
||||||
<Page Name="Help">
|
|
||||||
<Image X="11" Y="11" Width="64" Height="64" ImageFile="logo.png" />
|
|
||||||
<Text X="80" Y="11" Width="-11" Height="64" FontId="1" DisablePrefix="yes">#(loc.Title)</Text>
|
|
||||||
<Text X="11" Y="80" Width="-11" Height="30" FontId="2" DisablePrefix="yes">#(loc.HelpHeader)</Text>
|
|
||||||
<Text X="11" Y="112" Width="-11" Height="-35" FontId="3" DisablePrefix="yes">#(loc.HelpText)</Text>
|
|
||||||
<Button Name="HelpCancelButton" X="-11" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">#(loc.HelpCloseButton)</Button>
|
|
||||||
</Page>
|
|
||||||
<Page Name="Install">
|
|
||||||
<Text X="185" Y="11" Width="-11" Height="32" FontId="1" DisablePrefix="yes">#(loc.Title)</Text>
|
|
||||||
<Image X="11" Y="11" Width="165" Height="400" ImageFile="logoside.png"/>
|
|
||||||
<Text X="185" Y="50" Width="-11" Height="32" FontId="2" DisablePrefix="yes">#(loc.InstallHeader)</Text>
|
|
||||||
<Text X="185" Y="91" Width="-11" Height="64" FontId="3" DisablePrefix="yes">#(loc.InstallMessage)</Text>
|
|
||||||
<Richedit Name="EulaRichedit" X="185" Y="131" Width="-12" Height="-65" HexStyle="0x00800000" TabStop="yes" FontId="0" />
|
|
||||||
<Checkbox Name="EulaAcceptCheckbox" X="185" Y="-46" Width="-11" Height="17" TabStop="yes" FontId="3" HideWhenDisabled="yes">#(loc.InstallAcceptCheckbox)</Checkbox>
|
|
||||||
<Text Name="InstallVersion" X="185" Y="-11" Width="-11" Height="17" FontId="3" DisablePrefix="yes" HideWhenDisabled="yes">#(loc.InstallVersion)</Text>
|
|
||||||
<Button Name="InstallButton" X="-91" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">#(loc.InstallInstallButton)</Button>
|
|
||||||
<Button Name="WelcomeCancelButton" X="-11" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">#(loc.InstallCloseButton)</Button>
|
|
||||||
</Page>
|
|
||||||
<Page Name="FilesInUse">
|
|
||||||
<Image X="11" Y="11" Width="64" Height="64" ImageFile="logo.png" />
|
|
||||||
<Text X="80" Y="11" Width="-11" Height="64" FontId="1" DisablePrefix="yes">#(loc.Title)</Text>
|
|
||||||
<Text X="11" Y="80" Width="-11" Height="30" FontId="2" DisablePrefix="yes">#(loc.FilesInUseHeader)</Text>
|
|
||||||
<Text X="11" Y="121" Width="-11" Height="34" FontId="3" DisablePrefix="yes">#(loc.FilesInUseLabel)</Text>
|
|
||||||
<Text Name="FilesInUseText" X="11" Y="150" Width="-11" Height="-86" FontId="3" DisablePrefix="yes" HexStyle="0x0000000C">A</Text>
|
|
||||||
|
|
||||||
<Button Name="FilesInUseCloseRadioButton" X="11" Y="-60" Width="-11" Height="23" TabStop="yes" FontId="0" HideWhenDisabled="yes" HexStyle="0x000009">#(loc.FilesInUseCloseRadioButton)</Button>
|
|
||||||
<Button Name="FilesInUseDontCloseRadioButton" X="11" Y="-40" Width="-11" Height="23" TabStop="yes" FontId="0" HideWhenDisabled="yes" HexStyle="0x000009">#(loc.FilesInUseDontCloseRadioButton)</Button>
|
|
||||||
|
|
||||||
<Button Name="FilesInUseOkButton" X="-91" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0" HideWhenDisabled="yes">#(loc.FilesInUseOkButton)</Button>
|
|
||||||
<Button Name="FilesInUseCancelButton" X="-11" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">#(loc.FilesInUseCancelButton)</Button>
|
|
||||||
</Page>
|
|
||||||
<Page Name="Progress">
|
|
||||||
<Text X="80" Y="11" Width="-11" Height="32" FontId="1" DisablePrefix="yes">#(loc.Title)</Text>
|
|
||||||
<Image X="11" Y="11" Width="64" Height="64" ImageFile="logo.png"/>
|
|
||||||
<Text X="11" Y="80" Width="-11" Height="30" FontId="2" DisablePrefix="yes">#(loc.ProgressHeader)</Text>
|
|
||||||
<Text X="11" Y="141" Width="70" Height="17" FontId="3" DisablePrefix="yes">#(loc.ProgressLabel)</Text>
|
|
||||||
<Text Name="OverallProgressPackageText" X="85" Y="141" Width="-11" Height="17" FontId="3" DisablePrefix="yes">#(loc.OverallProgressPackageText)</Text>
|
|
||||||
<Progressbar Name="OverallCalculatedProgressbar" X="11" Y="163" Width="-11" Height="20" />
|
|
||||||
<Button Name="ProgressCancelButton" X="-11" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">#(loc.ProgressCancelButton)</Button>
|
|
||||||
</Page>
|
|
||||||
<Page Name="Modify">
|
|
||||||
<Image X="11" Y="11" Width="64" Height="64" ImageFile="logo.png" />
|
|
||||||
<Text X="80" Y="11" Width="-11" Height="64" FontId="1" DisablePrefix="yes">#(loc.Title)</Text>
|
|
||||||
<Text X="11" Y="80" Width="-11" Height="30" FontId="2" DisablePrefix="yes">#(loc.ModifyHeader)</Text>
|
|
||||||
<Button Name="RepairButton" X="-171" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0" HideWhenDisabled="yes">#(loc.ModifyRepairButton)</Button>
|
|
||||||
<Button Name="UninstallButton" X="-91" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">#(loc.ModifyUninstallButton)</Button>
|
|
||||||
<Button Name="ModifyCancelButton" X="-11" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">#(loc.ModifyCloseButton)</Button>
|
|
||||||
</Page>
|
|
||||||
<Page Name="Success">
|
|
||||||
<Text X="185" Y="11" Width="-11" Height="32" FontId="1" DisablePrefix="yes">#(loc.Title)</Text>
|
|
||||||
<Image X="11" Y="11" Width="165" Height="400" ImageFile="logoside.png"/>
|
|
||||||
<Text Name="SuccessHeader" X="185" Y="50" Width="-11" Height="30" FontId="2" HideWhenDisabled="yes" DisablePrefix="yes">#(loc.SuccessHeader)</Text>
|
|
||||||
<Text Name="SuccessInstallHeader" X="185" Y="50" Width="-11" Height="100" FontId="2" HideWhenDisabled="yes" DisablePrefix="yes">#(loc.SuccessInstallHeader)</Text>
|
|
||||||
<Text Name="SuccessRepairHeader" X="185" Y="50" Width="-11" Height="100" FontId="2" HideWhenDisabled="yes" DisablePrefix="yes">#(loc.SuccessRepairHeader)</Text>
|
|
||||||
<Text Name="SuccessUninstallHeader" X="185" Y="50" Width="-11" Height="30" FontId="2" HideWhenDisabled="yes" DisablePrefix="yes">#(loc.SuccessUninstallHeader)</Text>
|
|
||||||
<Button Name="LaunchButton" X="-91" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0" HideWhenDisabled="yes">#(loc.SuccessLaunchButton)</Button>
|
|
||||||
<Text Name="SuccessRestartText" X="185" Y="-51" Width="400" Height="34" FontId="3" HideWhenDisabled="yes" DisablePrefix="yes">#(loc.SuccessRestartText)</Text>
|
|
||||||
<Button Name="SuccessRestartButton" X="-91" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0" HideWhenDisabled="yes">#(loc.SuccessRestartButton)</Button>
|
|
||||||
<Button Name="SuccessCancelButton" X="-11" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">#(loc.SuccessCloseButton)</Button>
|
|
||||||
</Page>
|
|
||||||
<Page Name="Failure">
|
|
||||||
<Text X="185" Y="11" Width="-11" Height="32" FontId="1" DisablePrefix="yes">#(loc.Title)</Text>
|
|
||||||
<Image X="11" Y="11" Width="165" Height="400" ImageFile="logoside.png"/>
|
|
||||||
<Text Name="FailureHeader" X="185" Y="50" Width="-11" Height="30" FontId="2" HideWhenDisabled="yes" DisablePrefix="yes">#(loc.FailureHeader)</Text>
|
|
||||||
<Text Name="FailureInstallHeader" X="185" Y="50" Width="-11" Height="30" FontId="2" HideWhenDisabled="yes" DisablePrefix="yes">#(loc.FailureInstallHeader)</Text>
|
|
||||||
<Text Name="FailureUninstallHeader" X="185" Y="50" Width="-11" Height="30" FontId="2" HideWhenDisabled="yes" DisablePrefix="yes">#(loc.FailureUninstallHeader)</Text>
|
|
||||||
<Text Name="FailureRepairHeader" X="185" Y="50" Width="-11" Height="30" FontId="2" HideWhenDisabled="yes" DisablePrefix="yes">#(loc.FailureRepairHeader)</Text>
|
|
||||||
<Hypertext Name="FailureLogFileLink" X="185" Y="121" Width="-11" Height="68" FontId="3" TabStop="yes" HideWhenDisabled="yes">#(loc.FailureHyperlinkLogText)</Hypertext>
|
|
||||||
<Hypertext Name="FailureMessageText" X="185" Y="-80" Width="-11" Height="140" FontId="5" TabStop="yes" HideWhenDisabled="yes" />
|
|
||||||
<Text Name="FailureRestartText" X="185" Y="-57" Width="-11" Height="80" FontId="3" HideWhenDisabled="yes" DisablePrefix="yes">#(loc.FailureRestartText)</Text>
|
|
||||||
<Button Name="FailureRestartButton" X="-91" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0" HideWhenDisabled="yes">#(loc.FailureRestartButton)</Button>
|
|
||||||
<Button Name="FailureCloseButton" X="-11" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">#(loc.FailureCloseButton)</Button>
|
|
||||||
</Page>
|
|
||||||
</Theme>
|
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
<!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. -->
|
||||||
|
|
||||||
|
|
||||||
|
<WixLocalization Culture="en-us" Language="1033" xmlns="http://wixtoolset.org/schemas/v4/wxl">
|
||||||
|
<String Id="Caption" Value="[WixBundleName] Setup" />
|
||||||
|
<String Id="Title" Value="[WixBundleName]" />
|
||||||
|
<String Id="InstallHeader" Value="Welcome" />
|
||||||
|
<String Id="InstallMessage" Value="Setup will install [WixBundleName] on your computer." />
|
||||||
|
<String Id="InstallVersion" Value="Version [WixBundleVersion]" />
|
||||||
|
<String Id="CheckingForUpdatesLabel" Value="Checking for updates" />
|
||||||
|
<String Id="UpdateButton" Value="&Update to version [WixStdBAUpdateAvailable]" />
|
||||||
|
<String Id="InstallVersion" Value="Version [WixBundleVersion]" />
|
||||||
|
<String Id="ConfirmCancelMessage" Value="Are you sure you want to cancel?" />
|
||||||
|
<String Id="ExecuteUpgradeRelatedBundleMessage" Value="Previous version" />
|
||||||
|
<String Id="HelpHeader" Value="Setup Help" />
|
||||||
|
<String Id="HelpText" Value="/install | /repair | /uninstall | /layout [directory] - installs, repairs, uninstalls or
 creates a complete local copy of the bundle in directory. Install is the default.

/passive | /quiet - displays minimal UI with no prompts or displays no UI and
 no prompts. By default UI and all prompts are displayed.

/norestart - suppress any attempts to restart. By default UI will prompt before restart.
/log log.txt - logs to a specific file. By default a log file is created in %TEMP%." />
|
||||||
|
<String Id="HelpCloseButton" Value="&Close" />
|
||||||
|
<String Id="InstallAcceptCheckbox" Value="I &agree to the license terms and conditions" />
|
||||||
|
<String Id="InstallOptionsButton" Value="&Options" />
|
||||||
|
<String Id="InstallInstallButton" Value="&Install" />
|
||||||
|
<String Id="InstallCancelButton" Value="&Cancel" />
|
||||||
|
<String Id="OptionsHeader" Value="Setup Options" />
|
||||||
|
<String Id="OptionsLocationLabel" Value="Install location:" />
|
||||||
|
<String Id="OptionsBrowseButton" Value="&Browse" />
|
||||||
|
<String Id="OptionsOkButton" Value="&OK" />
|
||||||
|
<String Id="OptionsCancelButton" Value="&Cancel" />
|
||||||
|
<String Id="ProgressHeader" Value="Setup Progress" />
|
||||||
|
<String Id="ProgressLabel" Value="Processing:" />
|
||||||
|
<String Id="OverallProgressPackageText" Value="Initializing..." />
|
||||||
|
<String Id="ProgressCancelButton" Value="&Cancel" />
|
||||||
|
<String Id="ModifyHeader" Value="Modify Setup" />
|
||||||
|
<String Id="ModifyRepairButton" Value="&Repair" />
|
||||||
|
<String Id="ModifyUninstallButton" Value="&Uninstall" />
|
||||||
|
<String Id="ModifyCancelButton" Value="&Cancel" />
|
||||||
|
<String Id="SuccessHeader" Value="Setup Successful" />
|
||||||
|
<String Id="SuccessCacheHeader" Value="Cache Successfully Completed" />
|
||||||
|
<String Id="SuccessInstallHeader" Value="Installation Successfully Completed" />
|
||||||
|
<String Id="SuccessLayoutHeader" Value="Layout Successfully Completed" />
|
||||||
|
<String Id="SuccessModifyHeader" Value="Modify Successfully Completed" />
|
||||||
|
<String Id="SuccessRepairHeader" Value="Repair Successfully Completed" />
|
||||||
|
<String Id="SuccessUninstallHeader" Value="Uninstall Successfully Completed" />
|
||||||
|
<String Id="SuccessUnsafeUninstallHeader" Value="Uninstall Successfully Completed" />
|
||||||
|
<String Id="SuccessLaunchButton" Value="&Launch" />
|
||||||
|
<String Id="SuccessRestartText" Value="You must restart your computer before you can use the software." />
|
||||||
|
<String Id="SuccessUninstallRestartText" Value="You must restart your computer to complete the removal of the software." />
|
||||||
|
<String Id="SuccessRestartButton" Value="&Restart" />
|
||||||
|
<String Id="SuccessCloseButton" Value="&Close" />
|
||||||
|
<String Id="FailureHeader" Value="Setup Failed" />
|
||||||
|
<String Id="FailureCacheHeader" Value="Cache Failed" />
|
||||||
|
<String Id="FailureInstallHeader" Value="Setup Failed" />
|
||||||
|
<String Id="FailureLayoutHeader" Value="Layout Failed" />
|
||||||
|
<String Id="FailureModifyHeader" Value="Modify Failed" />
|
||||||
|
<String Id="FailureRepairHeader" Value="Repair Failed" />
|
||||||
|
<String Id="FailureUninstallHeader" Value="Uninstall Failed" />
|
||||||
|
<String Id="FailureUnsafeUninstallHeader" Value="Uninstall Failed" />
|
||||||
|
<String Id="FailureHyperlinkLogText" Value="One or more issues caused the setup to fail. Please fix the issues and then retry setup. For more information see the <a href="#">log file</a>." />
|
||||||
|
<String Id="FailureRestartText" Value="You must restart your computer to complete the rollback of the software." />
|
||||||
|
<String Id="FailureRestartButton" Value="&Restart" />
|
||||||
|
<String Id="FailureCloseButton" Value="&Close" />
|
||||||
|
<String Id="FilesInUseTitle" Value="Files In Use" />
|
||||||
|
<String Id="FilesInUseLabel" Value="The following applications are using files that need to be updated:" />
|
||||||
|
<String Id="FilesInUseNetfxCloseRadioButton" Value="Close the &applications." />
|
||||||
|
<String Id="FilesInUseCloseRadioButton" Value="Close the &applications and attempt to restart them." />
|
||||||
|
<String Id="FilesInUseDontCloseRadioButton" Value="&Do not close applications. A reboot will be required." />
|
||||||
|
<String Id="FilesInUseRetryButton" Value="&Retry" />
|
||||||
|
<String Id="FilesInUseIgnoreButton" Value="&Ignore" />
|
||||||
|
<String Id="FilesInUseExitButton" Value="E&xit" />
|
||||||
|
</WixLocalization>
|
||||||
@@ -0,0 +1,133 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. -->
|
||||||
|
|
||||||
|
|
||||||
|
<Theme xmlns="http://wixtoolset.org/schemas/v4/thmutil">
|
||||||
|
<Font Id="0" Height="-12" Weight="500" Foreground="windowtext" Background="window">Segoe UI</Font>
|
||||||
|
<Font Id="1" Height="-24" Weight="500" Foreground="windowtext">Segoe UI</Font>
|
||||||
|
<Font Id="2" Height="-22" Weight="500" Foreground="graytext">Segoe UI</Font>
|
||||||
|
<Font Id="3" Height="-12" Weight="500" Foreground="windowtext" Background="window">Segoe UI</Font>
|
||||||
|
|
||||||
|
<Window Width="600" Height="450" HexStyle="100a0000" FontId="0" Caption="#(loc.Caption)" IconFile="Cryptobot.ico">
|
||||||
|
<Page Name="Help">
|
||||||
|
<Label X="80" Y="11" Width="-11" Height="32" FontId="1" DisablePrefix="yes">#(loc.Title)</Label>
|
||||||
|
<ImageControl X="11" Y="11" Width="64" Height="64" ImageFile="logo.png"/>
|
||||||
|
<Label X="11" Y="80" Width="-11" Height="32" FontId="2" DisablePrefix="yes">#(loc.HelpHeader)</Label>
|
||||||
|
<Label X="11" Y="121" Width="-11" Height="-35" FontId="3" DisablePrefix="yes">#(loc.HelpText)</Label>
|
||||||
|
<Button Name="HelpCloseButton" X="-11" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">
|
||||||
|
<Text>#(loc.HelpCloseButton)</Text>
|
||||||
|
<CloseWindowAction />
|
||||||
|
</Button>
|
||||||
|
</Page>
|
||||||
|
<Page Name="Loading">
|
||||||
|
<Label X="185" Y="50" Width="-11" Height="30" FontId="2" DisablePrefix="yes" Visible="no" Name="CheckingForUpdatesLabel" />
|
||||||
|
</Page>
|
||||||
|
<Page Name="Install">
|
||||||
|
<ImageControl X="11" Y="11" Width="165" Height="400" ImageFile="logoside.png"/>
|
||||||
|
<Label X="185" Y="11" Width="-11" Height="32" FontId="2" DisablePrefix="yes">#(loc.InstallHeader)</Label>
|
||||||
|
<Label X="185" Y="50" Width="-11" Height="64" FontId="3" DisablePrefix="yes">
|
||||||
|
<Text Condition="WixStdBASuppressOptionsUI">#(loc.InstallMessage)</Text>
|
||||||
|
<Text Condition="NOT WixStdBASuppressOptionsUI">#(loc.InstallMessageOptions)</Text>
|
||||||
|
</Label>
|
||||||
|
<Richedit Name="EulaRichedit" X="185" Y="91" Width="-12" Height="-64" HexStyle="0x00800000" TabStop="yes" FontId="0" />
|
||||||
|
<Checkbox Name="EulaAcceptCheckbox" X="185" Y="-39" Width="-11" Height="17" TabStop="yes" FontId="3" HideWhenDisabled="yes">#(loc.InstallAcceptCheckbox)</Checkbox>
|
||||||
|
<Label Name="InstallVersion" X="11" Y="-11" Width="165" Height="17" FontId="3" DisablePrefix="yes" VisibleCondition="WixStdBAShowVersion">#(loc.InstallVersion)</Label>
|
||||||
|
<Button Name="InstallUpdateButton" X="11" Y="-11" Width="200" Height="23" TabStop="yes" FontId="0" EnableCondition="WixStdBAUpdateAvailable" HideWhenDisabled="yes">#(loc.UpdateButton)</Button>
|
||||||
|
<Button Name="OptionsButton" X="-171" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0" VisibleCondition="NOT WixStdBASuppressOptionsUI">
|
||||||
|
<Text>#(loc.InstallOptionsButton)</Text>
|
||||||
|
<ChangePageAction Page="Options" />
|
||||||
|
</Button>
|
||||||
|
<Button Name="InstallButton" X="-91" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">#(loc.InstallInstallButton)</Button>
|
||||||
|
<Button Name="InstallCancelButton" X="-11" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">
|
||||||
|
<Text>#(loc.InstallCancelButton)</Text>
|
||||||
|
<CloseWindowAction />
|
||||||
|
</Button>
|
||||||
|
</Page>
|
||||||
|
<Page Name="Options">
|
||||||
|
<Label X="80" Y="11" Width="-11" Height="32" FontId="1" DisablePrefix="yes">#(loc.Title)</Label>
|
||||||
|
<ImageControl X="11" Y="11" Width="64" Height="64" ImageFile="logo.png"/>
|
||||||
|
<Label X="11" Y="80" Width="-11" Height="30" FontId="2" DisablePrefix="yes">#(loc.OptionsHeader)</Label>
|
||||||
|
<Label X="11" Y="121" Width="-11" Height="17" FontId="3">#(loc.OptionsLocationLabel)</Label>
|
||||||
|
<Editbox Name="InstallFolder" X="11" Y="143" Width="-91" Height="21" TabStop="yes" FontId="3" FileSystemAutoComplete="yes" />
|
||||||
|
<Button Name="BrowseButton" X="-11" Y="142" Width="75" Height="23" TabStop="yes" FontId="3">
|
||||||
|
<Text>#(loc.OptionsBrowseButton)</Text>
|
||||||
|
<BrowseDirectoryAction VariableName="InstallFolder" />
|
||||||
|
</Button>
|
||||||
|
<Button Name="OptionsOkButton" X="-91" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">
|
||||||
|
<Text>#(loc.OptionsOkButton)</Text>
|
||||||
|
<ChangePageAction Page="Install" />
|
||||||
|
</Button>
|
||||||
|
<Button Name="OptionsCancelButton" X="-11" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">
|
||||||
|
<Text>#(loc.OptionsCancelButton)</Text>
|
||||||
|
<ChangePageAction Page="Install" Cancel="yes" />
|
||||||
|
</Button>
|
||||||
|
</Page>
|
||||||
|
<Page Name="Progress">
|
||||||
|
<Label X="80" Y="11" Width="-11" Height="32" FontId="1" DisablePrefix="yes">#(loc.Title)</Label>
|
||||||
|
<ImageControl X="11" Y="11" Width="64" Height="64" ImageFile="logo.png"/>
|
||||||
|
<Label X="11" Y="80" Width="-11" Height="30" FontId="2" DisablePrefix="yes">#(loc.ProgressHeader)</Label>
|
||||||
|
<Label X="11" Y="141" Width="70" Height="17" FontId="3" DisablePrefix="yes">#(loc.ProgressLabel)</Label>
|
||||||
|
<Label Name="OverallProgressPackageText" X="85" Y="141" Width="-11" Height="17" FontId="3" DisablePrefix="yes">#(loc.OverallProgressPackageText)</Label>
|
||||||
|
<Progressbar Name="OverallCalculatedProgressbar" X="11" Y="163" Width="-11" Height="20" />
|
||||||
|
<Button Name="ProgressCancelButton" X="-11" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">#(loc.ProgressCancelButton)</Button>
|
||||||
|
</Page>
|
||||||
|
<Page Name="Modify">
|
||||||
|
<ImageControl X="11" Y="11" Width="165" Height="400" ImageFile="logoside.png"/>
|
||||||
|
<Label X="185" Y="11" Width="-11" Height="32" FontId="2" DisablePrefix="yes">#(loc.ModifyHeader)</Label>
|
||||||
|
<Label Name="InstallVersion" X="11" Y="-11" Width="-11" Height="17" FontId="3" DisablePrefix="yes" VisibleCondition="WixStdBAShowVersion">#(loc.InstallVersion)</Label>
|
||||||
|
<Button Name="ModifyUpdateButton" X="11" Y="-11" Width="200" Height="23" TabStop="yes" FontId="0" EnableCondition="WixStdBAUpdateAvailable" HideWhenDisabled="yes">#(loc.UpdateButton)</Button>
|
||||||
|
<Button Name="RepairButton" X="-171" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0" HideWhenDisabled="yes">#(loc.ModifyRepairButton)</Button>
|
||||||
|
<Button Name="UninstallButton" X="-91" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">#(loc.ModifyUninstallButton)</Button>
|
||||||
|
<Button Name="ModifyCancelButton" X="-11" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">
|
||||||
|
<Text>#(loc.ModifyCancelButton)</Text>
|
||||||
|
<CloseWindowAction />
|
||||||
|
</Button>
|
||||||
|
</Page>
|
||||||
|
<Page Name="Success">
|
||||||
|
<ImageControl X="11" Y="11" Width="165" Height="400" ImageFile="logoside.png"/>
|
||||||
|
<Label X="185" Y="11" Width="-11" Height="32" FontId="2" DisablePrefix="yes">
|
||||||
|
<Text>#(loc.SuccessHeader)</Text>
|
||||||
|
<Text Condition="WixBundleAction = 2">#(loc.SuccessLayoutHeader)</Text>
|
||||||
|
<Text Condition="WixBundleAction = 3">#(loc.SuccessUnsafeUninstallHeader)</Text>
|
||||||
|
<Text Condition="WixBundleAction = 4">#(loc.SuccessUninstallHeader)</Text>
|
||||||
|
<Text Condition="WixBundleAction = 5">#(loc.SuccessCacheHeader)</Text>
|
||||||
|
<Text Condition="WixBundleAction = 6">#(loc.SuccessInstallHeader)</Text>
|
||||||
|
<Text Condition="WixBundleAction = 7">#(loc.SuccessModifyHeader)</Text>
|
||||||
|
<Text Condition="WixBundleAction = 8">#(loc.SuccessRepairHeader)</Text>
|
||||||
|
</Label>
|
||||||
|
<Button Name="LaunchButton" X="-91" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0" HideWhenDisabled="yes">#(loc.SuccessLaunchButton)</Button>
|
||||||
|
<Label X="185" Y="-51" Width="400" Height="34" FontId="3" DisablePrefix="yes" VisibleCondition="WixStdBARestartRequired">
|
||||||
|
<Text>#(loc.SuccessRestartText)</Text>
|
||||||
|
<Text Condition="WixBundleAction = 3">#(loc.SuccessUninstallRestartText)</Text>
|
||||||
|
</Label>
|
||||||
|
<Label Name="InstallVersion" X="11" Y="-11" Width="165" Height="17" FontId="3" DisablePrefix="yes" VisibleCondition="WixStdBAShowVersion">#(loc.InstallVersion)</Label>
|
||||||
|
<Button Name="SuccessRestartButton" X="-91" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0" HideWhenDisabled="yes">#(loc.SuccessRestartButton)</Button>
|
||||||
|
<Button Name="SuccessCloseButton" X="-11" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">
|
||||||
|
<Text>#(loc.SuccessCloseButton)</Text>
|
||||||
|
<CloseWindowAction />
|
||||||
|
</Button>
|
||||||
|
</Page>
|
||||||
|
<Page Name="Failure">
|
||||||
|
<ImageControl X="11" Y="11" Width="165" Height="400" ImageFile="logoside.png"/>
|
||||||
|
<Label X="185" Y="11" Width="-11" Height="32" FontId="2" DisablePrefix="yes">
|
||||||
|
<Text>#(loc.FailureHeader)</Text>
|
||||||
|
<Text Condition="WixBundleAction = 2">#(loc.FailureLayoutHeader)</Text>
|
||||||
|
<Text Condition="WixBundleAction = 3">#(loc.FailureUnsafeUninstallHeader)</Text>
|
||||||
|
<Text Condition="WixBundleAction = 4">#(loc.FailureUninstallHeader)</Text>
|
||||||
|
<Text Condition="WixBundleAction = 5">#(loc.FailureCacheHeader)</Text>
|
||||||
|
<Text Condition="WixBundleAction = 6">#(loc.FailureInstallHeader)</Text>
|
||||||
|
<Text Condition="WixBundleAction = 7">#(loc.FailureModifyHeader)</Text>
|
||||||
|
<Text Condition="WixBundleAction = 8">#(loc.FailureRepairHeader)</Text>
|
||||||
|
</Label>
|
||||||
|
<Hypertext Name="FailureLogFileLink" X="185" Y="121" Width="-11" Height="68" FontId="3" TabStop="yes" HideWhenDisabled="yes">#(loc.FailureHyperlinkLogText)</Hypertext>
|
||||||
|
<Hypertext Name="FailureMessageText" X="185" Y="-115" Width="-11" Height="80" FontId="3" TabStop="yes" HideWhenDisabled="yes" />
|
||||||
|
<Label Name="InstallVersion" X="11" Y="-11" Width="165" Height="17" FontId="3" DisablePrefix="yes" VisibleCondition="WixStdBAShowVersion">#(loc.InstallVersion)</Label>
|
||||||
|
<Label X="185" Y="-57" Width="-11" Height="80" FontId="3" DisablePrefix="yes" VisibleCondition="WixStdBARestartRequired">#(loc.FailureRestartText)</Label>
|
||||||
|
<Button Name="FailureRestartButton" X="-91" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0" HideWhenDisabled="yes">#(loc.FailureRestartButton)</Button>
|
||||||
|
<Button Name="FailureCloseButton" X="-11" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">
|
||||||
|
<Text>#(loc.FailureCloseButton)</Text>
|
||||||
|
<CloseWindowAction />
|
||||||
|
</Button>
|
||||||
|
</Page>
|
||||||
|
</Window>
|
||||||
|
</Theme>
|
||||||
+1
-1
@@ -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 2024 Skymatic GmbH \b0\par
|
\b\'a9 2016 \'96 2025 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
|
||||||
|
|||||||
Vendored
BIN
Binary file not shown.
+18
@@ -0,0 +1,18 @@
|
|||||||
|
@echo off
|
||||||
|
:: Batch wrapper for PowerShell script to modify Cryptomator update check settings
|
||||||
|
:: This is executed as a Custom Action during MSI installation
|
||||||
|
:: This file must be located in the INSTALLDIR
|
||||||
|
|
||||||
|
set "DISABLEUPDATECHECK=%~1"
|
||||||
|
|
||||||
|
:: Log for debugging
|
||||||
|
echo DISABLEUPDATECHECK=%DISABLEUPDATECHECK%
|
||||||
|
|
||||||
|
:: Change to INSTALLDIR
|
||||||
|
cd %~dp0
|
||||||
|
:: Execute the PowerShell script
|
||||||
|
powershell.exe -NoLogo -NoProfile -NonInteractive -ExecutionPolicy RemoteSigned -File ".\patchUpdateCheck.ps1"^
|
||||||
|
-DisableUpdateCheck "%DISABLEUPDATECHECK%"
|
||||||
|
|
||||||
|
:: Return the exit code from PowerShell
|
||||||
|
exit /b %ERRORLEVEL%
|
||||||
+58
@@ -0,0 +1,58 @@
|
|||||||
|
# PowerShell script to modify Cryptomator.cfg to set disableUpdateCheck property
|
||||||
|
# This script is executed as a Custom Action during MSI installation
|
||||||
|
# If the DisableUpdateCheck parameter is set to true, it disables the update check in Cryptomator by modifying the Cryptomator.cfg file.
|
||||||
|
# NOTE: This file must be located in the same directory as set in the MSI property INSTALLDIR
|
||||||
|
|
||||||
|
param(
|
||||||
|
[Parameter(Mandatory)][string]$DisableUpdateCheck
|
||||||
|
)
|
||||||
|
|
||||||
|
try {
|
||||||
|
# Log parameters for debugging (visible in MSI verbose logs)
|
||||||
|
Write-Host "DisableUpdateCheck: $DisableUpdateCheck"
|
||||||
|
|
||||||
|
# Parse DisableUpdateCheck value (handle various input formats)
|
||||||
|
$shouldDisable = $false
|
||||||
|
if ($DisableUpdateCheck) {
|
||||||
|
$DisableUpdateCheck = $DisableUpdateCheck.Trim().ToLower()
|
||||||
|
$shouldDisable = ($DisableUpdateCheck -eq 'true') -or ($DisableUpdateCheck -eq '1') -or ($DisableUpdateCheck -eq 'yes')
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host "Setting cryptomator.disableUpdateCheck to: $shouldDisable"
|
||||||
|
if (-not $shouldDisable) {
|
||||||
|
Write-Host 'Disable-Update-Check property is by default "false". Skipping config modification.'
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# Determine the .cfg file path
|
||||||
|
$cfgDir = Join-Path $PSScriptRoot 'app'
|
||||||
|
$cfgFiles = Get-ChildItem -Path $cfgDir -Filter '*.cfg' -File
|
||||||
|
|
||||||
|
if ($cfgFiles.Count -eq 0) {
|
||||||
|
Write-Error "No .cfg file found in directory: $cfgDir"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($file in $cfgFiles) {
|
||||||
|
$cfgFile = $file.FullName
|
||||||
|
Write-Host "Modifying configuration file: $cfgFile"
|
||||||
|
# Read the current configuration
|
||||||
|
$content = Get-Content $cfgFile -Raw -ErrorAction Stop
|
||||||
|
|
||||||
|
# Add the new option based on the property value
|
||||||
|
# Use regular expressions substitutions to replace the property
|
||||||
|
$searchExpression = '(?<Prefix>java-options=-Dcryptomator\.disableUpdateCheck)=false'
|
||||||
|
$replacementExpression = '${Prefix}=true'
|
||||||
|
$content = $content -replace $searchExpression,$replacementExpression
|
||||||
|
|
||||||
|
# Write the modified content back
|
||||||
|
Set-Content -Path $cfgFile -Value $content -NoNewline
|
||||||
|
Write-Host "Successfully updated $cfgFile"
|
||||||
|
}
|
||||||
|
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
Write-Error "Error modifying configuration file: $_"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
Vendored
+15
-4
@@ -1,7 +1,18 @@
|
|||||||
@echo off
|
@echo off
|
||||||
:: Default values for Cryptomator builds
|
:: Batch wrapper for PowerShell script to adjust Windows network settings for the Cryptomator WebDAVAdapter
|
||||||
::REPLACE ME
|
:: This is executed as a Custom Action during MSI installation
|
||||||
|
:: This file must be located in the INSTALLDIR
|
||||||
|
|
||||||
|
set "LOOPBACK_ALIAS=%1"
|
||||||
|
|
||||||
|
:: Log for debugging
|
||||||
|
echo LOOPBACK_ALIAS=%LOOPBACK_ALIAS%
|
||||||
|
|
||||||
|
:: Change to INSTALLDIR
|
||||||
cd %~dp0
|
cd %~dp0
|
||||||
powershell -NoLogo -NoProfile -NonInteractive -ExecutionPolicy RemoteSigned -Command .\patchWebDAV.ps1^
|
:: Execute the PowerShell script
|
||||||
-LoopbackAlias %LOOPBACK_ALIAS%
|
powershell -NoLogo -NoProfile -NonInteractive -ExecutionPolicy RemoteSigned -File .\patchWebDAV.ps1^
|
||||||
|
-LoopbackAlias %LOOPBACK_ALIAS%
|
||||||
|
|
||||||
|
:: Return the exit code from PowerShell
|
||||||
|
exit /b %ERRORLEVEL%
|
||||||
Vendored
+4
@@ -0,0 +1,4 @@
|
|||||||
|
win-console=true
|
||||||
|
win-shortcut=false
|
||||||
|
win-menu=false
|
||||||
|
description=Debug Launcher with Console for Cryptomator
|
||||||
Vendored
-14
@@ -1,14 +0,0 @@
|
|||||||
@echo off
|
|
||||||
java ^
|
|
||||||
-p "mods" ^
|
|
||||||
-cp "libs/*" ^
|
|
||||||
-Dcryptomator.settingsPath="~/AppData/Roaming/Cryptomator/settings.json" ^
|
|
||||||
-Dcryptomator.ipcSocketPath="~/AppData/Roaming/Cryptomator/ipc.socket" ^
|
|
||||||
-Dcryptomator.logDir="~/AppData/Roaming/Cryptomator" ^
|
|
||||||
-Dcryptomator.mountPointsDir="~/Cryptomator" ^
|
|
||||||
-Dcryptomator.keychainPath="~/AppData/Roaming/Cryptomator/keychain.json" ^
|
|
||||||
-Xss20m ^
|
|
||||||
-Xmx512m ^
|
|
||||||
--enable-preview `
|
|
||||||
--enable-native-access=org.cryptomator.jfuse.win `
|
|
||||||
-m org.cryptomator.desktop/org.cryptomator.launcher.Cryptomator
|
|
||||||
Vendored
-109
@@ -1,109 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Include>
|
|
||||||
<Fragment>
|
|
||||||
<!-- copy pasta from https://github.com/wixtoolset/wix3/blob/develop/src/ext/UIExtension/wixlib/WixUI_InstallDir.wxs with custom exit dialog-->
|
|
||||||
<UI Id="CustomWizard">
|
|
||||||
<TextStyle Id="WixUI_Font_Normal" FaceName="Tahoma" Size="8" />
|
|
||||||
<TextStyle Id="WixUI_Font_Bigger" FaceName="Tahoma" Size="12" />
|
|
||||||
<TextStyle Id="WixUI_Font_Title" FaceName="Tahoma" Size="9" Bold="yes" />
|
|
||||||
|
|
||||||
<Property Id="DefaultUIFont" Value="WixUI_Font_Normal" />
|
|
||||||
<Property Id="WixUI_Mode" Value="InstallDir" />
|
|
||||||
|
|
||||||
<DialogRef Id="BrowseDlg" />
|
|
||||||
<DialogRef Id="DiskCostDlg" />
|
|
||||||
<DialogRef Id="ErrorDlg" />
|
|
||||||
<DialogRef Id="FilesInUse" />
|
|
||||||
<DialogRef Id="MsiRMFilesInUse" />
|
|
||||||
<DialogRef Id="PrepareDlg" />
|
|
||||||
<DialogRef Id="ProgressDlg" />
|
|
||||||
<DialogRef Id="ResumeDlg" />
|
|
||||||
<DialogRef Id="UserExit" />
|
|
||||||
|
|
||||||
<Publish Dialog="BrowseDlg" Control="OK" Event="DoAction" Value="WixUIValidatePath" Order="3">1</Publish>
|
|
||||||
<Publish Dialog="BrowseDlg" Control="OK" Event="SpawnDialog" Value="InvalidDirDlg" Order="4"><![CDATA[NOT WIXUI_DONTVALIDATEPATH AND WIXUI_INSTALLDIR_VALID<>"1"]]></Publish>
|
|
||||||
|
|
||||||
<!-- custom end dialogs -->
|
|
||||||
<Publish Dialog="MyExitDialog" Control="Finish" Event="EndDialog" Value="Return" Order="999">1</Publish>
|
|
||||||
<Publish Dialog="MyFatalErrorDlg" Control="Finish" Event="EndDialog" Value="Return" Order="998">1</Publish>
|
|
||||||
|
|
||||||
<Publish Dialog="WelcomeDlg" Control="Next" Event="NewDialog" Value="LicenseAgreementDlg">NOT Installed</Publish>
|
|
||||||
<Publish Dialog="WelcomeDlg" Control="Next" Event="NewDialog" Value="VerifyReadyDlg">Installed AND PATCH</Publish>
|
|
||||||
|
|
||||||
<Publish Dialog="LicenseAgreementDlg" Control="Back" Event="NewDialog" Value="WelcomeDlg">1</Publish>
|
|
||||||
<Publish Dialog="LicenseAgreementDlg" Control="Next" Event="NewDialog" Value="InstallDirDlg">LicenseAccepted = "1"</Publish>
|
|
||||||
|
|
||||||
<Publish Dialog="InstallDirDlg" Control="Back" Event="NewDialog" Value="LicenseAgreementDlg">1</Publish>
|
|
||||||
<Publish Dialog="InstallDirDlg" Control="Next" Event="SetTargetPath" Value="[WIXUI_INSTALLDIR]" Order="1">1</Publish>
|
|
||||||
<Publish Dialog="InstallDirDlg" Control="Next" Event="DoAction" Value="WixUIValidatePath" Order="2">NOT WIXUI_DONTVALIDATEPATH</Publish>
|
|
||||||
<Publish Dialog="InstallDirDlg" Control="Next" Event="SpawnDialog" Value="InvalidDirDlg" Order="3"><![CDATA[NOT WIXUI_DONTVALIDATEPATH AND WIXUI_INSTALLDIR_VALID<>"1"]]></Publish>
|
|
||||||
<Publish Dialog="InstallDirDlg" Control="Next" Event="NewDialog" Value="VerifyReadyDlg" Order="4">WIXUI_DONTVALIDATEPATH OR WIXUI_INSTALLDIR_VALID="1"</Publish>
|
|
||||||
<Publish Dialog="InstallDirDlg" Control="ChangeFolder" Property="_BrowseProperty" Value="[WIXUI_INSTALLDIR]" Order="1">1</Publish>
|
|
||||||
<Publish Dialog="InstallDirDlg" Control="ChangeFolder" Event="SpawnDialog" Value="BrowseDlg" Order="2">1</Publish>
|
|
||||||
|
|
||||||
<Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="InstallDirDlg" Order="1">NOT Installed</Publish>
|
|
||||||
<Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="MaintenanceTypeDlg" Order="2">Installed AND NOT PATCH</Publish>
|
|
||||||
<Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="WelcomeDlg" Order="2">Installed AND PATCH</Publish>
|
|
||||||
|
|
||||||
<Publish Dialog="MaintenanceWelcomeDlg" Control="Next" Event="NewDialog" Value="MaintenanceTypeDlg">1</Publish>
|
|
||||||
|
|
||||||
<Publish Dialog="MaintenanceTypeDlg" Control="RepairButton" Event="NewDialog" Value="VerifyReadyDlg">1</Publish>
|
|
||||||
<Publish Dialog="MaintenanceTypeDlg" Control="RemoveButton" Event="NewDialog" Value="VerifyReadyDlg">1</Publish>
|
|
||||||
<Publish Dialog="MaintenanceTypeDlg" Control="Back" Event="NewDialog" Value="MaintenanceWelcomeDlg">1</Publish>
|
|
||||||
|
|
||||||
<Property Id="ARPNOMODIFY" Value="1" />
|
|
||||||
|
|
||||||
<!-- copy pasta from https://github.com/wixtoolset/wix3/blob/develop/src/ext/UIExtension/wixlib/ExitDialog.wxs with adjustments-->
|
|
||||||
<Dialog Id="MyExitDialog" Width="370" Height="270" Title="!(loc.ExitDialog_Title)">
|
|
||||||
<Control Id="Finish" Type="PushButton" X="236" Y="243" Width="56" Height="17" Default="yes" Cancel="yes" Text="!(loc.WixUIFinish)" />
|
|
||||||
<Control Id="Cancel" Type="PushButton" X="304" Y="243" Width="56" Height="17" Disabled="yes" Text="!(loc.WixUICancel)" />
|
|
||||||
<Control Id="Bitmap" Type="Bitmap" X="0" Y="0" Width="370" Height="234" TabSkip="no" Text="!(loc.ExitDialogBitmap)" />
|
|
||||||
<Control Id="Back" Type="PushButton" X="180" Y="243" Width="56" Height="17" Disabled="yes" Text="!(loc.WixUIBack)" />
|
|
||||||
<Control Id="BottomLine" Type="Line" X="0" Y="234" Width="370" Height="0" />
|
|
||||||
<Control Id="Description" Type="Text" X="135" Y="70" Width="220" Height="40" Transparent="yes" NoPrefix="yes" Text="!(loc.ExitDialogDescription)" />
|
|
||||||
|
|
||||||
<Control Id="Title" Type="Text" X="135" Y="20" Width="220" Height="60" Transparent="yes" NoPrefix="yes" Text="!(loc.ExitDialogTitle)" />
|
|
||||||
<!-- TODO: localize? -->
|
|
||||||
<Control Id="Suggestion" Type="Text" X="135" Y="100" Width="220" Height="60" Transparent="yes" NoPrefix="yes">
|
|
||||||
<Text>We recommend for the best user experience to download and install the following third party Windows driver:</Text>
|
|
||||||
</Control>
|
|
||||||
<Control Id="WinFsp" Type="Hyperlink" X="140" Y="125" Width="220" Height="60" Transparent="yes">
|
|
||||||
<Text><![CDATA[WinFsp (<a href="https://winfsp.dev/">Homepage</a>)]]></Text>
|
|
||||||
</Control>
|
|
||||||
</Dialog>
|
|
||||||
|
|
||||||
<!-- copy pasta from https://github.com/wixtoolset/wix3/blob/develop/src/ext/UIExtension/wixlib/FatalError.wxs with adjustments-->
|
|
||||||
<Dialog Id="MyFatalErrorDlg" Width="370" Height="270" Title="!(loc.FatalError_Title)">
|
|
||||||
<Control Id="Finish" Type="PushButton" X="236" Y="243" Width="56" Height="17" Default="yes" Cancel="yes" Text="!(loc.WixUIFinish)">
|
|
||||||
<Publish Event="EndDialog" Value="Exit">1</Publish>
|
|
||||||
</Control>
|
|
||||||
<Control Id="Cancel" Type="PushButton" X="304" Y="243" Width="56" Height="17" Disabled="yes" Text="!(loc.WixUICancel)" />
|
|
||||||
<Control Id="Bitmap" Type="Bitmap" X="0" Y="0" Width="370" Height="234" TabSkip="no" Text="!(loc.FatalErrorBitmap)" />
|
|
||||||
<Control Id="Back" Type="PushButton" X="180" Y="243" Width="56" Height="17" Disabled="yes" Text="!(loc.WixUIBack)" />
|
|
||||||
<Control Id="BottomLine" Type="Line" X="0" Y="234" Width="370" Height="0" />
|
|
||||||
<Control Id="Title" Type="Text" X="135" Y="20" Width="220" Height="60" Transparent="yes" NoPrefix="yes" Text="!(loc.FatalErrorTitle)" />
|
|
||||||
<Control Id="Description" Type="Text" X="135" Y="70" Width="220" Height="80" Transparent="yes" NoPrefix="yes" Text="!(loc.FatalErrorDescription1) !(loc.FatalErrorDescription2)" />
|
|
||||||
<Control Id="DescriptionReason1" Type="Text" X="135" Y="160" Width="220" Height="20" Transparent="yes" NoPrefix="yes" Hidden="yes" >
|
|
||||||
<Text>Reason:</Text>
|
|
||||||
<Condition Action="show">FOUNDRUNNINGAPP</Condition>
|
|
||||||
</Control>
|
|
||||||
<Control Id="DescriptionReason2" Type="Text" X="135" Y="170" Width="220" Height="40" Transparent="yes" NoPrefix="yes" Hidden="yes" >
|
|
||||||
<Text>Application to update was still running during installation.</Text>
|
|
||||||
<Condition Action="show">FOUNDRUNNINGAPP</Condition>
|
|
||||||
</Control>
|
|
||||||
</Dialog>
|
|
||||||
|
|
||||||
<InstallUISequence>
|
|
||||||
<Show Dialog="MyExitDialog" Overridable="yes" OnExit="success"/>
|
|
||||||
<Show Dialog="MyFatalErrorDlg" Overridable="yes" OnExit="error"/>
|
|
||||||
</InstallUISequence>
|
|
||||||
<AdminUISequence>
|
|
||||||
<Show Dialog="MyExitDialog" Overridable="yes" OnExit="success"/>
|
|
||||||
<Show Dialog="MyFatalErrorDlg" Overridable="yes" OnExit="error"/>
|
|
||||||
</AdminUISequence>
|
|
||||||
|
|
||||||
</UI>
|
|
||||||
|
|
||||||
<UIRef Id="WixUI_Common" />
|
|
||||||
</Fragment>
|
|
||||||
</Include>
|
|
||||||
+1
-1
@@ -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 2024 Skymatic GmbH \b0\par
|
\b\'a9 2016 \'96 2025 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
|
||||||
|
|||||||
Vendored
+116
-115
@@ -1,6 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
|
<ns0:Wix xmlns:ns0="http://wixtoolset.org/schemas/v4/wxs" xmlns:util="http://wixtoolset.org/schemas/v4/wxs/util" >
|
||||||
xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
|
|
||||||
|
|
||||||
<?ifdef JpIsSystemWide ?>
|
<?ifdef JpIsSystemWide ?>
|
||||||
<?define JpInstallScope="perMachine"?>
|
<?define JpInstallScope="perMachine"?>
|
||||||
@@ -27,177 +26,179 @@
|
|||||||
<?define IconFileEncryptedData= "Cryptomator-Vault.ico" ?>
|
<?define IconFileEncryptedData= "Cryptomator-Vault.ico" ?>
|
||||||
<?define ProgIdContentType= "application/vnd.cryptomator.encrypted" ?>
|
<?define ProgIdContentType= "application/vnd.cryptomator.encrypted" ?>
|
||||||
<?define CloseApplicationTarget= "cryptomator.exe" ?>
|
<?define CloseApplicationTarget= "cryptomator.exe" ?>
|
||||||
|
<?define LoopbackAlias= "cryptomator-vault" ?>
|
||||||
|
|
||||||
<?include $(var.JpConfigDir)/overrides.wxi ?>
|
<?include $(var.JpConfigDir)/overrides.wxi ?>
|
||||||
|
|
||||||
<Product
|
<ns0:Package
|
||||||
Id="$(var.JpProductCode)"
|
Name="$(var.JpAppName)"
|
||||||
Name="$(var.JpAppName)"
|
Language="$(var.JpProductLanguage)"
|
||||||
Language="$(var.JpProductLanguage)"
|
Version="$(var.JpAppVersion)"
|
||||||
Version="$(var.JpAppVersion)"
|
Manufacturer="$(var.JpAppVendor)"
|
||||||
Manufacturer="$(var.JpAppVendor)"
|
UpgradeCode="$(var.JpProductUpgradeCode)"
|
||||||
UpgradeCode="$(var.JpProductUpgradeCode)">
|
InstallerVersion="$(var.JpInstallerVersion)"
|
||||||
|
Compressed="$(var.JpCompressedMsi)"
|
||||||
|
ProductCode="$(var.JpProductCode)"
|
||||||
|
Scope="$(var.JpInstallScope)">
|
||||||
|
|
||||||
<Package
|
<ns0:SummaryInformation Manufacturer="$(var.JpAppVendor)" Description="$(var.JpAppDescription)"/>
|
||||||
Description="$(var.JpAppDescription)"
|
<ns0:Media Id="1" Cabinet="Data.cab" EmbedCab="yes" />
|
||||||
Manufacturer="$(var.JpAppVendor)"
|
|
||||||
InstallerVersion="$(var.JpInstallerVersion)"
|
|
||||||
Compressed="$(var.JpCompressedMsi)"
|
|
||||||
InstallScope="$(var.JpInstallScope)" Platform="x64"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<Media Id="1" Cabinet="Data.cab" EmbedCab="yes" />
|
|
||||||
|
|
||||||
<Upgrade Id="$(var.JpProductUpgradeCode)">
|
<ns0:Upgrade Id="$(var.JpProductUpgradeCode)">
|
||||||
<UpgradeVersion
|
<ns0:UpgradeVersion
|
||||||
OnlyDetect="$(var.JpUpgradeVersionOnlyDetectUpgrade)"
|
OnlyDetect="$(var.JpUpgradeVersionOnlyDetectUpgrade)"
|
||||||
Property="JP_UPGRADABLE_FOUND"
|
Property="JP_UPGRADABLE_FOUND"
|
||||||
Maximum="$(var.JpAppVersion)"
|
Maximum="$(var.JpAppVersion)"
|
||||||
MigrateFeatures="yes"
|
MigrateFeatures="yes"
|
||||||
IncludeMaximum="yes" /> <!-- TODO: check if this needs to be set to yes-->
|
IncludeMaximum="$(var.JpUpgradeVersionOnlyDetectUpgrade)"/> <!-- TODO in earlier versions, this was set to yes-->
|
||||||
<UpgradeVersion
|
<ns0:UpgradeVersion
|
||||||
OnlyDetect="$(var.JpUpgradeVersionOnlyDetectDowngrade)"
|
OnlyDetect="$(var.JpUpgradeVersionOnlyDetectDowngrade)"
|
||||||
Property="JP_DOWNGRADABLE_FOUND"
|
Property="JP_DOWNGRADABLE_FOUND"
|
||||||
Minimum="$(var.JpAppVersion)"
|
Minimum="$(var.JpAppVersion)"
|
||||||
MigrateFeatures="yes"
|
MigrateFeatures="yes"
|
||||||
IncludeMinimum="$(var.JpUpgradeVersionOnlyDetectDowngrade)" />
|
IncludeMinimum="$(var.JpUpgradeVersionOnlyDetectDowngrade)" />
|
||||||
</Upgrade>
|
</ns0:Upgrade>
|
||||||
|
|
||||||
<?ifndef JpAllowUpgrades ?>
|
<?ifndef JpAllowUpgrades ?>
|
||||||
<CustomAction Id="JpDisallowUpgrade" Error="!(loc.DisallowUpgradeErrorMessage)" />
|
<ns0:CustomAction Id="JpDisallowUpgrade" Error="!(loc.DisallowUpgradeErrorMessage)" />
|
||||||
<?endif?>
|
<?endif?>
|
||||||
<?ifndef JpAllowDowngrades ?>
|
<?ifndef JpAllowDowngrades ?>
|
||||||
<CustomAction Id="JpDisallowDowngrade" Error="!(loc.DowngradeErrorMessage)" />
|
<ns0:CustomAction Id="JpDisallowDowngrade" Error="!(loc.DowngradeErrorMessage)" />
|
||||||
<?endif?>
|
<?endif?>
|
||||||
|
|
||||||
<Binary Id="JpCaDll" SourceFile="$(env.JP_WIXHELPER_DIR)\wixhelper.dll"/>
|
<!-- TODO: how does this work again? -->
|
||||||
<CustomAction Id="JpFindRelatedProducts" BinaryKey="JpCaDll" DllEntry="FindRelatedProductsEx" />
|
<ns0:Binary Id="JpCaDll" SourceFile="$(env.JP_WIXHELPER_DIR)\wixhelper.dll" />
|
||||||
|
<ns0:CustomAction Id="JpFindRelatedProducts" BinaryRef="JpCaDll" DllEntry="FindRelatedProductsEx" />
|
||||||
|
|
||||||
<?ifndef SkipCryptomatorLegacyCheck ?>
|
<?ifndef SkipCryptomatorLegacyCheck ?>
|
||||||
<!-- Block installation if innosetup entry of Cryptomator is found -->
|
<!-- Block installation if innosetup entry of Cryptomator is found -->
|
||||||
<Property Id="OLDEXEINSTALLER">
|
<ns0:Property Id="OLDEXEINSTALLER">
|
||||||
<RegistrySearch Id="InnoSetupInstallation" Root="HKLM" Key="Software\Microsoft\Windows\CurrentVersion\Uninstall\Cryptomator_is1" Type="raw" Name="DisplayName" />
|
<ns0:RegistrySearch Id="InnoSetupInstallation" Root="HKLM" Key="Software\Microsoft\Windows\CurrentVersion\Uninstall\Cryptomator_is1" Type="raw" Name="DisplayName" />
|
||||||
</Property>
|
</ns0:Property>
|
||||||
<!-- TODO: localize -->
|
<!-- TODO: localize -->
|
||||||
<Condition Message="A lower version of [ProductName] is already installed. Uninstall it first and then start the setup again. Setup will now exit.">
|
<ns0:Launch Message="A lower version of [ProductName] is already installed. Uninstall it first and then start the setup again. Setup will now exit." Condition="Installed OR NOT OLDEXEINSTALLER" />
|
||||||
<![CDATA[Installed OR NOT OLDEXEINSTALLER]]>
|
|
||||||
</Condition>
|
|
||||||
<?endif?>
|
<?endif?>
|
||||||
<!-- Cryptomator uses UNIX Sockets, which are supported starting with Windows 10 v1803-->
|
<!-- Cryptomator uses UNIX Sockets, which are supported starting with Windows 10 v1803-->
|
||||||
<Property Id="WINDOWSBUILDNUMBER" Secure="yes">
|
<ns0:Property Id="WINDOWSBUILDNUMBER" Secure="yes">
|
||||||
<RegistrySearch Id="BuildNumberSearch" Root="HKLM" Key="SOFTWARE\Microsoft\Windows NT\CurrentVersion" Name="CurrentBuildNumber" Type="raw" />
|
<ns0:RegistrySearch Id="BuildNumberSearch" Root="HKLM" Key="SOFTWARE\Microsoft\Windows NT\CurrentVersion" Name="CurrentBuildNumber" Type="raw" />
|
||||||
</Property>
|
</ns0:Property>
|
||||||
<Condition Message="This application requires Windows 10 version 1803 (build 17134) or newer.">
|
<ns0:Launch Message="This application requires Windows 10 version 1803 (build 17134) or newer." Condition="Installed OR (WINDOWSBUILDNUMBER >= 17134)" />
|
||||||
<![CDATA[Installed OR (WINDOWSBUILDNUMBER >= 17134)]]>
|
|
||||||
</Condition>
|
|
||||||
|
|
||||||
<!-- Non-Opening ProgID -->
|
<!-- Non-Opening ProgID -->
|
||||||
<DirectoryRef Id="INSTALLDIR">
|
<ns0:DirectoryRef Id="INSTALLDIR">
|
||||||
<Component Win64="yes" Id="nonStartingProgID" >
|
<ns0:Component Bitness="always64" Id="nonStartingProgID" >
|
||||||
<File Id="IconFileForEncryptedData" KeyPath="yes" Source="$(env.JP_WIXWIZARD_RESOURCES)\$(var.IconFileEncryptedData)" Name="$(var.IconFileEncryptedData)"></File>
|
<ns0:File Id="IconFileForEncryptedData" KeyPath="yes" Source="$(env.JP_WIXWIZARD_RESOURCES)\$(var.IconFileEncryptedData)" Name="$(var.IconFileEncryptedData)"/>
|
||||||
<ProgId Id="$(var.JpAppName).Encrypted.1" Description="$(var.JpAppName) Encrypted Data" Icon="IconFileForEncryptedData" IconIndex="0">
|
<ns0:ProgId Id="$(var.JpAppName).Encrypted.1" Description="$(var.JpAppName) Encrypted Data" Icon="IconFileForEncryptedData" IconIndex="0">
|
||||||
<Extension Id="c9r" Advertise="no" ContentType="$(var.ProgIdContentType)">
|
<ns0:Extension Id="c9r" Advertise="no" ContentType="$(var.ProgIdContentType)">
|
||||||
<MIME ContentType="$(var.ProgIdContentType)" Default="yes"></MIME>
|
<ns0:MIME ContentType="$(var.ProgIdContentType)" Default="yes"/>
|
||||||
</Extension>
|
</ns0:Extension>
|
||||||
<Extension Id="c9s" Advertise="no" ContentType="$(var.ProgIdContentType)"/>
|
<ns0:Extension Id="c9s" Advertise="no" ContentType="$(var.ProgIdContentType)"/>
|
||||||
</ProgId>
|
</ns0:ProgId>
|
||||||
</Component>
|
</ns0:Component>
|
||||||
</DirectoryRef>
|
</ns0:DirectoryRef>
|
||||||
|
|
||||||
<!-- Standard required root -->
|
<!-- Standard required root -->
|
||||||
<Directory Id="TARGETDIR" Name="SourceDir"/>
|
|
||||||
|
|
||||||
<Feature Id="DefaultFeature" Title="!(loc.MainFeatureTitle)" Level="1">
|
<ns0:Feature Id="DefaultFeature" Title="!(loc.MainFeatureTitle)" Level="1">
|
||||||
<ComponentGroupRef Id="Shortcuts"/>
|
<ns0:ComponentGroupRef Id="Shortcuts"/>
|
||||||
<ComponentGroupRef Id="Files"/>
|
<ns0:ComponentGroupRef Id="Files"/>
|
||||||
<ComponentGroupRef Id="FileAssociations"/>
|
<ns0:ComponentGroupRef Id="FileAssociations"/>
|
||||||
<!-- Ref to additional ProgIDs -->
|
<!-- Ref to additional ProgIDs -->
|
||||||
<ComponentRef Id="nonStartingProgID" />
|
<ns0:ComponentRef Id="nonStartingProgID" />
|
||||||
</Feature>
|
</ns0:Feature>
|
||||||
|
|
||||||
<CustomAction Id="JpSetARPINSTALLLOCATION" Property="ARPINSTALLLOCATION" Value="[INSTALLDIR]" />
|
<ns0:CustomAction Id="JpSetARPINSTALLLOCATION" Property="ARPINSTALLLOCATION" Value="[INSTALLDIR]" />
|
||||||
<CustomAction Id="JpSetARPCOMMENTS" Property="ARPCOMMENTS" Value="$(var.JpAppDescription)" />
|
<ns0:CustomAction Id="JpSetARPCOMMENTS" Property="ARPCOMMENTS" Value="$(var.JpAppDescription)" />
|
||||||
<CustomAction Id="JpSetARPCONTACT" Property="ARPCONTACT" Value="$(var.JpAppVendor)" />
|
<ns0:CustomAction Id="JpSetARPCONTACT" Property="ARPCONTACT" Value="$(var.JpAppVendor)" />
|
||||||
<CustomAction Id="JpSetARPSIZE" Property="ARPSIZE" Value="$(var.JpAppSizeKb)" />
|
<ns0:CustomAction Id="JpSetARPSIZE" Property="ARPSIZE" Value="$(var.JpAppSizeKb)" />
|
||||||
|
|
||||||
<?ifdef JpHelpURL ?>
|
<?ifdef JpHelpURL ?>
|
||||||
<CustomAction Id="JpSetARPHELPLINK" Property="ARPHELPLINK" Value="$(var.JpHelpURL)" />
|
<ns0:CustomAction Id="JpSetARPHELPLINK" Property="ARPHELPLINK" Value="$(var.JpHelpURL)" />
|
||||||
<?endif?>
|
<?endif?>
|
||||||
|
|
||||||
<?ifdef JpAboutURL ?>
|
<?ifdef JpAboutURL ?>
|
||||||
<CustomAction Id="JpSetARPURLINFOABOUT" Property="ARPURLINFOABOUT" Value="$(var.JpAboutURL)" />
|
<ns0:CustomAction Id="JpSetARPURLINFOABOUT" Property="ARPURLINFOABOUT" Value="$(var.JpAboutURL)" />
|
||||||
<?endif?>
|
<?endif?>
|
||||||
|
|
||||||
<?ifdef JpUpdateURL ?>
|
<?ifdef JpUpdateURL ?>
|
||||||
<CustomAction Id="JpSetARPURLUPDATEINFO" Property="ARPURLUPDATEINFO" Value="$(var.JpUpdateURL)" />
|
<ns0:CustomAction Id="JpSetARPURLUPDATEINFO" Property="ARPURLUPDATEINFO" Value="$(var.JpUpdateURL)" />
|
||||||
<?endif?>
|
<?endif?>
|
||||||
|
|
||||||
<Property Id="WixQuietExec64CmdTimeout" Value="20" />
|
<ns0:Property Id="WixQuietExec64CmdTimeout" Value="20" />
|
||||||
<!-- Note for custom actions: Immediate CAs run BEFORE the files are installed, hence if you depend on installed files, the CAs must be deferred.-->
|
<!-- Note for custom actions: Immediate CAs run BEFORE the files are installed, hence if you depend on installed files, the CAs must be deferred.-->
|
||||||
|
|
||||||
|
<!-- Property for controlling update check behavior (can be set via command line) -->
|
||||||
|
<ns0:Property Id="DISABLEUPDATECHECK" Secure="yes" />
|
||||||
|
|
||||||
<!-- WebDAV patches -->
|
<!-- WebDAV patches -->
|
||||||
<SetProperty Id="PatchWebDAV" Value=""[INSTALLDIR]patchWebDAV.bat""
|
<ns0:SetProperty Id="PatchWebDAV" Value=""[INSTALLDIR]patchWebDAV.bat" "$(var.LoopbackAlias)"" Sequence="execute" Before="PatchWebDAV" />
|
||||||
Sequence="execute" Before="PatchWebDAV" />
|
<ns0:CustomAction Id="PatchWebDAV" BinaryRef="Wix4UtilCA_$(sys.BUILDARCHSHORT)" DllEntry="WixQuietExec" Execute="deferred" Return="ignore" Impersonate="no"/>
|
||||||
<CustomAction Id="PatchWebDAV" BinaryKey="WixCA" DllEntry="WixQuietExec64" Execute="deferred" Return="ignore" Impersonate="no"/>
|
|
||||||
|
<!-- Update check configuration -->
|
||||||
|
<ns0:SetProperty Id="PatchUpdateCheck" Value=""[INSTALLDIR]patchUpdateCheck.bat" "[DISABLEUPDATECHECK]"" Sequence="execute" Before="PatchUpdateCheck" />
|
||||||
|
<ns0:CustomAction Id="PatchUpdateCheck" BinaryRef="Wix4UtilCA_$(sys.BUILDARCHSHORT)" DllEntry="WixQuietExec64" Execute="deferred" Return="ignore" Impersonate="no"/>
|
||||||
|
|
||||||
<!-- Running App detection and exit -->
|
<!-- Running App detection and exit -->
|
||||||
<Property Id="FOUNDRUNNINGAPP" Admin="yes"/>
|
<ns0:Property Id="FOUNDRUNNINGAPP" Admin="yes"/>
|
||||||
<util:CloseApplication
|
<util:CloseApplication
|
||||||
Target="$(var.CloseApplicationTarget)"
|
Target="$(var.CloseApplicationTarget)"
|
||||||
Id="Close$(var.JpAppName)"
|
Id="Close$(var.JpAppName)"
|
||||||
CloseMessage="no"
|
CloseMessage="no"
|
||||||
RebootPrompt="no"
|
RebootPrompt="no"
|
||||||
PromptToContinue="yes"
|
PromptToContinue="yes"
|
||||||
Description="A running instance of $(var.JpAppName) is found, using files marked for update. Please close it to continue."
|
Description="A running instance of $(var.JpAppName) is found, using files marked for update. Please close it to continue."
|
||||||
Property="FOUNDRUNNINGAPP"
|
Property="FOUNDRUNNINGAPP"
|
||||||
>
|
/>
|
||||||
</util:CloseApplication>
|
<ns0:CustomAction Id="FailOnRunningApp" Error="Installation aborted, because files marked for update are used by a running instance of $(var.JpAppName)."/>
|
||||||
<CustomAction Id="FailOnRunningApp" Error="Installation aborted, because files marked for update are used by a running instance of $(var.JpAppName)."/>
|
|
||||||
|
|
||||||
<?ifdef JpIcon ?>
|
<?ifdef JpIcon ?>
|
||||||
<Property Id="ARPPRODUCTICON" Value="JpARPPRODUCTICON"/>
|
<ns0:Property Id="ARPPRODUCTICON" Value="JpARPPRODUCTICON"/>
|
||||||
<Icon Id="JpARPPRODUCTICON" SourceFile="$(var.JpIcon)"/>
|
<ns0:Icon Id="JpARPPRODUCTICON" SourceFile="$(var.JpIcon)"/>
|
||||||
<?endif?>
|
<?endif?>
|
||||||
|
|
||||||
<UIRef Id="JpUI"/>
|
<ns0:UIRef Id="JpUI"/>
|
||||||
|
|
||||||
<InstallExecuteSequence>
|
<ns0:InstallExecuteSequence>
|
||||||
<Custom Action="JpSetARPINSTALLLOCATION" After="CostFinalize">Not Installed</Custom>
|
<ns0:Custom Action="JpSetARPINSTALLLOCATION" After="CostFinalize" Condition="Not Installed" />
|
||||||
<Custom Action="JpSetARPCOMMENTS" After="CostFinalize">Not Installed</Custom>
|
<ns0:Custom Action="JpSetARPCOMMENTS" After="CostFinalize" Condition="Not Installed" />
|
||||||
<Custom Action="JpSetARPCONTACT" After="CostFinalize">Not Installed</Custom>
|
<ns0:Custom Action="JpSetARPCONTACT" After="CostFinalize" Condition="Not Installed" />
|
||||||
<Custom Action="JpSetARPSIZE" After="CostFinalize">Not Installed</Custom>
|
<ns0:Custom Action="JpSetARPSIZE" After="CostFinalize" Condition="Not Installed" />
|
||||||
<?ifdef JpHelpURL ?>
|
<?ifdef JpHelpURL ?>
|
||||||
<Custom Action="JpSetARPHELPLINK" After="CostFinalize">Not Installed</Custom>
|
<ns0:Custom Action="JpSetARPHELPLINK" After="CostFinalize" Condition="Not Installed" />
|
||||||
<?endif?>
|
<?endif?>
|
||||||
<?ifdef JpAboutURL ?>
|
<?ifdef JpAboutURL ?>
|
||||||
<Custom Action="JpSetARPURLINFOABOUT" After="CostFinalize">Not Installed</Custom>
|
<ns0:Custom Action="JpSetARPURLINFOABOUT" After="CostFinalize" Condition="Not Installed" />
|
||||||
<?endif?>
|
<?endif?>
|
||||||
<?ifdef JpUpdateURL ?>
|
<?ifdef JpUpdateURL ?>
|
||||||
<Custom Action="JpSetARPURLUPDATEINFO" After="CostFinalize">Not Installed</Custom>
|
<ns0:Custom Action="JpSetARPURLUPDATEINFO" After="CostFinalize" Condition="Not Installed" />
|
||||||
<?endif?>
|
<?endif?>
|
||||||
|
|
||||||
<?ifndef JpAllowUpgrades ?>
|
<?ifndef JpAllowUpgrades ?>
|
||||||
<Custom Action="JpDisallowUpgrade" After="JpFindRelatedProducts">JP_UPGRADABLE_FOUND</Custom>
|
<ns0:Custom Action="JpDisallowUpgrade" After="JpFindRelatedProducts" Condition="JP_UPGRADABLE_FOUND"/>
|
||||||
<?endif?>
|
<?endif?>
|
||||||
<?ifndef JpAllowDowngrades ?>
|
<?ifndef JpAllowDowngrades ?>
|
||||||
<Custom Action="JpDisallowDowngrade" After="JpFindRelatedProducts">JP_DOWNGRADABLE_FOUND</Custom>
|
<ns0:Custom Action="JpDisallowDowngrade" After="JpFindRelatedProducts" Condition="JP_DOWNGRADABLE_FOUND" />
|
||||||
<?endif?>
|
<?endif?>
|
||||||
<Custom Action="JpFindRelatedProducts" After="FindRelatedProducts"/>
|
<ns0:Custom Action="JpFindRelatedProducts" After="FindRelatedProducts"/>
|
||||||
|
|
||||||
<!-- Check and fail if Cryptomator is running -->
|
<!-- Check and fail if Cryptomator is running -->
|
||||||
<Custom Action="WixCloseApplications" Before="InstallValidate"></Custom>
|
<ns0:Custom Action="override Wix4CloseApplications_$(sys.BUILDARCHSHORT)" Before="InstallValidate" />
|
||||||
<Custom Action="FailOnRunningApp" After="WixCloseApplications" >FOUNDRUNNINGAPP</Custom>
|
<ns0:Custom Action="FailOnRunningApp" After="Wix4CloseApplications_$(sys.BUILDARCHSHORT)" Condition="FOUNDRUNNINGAPP" />
|
||||||
|
|
||||||
<RemoveExistingProducts After="InstallValidate"/> <!-- Moved from CostInitialize, due to WixCloseApplications -->
|
<ns0:RemoveExistingProducts After="InstallValidate"/> <!-- Moved from CostInitialize, due to Wix4CloseApplications_* -->
|
||||||
|
<!-- Skip action on uninstall -->
|
||||||
|
<!-- TODO: don't skip action, but remove cryptomator alias from hosts file -->
|
||||||
|
<ns0:Custom Action="PatchWebDAV" After="InstallFiles" Condition="NOT (Installed AND (NOT REINSTALL) AND (NOT UPGRADINGPRODUCTCODE) AND REMOVE)"/>
|
||||||
|
<!-- Configure update check setting if property is provided -->
|
||||||
|
<ns0:Custom Action="PatchUpdateCheck" After="PatchWebDAV" Condition="DISABLEUPDATECHECK AND NOT (Installed AND (NOT REINSTALL) AND (NOT UPGRADINGPRODUCTCODE) AND REMOVE)"/>
|
||||||
|
</ns0:InstallExecuteSequence>
|
||||||
|
|
||||||
<Custom Action="PatchWebDAV" After="InstallFiles">NOT Installed OR REINSTALL</Custom>
|
<ns0:InstallUISequence>
|
||||||
</InstallExecuteSequence>
|
<ns0:Custom Action="JpFindRelatedProducts" After="FindRelatedProducts"/>
|
||||||
|
</ns0:InstallUISequence>
|
||||||
|
|
||||||
<InstallUISequence>
|
<ns0:WixVariable Id="WixUIBannerBmp" Value="$(env.JP_WIXWIZARD_RESOURCES)\banner.bmp" />
|
||||||
<Custom Action="JpFindRelatedProducts" After="FindRelatedProducts"/>
|
<ns0:WixVariable Id="WixUIDialogBmp" Value="$(env.JP_WIXWIZARD_RESOURCES)\background.bmp" />
|
||||||
</InstallUISequence>
|
</ns0:Package>
|
||||||
|
</ns0:Wix>
|
||||||
<WixVariable Id="WixUIBannerBmp" Value="$(env.JP_WIXWIZARD_RESOURCES)\banner.bmp" />
|
|
||||||
<WixVariable Id="WixUIDialogBmp" Value="$(env.JP_WIXWIZARD_RESOURCES)\background.bmp" />
|
|
||||||
</Product>
|
|
||||||
|
|
||||||
</Wix>
|
|
||||||
|
|||||||
Vendored
+2
-2
@@ -41,10 +41,10 @@ Media Type of the encrypted data files. Default is "application/vnd.cryptomator.
|
|||||||
|
|
||||||
Close Application settings:
|
Close Application settings:
|
||||||
- CloseApplicationTarget
|
- CloseApplicationTarget
|
||||||
Full name of executable to be checkd in the close application util. Default is "cryptomator.exe"
|
Full name of executable to be checked in the close application util. Default is "cryptomator.exe"
|
||||||
|
|
||||||
Legacy Installation settings:
|
Legacy Installation settings:
|
||||||
- SkipCryptomatorLegacyCheck
|
- SkipCryptomatorLegacyCheck
|
||||||
Should be defined to disable checking for the inno setup installation of Cryptomator and undefined, to enable it.
|
Should be defined to disable checking for the inno setup installation of Cryptomator and undefined, to enable it.
|
||||||
-->
|
-->
|
||||||
<Include/>
|
<ns0:Include xmlns:ns0="http://wixtoolset.org/schemas/v4/wxs"></ns0:Include>
|
||||||
|
|||||||
Vendored
-16
@@ -1,16 +0,0 @@
|
|||||||
<?xml version="1.0" ?>
|
|
||||||
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
|
|
||||||
<Fragment>
|
|
||||||
<Property Id="WIXUI_INSTALLDIR" Value="INSTALLDIR"></Property>
|
|
||||||
<WixVariable Id="WixUILicenseRtf" Value="$(var.JpLicenseRtf)"></WixVariable>
|
|
||||||
<UI Id="JpUI">
|
|
||||||
<UIRef Id="CustomWizard" />
|
|
||||||
<DialogRef Id="InstallDirNotEmptyDlg"></DialogRef>
|
|
||||||
<Publish Dialog="ShortcutPromptDlg" Control="Back" Event="NewDialog" Value="InstallDirDlg">1</Publish>
|
|
||||||
<Publish Dialog="ShortcutPromptDlg" Control="Next" Event="NewDialog" Value="VerifyReadyDlg">1</Publish>
|
|
||||||
<Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="ShortcutPromptDlg" Order="6">NOT Installed</Publish>
|
|
||||||
<UIRef Id="CustomWizard" />
|
|
||||||
</UI>
|
|
||||||
</Fragment>
|
|
||||||
<?include $(env.JP_WIXWIZARD_RESOURCES)\customWizard.wxi ?>
|
|
||||||
</Wix>
|
|
||||||
+3
-3
@@ -1,6 +1,6 @@
|
|||||||
Apache License v2.0|Apache License, Version 2.0|The Apache Software License, Version 2.0|Apache 2.0|Apache Software License - Version 2.0|Apache-2.0
|
Apache License v2.0|Apache License, Version 2.0|The Apache License, Version 2.0|The Apache Software License, Version 2.0|Apache 2.0|Apache Software License - Version 2.0|Apache-2.0
|
||||||
MIT License|The MIT License (MIT)|The MIT License|MIT license
|
MIT License|MIT|The MIT License (MIT)|The MIT License|MIT license
|
||||||
LGPL 2.1|LGPL, version 2.1|GNU Lesser/Library General Public License version 2|GNU Lesser General Public License Version 2.1
|
LGPL 2.1|LGPL, version 2.1|GNU Lesser/Library General Public License version 2|GNU Lesser General Public License Version 2.1|GNU Lesser General Public License
|
||||||
GPLv2|GNU General Public License Version 2
|
GPLv2|GNU General Public License Version 2
|
||||||
GPLv2+CE|CDDL + GPLv2 with classpath exception
|
GPLv2+CE|CDDL + GPLv2 with classpath exception
|
||||||
Eclipse Public License - Version 1.0|Eclipse Public License - v 1.0
|
Eclipse Public License - Version 1.0|Eclipse Public License - v 1.0
|
||||||
|
|||||||
@@ -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.14.0</version>
|
<version>1.19.0</version>
|
||||||
<name>Cryptomator Desktop App</name>
|
<name>Cryptomator Desktop App</name>
|
||||||
|
|
||||||
<organization>
|
<organization>
|
||||||
@@ -26,59 +26,75 @@
|
|||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
<project.jdk.version>22</project.jdk.version>
|
<project.jdk.version>25</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.7.0-beta1</cryptomator.cryptofs.version>
|
<cryptomator.cryptofs.version>2.9.0</cryptomator.cryptofs.version>
|
||||||
<cryptomator.integrations.version>1.4.0-beta2</cryptomator.integrations.version>
|
<cryptomator.integrations.version>1.8.0-beta1</cryptomator.integrations.version>
|
||||||
<cryptomator.integrations.win.version>1.3.0-beta1</cryptomator.integrations.win.version> <!-- TODO update to 1.3.0 once released -->
|
<cryptomator.integrations.win.version>1.5.1</cryptomator.integrations.win.version>
|
||||||
<cryptomator.integrations.mac.version>1.2.4</cryptomator.integrations.mac.version>
|
<cryptomator.integrations.mac.version>1.5.0-beta1</cryptomator.integrations.mac.version>
|
||||||
<cryptomator.integrations.linux.version>1.5.0-beta4</cryptomator.integrations.linux.version> <!-- TODO update to 1.5.0 once released -->
|
<cryptomator.integrations.linux.version>1.7.0-beta1</cryptomator.integrations.linux.version>
|
||||||
<cryptomator.fuse.version>5.0.0</cryptomator.fuse.version>
|
<cryptomator.fuse.version>5.1.0</cryptomator.fuse.version>
|
||||||
<cryptomator.webdav.version>2.0.6</cryptomator.webdav.version>
|
<cryptomator.webdav.version>3.0.0</cryptomator.webdav.version>
|
||||||
|
|
||||||
<!-- 3rd party dependencies -->
|
<!-- 3rd party dependencies -->
|
||||||
<commons-lang3.version>3.16.0</commons-lang3.version>
|
<commons-lang3.version>3.19.0</commons-lang3.version>
|
||||||
<dagger.version>2.51.1</dagger.version>
|
<dagger.version>2.57.2</dagger.version>
|
||||||
<easybind.version>2.2</easybind.version>
|
<easybind.version>2.2</easybind.version>
|
||||||
<guava.version>33.3.0-jre</guava.version>
|
<jackson.version>2.20.0</jackson.version>
|
||||||
<jackson.version>2.17.2</jackson.version>
|
<javafx.version>25</javafx.version>
|
||||||
<javafx.version>22.0.2</javafx.version>
|
<jwt.version>4.5.0</jwt.version>
|
||||||
<jwt.version>4.4.0</jwt.version>
|
<nimbus-jose.version>10.5</nimbus-jose.version>
|
||||||
<nimbus-jose.version>9.37.3</nimbus-jose.version>
|
<logback.version>1.5.19</logback.version>
|
||||||
<logback.version>1.5.7</logback.version>
|
<slf4j.version>2.0.17</slf4j.version>
|
||||||
<slf4j.version>2.0.16</slf4j.version>
|
<tinyoauth2.version>0.8.1</tinyoauth2.version>
|
||||||
<tinyoauth2.version>0.8.0</tinyoauth2.version>
|
|
||||||
<zxcvbn.version>1.9.0</zxcvbn.version>
|
<zxcvbn.version>1.9.0</zxcvbn.version>
|
||||||
|
|
||||||
<!-- test dependencies -->
|
<!-- test dependencies -->
|
||||||
<junit.jupiter.version>5.11.0</junit.jupiter.version>
|
<junit.jupiter.version>5.13.4</junit.jupiter.version>
|
||||||
<mockito.version>5.12.0</mockito.version>
|
<mockito.version>5.20.0</mockito.version>
|
||||||
<hamcrest.version>3.0</hamcrest.version>
|
<hamcrest.version>3.0</hamcrest.version>
|
||||||
|
|
||||||
<!-- build-time dependencies -->
|
<!-- build-time dependencies -->
|
||||||
<jetbrains.annotations.version>24.1.0</jetbrains.annotations.version>
|
<jetbrains.annotations.version>26.0.2-1</jetbrains.annotations.version>
|
||||||
<dependency-check.version>10.0.3</dependency-check.version>
|
<dependency-check.version>12.1.5</dependency-check.version>
|
||||||
<jacoco.version>0.8.12</jacoco.version>
|
<jacoco.version>0.8.14</jacoco.version>
|
||||||
<license-generator.version>2.4.0</license-generator.version>
|
<license-generator.version>2.7.0</license-generator.version>
|
||||||
<junit-tree-reporter.version>1.3.0</junit-tree-reporter.version>
|
<junit-tree-reporter.version>1.4.0</junit-tree-reporter.version>
|
||||||
<mvn-compiler.version>3.13.0</mvn-compiler.version>
|
<mvn-compiler.version>3.14.1</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.7.1</mvn-dependency.version>
|
<mvn-dependency.version>3.8.1</mvn-dependency.version>
|
||||||
<mvn-surefire.version>3.4.0</mvn-surefire.version>
|
<mvn-surefire.version>3.5.4</mvn-surefire.version>
|
||||||
<mvn-jar.version>3.4.2</mvn-jar.version>
|
<mvn-jar.version>3.4.2</mvn-jar.version>
|
||||||
|
|
||||||
|
<!-- Property used by surefire to determine jacoco engine -->
|
||||||
|
<surefire.jacoco.args></surefire.jacoco.args>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
|
<repositories>
|
||||||
|
<repository>
|
||||||
|
<name>Central Portal Snapshots</name>
|
||||||
|
<id>central-portal-snapshots</id>
|
||||||
|
<url>https://central.sonatype.com/repository/maven-snapshots/</url>
|
||||||
|
<releases>
|
||||||
|
<enabled>false</enabled>
|
||||||
|
</releases>
|
||||||
|
<snapshots>
|
||||||
|
<enabled>true</enabled>
|
||||||
|
</snapshots>
|
||||||
|
</repository>
|
||||||
|
</repositories>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<!-- Cryptomator Libs -->
|
<!-- Cryptomator Libs -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.cryptomator</groupId>
|
<groupId>org.cryptomator</groupId>
|
||||||
<artifactId>cryptolib</artifactId>
|
<artifactId>cryptolib</artifactId>
|
||||||
<version>2.2.0</version>
|
<version>2.2.1</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.cryptomator</groupId>
|
<groupId>org.cryptomator</groupId>
|
||||||
@@ -157,6 +173,12 @@
|
|||||||
<groupId>com.auth0</groupId>
|
<groupId>com.auth0</groupId>
|
||||||
<artifactId>java-jwt</artifactId>
|
<artifactId>java-jwt</artifactId>
|
||||||
<version>${jwt.version}</version>
|
<version>${jwt.version}</version>
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>com.fasterxml.jackson.core</groupId>
|
||||||
|
<artifactId>jackson-core</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.nimbusds</groupId>
|
<groupId>com.nimbusds</groupId>
|
||||||
@@ -191,40 +213,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.2.2</version>
|
||||||
|
</dependency>
|
||||||
<!-- JUnit / Mockito / Hamcrest -->
|
<!-- JUnit / Mockito / Hamcrest -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.junit.jupiter</groupId>
|
<groupId>org.junit.jupiter</groupId>
|
||||||
@@ -253,7 +258,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.google.jimfs</groupId>
|
<groupId>com.google.jimfs</groupId>
|
||||||
<artifactId>jimfs</artifactId>
|
<artifactId>jimfs</artifactId>
|
||||||
<version>1.3.0</version>
|
<version>1.3.1</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
@@ -326,7 +331,6 @@
|
|||||||
<compilerArgs>
|
<compilerArgs>
|
||||||
<arg>-Adagger.fastInit=enabled</arg>
|
<arg>-Adagger.fastInit=enabled</arg>
|
||||||
<arg>-Adagger.formatGeneratedSource=enabled</arg>
|
<arg>-Adagger.formatGeneratedSource=enabled</arg>
|
||||||
<arg>--enable-preview</arg>
|
|
||||||
</compilerArgs>
|
</compilerArgs>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
@@ -353,11 +357,11 @@
|
|||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<configuration>
|
<configuration>
|
||||||
<argLine>--enable-preview</argLine>
|
|
||||||
<reportFormat>plain</reportFormat>
|
<reportFormat>plain</reportFormat>
|
||||||
<consoleOutputReporter>
|
<consoleOutputReporter>
|
||||||
<disable>true</disable>
|
<disable>true</disable>
|
||||||
</consoleOutputReporter>
|
</consoleOutputReporter>
|
||||||
|
<argLine>@{surefire.jacoco.args} -javaagent:${org.mockito:mockito-core:jar} --enable-native-access=javafx.graphics</argLine>
|
||||||
<statelessTestsetInfoReporter
|
<statelessTestsetInfoReporter
|
||||||
implementation="org.apache.maven.plugin.surefire.extensions.junit5.JUnit5StatelessTestsetInfoTreeReporter">
|
implementation="org.apache.maven.plugin.surefire.extensions.junit5.JUnit5StatelessTestsetInfoTreeReporter">
|
||||||
</statelessTestsetInfoReporter>
|
</statelessTestsetInfoReporter>
|
||||||
@@ -367,6 +371,13 @@
|
|||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-dependency-plugin</artifactId>
|
<artifactId>maven-dependency-plugin</artifactId>
|
||||||
<executions>
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>jar-paths-to-properties</id>
|
||||||
|
<phase>validate</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>properties</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
<!-- sort jars into two buckets (classpath and modulepath). exclude openjfx, which gets jlinked separately -->
|
<!-- sort jars into two buckets (classpath and modulepath). exclude openjfx, which gets jlinked separately -->
|
||||||
<execution>
|
<execution>
|
||||||
<id>copy-mods</id>
|
<id>copy-mods</id>
|
||||||
@@ -439,6 +450,9 @@
|
|||||||
<goals>
|
<goals>
|
||||||
<goal>prepare-agent</goal>
|
<goal>prepare-agent</goal>
|
||||||
</goals>
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<propertyName>surefire.jacoco.args</propertyName>
|
||||||
|
</configuration>
|
||||||
</execution>
|
</execution>
|
||||||
<execution>
|
<execution>
|
||||||
<id>report</id>
|
<id>report</id>
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
import ch.qos.logback.classic.spi.Configurator;
|
import ch.qos.logback.classic.spi.Configurator;
|
||||||
|
import org.cryptomator.networking.SSLContextWithPKCS12TrustStore;
|
||||||
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;
|
||||||
@@ -12,6 +14,9 @@ import org.cryptomator.common.locationpresets.OneDriveLinuxLocationPresetsProvid
|
|||||||
import org.cryptomator.common.locationpresets.OneDriveMacLocationPresetsProvider;
|
import org.cryptomator.common.locationpresets.OneDriveMacLocationPresetsProvider;
|
||||||
import org.cryptomator.common.locationpresets.OneDriveWindowsLocationPresetsProvider;
|
import org.cryptomator.common.locationpresets.OneDriveWindowsLocationPresetsProvider;
|
||||||
import org.cryptomator.common.locationpresets.PCloudLocationPresetsProvider;
|
import org.cryptomator.common.locationpresets.PCloudLocationPresetsProvider;
|
||||||
|
import org.cryptomator.networking.SSLContextWithMacKeychain;
|
||||||
|
import org.cryptomator.networking.SSLContextProvider;
|
||||||
|
import org.cryptomator.networking.SSLContextWithWindowsCertStore;
|
||||||
import org.cryptomator.integrations.tray.TrayMenuController;
|
import org.cryptomator.integrations.tray.TrayMenuController;
|
||||||
import org.cryptomator.logging.LogbackConfiguratorFactory;
|
import org.cryptomator.logging.LogbackConfiguratorFactory;
|
||||||
import org.cryptomator.ui.traymenu.AwtTrayMenuController;
|
import org.cryptomator.ui.traymenu.AwtTrayMenuController;
|
||||||
@@ -42,21 +47,26 @@ open module org.cryptomator.desktop {
|
|||||||
requires com.nulabinc.zxcvbn;
|
requires com.nulabinc.zxcvbn;
|
||||||
requires com.tobiasdiez.easybind;
|
requires com.tobiasdiez.easybind;
|
||||||
requires dagger;
|
requires dagger;
|
||||||
requires java.compiler;
|
|
||||||
requires io.github.coffeelibs.tinyoauth2client;
|
requires io.github.coffeelibs.tinyoauth2client;
|
||||||
requires org.slf4j;
|
requires org.slf4j;
|
||||||
requires org.apache.commons.lang3;
|
requires org.apache.commons.lang3;
|
||||||
|
requires com.github.benmanes.caffeine;
|
||||||
|
|
||||||
/* TODO: filename-based modules: */
|
/* dagger bs */
|
||||||
requires static javax.inject; /* ugly dagger/guava crap */
|
requires jakarta.inject;
|
||||||
|
requires static javax.inject;
|
||||||
|
requires java.compiler;
|
||||||
|
|
||||||
uses org.cryptomator.common.locationpresets.LocationPresetsProvider;
|
uses org.cryptomator.common.locationpresets.LocationPresetsProvider;
|
||||||
|
uses SSLContextProvider;
|
||||||
|
uses org.cryptomator.event.NotificationHandler;
|
||||||
|
|
||||||
provides TrayMenuController with AwtTrayMenuController;
|
provides TrayMenuController with AwtTrayMenuController;
|
||||||
provides Configurator with LogbackConfiguratorFactory;
|
provides Configurator with LogbackConfiguratorFactory;
|
||||||
|
provides SSLContextProvider with SSLContextWithWindowsCertStore, SSLContextWithMacKeychain, SSLContextWithPKCS12TrustStore;
|
||||||
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,22 @@
|
|||||||
|
package org.cryptomator;
|
||||||
|
|
||||||
|
import javafx.application.Platform;
|
||||||
|
import java.util.concurrent.CountDownLatch;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
public class JavaFXUtil {
|
||||||
|
|
||||||
|
private 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -74,13 +74,6 @@ public abstract class CommonsModule {
|
|||||||
return new MasterkeyFileAccess(Constants.PEPPER, csprng);
|
return new MasterkeyFileAccess(Constants.PEPPER, csprng);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
|
||||||
@Singleton
|
|
||||||
@Named("SemVer")
|
|
||||||
static Comparator<String> providesSemVerComparator() {
|
|
||||||
return new SemVerComparator();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
static Optional<RevealPathService> provideRevealPathService() {
|
static Optional<RevealPathService> provideRevealPathService() {
|
||||||
|
|||||||
@@ -23,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";
|
||||||
@@ -45,6 +46,7 @@ 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(P12_PATH_PROP_NAME);
|
||||||
logCryptomatorSystemProperty(LOG_DIR_PROP_NAME);
|
logCryptomatorSystemProperty(LOG_DIR_PROP_NAME);
|
||||||
logCryptomatorSystemProperty(LOOPBACK_ALIAS_PROP_NAME);
|
logCryptomatorSystemProperty(LOOPBACK_ALIAS_PROP_NAME);
|
||||||
@@ -85,6 +87,10 @@ 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() {
|
public Stream<Path> getP12Path() {
|
||||||
return getPaths(P12_PATH_PROP_NAME);
|
return getPaths(P12_PATH_PROP_NAME);
|
||||||
}
|
}
|
||||||
@@ -118,6 +124,15 @@ public class Environment {
|
|||||||
return Optional.ofNullable(System.getProperty(BUILD_NUMBER_PROP_NAME));
|
return Optional.ofNullable(System.getProperty(BUILD_NUMBER_PROP_NAME));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the app version concatenated with the build number (if defined).
|
||||||
|
*
|
||||||
|
* @return version string formatted like {@code 1.2.3-4567} or {@code 1.2.3} if no build number is defined.
|
||||||
|
*/
|
||||||
|
public String getAppVersionWithBuildNumber() {
|
||||||
|
return getAppVersion() + getBuildNumber().map("-"::concat).orElse("");
|
||||||
|
}
|
||||||
|
|
||||||
public Optional<Path> getPluginDir() {
|
public Optional<Path> getPluginDir() {
|
||||||
return getPath(PLUGIN_DIR_PROP_NAME);
|
return getPath(PLUGIN_DIR_PROP_NAME);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,160 @@
|
|||||||
|
package org.cryptomator.common;
|
||||||
|
|
||||||
|
import org.cryptomator.cryptofs.event.BrokenDirFileEvent;
|
||||||
|
import org.cryptomator.cryptofs.event.BrokenFileNodeEvent;
|
||||||
|
import org.cryptomator.cryptofs.event.ConflictResolutionFailedEvent;
|
||||||
|
import org.cryptomator.cryptofs.event.ConflictResolvedEvent;
|
||||||
|
import org.cryptomator.cryptofs.event.DecryptionFailedEvent;
|
||||||
|
import org.cryptomator.cryptofs.event.FilesystemEvent;
|
||||||
|
import org.cryptomator.event.VaultEvent;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
import javafx.beans.InvalidationListener;
|
||||||
|
import javafx.collections.FXCollections;
|
||||||
|
import javafx.collections.MapChangeListener;
|
||||||
|
import javafx.collections.ObservableMap;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Map containing {@link VaultEvent}s.
|
||||||
|
* The map is keyed by the ciphertext path of the affected resource _and_ the {@link FilesystemEvent}s class in order to group same events
|
||||||
|
* <p>
|
||||||
|
* Use {@link EventMap#put(VaultEvent)} to add an element and {@link EventMap#remove(VaultEvent)} to remove it.
|
||||||
|
* <p>
|
||||||
|
* The map is size restricted to {@value MAX_SIZE} elements. If a _new_ element (i.e. not already present) is added, the least recently added is removed.
|
||||||
|
*/
|
||||||
|
@Singleton
|
||||||
|
public class EventMap implements ObservableMap<EventMap.EventKey, VaultEvent> {
|
||||||
|
|
||||||
|
private static final int MAX_SIZE = 300;
|
||||||
|
|
||||||
|
public record EventKey(Path ciphertextPath, Class<? extends FilesystemEvent> c) {}
|
||||||
|
|
||||||
|
private final ObservableMap<EventMap.EventKey, VaultEvent> delegate;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public EventMap() {
|
||||||
|
delegate = FXCollections.observableHashMap();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addListener(MapChangeListener<? super EventKey, ? super VaultEvent> mapChangeListener) {
|
||||||
|
delegate.addListener(mapChangeListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeListener(MapChangeListener<? super EventKey, ? super VaultEvent> mapChangeListener) {
|
||||||
|
delegate.removeListener(mapChangeListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int size() {
|
||||||
|
return delegate.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEmpty() {
|
||||||
|
return delegate.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean containsKey(Object key) {
|
||||||
|
return delegate.containsKey(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean containsValue(Object value) {
|
||||||
|
return delegate.containsValue(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public VaultEvent get(Object key) {
|
||||||
|
return delegate.get(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable VaultEvent put(EventKey key, VaultEvent value) {
|
||||||
|
return delegate.put(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public VaultEvent remove(Object key) {
|
||||||
|
return delegate.remove(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void putAll(@NotNull Map<? extends EventKey, ? extends VaultEvent> m) {
|
||||||
|
delegate.putAll(m);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clear() {
|
||||||
|
delegate.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull Set<EventKey> keySet() {
|
||||||
|
return delegate.keySet();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull Collection<VaultEvent> values() {
|
||||||
|
return delegate.values();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull Set<Entry<EventKey, VaultEvent>> entrySet() {
|
||||||
|
return delegate.entrySet();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addListener(InvalidationListener invalidationListener) {
|
||||||
|
delegate.addListener(invalidationListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeListener(InvalidationListener invalidationListener) {
|
||||||
|
delegate.removeListener(invalidationListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void put(VaultEvent e) {
|
||||||
|
//compute key
|
||||||
|
var key = computeKey(e.actualEvent());
|
||||||
|
//if-else
|
||||||
|
var nullOrEntry = delegate.get(key);
|
||||||
|
if (nullOrEntry == null) {
|
||||||
|
if (size() == MAX_SIZE) {
|
||||||
|
delegate.entrySet().stream() //
|
||||||
|
.min(Comparator.comparing(entry -> entry.getValue().actualEvent().getTimestamp())) //
|
||||||
|
.ifPresent(oldestEntry -> delegate.remove(oldestEntry.getKey()));
|
||||||
|
}
|
||||||
|
delegate.put(key, e);
|
||||||
|
} else {
|
||||||
|
delegate.put(key, nullOrEntry.incrementCount(e.actualEvent()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized VaultEvent remove(VaultEvent similar) {
|
||||||
|
//compute key
|
||||||
|
var key = computeKey(similar.actualEvent());
|
||||||
|
return this.remove(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
private EventKey computeKey(FilesystemEvent e) {
|
||||||
|
var p = switch (e) {
|
||||||
|
case DecryptionFailedEvent(_, Path ciphertextPath, _) -> ciphertextPath;
|
||||||
|
case ConflictResolvedEvent(_, _, _, _, Path resolvedCiphertext) -> resolvedCiphertext;
|
||||||
|
case ConflictResolutionFailedEvent(_, _, Path conflictingCiphertext, _) -> conflictingCiphertext;
|
||||||
|
case BrokenDirFileEvent(_, Path ciphertext) -> ciphertext;
|
||||||
|
case BrokenFileNodeEvent(_, _, Path ciphertext) -> ciphertext;
|
||||||
|
};
|
||||||
|
return new EventKey(p, e.getClass());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,81 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
* Copyright (c) 2016, 2017 Sebastian Stenzel and others.
|
|
||||||
* All rights reserved.
|
|
||||||
* This program and the accompanying materials are made available under the terms of the accompanying LICENSE file.
|
|
||||||
*
|
|
||||||
* Contributors:
|
|
||||||
* Sebastian Stenzel - initial API and implementation
|
|
||||||
*******************************************************************************/
|
|
||||||
package org.cryptomator.common;
|
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
|
|
||||||
import java.util.Comparator;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Compares version strings according to <a href="http://semver.org/spec/v2.0.0.html">SemVer 2.0.0</a>.
|
|
||||||
*/
|
|
||||||
public class SemVerComparator implements Comparator<String> {
|
|
||||||
|
|
||||||
private static final char VERSION_SEP = '.'; // http://semver.org/spec/v2.0.0.html#spec-item-2
|
|
||||||
private static final String PRE_RELEASE_SEP = "-"; // http://semver.org/spec/v2.0.0.html#spec-item-9
|
|
||||||
private static final String BUILD_SEP = "+"; // http://semver.org/spec/v2.0.0.html#spec-item-10
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int compare(String version1, String version2) {
|
|
||||||
// "Build metadata SHOULD be ignored when determining version precedence.
|
|
||||||
// Thus two versions that differ only in the build metadata, have the same precedence."
|
|
||||||
String v1WithoutBuildMetadata = StringUtils.substringBefore(version1, BUILD_SEP);
|
|
||||||
String v2WithoutBuildMetadata = StringUtils.substringBefore(version2, BUILD_SEP);
|
|
||||||
|
|
||||||
if (v1WithoutBuildMetadata.equals(v2WithoutBuildMetadata)) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
String v1MajorMinorPatch = StringUtils.substringBefore(v1WithoutBuildMetadata, PRE_RELEASE_SEP);
|
|
||||||
String v2MajorMinorPatch = StringUtils.substringBefore(v2WithoutBuildMetadata, PRE_RELEASE_SEP);
|
|
||||||
String v1PreReleaseVersion = StringUtils.substringAfter(v1WithoutBuildMetadata, PRE_RELEASE_SEP);
|
|
||||||
String v2PreReleaseVersion = StringUtils.substringAfter(v2WithoutBuildMetadata, PRE_RELEASE_SEP);
|
|
||||||
return compare(v1MajorMinorPatch, v1PreReleaseVersion, v2MajorMinorPatch, v2PreReleaseVersion);
|
|
||||||
}
|
|
||||||
|
|
||||||
private int compare(String v1MajorMinorPatch, String v1PreReleaseVersion, String v2MajorMinorPatch, String v2PreReleaseVersion) {
|
|
||||||
int comparisonResult = compareNumericallyThenLexicographically(v1MajorMinorPatch, v2MajorMinorPatch);
|
|
||||||
if (comparisonResult == 0) {
|
|
||||||
if (v1PreReleaseVersion.isEmpty()) {
|
|
||||||
return 1; // 1.0.0 > 1.0.0-BETA
|
|
||||||
} else if (v2PreReleaseVersion.isEmpty()) {
|
|
||||||
return -1; // 1.0.0-BETA < 1.0.0
|
|
||||||
} else {
|
|
||||||
return compareNumericallyThenLexicographically(v1PreReleaseVersion, v2PreReleaseVersion);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return comparisonResult;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private int compareNumericallyThenLexicographically(String version1, String version2) {
|
|
||||||
final String[] vComps1 = StringUtils.split(version1, VERSION_SEP);
|
|
||||||
final String[] vComps2 = StringUtils.split(version2, VERSION_SEP);
|
|
||||||
final int commonCompCount = Math.min(vComps1.length, vComps2.length);
|
|
||||||
|
|
||||||
for (int i = 0; i < commonCompCount; i++) {
|
|
||||||
int subversionComparisonResult = 0;
|
|
||||||
try {
|
|
||||||
final int v1 = Integer.parseInt(vComps1[i]);
|
|
||||||
final int v2 = Integer.parseInt(vComps2[i]);
|
|
||||||
subversionComparisonResult = v1 - v2;
|
|
||||||
} catch (NumberFormatException ex) {
|
|
||||||
// ok, lets compare this fragment lexicographically
|
|
||||||
subversionComparisonResult = vComps1[i].compareTo(vComps2[i]);
|
|
||||||
}
|
|
||||||
if (subversionComparisonResult != 0) {
|
|
||||||
return subversionComparisonResult;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// all in common so far? longest version string is considered the higher version:
|
|
||||||
return vComps1.length - vComps2.length;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
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.common.Passphrase;
|
||||||
import org.cryptomator.integrations.keychain.KeychainAccessException;
|
import org.cryptomator.integrations.keychain.KeychainAccessException;
|
||||||
import org.cryptomator.integrations.keychain.KeychainAccessProvider;
|
import org.cryptomator.integrations.keychain.KeychainAccessProvider;
|
||||||
|
|
||||||
@@ -14,20 +14,24 @@ import javafx.beans.property.BooleanProperty;
|
|||||||
import javafx.beans.property.ReadOnlyBooleanProperty;
|
import javafx.beans.property.ReadOnlyBooleanProperty;
|
||||||
import javafx.beans.property.SimpleBooleanProperty;
|
import javafx.beans.property.SimpleBooleanProperty;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
public class KeychainManager implements KeychainAccessProvider {
|
public class KeychainManager implements KeychainAccessProvider {
|
||||||
|
|
||||||
private final ObjectExpression<KeychainAccessProvider> keychain;
|
private final ObjectExpression<KeychainAccessProvider> keychain;
|
||||||
private final LoadingCache<String, BooleanProperty> passphraseStoredProperties;
|
private final LoadingCache<String, BooleanProperty> passphraseStoredProperties;
|
||||||
|
private final ReentrantReadWriteLock lock;
|
||||||
|
|
||||||
@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());
|
||||||
|
this.lock = new ReentrantReadWriteLock(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private KeychainAccessProvider getKeychainOrFail() throws KeychainAccessException {
|
private KeychainAccessProvider getKeychainOrFail() throws KeychainAccessException {
|
||||||
@@ -38,34 +42,50 @@ public class KeychainManager implements KeychainAccessProvider {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String displayName() {
|
|
||||||
return getClass().getName();
|
|
||||||
}
|
|
||||||
|
|
||||||
@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);
|
try {
|
||||||
|
lock.writeLock().lock();
|
||||||
|
getKeychainOrFail().storePassphrase(key, displayName, passphrase);
|
||||||
|
} finally {
|
||||||
|
lock.writeLock().unlock();
|
||||||
|
}
|
||||||
setPassphraseStored(key, true);
|
setPassphraseStored(key, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public char[] loadPassphrase(String key) throws KeychainAccessException {
|
public char[] loadPassphrase(String key) throws KeychainAccessException {
|
||||||
char[] passphrase = getKeychainOrFail().loadPassphrase(key);
|
char[] passphrase = null;
|
||||||
|
try {
|
||||||
|
lock.readLock().lock();
|
||||||
|
passphrase = getKeychainOrFail().loadPassphrase(key);
|
||||||
|
} finally {
|
||||||
|
lock.readLock().unlock();
|
||||||
|
}
|
||||||
setPassphraseStored(key, passphrase != null);
|
setPassphraseStored(key, passphrase != null);
|
||||||
return passphrase;
|
return passphrase;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void deletePassphrase(String key) throws KeychainAccessException {
|
public void deletePassphrase(String key) throws KeychainAccessException {
|
||||||
getKeychainOrFail().deletePassphrase(key);
|
try {
|
||||||
|
lock.writeLock().lock();
|
||||||
|
getKeychainOrFail().deletePassphrase(key);
|
||||||
|
} finally {
|
||||||
|
lock.writeLock().unlock();
|
||||||
|
}
|
||||||
setPassphraseStored(key, false);
|
setPassphraseStored(key, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void changePassphrase(String key, String displayName, CharSequence passphrase) throws KeychainAccessException {
|
public void changePassphrase(String key, String displayName, CharSequence passphrase) throws KeychainAccessException {
|
||||||
if (isPassphraseStored(key)) {
|
if (isPassphraseStored(key)) {
|
||||||
getKeychainOrFail().changePassphrase(key, displayName, passphrase);
|
try {
|
||||||
|
lock.writeLock().lock();
|
||||||
|
getKeychainOrFail().changePassphrase(key, displayName, passphrase);
|
||||||
|
} finally {
|
||||||
|
lock.writeLock().unlock();
|
||||||
|
}
|
||||||
setPassphraseStored(key, true);
|
setPassphraseStored(key, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -102,13 +122,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 +142,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 +153,22 @@ public class KeychainManager implements KeychainAccessProvider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ObjectExpression<KeychainAccessProvider> getKeychainImplementation() {
|
||||||
|
return this.keychain;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void migrate(KeychainAccessProvider oldProvider, KeychainAccessProvider newProvider, Map<String, String> idsAndNames) throws KeychainAccessException {
|
||||||
|
if (oldProvider instanceof KeychainManager || newProvider instanceof KeychainManager) {
|
||||||
|
throw new IllegalArgumentException("KeychainManger must not be the source or target of migration");
|
||||||
|
}
|
||||||
|
for (var entry : idsAndNames.entrySet()) {
|
||||||
|
var passphrase = oldProvider.loadPassphrase(entry.getKey());
|
||||||
|
if (passphrase != null) {
|
||||||
|
var wrapper = new Passphrase(passphrase);
|
||||||
|
oldProvider.deletePassphrase(entry.getKey()); //we cannot apply "first-write-then-delete" pattern here, since we can potentially write to the same passphrase store (e.g., touchID and regular keychain)
|
||||||
|
newProvider.storePassphrase(entry.getKey(), entry.getValue(), wrapper);
|
||||||
|
wrapper.destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+144
@@ -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 project’s 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");
|
||||||
|
}
|
||||||
+1
-4
@@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -160,7 +160,7 @@ public class Mounter {
|
|||||||
var mountService = mountProviders.stream().filter(s -> s.getClass().getName().equals(vaultSettings.mountService.getValue())).findFirst().orElse(defaultMountService.getValue());
|
var mountService = mountProviders.stream().filter(s -> s.getClass().getName().equals(vaultSettings.mountService.getValue())).findFirst().orElse(defaultMountService.getValue());
|
||||||
|
|
||||||
if (isConflictingMountService(mountService)) {
|
if (isConflictingMountService(mountService)) {
|
||||||
var msg = STR."\{mountService.getClass()} unavailable due to conflict with either of \{CONFLICTING_MOUNT_SERVICES.get(mountService.getClass().getName())}";
|
var msg = mountService.getClass() + " unavailable due to conflict with either of " + CONFLICTING_MOUNT_SERVICES.get(mountService.getClass().getName());
|
||||||
throw new ConflictingMountServiceException(msg);
|
throw new ConflictingMountServiceException(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,53 @@
|
|||||||
|
package org.cryptomator.common.recovery;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.StandardCopyOption;
|
||||||
|
import java.nio.file.attribute.FileTime;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import static org.cryptomator.common.Constants.MASTERKEY_BACKUP_SUFFIX;
|
||||||
|
|
||||||
|
public final class BackupRestorer {
|
||||||
|
|
||||||
|
private static final Logger LOG = LoggerFactory.getLogger(BackupRestorer.class);
|
||||||
|
|
||||||
|
private BackupRestorer() {}
|
||||||
|
|
||||||
|
public static void restoreIfBackupPresent(Path vaultPath, String filePrefix) {
|
||||||
|
Path targetFile = vaultPath.resolve(filePrefix);
|
||||||
|
|
||||||
|
try (Stream<Path> files = Files.list(vaultPath)) {
|
||||||
|
files.filter(file -> isFileMatchingPattern(file.getFileName().toString(), filePrefix))
|
||||||
|
.max((f1, f2) -> {
|
||||||
|
try {
|
||||||
|
FileTime time1 = Files.getLastModifiedTime(f1);
|
||||||
|
FileTime time2 = Files.getLastModifiedTime(f2);
|
||||||
|
return time1.compareTo(time2);
|
||||||
|
} catch (IOException e) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.ifPresent(backupFile -> copyBackupFile(backupFile, targetFile));
|
||||||
|
} catch (IOException e) {
|
||||||
|
LOG.info("Unable to restore backup files in '{}'", vaultPath, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isFileMatchingPattern(String fileName, String filePrefix) {
|
||||||
|
return fileName.startsWith(filePrefix) && fileName.endsWith(MASTERKEY_BACKUP_SUFFIX);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void copyBackupFile(Path backupFile, Path configPath) {
|
||||||
|
try {
|
||||||
|
Files.copy(backupFile, configPath, StandardCopyOption.REPLACE_EXISTING);
|
||||||
|
LOG.debug("Backup restored - file: '{}' path: '{}'", backupFile, configPath);
|
||||||
|
} catch (IOException e) {
|
||||||
|
LOG.warn("Unable to copy backup file from '{}' to '{}'", backupFile, configPath, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package org.cryptomator.common.recovery;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
|
||||||
|
import org.cryptomator.cryptofs.CryptoFileSystemProperties;
|
||||||
|
import org.cryptomator.cryptofs.CryptoFileSystemProvider;
|
||||||
|
import org.cryptomator.cryptolib.api.Masterkey;
|
||||||
|
import org.cryptomator.cryptolib.api.CryptorProvider;
|
||||||
|
import org.cryptomator.cryptolib.api.CryptoException;
|
||||||
|
import org.cryptomator.cryptolib.api.MasterkeyLoader;
|
||||||
|
|
||||||
|
import static org.cryptomator.common.Constants.DEFAULT_KEY_ID;
|
||||||
|
|
||||||
|
public final class CryptoFsInitializer {
|
||||||
|
|
||||||
|
private CryptoFsInitializer() {}
|
||||||
|
|
||||||
|
public static void init(Path recoveryPath,
|
||||||
|
Masterkey masterkey,
|
||||||
|
int shorteningThreshold,
|
||||||
|
CryptorProvider.Scheme scheme) throws IOException, CryptoException {
|
||||||
|
|
||||||
|
MasterkeyLoader loader = ignored -> masterkey.copy();
|
||||||
|
CryptoFileSystemProperties fsProps = CryptoFileSystemProperties //
|
||||||
|
.cryptoFileSystemProperties() //
|
||||||
|
.withCipherCombo(scheme) //
|
||||||
|
.withKeyLoader(loader) //
|
||||||
|
.withShorteningThreshold(shorteningThreshold) //
|
||||||
|
.build();
|
||||||
|
CryptoFileSystemProvider.initialize(recoveryPath, fsProps, DEFAULT_KEY_ID);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,101 @@
|
|||||||
|
package org.cryptomator.common.recovery;
|
||||||
|
|
||||||
|
import org.cryptomator.common.vaults.Vault;
|
||||||
|
import org.cryptomator.cryptolib.api.CryptoException;
|
||||||
|
import org.cryptomator.cryptolib.api.Cryptor;
|
||||||
|
import org.cryptomator.cryptolib.api.CryptorProvider;
|
||||||
|
import org.cryptomator.cryptolib.api.Masterkey;
|
||||||
|
import org.cryptomator.cryptolib.common.MasterkeyFileAccess;
|
||||||
|
import org.cryptomator.ui.recoverykey.RecoveryKeyFactory;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.channels.FileChannel;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.StandardOpenOption;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.security.SecureRandom;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.NoSuchElementException;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import static org.cryptomator.common.Constants.MASTERKEY_FILENAME;
|
||||||
|
import static org.cryptomator.cryptofs.common.Constants.DATA_DIR_NAME;
|
||||||
|
|
||||||
|
public final class MasterkeyService {
|
||||||
|
|
||||||
|
private static final Logger LOG = LoggerFactory.getLogger(MasterkeyService.class);
|
||||||
|
|
||||||
|
private MasterkeyService() {}
|
||||||
|
|
||||||
|
public static void recoverFromRecoveryKey(String recoveryKey, RecoveryKeyFactory recoveryKeyFactory, Path recoveryPath, CharSequence newPassword) throws IOException {
|
||||||
|
recoveryKeyFactory.newMasterkeyFileWithPassphrase(recoveryPath, recoveryKey, newPassword);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Masterkey load(MasterkeyFileAccess masterkeyFileAccess, Path masterkeyFilePath, CharSequence password) throws IOException {
|
||||||
|
return masterkeyFileAccess.load(masterkeyFilePath, password);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static CryptorProvider.Scheme validateRecoveryKeyAndDetectCombo(RecoveryKeyFactory recoveryKeyFactory, //
|
||||||
|
Vault vault, String recoveryKey, //
|
||||||
|
MasterkeyFileAccess masterkeyFileAccess) throws IOException, CryptoException, NoSuchElementException {
|
||||||
|
String tmpPass = UUID.randomUUID().toString();
|
||||||
|
try (RecoveryDirectory recoveryDirectory = RecoveryDirectory.create(vault.getPath())) {
|
||||||
|
Path tempRecoveryPath = recoveryDirectory.getRecoveryPath();
|
||||||
|
recoverFromRecoveryKey(recoveryKey, recoveryKeyFactory, tempRecoveryPath, tmpPass);
|
||||||
|
Path masterkeyFilePath = tempRecoveryPath.resolve(MASTERKEY_FILENAME);
|
||||||
|
|
||||||
|
try (Masterkey mk = load(masterkeyFileAccess, masterkeyFilePath, tmpPass)) {
|
||||||
|
return detect(mk, vault.getPath()).orElseThrow();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Optional<CryptorProvider.Scheme> detect(Masterkey masterkey, Path vaultPath) {
|
||||||
|
try (Stream<Path> paths = Files.walk(vaultPath.resolve(DATA_DIR_NAME))) {
|
||||||
|
Optional<Path> c9rFile = paths //
|
||||||
|
.filter(p -> p.toString().endsWith(".c9r")) //
|
||||||
|
.filter(p -> !p.endsWith("dir.c9r")) //
|
||||||
|
.findFirst();
|
||||||
|
if (c9rFile.isEmpty()) {
|
||||||
|
LOG.info("Unable to detect Crypto scheme: No *.c9r file found in {}", vaultPath);
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
return determineScheme(c9rFile.get(), masterkey);
|
||||||
|
} catch (IOException e) {
|
||||||
|
LOG.info("Unable to detect Crypto scheme: Failed to inspect vault", e);
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Optional<CryptorProvider.Scheme> determineScheme(Path c9rFile, Masterkey masterkey) {
|
||||||
|
return Arrays.stream(CryptorProvider.Scheme.values()).filter(scheme -> {
|
||||||
|
try (Cryptor cryptor = CryptorProvider.forScheme(scheme).provide(masterkey.copy(), SecureRandom.getInstanceStrong())) {
|
||||||
|
int headerSize = cryptor.fileHeaderCryptor().headerSize();
|
||||||
|
|
||||||
|
ByteBuffer headerBuf = ByteBuffer.allocate(headerSize);
|
||||||
|
|
||||||
|
try (FileChannel channel = FileChannel.open(c9rFile, StandardOpenOption.READ)) {
|
||||||
|
channel.read(headerBuf, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
headerBuf.flip();
|
||||||
|
cryptor.fileHeaderCryptor().decryptHeader(headerBuf.duplicate());
|
||||||
|
LOG.debug("Detected Crypto scheme: {}", scheme);
|
||||||
|
return true;
|
||||||
|
} catch (IllegalArgumentException | CryptoException e) {
|
||||||
|
LOG.debug("Could not decrypt with scheme: {}", scheme);
|
||||||
|
return false;
|
||||||
|
} catch (IOException | NoSuchAlgorithmException e) {
|
||||||
|
LOG.warn("Unable to detect Crypto scheme: Failed to decrypt .c9r file", e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}).findFirst();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package org.cryptomator.common.recovery;
|
||||||
|
|
||||||
|
public enum RecoveryActionType {
|
||||||
|
RESTORE_ALL,
|
||||||
|
RESTORE_MASTERKEY,
|
||||||
|
RESTORE_VAULT_CONFIG,
|
||||||
|
RESET_PASSWORD,
|
||||||
|
SHOW_KEY,
|
||||||
|
CONVERT_VAULT
|
||||||
|
}
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
package org.cryptomator.common.recovery;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.StandardCopyOption;
|
||||||
|
import java.util.Comparator;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public final class RecoveryDirectory implements AutoCloseable {
|
||||||
|
|
||||||
|
private static final Logger LOG = LoggerFactory.getLogger(RecoveryDirectory.class);
|
||||||
|
|
||||||
|
private final Path recoveryPath;
|
||||||
|
private final Path vaultPath;
|
||||||
|
|
||||||
|
private RecoveryDirectory(Path vaultPath, Path recoveryPath) {
|
||||||
|
this.vaultPath = vaultPath;
|
||||||
|
this.recoveryPath = recoveryPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static RecoveryDirectory create(Path vaultPath) throws IOException {
|
||||||
|
Path tempDir = Files.createTempDirectory("cryptomator");
|
||||||
|
return new RecoveryDirectory(vaultPath, tempDir);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void moveRecoveredFile(String file) throws IOException {
|
||||||
|
Files.move(recoveryPath.resolve(file), vaultPath.resolve(file), StandardCopyOption.REPLACE_EXISTING);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void deleteRecoveryDirectory() {
|
||||||
|
try (var paths = Files.walk(recoveryPath)) {
|
||||||
|
paths.sorted(Comparator.reverseOrder()).forEach(p -> {
|
||||||
|
try {
|
||||||
|
Files.delete(p);
|
||||||
|
} catch (IOException e) {
|
||||||
|
LOG.info("Unable to delete {}. Please delete it manually.", p);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (IOException e) {
|
||||||
|
LOG.error("Failed to clean up recovery directory", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
deleteRecoveryDirectory();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Path getRecoveryPath() {
|
||||||
|
return recoveryPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
package org.cryptomator.common.recovery;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.SystemUtils;
|
||||||
|
import org.cryptomator.common.settings.VaultSettings;
|
||||||
|
import org.cryptomator.common.vaults.Vault;
|
||||||
|
import org.cryptomator.common.vaults.VaultComponent;
|
||||||
|
import org.cryptomator.common.vaults.VaultConfigCache;
|
||||||
|
import org.cryptomator.common.vaults.VaultListManager;
|
||||||
|
import org.cryptomator.integrations.mount.MountService;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.ResourceBundle;
|
||||||
|
|
||||||
|
import static org.cryptomator.common.vaults.VaultState.Value.LOCKED;
|
||||||
|
|
||||||
|
public final class VaultPreparator {
|
||||||
|
|
||||||
|
private static final Logger LOG = LoggerFactory.getLogger(VaultPreparator.class);
|
||||||
|
|
||||||
|
private VaultPreparator() {}
|
||||||
|
|
||||||
|
public static Vault prepareVault(Path selectedDirectory, //
|
||||||
|
VaultComponent.Factory vaultComponentFactory, //
|
||||||
|
List<MountService> mountServices, //
|
||||||
|
ResourceBundle resourceBundle) {
|
||||||
|
VaultSettings vaultSettings = VaultSettings.withRandomId();
|
||||||
|
vaultSettings.path.set(selectedDirectory);
|
||||||
|
if (selectedDirectory.getFileName() != null) {
|
||||||
|
vaultSettings.displayName.set(selectedDirectory.getFileName().toString());
|
||||||
|
} else {
|
||||||
|
vaultSettings.displayName.set(resourceBundle.getString("defaults.vault.vaultName"));
|
||||||
|
}
|
||||||
|
|
||||||
|
var wrapper = new VaultConfigCache(vaultSettings);
|
||||||
|
Vault vault = vaultComponentFactory.create(vaultSettings, wrapper, LOCKED, null).vault();
|
||||||
|
try {
|
||||||
|
VaultListManager.determineVaultState(vault.getPath());
|
||||||
|
} catch (IOException e) {
|
||||||
|
LOG.warn("Failed to determine vault state for {}", vaultSettings.path.get(), e);
|
||||||
|
}
|
||||||
|
|
||||||
|
//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 vault;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -25,14 +25,13 @@ 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.nio.file.Path;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
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;
|
||||||
@@ -45,16 +44,15 @@ public class Settings {
|
|||||||
@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" : //
|
static final String DEFAULT_KEYCHAIN_PROVIDER = SystemUtils.IS_OS_WINDOWS ? "org.cryptomator.windows.keychain.WindowsProtectedKeychainAccess" : //
|
||||||
SystemUtils.IS_OS_MAC ? "org.cryptomator.macos.keychain.MacSystemKeychainAccess" : //
|
SystemUtils.IS_OS_MAC ? "org.cryptomator.macos.keychain.MacSystemKeychainAccess" : //
|
||||||
"org.cryptomator.linux.keychain.SecretServiceKeychainAccess";
|
"org.cryptomator.linux.keychain.GnomeKeyringKeychainAccess";
|
||||||
static final String DEFAULT_QUICKACCESS_SERVICE = SystemUtils.IS_OS_WINDOWS ? "org.cryptomator.windows.quickaccess.ExplorerQuickAccessService" : //
|
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;
|
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");
|
public static final Instant DEFAULT_TIMESTAMP = Instant.parse("2000-01-01T00:00:00Z");
|
||||||
|
|
||||||
|
private final SettingsProvider provider;
|
||||||
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;
|
||||||
@@ -67,22 +65,24 @@ public class Settings {
|
|||||||
public final StringProperty quickAccessService;
|
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 BooleanProperty checkForUpdates;
|
||||||
|
public final ObjectProperty<Instant> lastUpdateCheckReminder;
|
||||||
public final ObjectProperty<Instant> lastSuccessfulUpdateCheck;
|
public final ObjectProperty<Instant> lastSuccessfulUpdateCheck;
|
||||||
|
public final ObjectProperty<Path> previouslyUsedVaultDirectory;
|
||||||
|
public final StringProperty lastUpdateAttemptedByVersion;
|
||||||
|
|
||||||
private Consumer<Settings> saveCmd;
|
public static Settings create(SettingsProvider provider, Environment env) {
|
||||||
|
|
||||||
public static Settings create(Environment env) {
|
|
||||||
var defaults = new SettingsJson();
|
var defaults = new SettingsJson();
|
||||||
defaults.showTrayIcon = env.showTrayIcon();
|
defaults.showTrayIcon = env.showTrayIcon();
|
||||||
return new Settings(defaults);
|
return new Settings(provider, defaults);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -90,10 +90,9 @@ public class Settings {
|
|||||||
*
|
*
|
||||||
* @param json The parsed settings.json
|
* @param json The parsed settings.json
|
||||||
*/
|
*/
|
||||||
Settings(SettingsJson json) {
|
Settings(SettingsProvider provider, SettingsJson json) {
|
||||||
|
this.provider = provider;
|
||||||
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);
|
||||||
@@ -105,8 +104,8 @@ 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);
|
||||||
@@ -114,15 +113,17 @@ public class Settings {
|
|||||||
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.quickAccessService = new SimpleStringProperty(this, "quickAccessService", json.quickAccessService);
|
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.lastSuccessfulUpdateCheck = new SimpleObjectProperty<>(this, "lastSuccessfulUpdateCheck", json.lastSuccessfulUpdateCheck);
|
||||||
|
this.previouslyUsedVaultDirectory = new SimpleObjectProperty<>(this, "previouslyUsedVaultDirectory", json.previouslyUsedVaultDirectory);
|
||||||
|
this.lastUpdateAttemptedByVersion = new SimpleStringProperty(this, "lastUpdateAttemptedByVersion", json.lastUpdateAttemptedByVersion);
|
||||||
|
|
||||||
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);
|
||||||
@@ -134,8 +135,8 @@ 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);
|
||||||
@@ -143,11 +144,20 @@ public class Settings {
|
|||||||
language.addListener(this::somethingChanged);
|
language.addListener(this::somethingChanged);
|
||||||
mountService.addListener(this::somethingChanged);
|
mountService.addListener(this::somethingChanged);
|
||||||
quickAccessService.addListener(this::somethingChanged);
|
quickAccessService.addListener(this::somethingChanged);
|
||||||
|
checkForUpdates.addListener(this::somethingChanged);
|
||||||
|
lastUpdateCheckReminder.addListener(this::somethingChanged);
|
||||||
lastSuccessfulUpdateCheck.addListener(this::somethingChanged);
|
lastSuccessfulUpdateCheck.addListener(this::somethingChanged);
|
||||||
|
previouslyUsedVaultDirectory.addListener(this::somethingChanged);
|
||||||
|
lastUpdateAttemptedByVersion.addListener(this::somethingChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
private void migrateLegacySettings(SettingsJson json) {
|
private void migrateLegacySettings(SettingsJson json) {
|
||||||
|
// migrate renamed keychainAccess
|
||||||
|
if(this.keychainProvider.getValueSafe().equals("org.cryptomator.linux.keychain.SecretServiceKeychainAccess")) {
|
||||||
|
this.keychainProvider.setValue("org.cryptomator.linux.keychain.GnomeKeyringKeychainAccess");
|
||||||
|
}
|
||||||
|
|
||||||
// implicit migration of 1.6.x legacy setting "preferredVolumeImpl":
|
// implicit migration of 1.6.x legacy setting "preferredVolumeImpl":
|
||||||
if (this.mountService.get() == null && json.preferredVolumeImpl != null) {
|
if (this.mountService.get() == null && json.preferredVolumeImpl != null) {
|
||||||
this.mountService.set(switch (json.preferredVolumeImpl) {
|
this.mountService.set(switch (json.preferredVolumeImpl) {
|
||||||
@@ -177,8 +187,6 @@ 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();
|
||||||
@@ -190,8 +198,8 @@ 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();
|
||||||
@@ -199,7 +207,11 @@ public class Settings {
|
|||||||
json.language = language.get();
|
json.language = language.get();
|
||||||
json.mountService = mountService.get();
|
json.mountService = mountService.get();
|
||||||
json.quickAccessService = quickAccessService.get();
|
json.quickAccessService = quickAccessService.get();
|
||||||
|
json.checkForUpdatesEnabled = checkForUpdates.get();
|
||||||
|
json.lastReminderForUpdateCheck = lastUpdateCheckReminder.get();
|
||||||
json.lastSuccessfulUpdateCheck = lastSuccessfulUpdateCheck.get();
|
json.lastSuccessfulUpdateCheck = lastSuccessfulUpdateCheck.get();
|
||||||
|
json.previouslyUsedVaultDirectory = previouslyUsedVaultDirectory.get();
|
||||||
|
json.lastUpdateAttemptedByVersion = lastUpdateAttemptedByVersion.get();
|
||||||
return json;
|
return json;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -212,20 +224,12 @@ public class Settings {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// TODO rename to setChangeListener
|
|
||||||
void setSaveCmd(Consumer<Settings> saveCmd) {
|
|
||||||
this.saveCmd = saveCmd;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void somethingChanged(@SuppressWarnings("unused") Observable observable) {
|
private void somethingChanged(@SuppressWarnings("unused") Observable observable) {
|
||||||
this.save();
|
provider.scheduleSave(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void save() {
|
public void saveNow() {
|
||||||
if (saveCmd != null) {
|
provider.saveNow(this);
|
||||||
saveCmd.accept(this);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ 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.nio.file.Path;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -18,15 +19,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;
|
||||||
|
|
||||||
@@ -51,12 +46,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;
|
||||||
|
|
||||||
@@ -82,6 +77,13 @@ 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("checkForUpdatesEnabled")
|
||||||
|
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")
|
@JsonProperty("lastSuccessfulUpdateCheck")
|
||||||
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss'Z'", timezone = "UTC")
|
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss'Z'", timezone = "UTC")
|
||||||
Instant lastSuccessfulUpdateCheck = Settings.DEFAULT_TIMESTAMP;
|
Instant lastSuccessfulUpdateCheck = Settings.DEFAULT_TIMESTAMP;
|
||||||
@@ -91,4 +93,10 @@ class SettingsJson {
|
|||||||
|
|
||||||
@JsonProperty("quickAccessService")
|
@JsonProperty("quickAccessService")
|
||||||
String quickAccessService = Settings.DEFAULT_QUICKACCESS_SERVICE;
|
String quickAccessService = Settings.DEFAULT_QUICKACCESS_SERVICE;
|
||||||
|
|
||||||
|
@JsonProperty("previouslyUsedVaultDirectory")
|
||||||
|
Path previouslyUsedVaultDirectory;
|
||||||
|
|
||||||
|
@JsonProperty("lastUpdateAttemptedByVersion")
|
||||||
|
String lastUpdateAttemptedByVersion;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,9 @@ import java.nio.file.NoSuchFileException;
|
|||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.StandardCopyOption;
|
import java.nio.file.StandardCopyOption;
|
||||||
import java.nio.file.StandardOpenOption;
|
import java.nio.file.StandardOpenOption;
|
||||||
import java.util.Optional;
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
import java.util.concurrent.ScheduledExecutorService;
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
import java.util.concurrent.ScheduledFuture;
|
import java.util.concurrent.ScheduledFuture;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
@@ -61,8 +63,7 @@ public class SettingsProvider implements Supplier<Settings> {
|
|||||||
Settings settings = env.getSettingsPath() //
|
Settings settings = env.getSettingsPath() //
|
||||||
.flatMap(this::tryLoad) //
|
.flatMap(this::tryLoad) //
|
||||||
.findFirst() //
|
.findFirst() //
|
||||||
.orElseGet(() -> Settings.create(env));
|
.orElseGet(() -> Settings.create(this, env));
|
||||||
settings.setSaveCmd(this::scheduleSave);
|
|
||||||
return settings;
|
return settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,7 +72,7 @@ public class SettingsProvider implements Supplier<Settings> {
|
|||||||
try (InputStream in = Files.newInputStream(path, StandardOpenOption.READ)) {
|
try (InputStream in = Files.newInputStream(path, StandardOpenOption.READ)) {
|
||||||
var json = JSON.reader().readValue(in, SettingsJson.class);
|
var json = JSON.reader().readValue(in, SettingsJson.class);
|
||||||
LOG.info("Settings loaded from {}", path);
|
LOG.info("Settings loaded from {}", path);
|
||||||
var settings = new Settings(json);
|
var settings = new Settings(this, json);
|
||||||
return Stream.of(settings);
|
return Stream.of(settings);
|
||||||
} catch (JacksonException e) {
|
} catch (JacksonException e) {
|
||||||
LOG.warn("Failed to parse json file {}", path, e);
|
LOG.warn("Failed to parse json file {}", path, e);
|
||||||
@@ -84,19 +85,33 @@ public class SettingsProvider implements Supplier<Settings> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void scheduleSave(Settings settings) {
|
void saveNow(Settings settings) {
|
||||||
if (settings == null) {
|
try {
|
||||||
return;
|
scheduleSave(settings, 0L).get();
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
LOG.error("Saving settings was interrupted.", e);
|
||||||
|
} catch (ExecutionException e) {
|
||||||
|
LOG.error("Unexpected exception while saving.", e);
|
||||||
}
|
}
|
||||||
final Optional<Path> settingsPath = env.getSettingsPath().findFirst(); // always save to preferred (first) path
|
}
|
||||||
settingsPath.ifPresent(path -> {
|
|
||||||
Runnable saveCommand = () -> this.save(settings, path);
|
void scheduleSave(Settings settings) {
|
||||||
ScheduledFuture<?> scheduledTask = scheduler.schedule(saveCommand, SAVE_DELAY_MS, TimeUnit.MILLISECONDS);
|
scheduleSave(settings, SAVE_DELAY_MS);
|
||||||
ScheduledFuture<?> previouslyScheduledTask = scheduledSaveCmd.getAndSet(scheduledTask);
|
}
|
||||||
if (previouslyScheduledTask != null) {
|
|
||||||
previouslyScheduledTask.cancel(false);
|
private Future<?> scheduleSave(Settings settings, long delayMillis) {
|
||||||
}
|
if (settings == null) {
|
||||||
});
|
return CompletableFuture.completedFuture(null);
|
||||||
|
}
|
||||||
|
final Path settingsPath = env.getSettingsPath().findFirst().orElseThrow(); // always save to preferred (first) path
|
||||||
|
Runnable saveCommand = () -> this.save(settings, settingsPath);
|
||||||
|
ScheduledFuture<?> scheduledTask = scheduler.schedule(saveCommand, delayMillis, TimeUnit.MILLISECONDS);
|
||||||
|
ScheduledFuture<?> previouslyScheduledTask = scheduledSaveCmd.getAndSet(scheduledTask);
|
||||||
|
if (previouslyScheduledTask != null) {
|
||||||
|
previouslyScheduledTask.cancel(false);
|
||||||
|
}
|
||||||
|
return scheduledTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void save(Settings settings, Path settingsPath) {
|
private void save(Settings settings, Path settingsPath) {
|
||||||
@@ -107,7 +122,7 @@ public class SettingsProvider implements Supplier<Settings> {
|
|||||||
Path tmpPath = settingsPath.resolveSibling(settingsPath.getFileName().toString() + ".tmp");
|
Path tmpPath = settingsPath.resolveSibling(settingsPath.getFileName().toString() + ".tmp");
|
||||||
try (OutputStream out = Files.newOutputStream(tmpPath, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.WRITE)) {
|
try (OutputStream out = Files.newOutputStream(tmpPath, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.WRITE)) {
|
||||||
var jsonObj = settings.serialized();
|
var jsonObj = settings.serialized();
|
||||||
jsonObj.writtenByVersion = env.getAppVersion() + env.getBuildNumber().map("-"::concat).orElse("");
|
jsonObj.writtenByVersion = env.getAppVersionWithBuildNumber();
|
||||||
JSON.writerWithDefaultPrettyPrinter().writeValue(out, jsonObj);
|
JSON.writerWithDefaultPrettyPrinter().writeValue(out, jsonObj);
|
||||||
}
|
}
|
||||||
Files.move(tmpPath, settingsPath, StandardCopyOption.REPLACE_EXISTING);
|
Files.move(tmpPath, settingsPath, StandardCopyOption.REPLACE_EXISTING);
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ public class VaultSettings {
|
|||||||
public final StringExpression mountName;
|
public final StringExpression mountName;
|
||||||
public final StringProperty mountService;
|
public final StringProperty mountService;
|
||||||
public final IntegerProperty port;
|
public final IntegerProperty port;
|
||||||
|
public final StringProperty lastKnownKeyLoader;
|
||||||
|
|
||||||
VaultSettings(VaultSettingsJson json) {
|
VaultSettings(VaultSettingsJson json) {
|
||||||
this.id = json.id;
|
this.id = json.id;
|
||||||
@@ -74,6 +75,7 @@ public class VaultSettings {
|
|||||||
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.mountService = new SimpleStringProperty(this, "mountService", json.mountService);
|
||||||
this.port = new SimpleIntegerProperty(this, "port", json.port);
|
this.port = new SimpleIntegerProperty(this, "port", json.port);
|
||||||
|
this.lastKnownKeyLoader = new SimpleStringProperty(this, "lastKnownKeyLoader", json.lastKnownKeyLoader);
|
||||||
// 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;
|
||||||
@@ -99,7 +101,7 @@ public class VaultSettings {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Observable[] observables() {
|
Observable[] observables() {
|
||||||
return new Observable[]{actionAfterUnlock, autoLockIdleSeconds, autoLockWhenIdle, displayName, maxCleartextFilenameLength, mountFlags, mountPoint, path, revealAfterMount, unlockAfterStartup, usesReadOnlyMode, port, mountService};
|
return new Observable[]{actionAfterUnlock, autoLockIdleSeconds, autoLockWhenIdle, displayName, maxCleartextFilenameLength, mountFlags, mountPoint, path, revealAfterMount, unlockAfterStartup, usesReadOnlyMode, port, mountService, lastKnownKeyLoader};
|
||||||
}
|
}
|
||||||
|
|
||||||
public static VaultSettings withRandomId() {
|
public static VaultSettings withRandomId() {
|
||||||
@@ -130,6 +132,7 @@ public class VaultSettings {
|
|||||||
json.mountPoint = mountPoint.map(Path::toString).getValue();
|
json.mountPoint = mountPoint.map(Path::toString).getValue();
|
||||||
json.mountService = mountService.get();
|
json.mountService = mountService.get();
|
||||||
json.port = port.get();
|
json.port = port.get();
|
||||||
|
json.lastKnownKeyLoader = lastKnownKeyLoader.get();
|
||||||
return json;
|
return json;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -48,6 +48,9 @@ class VaultSettingsJson {
|
|||||||
@JsonProperty("mountService")
|
@JsonProperty("mountService")
|
||||||
String mountService;
|
String mountService;
|
||||||
|
|
||||||
|
@JsonProperty("lastKnownKeyLoader")
|
||||||
|
String lastKnownKeyLoader;
|
||||||
|
|
||||||
@JsonProperty("port")
|
@JsonProperty("port")
|
||||||
int port = VaultSettings.DEFAULT_PORT;
|
int port = VaultSettings.DEFAULT_PORT;
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,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.event.FileSystemEventAggregator;
|
||||||
import org.cryptomator.common.mount.Mounter;
|
import org.cryptomator.common.mount.Mounter;
|
||||||
import org.cryptomator.common.settings.Settings;
|
import org.cryptomator.common.settings.Settings;
|
||||||
import org.cryptomator.common.settings.VaultSettings;
|
import org.cryptomator.common.settings.VaultSettings;
|
||||||
@@ -18,6 +19,7 @@ import org.cryptomator.cryptofs.CryptoFileSystemProperties;
|
|||||||
import org.cryptomator.cryptofs.CryptoFileSystemProperties.FileSystemFlags;
|
import org.cryptomator.cryptofs.CryptoFileSystemProperties.FileSystemFlags;
|
||||||
import org.cryptomator.cryptofs.CryptoFileSystemProvider;
|
import org.cryptomator.cryptofs.CryptoFileSystemProvider;
|
||||||
import org.cryptomator.cryptofs.common.FileSystemCapabilityChecker;
|
import org.cryptomator.cryptofs.common.FileSystemCapabilityChecker;
|
||||||
|
import org.cryptomator.cryptofs.event.FilesystemEvent;
|
||||||
import org.cryptomator.cryptolib.api.CryptoException;
|
import org.cryptomator.cryptolib.api.CryptoException;
|
||||||
import org.cryptomator.cryptolib.api.MasterkeyLoader;
|
import org.cryptomator.cryptolib.api.MasterkeyLoader;
|
||||||
import org.cryptomator.cryptolib.api.MasterkeyLoadingFailedException;
|
import org.cryptomator.cryptolib.api.MasterkeyLoadingFailedException;
|
||||||
@@ -44,6 +46,7 @@ import javafx.beans.property.SimpleBooleanProperty;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
|
import java.nio.file.ReadOnlyFileSystemException;
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@@ -70,9 +73,11 @@ public class Vault {
|
|||||||
private final BooleanBinding missing;
|
private final BooleanBinding missing;
|
||||||
private final BooleanBinding needsMigration;
|
private final BooleanBinding needsMigration;
|
||||||
private final BooleanBinding unknownError;
|
private final BooleanBinding unknownError;
|
||||||
|
private final BooleanBinding missingVaultConfig;
|
||||||
private final ObjectBinding<Mountpoint> mountPoint;
|
private final ObjectBinding<Mountpoint> mountPoint;
|
||||||
private final Mounter mounter;
|
private final Mounter mounter;
|
||||||
private final Settings settings;
|
private final Settings settings;
|
||||||
|
private final FileSystemEventAggregator fileSystemEventAggregator;
|
||||||
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);
|
||||||
@@ -84,7 +89,8 @@ public class Vault {
|
|||||||
VaultState state, //
|
VaultState state, //
|
||||||
@Named("lastKnownException") ObjectProperty<Exception> lastKnownException, //
|
@Named("lastKnownException") ObjectProperty<Exception> lastKnownException, //
|
||||||
VaultStats stats, //
|
VaultStats stats, //
|
||||||
Mounter mounter, Settings settings) {
|
Mounter mounter, Settings settings, //
|
||||||
|
FileSystemEventAggregator fileSystemEventAggregator) {
|
||||||
this.vaultSettings = vaultSettings;
|
this.vaultSettings = vaultSettings;
|
||||||
this.configCache = configCache;
|
this.configCache = configCache;
|
||||||
this.cryptoFileSystem = cryptoFileSystem;
|
this.cryptoFileSystem = cryptoFileSystem;
|
||||||
@@ -96,11 +102,13 @@ public class Vault {
|
|||||||
this.processing = Bindings.createBooleanBinding(this::isProcessing, state);
|
this.processing = Bindings.createBooleanBinding(this::isProcessing, state);
|
||||||
this.unlocked = Bindings.createBooleanBinding(this::isUnlocked, state);
|
this.unlocked = Bindings.createBooleanBinding(this::isUnlocked, state);
|
||||||
this.missing = Bindings.createBooleanBinding(this::isMissing, state);
|
this.missing = Bindings.createBooleanBinding(this::isMissing, state);
|
||||||
|
this.missingVaultConfig = Bindings.createBooleanBinding(this::isMissingVaultConfig, state);
|
||||||
this.needsMigration = Bindings.createBooleanBinding(this::isNeedsMigration, state);
|
this.needsMigration = Bindings.createBooleanBinding(this::isNeedsMigration, state);
|
||||||
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.settings = settings;
|
||||||
|
this.fileSystemEventAggregator = fileSystemEventAggregator;
|
||||||
this.showingStats = new SimpleBooleanProperty(false);
|
this.showingStats = new SimpleBooleanProperty(false);
|
||||||
this.quickAccessEntry = new AtomicReference<>(null);
|
this.quickAccessEntry = new AtomicReference<>(null);
|
||||||
}
|
}
|
||||||
@@ -111,15 +119,22 @@ public class Vault {
|
|||||||
|
|
||||||
private CryptoFileSystem createCryptoFileSystem(MasterkeyLoader keyLoader) throws IOException, MasterkeyLoadingFailedException {
|
private CryptoFileSystem createCryptoFileSystem(MasterkeyLoader keyLoader) throws IOException, MasterkeyLoadingFailedException {
|
||||||
Set<FileSystemFlags> flags = EnumSet.noneOf(FileSystemFlags.class);
|
Set<FileSystemFlags> flags = EnumSet.noneOf(FileSystemFlags.class);
|
||||||
if (vaultSettings.usesReadOnlyMode.get()) {
|
var createReadOnly = vaultSettings.usesReadOnlyMode.get();
|
||||||
|
try {
|
||||||
|
FileSystemCapabilityChecker.assertWriteAccess(getPath());
|
||||||
|
} catch (FileSystemCapabilityChecker.MissingCapabilityException e) {
|
||||||
|
if (!createReadOnly) {
|
||||||
|
throw new ReadOnlyFileSystemException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (createReadOnly) {
|
||||||
flags.add(FileSystemFlags.READONLY);
|
flags.add(FileSystemFlags.READONLY);
|
||||||
} else if (vaultSettings.maxCleartextFilenameLength.get() == -1) {
|
} else if (vaultSettings.maxCleartextFilenameLength.get() == -1) {
|
||||||
LOG.debug("Determining cleartext filename length limitations...");
|
LOG.debug("Determining cleartext filename length limitations...");
|
||||||
var checker = new FileSystemCapabilityChecker();
|
|
||||||
int shorteningThreshold = configCache.get().allegedShorteningThreshold();
|
int shorteningThreshold = configCache.get().allegedShorteningThreshold();
|
||||||
int ciphertextLimit = checker.determineSupportedCiphertextFileNameLength(getPath());
|
int ciphertextLimit = FileSystemCapabilityChecker.determineSupportedCiphertextFileNameLength(getPath());
|
||||||
if (ciphertextLimit < shorteningThreshold) {
|
if (ciphertextLimit < shorteningThreshold) {
|
||||||
int cleartextLimit = checker.determineSupportedCleartextFileNameLength(getPath());
|
int cleartextLimit = FileSystemCapabilityChecker.determineSupportedCleartextFileNameLength(getPath());
|
||||||
vaultSettings.maxCleartextFilenameLength.set(cleartextLimit);
|
vaultSettings.maxCleartextFilenameLength.set(cleartextLimit);
|
||||||
} else {
|
} else {
|
||||||
vaultSettings.maxCleartextFilenameLength.setValue(UNLIMITED_FILENAME_LENGTH);
|
vaultSettings.maxCleartextFilenameLength.setValue(UNLIMITED_FILENAME_LENGTH);
|
||||||
@@ -135,6 +150,7 @@ public class Vault {
|
|||||||
.withFlags(flags) //
|
.withFlags(flags) //
|
||||||
.withMaxCleartextNameLength(vaultSettings.maxCleartextFilenameLength.get()) //
|
.withMaxCleartextNameLength(vaultSettings.maxCleartextFilenameLength.get()) //
|
||||||
.withVaultConfigFilename(Constants.VAULTCONFIG_FILENAME) //
|
.withVaultConfigFilename(Constants.VAULTCONFIG_FILENAME) //
|
||||||
|
.withFilesystemEventConsumer(this::consumeVaultEvent) //
|
||||||
.build();
|
.build();
|
||||||
return CryptoFileSystemProvider.newFileSystem(getPath(), fsProps);
|
return CryptoFileSystemProvider.newFileSystem(getPath(), fsProps);
|
||||||
}
|
}
|
||||||
@@ -243,6 +259,11 @@ public class Vault {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void consumeVaultEvent(FilesystemEvent e) {
|
||||||
|
fileSystemEventAggregator.put(this, e);
|
||||||
|
}
|
||||||
|
|
||||||
// ******************************************************************************
|
// ******************************************************************************
|
||||||
// Observable Properties
|
// Observable Properties
|
||||||
// *******************************************************************************
|
// *******************************************************************************
|
||||||
@@ -315,6 +336,14 @@ public class Vault {
|
|||||||
return state.get() == VaultState.Value.ERROR;
|
return state.get() == VaultState.Value.ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public BooleanBinding missingVaultConfigProperty() {
|
||||||
|
return missingVaultConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isMissingVaultConfig() {
|
||||||
|
return state.get() == VaultState.Value.VAULT_CONFIG_MISSING || state.get() == VaultState.Value.ALL_MISSING;
|
||||||
|
}
|
||||||
|
|
||||||
public ReadOnlyStringProperty displayNameProperty() {
|
public ReadOnlyStringProperty displayNameProperty() {
|
||||||
return vaultSettings.displayName;
|
return vaultSettings.displayName;
|
||||||
}
|
}
|
||||||
@@ -404,6 +433,17 @@ public class Vault {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the cleartext name from a given path to an encrypted vault file
|
||||||
|
*/
|
||||||
|
public String getCleartextName(Path ciphertextPath) throws IOException {
|
||||||
|
if (!state.getValue().equals(VaultState.Value.UNLOCKED)) {
|
||||||
|
throw new IllegalStateException("Vault is not unlocked");
|
||||||
|
}
|
||||||
|
var fs = cryptoFileSystem.get();
|
||||||
|
return fs.getCleartextName(ciphertextPath);
|
||||||
|
}
|
||||||
|
|
||||||
public VaultConfigCache getVaultConfigCache() {
|
public VaultConfigCache getVaultConfigCache() {
|
||||||
return configCache;
|
return configCache;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ public class VaultConfigCache {
|
|||||||
private final VaultSettings settings;
|
private final VaultSettings settings;
|
||||||
private final AtomicReference<VaultConfig.UnverifiedVaultConfig> config;
|
private final AtomicReference<VaultConfig.UnverifiedVaultConfig> config;
|
||||||
|
|
||||||
VaultConfigCache(VaultSettings settings) {
|
public VaultConfigCache(VaultSettings settings) {
|
||||||
this.settings = settings;
|
this.settings = settings;
|
||||||
this.config = new AtomicReference<>(null);
|
this.config = new AtomicReference<>(null);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,12 +9,14 @@
|
|||||||
package org.cryptomator.common.vaults;
|
package org.cryptomator.common.vaults;
|
||||||
|
|
||||||
import org.apache.commons.lang3.SystemUtils;
|
import org.apache.commons.lang3.SystemUtils;
|
||||||
|
import org.cryptomator.common.recovery.BackupRestorer;
|
||||||
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.cryptomator.integrations.mount.MountService;
|
||||||
|
import org.cryptomator.ui.keyloading.masterkeyfile.MasterkeyFileLoadingStrategy;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
@@ -27,13 +29,13 @@ 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.List;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.ResourceBundle;
|
import java.util.ResourceBundle;
|
||||||
|
|
||||||
import static org.cryptomator.common.Constants.MASTERKEY_FILENAME;
|
import static org.cryptomator.common.Constants.MASTERKEY_FILENAME;
|
||||||
import static org.cryptomator.common.Constants.VAULTCONFIG_FILENAME;
|
import static org.cryptomator.common.Constants.VAULTCONFIG_FILENAME;
|
||||||
import static org.cryptomator.common.vaults.VaultState.Value.ERROR;
|
import static org.cryptomator.common.vaults.VaultState.Value.*;
|
||||||
import static org.cryptomator.common.vaults.VaultState.Value.LOCKED;
|
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
public class VaultListManager {
|
public class VaultListManager {
|
||||||
@@ -49,9 +51,9 @@ public class VaultListManager {
|
|||||||
@Inject
|
@Inject
|
||||||
public VaultListManager(ObservableList<Vault> vaultList, //
|
public VaultListManager(ObservableList<Vault> vaultList, //
|
||||||
AutoLocker autoLocker, //
|
AutoLocker autoLocker, //
|
||||||
List<MountService> mountServices,
|
List<MountService> mountServices, //
|
||||||
VaultComponent.Factory vaultComponentFactory,
|
VaultComponent.Factory vaultComponentFactory, //
|
||||||
ResourceBundle resourceBundle,
|
ResourceBundle resourceBundle, //
|
||||||
Settings settings) {
|
Settings settings) {
|
||||||
this.vaultList = vaultList;
|
this.vaultList = vaultList;
|
||||||
this.autoLocker = autoLocker;
|
this.autoLocker = autoLocker;
|
||||||
@@ -64,6 +66,12 @@ public class VaultListManager {
|
|||||||
autoLocker.init();
|
autoLocker.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isAlreadyAdded(Path vaultPath) {
|
||||||
|
assert vaultPath.isAbsolute();
|
||||||
|
assert vaultPath.normalize().equals(vaultPath);
|
||||||
|
return vaultList.stream().anyMatch(v -> vaultPath.equals(v.getPath()));
|
||||||
|
}
|
||||||
|
|
||||||
public Vault add(Path pathToVault) throws IOException {
|
public Vault add(Path pathToVault) throws IOException {
|
||||||
Path normalizedPathToVault = pathToVault.normalize().toAbsolutePath();
|
Path normalizedPathToVault = pathToVault.normalize().toAbsolutePath();
|
||||||
if (CryptoFileSystemProvider.checkDirStructureForVault(normalizedPathToVault, VAULTCONFIG_FILENAME, MASTERKEY_FILENAME) == DirStructure.UNRELATED) {
|
if (CryptoFileSystemProvider.checkDirStructureForVault(normalizedPathToVault, VAULTCONFIG_FILENAME, MASTERKEY_FILENAME) == DirStructure.UNRELATED) {
|
||||||
@@ -103,7 +111,7 @@ public class VaultListManager {
|
|||||||
vaultList.addAll(vaults);
|
vaultList.addAll(vaults);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Optional<Vault> get(Path vaultPath) {
|
public Optional<Vault> get(Path vaultPath) {
|
||||||
assert vaultPath.isAbsolute();
|
assert vaultPath.isAbsolute();
|
||||||
assert vaultPath.normalize().equals(vaultPath);
|
assert vaultPath.normalize().equals(vaultPath);
|
||||||
return vaultList.stream() //
|
return vaultList.stream() //
|
||||||
@@ -111,53 +119,122 @@ public class VaultListManager {
|
|||||||
.findAny();
|
.findAny();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void addVault(Vault vault) {
|
||||||
|
Path path = vault.getPath().normalize().toAbsolutePath();
|
||||||
|
if (!isAlreadyAdded(path)) {
|
||||||
|
vaultList.add(vault);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private Vault create(VaultSettings vaultSettings) {
|
private Vault create(VaultSettings vaultSettings) {
|
||||||
var wrapper = new VaultConfigCache(vaultSettings);
|
var wrapper = new VaultConfigCache(vaultSettings);
|
||||||
try {
|
try {
|
||||||
var vaultState = determineVaultState(vaultSettings.path.get());
|
var vaultState = determineVaultState(vaultSettings.path.get());
|
||||||
if (vaultState == LOCKED) { //for legacy reasons: pre v8 vault do not have a config, but they are in the NEEDS_MIGRATION state
|
initializeLastKnownKeyLoaderIfPossible(vaultSettings, vaultState, wrapper);
|
||||||
wrapper.reloadConfig();
|
|
||||||
}
|
|
||||||
return vaultComponentFactory.create(vaultSettings, wrapper, vaultState, null).vault();
|
return vaultComponentFactory.create(vaultSettings, wrapper, vaultState, null).vault();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
LOG.warn("Failed to determine vault state for " + vaultSettings.path.get(), e);
|
LOG.warn("Failed to determine vault state for {}", vaultSettings.path.get(), e);
|
||||||
return vaultComponentFactory.create(vaultSettings, wrapper, ERROR, e).vault();
|
return vaultComponentFactory.create(vaultSettings, wrapper, ERROR, e).vault();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void initializeLastKnownKeyLoaderIfPossible(VaultSettings vaultSettings, VaultState.Value vaultState, VaultConfigCache wrapper) throws IOException {
|
||||||
|
if (vaultSettings.lastKnownKeyLoader.get() != null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (vaultState) {
|
||||||
|
case LOCKED -> {
|
||||||
|
wrapper.reloadConfig();
|
||||||
|
vaultSettings.lastKnownKeyLoader.set(wrapper.get().getKeyId().getScheme());
|
||||||
|
}
|
||||||
|
case NEEDS_MIGRATION -> {
|
||||||
|
//for legacy reasons: pre v8 vault do not have a config, but they are in the NEEDS_MIGRATION state
|
||||||
|
vaultSettings.lastKnownKeyLoader.set(MasterkeyFileLoadingStrategy.SCHEME);
|
||||||
|
}
|
||||||
|
case VAULT_CONFIG_MISSING -> {
|
||||||
|
//Nothing to do here, since there is no config to read
|
||||||
|
}
|
||||||
|
case MISSING, ALL_MISSING, ERROR, PROCESSING -> {
|
||||||
|
// no config available or not safe to load
|
||||||
|
}
|
||||||
|
default -> {
|
||||||
|
if (Files.exists(vaultSettings.path.get().resolve(VAULTCONFIG_FILENAME))) {
|
||||||
|
try {
|
||||||
|
wrapper.reloadConfig();
|
||||||
|
vaultSettings.lastKnownKeyLoader.set(wrapper.get().getKeyId().getScheme());
|
||||||
|
} catch (IOException e) {
|
||||||
|
LOG.debug("Unable to load config for {}", vaultSettings.path.get(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static VaultState.Value redetermineVaultState(Vault vault) {
|
public static VaultState.Value redetermineVaultState(Vault vault) {
|
||||||
VaultState state = vault.stateProperty();
|
VaultState state = vault.stateProperty();
|
||||||
VaultState.Value previousState = state.getValue();
|
VaultState.Value previous = state.getValue();
|
||||||
return switch (previousState) {
|
|
||||||
case LOCKED, NEEDS_MIGRATION, MISSING -> {
|
if (previous.equals(UNLOCKED) || previous.equals(PROCESSING)) {
|
||||||
try {
|
return previous;
|
||||||
var determinedState = determineVaultState(vault.getPath());
|
}
|
||||||
if (determinedState == LOCKED) {
|
|
||||||
vault.getVaultConfigCache().reloadConfig();
|
try {
|
||||||
}
|
VaultState.Value determined = determineVaultState(vault.getPath());
|
||||||
state.set(determinedState);
|
|
||||||
yield determinedState;
|
if (determined == LOCKED) {
|
||||||
} catch (IOException e) {
|
vault.getVaultConfigCache().reloadConfig();
|
||||||
LOG.warn("Failed to determine vault state for " + vault.getPath(), e);
|
|
||||||
state.set(ERROR);
|
|
||||||
vault.setLastKnownException(e);
|
|
||||||
yield ERROR;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
case ERROR, UNLOCKED, PROCESSING -> previousState;
|
|
||||||
};
|
state.set(determined);
|
||||||
|
return determined;
|
||||||
|
} catch (IOException e) {
|
||||||
|
LOG.warn("Failed to (re)determine vault state for {}", vault.getPath(), e);
|
||||||
|
vault.setLastKnownException(e);
|
||||||
|
state.set(ERROR);
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static VaultState.Value determineVaultState(Path pathToVault) throws IOException {
|
public static VaultState.Value determineVaultState(Path pathToVault) throws IOException {
|
||||||
if (!Files.exists(pathToVault)) {
|
if (!Files.exists(pathToVault)) {
|
||||||
return VaultState.Value.MISSING;
|
return MISSING;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VaultState.Value structureResult = checkDirStructure(pathToVault);
|
||||||
|
|
||||||
|
if (structureResult == LOCKED || structureResult == NEEDS_MIGRATION) {
|
||||||
|
return structureResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
Path pathToVaultConfig = pathToVault.resolve(VAULTCONFIG_FILENAME);
|
||||||
|
Path pathToMasterkey = pathToVault.resolve(MASTERKEY_FILENAME);
|
||||||
|
|
||||||
|
if (!Files.exists(pathToVaultConfig)) {
|
||||||
|
BackupRestorer.restoreIfBackupPresent(pathToVault, VAULTCONFIG_FILENAME);
|
||||||
|
}
|
||||||
|
if (!Files.exists(pathToMasterkey)) {
|
||||||
|
BackupRestorer.restoreIfBackupPresent(pathToVault, MASTERKEY_FILENAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean hasConfig = Files.exists(pathToVaultConfig);
|
||||||
|
|
||||||
|
if (!hasConfig && !Files.exists(pathToMasterkey)) {
|
||||||
|
return ALL_MISSING;
|
||||||
|
}
|
||||||
|
if (!hasConfig) {
|
||||||
|
return VAULT_CONFIG_MISSING;
|
||||||
|
}
|
||||||
|
|
||||||
|
return checkDirStructure(pathToVault);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static VaultState.Value checkDirStructure(Path pathToVault) throws IOException {
|
||||||
return switch (CryptoFileSystemProvider.checkDirStructureForVault(pathToVault, VAULTCONFIG_FILENAME, MASTERKEY_FILENAME)) {
|
return switch (CryptoFileSystemProvider.checkDirStructureForVault(pathToVault, VAULTCONFIG_FILENAME, MASTERKEY_FILENAME)) {
|
||||||
case VAULT -> VaultState.Value.LOCKED;
|
case VAULT -> LOCKED;
|
||||||
case UNRELATED -> VaultState.Value.MISSING;
|
case UNRELATED -> MISSING;
|
||||||
case MAYBE_LEGACY -> Migrators.get().needsMigration(pathToVault, VAULTCONFIG_FILENAME, MASTERKEY_FILENAME) ? //
|
case MAYBE_LEGACY -> Migrators.get().needsMigration(pathToVault, VAULTCONFIG_FILENAME, MASTERKEY_FILENAME) ? NEEDS_MIGRATION : MISSING;
|
||||||
VaultState.Value.NEEDS_MIGRATION //
|
|
||||||
: VaultState.Value.MISSING;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,6 +25,16 @@ public class VaultState extends ObservableValueBase<VaultState.Value> implements
|
|||||||
*/
|
*/
|
||||||
MISSING,
|
MISSING,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* No vault config found at the provided path
|
||||||
|
*/
|
||||||
|
VAULT_CONFIG_MISSING,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* No vault config and masterkey found at the provided path
|
||||||
|
*/
|
||||||
|
ALL_MISSING,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Vault requires migration to a newer vault format
|
* Vault requires migration to a newer vault format
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package org.cryptomator.event;
|
||||||
|
|
||||||
|
public sealed interface Answer permits Answer.DoNothing, Answer.DoSomething {
|
||||||
|
|
||||||
|
|
||||||
|
record DoNothing() implements Answer {}
|
||||||
|
|
||||||
|
record DoSomething(Runnable action) implements Answer {
|
||||||
|
|
||||||
|
void run() {
|
||||||
|
action.run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user