mirror of
https://github.com/cryptomator/cryptomator.git
synced 2026-09-22 07:54:19 +00:00
Compare commits
776
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
58eb6a6dee | ||
|
|
b256670bcc | ||
|
|
91162d3d8f | ||
|
|
683f17ef24 | ||
|
|
e626104c06 | ||
|
|
f73bcc0a9e | ||
|
|
4167fdc850 | ||
|
|
f544f72327 | ||
|
|
a96115ecd6 | ||
|
|
c6aceb3e59 | ||
|
|
cadd071ebd | ||
|
|
b64264ef8b | ||
|
|
46691f057e | ||
|
|
f1b40e32a7 | ||
|
|
b4a97803ff | ||
|
|
8ac253504f | ||
|
|
135b61070d | ||
|
|
903f55a24f | ||
|
|
f2fadafa66 | ||
|
|
0676732796 | ||
|
|
08cbfd47ea | ||
|
|
b15cda260e | ||
|
|
74355b128a | ||
|
|
000f27e166 | ||
|
|
e1d83c996e | ||
|
|
0dc401883f | ||
|
|
364d59fdf7 | ||
|
|
210050d9d5 | ||
|
|
f10d2b713b | ||
|
|
f9545b5532 | ||
|
|
58376bddef | ||
|
|
72e2f64a68 | ||
|
|
48ad74715e | ||
|
|
2e1f33ca82 | ||
|
|
2d3f4d1c03 | ||
|
|
04c13ba242 | ||
|
|
b70033e777 | ||
|
|
fafb7b229f | ||
|
|
7fac6da448 | ||
|
|
72bd9c1fdf | ||
|
|
39b8e25f4f | ||
|
|
c8fa7f1edd | ||
|
|
95b98b8a36 | ||
|
|
005d2a82fe | ||
|
|
820f7989d0 | ||
|
|
751a6079c3 | ||
|
|
9be95efd10 | ||
|
|
8f8fa0248c | ||
|
|
cd7acea54e | ||
|
|
18152e4f3d | ||
|
|
7b689c6b78 | ||
|
|
1159681824 | ||
|
|
c868ac32cc | ||
|
|
f85f953668 | ||
|
|
5185df631d | ||
|
|
617feec111 | ||
|
|
eb196165c5 | ||
|
|
8c37ab3675 | ||
|
|
7eaade1555 | ||
|
|
186c129a30 | ||
|
|
f74b9d3347 | ||
|
|
6038559172 | ||
|
|
98a899c7e2 | ||
|
|
783c8718c1 | ||
|
|
b47382811f | ||
|
|
62f279b9f7 | ||
|
|
ab961f1a8b | ||
|
|
9562db7e13 | ||
|
|
1ca2e029dc | ||
|
|
944e3e6c50 | ||
|
|
e134d2f422 | ||
|
|
04e5170403 | ||
|
|
ea008df9f7 | ||
|
|
e25dfaad35 | ||
|
|
e98f92c63f | ||
|
|
85b761a9d7 | ||
|
|
be8dcd4dc4 | ||
|
|
c01c405f20 | ||
|
|
b4f268f551 | ||
|
|
21f9e72cc5 | ||
|
|
4845984a35 | ||
|
|
b6f5ddaf30 | ||
|
|
1abf0e1bfa | ||
|
|
a8364a8c1a | ||
|
|
13c95868fa | ||
|
|
85ff7542f1 | ||
|
|
432be6dd80 | ||
|
|
ca0402aaf0 | ||
|
|
c7ef0056f9 | ||
|
|
cf13311665 | ||
|
|
a7133dbebe | ||
|
|
168f9b9fb9 | ||
|
|
2b332c3831 | ||
|
|
66e3625a0b | ||
|
|
20f88e203a | ||
|
|
66a8dc9811 | ||
|
|
9d89efc98c | ||
|
|
dfbe017316 | ||
|
|
d2680b9857 | ||
|
|
8e1be4c67b | ||
|
|
749e0ac02d | ||
|
|
a2ad7d69ab | ||
|
|
a47c05c87d | ||
|
|
6b871e56c8 | ||
|
|
40dbc0ba48 | ||
|
|
2e52afed51 | ||
|
|
64d54133f8 | ||
|
|
ac289cc3f7 | ||
|
|
189699d359 | ||
|
|
0ce41e7ac3 | ||
|
|
c1a249fd7f | ||
|
|
c266c7583b | ||
|
|
00331d4857 | ||
|
|
8fd484e2bb | ||
|
|
165d740acd | ||
|
|
fd4010c6c9 | ||
|
|
aa2900fa9e | ||
|
|
76d1875e01 | ||
|
|
bc83e23a34 | ||
|
|
6a326bcbce | ||
|
|
573ad03d68 | ||
|
|
07efb3e94d | ||
|
|
89e680fb45 | ||
|
|
54128a0016 | ||
|
|
e2565097cd | ||
|
|
f827b1fc89 | ||
|
|
c0baab2329 | ||
|
|
70baa4d09f | ||
|
|
d710d406d0 | ||
|
|
554f245f5d | ||
|
|
34995088ba | ||
|
|
69c63702f2 | ||
|
|
db7e731554 | ||
|
|
e08b43bf17 | ||
|
|
58b45bacd1 | ||
|
|
4f942bc23f | ||
|
|
09a8618fa0 | ||
|
|
52af530d1b | ||
|
|
86a42234c6 | ||
|
|
37c4e78b1d | ||
|
|
9c2c234bee | ||
|
|
59f91267ae | ||
|
|
b3ff9423b4 | ||
|
|
e3f3090341 | ||
|
|
83be6c0864 | ||
|
|
c654951dc1 | ||
|
|
4e177c9ea7 | ||
|
|
dc3a951a1b | ||
|
|
defa9c75eb | ||
|
|
c1f498a114 | ||
|
|
8457c50ebc | ||
|
|
0144cbb99f | ||
|
|
d6e4c7d177 | ||
|
|
3376b16b7b | ||
|
|
673fdcd095 | ||
|
|
0d00520ac1 | ||
|
|
22a0d3a9a5 | ||
|
|
24baa44e70 | ||
|
|
03886f88e8 | ||
|
|
642816b631 | ||
|
|
f3a03c71ec | ||
|
|
1fab246fcd | ||
|
|
cd5c55aad7 | ||
|
|
b066b4b045 | ||
|
|
41d2a2c77e | ||
|
|
69186b916c | ||
|
|
0840695e0a | ||
|
|
8447f105b0 | ||
|
|
c306d8df04 | ||
|
|
beba6490c3 | ||
|
|
fb1078b35b | ||
|
|
be0912e6ca | ||
|
|
13db1aa9b9 | ||
|
|
d2cd2c923d | ||
|
|
92de05b3db | ||
|
|
c1000d9958 | ||
|
|
2810c044ea | ||
|
|
e09bd160b7 | ||
|
|
e6d1e4697c | ||
|
|
497e5ce73f | ||
|
|
cf7cbae567 | ||
|
|
803f517c62 | ||
|
|
0afa7b8e37 | ||
|
|
1a0f70f8e8 | ||
|
|
8737eb83f0 | ||
|
|
a96239a19f | ||
|
|
2b7cfcd1dc | ||
|
|
ebccb61750 | ||
|
|
285f2aec23 | ||
|
|
217e31fbd7 | ||
|
|
f0ebf7a638 | ||
|
|
c05c5e3f90 | ||
|
|
30f0c5e697 | ||
|
|
f989b8627c | ||
|
|
ff84230566 | ||
|
|
3b4f6276b5 | ||
|
|
2be7a050a4 | ||
|
|
1c01228778 | ||
|
|
1c35780d9e | ||
|
|
96a612127c | ||
|
|
0bdfb7c9f9 | ||
|
|
f556301249 | ||
|
|
f77b237e59 | ||
|
|
61b7a39aad | ||
|
|
2cee6e45f1 | ||
|
|
1292548042 | ||
|
|
16bd84ee62 | ||
|
|
3d0a97fcdf | ||
|
|
5ae2419e6d | ||
|
|
786d156b9f | ||
|
|
629b6fb97d | ||
|
|
17dc32bb79 | ||
|
|
c05e00d32a | ||
|
|
9dc8b2cb47 | ||
|
|
0e32e96c7d | ||
|
|
97afadd7b9 | ||
|
|
b199b65e38 | ||
|
|
999abf3c13 | ||
|
|
2cdde54db6 | ||
|
|
6941603cdd | ||
|
|
cdca4e047d | ||
|
|
31e938de6a | ||
|
|
4c10ab764a | ||
|
|
4e075ab0ca | ||
|
|
f73ae9759f | ||
|
|
f6283b2f7e | ||
|
|
b23d2e4def | ||
|
|
91a2943599 | ||
|
|
e32ce22d24 | ||
|
|
e75c415b46 | ||
|
|
8592e3667b | ||
|
|
5a11d02fa8 | ||
|
|
0ab28602d1 | ||
|
|
62c8edff04 | ||
|
|
d01c6268f8 | ||
|
|
e083fd0bcc | ||
|
|
ff687f1bae | ||
|
|
557aaa2480 | ||
|
|
78e43d401d | ||
|
|
7b08c5d287 | ||
|
|
84d2644f19 | ||
|
|
d13dfe3526 | ||
|
|
f9a9d7b870 | ||
|
|
d75a8c4bba | ||
|
|
8fccb1b8f0 | ||
|
|
d326c7c990 | ||
|
|
e8e63ca4fc | ||
|
|
c82e5577a1 | ||
|
|
6878f2e94b | ||
|
|
a17b416262 | ||
|
|
fed572694f | ||
|
|
fe3d67d937 | ||
|
|
3dcdeb1033 | ||
|
|
0898158c5a | ||
|
|
81091d4bdf | ||
|
|
c9b1b1baa5 | ||
|
|
c81f3bd972 | ||
|
|
9f86b74320 | ||
|
|
2d8390a0f3 | ||
|
|
8d3671175f | ||
|
|
366011a222 | ||
|
|
c0c2e21055 | ||
|
|
63be96a151 | ||
|
|
fc1df4bd99 | ||
|
|
7657330931 | ||
|
|
4e44de3c3b | ||
|
|
8d902a72ca | ||
|
|
7378031a72 | ||
|
|
f898c07c27 | ||
|
|
c8f02d1045 | ||
|
|
4cc13b986b | ||
|
|
af7b6780f3 | ||
|
|
4a17d01004 | ||
|
|
1d68408e21 | ||
|
|
821b1ee660 | ||
|
|
c6616bd467 | ||
|
|
4bb2589f16 | ||
|
|
896c3b3565 | ||
|
|
6ee717a693 | ||
|
|
07ec858e1e | ||
|
|
a7c1e43ebc | ||
|
|
ac1cd3b073 | ||
|
|
7474519faf | ||
|
|
340e474c33 | ||
|
|
c90ab75427 | ||
|
|
848b3f77d3 | ||
|
|
fb8cdb31ca | ||
|
|
ba5f8053fb | ||
|
|
38165becca | ||
|
|
f731ac5c90 | ||
|
|
0291702736 | ||
|
|
ab63929861 | ||
|
|
ca36fb8af3 | ||
|
|
8cb29ff83b | ||
|
|
304fa67dd7 | ||
|
|
a80ec32d2c | ||
|
|
dc4f21162e | ||
|
|
3b8d7e0241 | ||
|
|
6891c68cf1 | ||
|
|
18b26fbc58 | ||
|
|
1db8da6b6b | ||
|
|
14bce7e91d | ||
|
|
2674bc6f23 | ||
|
|
74e1d6f991 | ||
|
|
25dba028f8 | ||
|
|
bf51cc13d1 | ||
|
|
24be36cccb | ||
|
|
797e15c775 | ||
|
|
2395dbcae9 | ||
|
|
efacbbe2b6 | ||
|
|
2518086e46 | ||
|
|
c733247611 | ||
|
|
4f44e71e13 | ||
|
|
02aa46ece8 | ||
|
|
635f64c847 | ||
|
|
0a8516ae9a | ||
|
|
c1edb30472 | ||
|
|
93c78b63ca | ||
|
|
3ccae93757 | ||
|
|
450dec2baf | ||
|
|
36121527ca | ||
|
|
f30451f7e1 | ||
|
|
74d7f63f64 | ||
|
|
350a4ab762 | ||
|
|
0e0e75b89c | ||
|
|
e76440d928 | ||
|
|
0cbace67a5 | ||
|
|
84a3082589 | ||
|
|
cdfcca06d1 | ||
|
|
630bfa4cee | ||
|
|
90cb7beb1f | ||
|
|
d37fa33278 | ||
|
|
eed9c906cc | ||
|
|
2b7ed5f4dd | ||
|
|
6a7a309a2b | ||
|
|
0382069995 | ||
|
|
7c5f40d7d1 | ||
|
|
09e9530660 | ||
|
|
947d25b335 | ||
|
|
80cbc6699a | ||
|
|
da0933fa92 | ||
|
|
9ad217ca55 | ||
|
|
adc9f32fb3 | ||
|
|
65369bdbff | ||
|
|
d18e618ef1 | ||
|
|
970216dd59 | ||
|
|
6840a649c7 | ||
|
|
1a0bc92bde | ||
|
|
e4709ed6fe | ||
|
|
21038212c1 | ||
|
|
b15471b4ff | ||
|
|
19ebc7e562 | ||
|
|
0fa052d2d1 | ||
|
|
402861b9c0 | ||
|
|
aca1666dea | ||
|
|
ff17b60f56 | ||
|
|
3284578445 | ||
|
|
70f6a4877c | ||
|
|
85c5dc8dfb | ||
|
|
4b670a59a3 | ||
|
|
23c113948f | ||
|
|
d86ea20c31 | ||
|
|
3f928cf958 | ||
|
|
01929c2288 | ||
|
|
2634433b2c | ||
|
|
c1f44f76b9 | ||
|
|
b2f27c0a3d | ||
|
|
b1d7cfc81b | ||
|
|
7cd5c66836 | ||
|
|
95cef34234 | ||
|
|
8977440697 | ||
|
|
d5eb84a000 | ||
|
|
81fb6b8794 | ||
|
|
92b390d5bb | ||
|
|
8867532210 | ||
|
|
77db435b4f | ||
|
|
cb2bc17283 | ||
|
|
aaa93239d0 | ||
|
|
93445e22d4 | ||
|
|
64897cfa21 | ||
|
|
7349a29831 | ||
|
|
73554b4759 | ||
|
|
0312f045aa | ||
|
|
1134c1b2ff | ||
|
|
efebbc059a | ||
|
|
6e860d293a | ||
|
|
8bb925fd93 | ||
|
|
ca5d9eba36 | ||
|
|
1a49e24d8a | ||
|
|
24b0ed2502 | ||
|
|
a226d5403a | ||
|
|
0f3085cc73 | ||
|
|
f0a040cf29 | ||
|
|
0676748dde | ||
|
|
589b8384eb | ||
|
|
9e3947f337 | ||
|
|
790cc4e772 | ||
|
|
72f4988632 | ||
|
|
b3fa6bbf32 | ||
|
|
c2dc487c79 | ||
|
|
e74dd3be9e | ||
|
|
1eeee61572 | ||
|
|
984b7a2d0e | ||
|
|
45c714a123 | ||
|
|
96bb97d50a | ||
|
|
046acb9bbf | ||
|
|
ce4ec16c62 | ||
|
|
96c8c9a9a9 | ||
|
|
44db97327d | ||
|
|
f441700c25 | ||
|
|
76b023bdbd | ||
|
|
241d9781bb | ||
|
|
ff94532560 | ||
|
|
e949023321 | ||
|
|
da31407d63 | ||
|
|
8c7c5da89a | ||
|
|
e3a0e1ec5a | ||
|
|
4cee27d8dd | ||
|
|
b0fce66d77 | ||
|
|
bf47ba0145 | ||
|
|
fc7b484c9a | ||
|
|
4402c19d90 | ||
|
|
4e89de9e47 | ||
|
|
a27c9d63d9 | ||
|
|
da6aa0f002 | ||
|
|
0bf3533f45 | ||
|
|
295cb0ef6d | ||
|
|
6fac84e9c2 | ||
|
|
77b2e67c49 | ||
|
|
c48c9b1568 | ||
|
|
6da7eae2f8 | ||
|
|
aec56c48c5 | ||
|
|
c0a9a95e4f | ||
|
|
3b73544766 | ||
|
|
fbc471635a | ||
|
|
3c5b9ed3a6 | ||
|
|
8479122561 | ||
|
|
91c883d5cc | ||
|
|
1cd4da0796 | ||
|
|
935aaccdae | ||
|
|
ab3dd779d2 | ||
|
|
1fbcf6d517 | ||
|
|
82538091c9 | ||
|
|
62ade6113b | ||
|
|
4779bbf415 | ||
|
|
c6b786a771 | ||
|
|
6381227897 | ||
|
|
e82167b5e6 | ||
|
|
dc4fd482b5 | ||
|
|
a71f8b350e | ||
|
|
c9ec8fecef | ||
|
|
e72d32f2d1 | ||
|
|
2545aa2a7e | ||
|
|
51aac15622 | ||
|
|
afa0cfeafb | ||
|
|
19e24ba12c | ||
|
|
c47ce2c730 | ||
|
|
5d00b3dd76 | ||
|
|
4db57cc0dc | ||
|
|
432a9a27f1 | ||
|
|
57bfa3276d | ||
|
|
02fc9b263a | ||
|
|
4c66f81736 | ||
|
|
2de151aebe | ||
|
|
c44911dcac | ||
|
|
bcf2a3d20c | ||
|
|
422ce4a387 | ||
|
|
21387bd76c | ||
|
|
52cd560cb2 | ||
|
|
6c440dfbbb | ||
|
|
a074450452 | ||
|
|
b781cf6f25 | ||
|
|
9b653f488b | ||
|
|
17c580267f | ||
|
|
490d1b8f87 | ||
|
|
b0ad86f16b | ||
|
|
df2b4ac086 | ||
|
|
aee4ececba | ||
|
|
b2992aa6ae | ||
|
|
4c546d281a | ||
|
|
c90e445a67 | ||
|
|
d3c2b0509e | ||
|
|
c6d1c2ca6b | ||
|
|
86dec80726 | ||
|
|
9083976989 | ||
|
|
d9c5d76417 | ||
|
|
c19c3754c6 | ||
|
|
947e0e2369 | ||
|
|
6eca8f2e0c | ||
|
|
9f61ad1941 | ||
|
|
41492a951a | ||
|
|
cbbfec5531 | ||
|
|
d7a4dff080 | ||
|
|
8e56218fbb | ||
|
|
9c40386106 | ||
|
|
c865805f55 | ||
|
|
8e352301cd | ||
|
|
52db1e8bdd | ||
|
|
1947623be8 | ||
|
|
4f8602684d | ||
|
|
75f66e40bf | ||
|
|
73587437cb | ||
|
|
18f6e70bba | ||
|
|
e067b94aca | ||
|
|
b04d5669fb | ||
|
|
ad44af338d | ||
|
|
4f4ddbc3e0 | ||
|
|
4e9af1c713 | ||
|
|
9a94b6f95e | ||
|
|
371b826aa0 | ||
|
|
d3fb90bf6d | ||
|
|
d24c478faa | ||
|
|
48d0aa423c | ||
|
|
5695fa2916 | ||
|
|
bcea1a4b32 | ||
|
|
2f8d4568fc | ||
|
|
5b55318e52 | ||
|
|
459f2ea2c3 | ||
|
|
d26147a34a | ||
|
|
afb9d4f010 | ||
|
|
db3bf9723e | ||
|
|
3a5937b35f | ||
|
|
f5cddda7a8 | ||
|
|
e9fa1d6476 | ||
|
|
084c1881ba | ||
|
|
ce131e4653 | ||
|
|
a121c7d0fe | ||
|
|
603bf99b25 | ||
|
|
9076fe5b46 | ||
|
|
6848f1a38e | ||
|
|
f4103fc917 | ||
|
|
c838da9df4 | ||
|
|
78df4e24b3 | ||
|
|
c0e2d01297 | ||
|
|
313f8b36d2 | ||
|
|
343794c1fe | ||
|
|
813c01aaed | ||
|
|
510ea8a6f6 | ||
|
|
a22fbea467 | ||
|
|
f64144d1da | ||
|
|
c01dd225c9 | ||
|
|
18b408a83a | ||
|
|
efaf107b20 | ||
|
|
86cba5e8a7 | ||
|
|
f4cee6d161 | ||
|
|
28c40b2277 | ||
|
|
8853054ed4 | ||
|
|
3eb44b06af | ||
|
|
1554437884 | ||
|
|
268bae8879 | ||
|
|
b382e436e2 | ||
|
|
6ccd248675 | ||
|
|
c760e63995 | ||
|
|
959dee153e | ||
|
|
aa22f656e8 | ||
|
|
d24734e16f | ||
|
|
01522e8c97 | ||
|
|
14e056551d | ||
|
|
82a42ea183 | ||
|
|
bfde26be79 | ||
|
|
51e43a0567 | ||
|
|
9a375cb3f6 | ||
|
|
2b8f39a149 | ||
|
|
2720a999d1 | ||
|
|
f675bd5017 | ||
|
|
16be3e7a97 | ||
|
|
551d9d1af1 | ||
|
|
0acc8ddb0a | ||
|
|
f0e1bcb899 | ||
|
|
d331c30224 | ||
|
|
d0d39a1c72 | ||
|
|
8904df91b4 | ||
|
|
786365c095 | ||
|
|
eb8f5f523d | ||
|
|
9c22adc97d | ||
|
|
265212cc0f | ||
|
|
9c860cc17c | ||
|
|
7f63153bc1 | ||
|
|
9531d44ab5 | ||
|
|
253abd4930 | ||
|
|
022ba81f2f | ||
|
|
26160e9bbc | ||
|
|
0a32de2c92 | ||
|
|
60aeb6a04b | ||
|
|
0206fc0b8f | ||
|
|
06b3343a6d | ||
|
|
598bec3050 | ||
|
|
0e5d72c22a | ||
|
|
21f4fab9ed | ||
|
|
58e2ec4742 | ||
|
|
6b6867b826 | ||
|
|
92321a7569 | ||
|
|
7781572b6d | ||
|
|
b5efe39eb8 | ||
|
|
cae86cd71f | ||
|
|
667617b480 | ||
|
|
9329311491 | ||
|
|
22438d1eba | ||
|
|
d295084312 | ||
|
|
ab538cd215 | ||
|
|
f9cb438a0b | ||
|
|
354de225ed | ||
|
|
0b7f8d71ed | ||
|
|
9657a13912 | ||
|
|
c5a3b29554 | ||
|
|
ae957c2588 | ||
|
|
da84133732 | ||
|
|
10275eb80f | ||
|
|
29a9c7dffe | ||
|
|
d5b8996a39 | ||
|
|
f012977aac | ||
|
|
8680bd1dee | ||
|
|
528510eb53 | ||
|
|
e8d17cfb7b | ||
|
|
cdbcd20241 | ||
|
|
fef3ade5c6 | ||
|
|
194d7f0da9 | ||
|
|
8ad20c27da | ||
|
|
f891a9f1a7 | ||
|
|
2a335eb7af | ||
|
|
6578ac0121 | ||
|
|
83f9514a42 | ||
|
|
c92f1aa655 | ||
|
|
688993ba37 | ||
|
|
ddfc8d5bc3 | ||
|
|
c3141e3601 | ||
|
|
f49974180b | ||
|
|
eb6ade49f6 | ||
|
|
6553c04256 | ||
|
|
a8cb015a06 | ||
|
|
ee81dca71c | ||
|
|
ce06ddf312 | ||
|
|
fee2d4bc0c | ||
|
|
a2a990bd0c | ||
|
|
cedbe6523d | ||
|
|
ec64055d93 | ||
|
|
6f542ac8b8 | ||
|
|
8a3c101764 | ||
|
|
49a8689090 | ||
|
|
8f5c4997b1 | ||
|
|
900fdd7f6f | ||
|
|
4723416d45 | ||
|
|
8483f71f57 | ||
|
|
5dac594cc9 | ||
|
|
06f4e160d6 | ||
|
|
1d38ee2fcb | ||
|
|
921b70ebaa | ||
|
|
0f56d424da | ||
|
|
4cd43a2b1c | ||
|
|
1ef359e68b | ||
|
|
58ce1e45b8 | ||
|
|
bd854e7f7a | ||
|
|
3ecc0cf906 | ||
|
|
ea6925f905 | ||
|
|
f45b78d8c0 | ||
|
|
75ca8a91f8 | ||
|
|
16462d05c8 | ||
|
|
cbef54f05c | ||
|
|
f601ff4ce3 | ||
|
|
84fbf7392b | ||
|
|
bbf9379f56 | ||
|
|
6aa14fcfb1 | ||
|
|
710c7d0da7 | ||
|
|
841d4eb9c7 | ||
|
|
8c4d35d3db | ||
|
|
4110057fa1 | ||
|
|
9b1d6d2f2f | ||
|
|
1c45455cb2 | ||
|
|
411aca8695 | ||
|
|
3de69021df | ||
|
|
8418038736 | ||
|
|
3bf2b499a7 | ||
|
|
430da2b78d | ||
|
|
51047dcbce | ||
|
|
708bcaa630 | ||
|
|
724b20c826 | ||
|
|
69f8c46f15 | ||
|
|
b7f2fb0bdf | ||
|
|
222ffd8c53 | ||
|
|
00e0a0f79a | ||
|
|
d6bbc4383b | ||
|
|
b51a2602a9 | ||
|
|
c3fbddc671 | ||
|
|
ce262b691a | ||
|
|
65de6fef9b | ||
|
|
31d95ae5b0 | ||
|
|
429098733c | ||
|
|
597899d2bf | ||
|
|
b1c66b181d | ||
|
|
100b836979 | ||
|
|
817907c25a | ||
|
|
25195fffe2 | ||
|
|
0e784a6ffc | ||
|
|
351f96fa8b | ||
|
|
703fb4fb51 | ||
|
|
a975df6f8c | ||
|
|
fb90128b63 | ||
|
|
ea4c91fb37 | ||
|
|
7c1d6973ba | ||
|
|
4f2120b729 | ||
|
|
51f7d74e4a | ||
|
|
32a810fe1d | ||
|
|
570482521a | ||
|
|
3bd2a2f911 | ||
|
|
1ac6d086bd | ||
|
|
8374599183 | ||
|
|
0091c401df | ||
|
|
00dd67e345 | ||
|
|
158677bd54 | ||
|
|
a1b375316c | ||
|
|
dae2814b0f | ||
|
|
341a98848d | ||
|
|
902e66906a | ||
|
|
c59d3cd03f | ||
|
|
ed9f16e012 | ||
|
|
ed77a4aacd | ||
|
|
ff2fa70bd6 | ||
|
|
3519346df9 | ||
|
|
45f6caa7bd | ||
|
|
e2e7755af2 | ||
|
|
4ab7bfaa20 | ||
|
|
7e0ffb43a6 | ||
|
|
526c8328f6 | ||
|
|
81bad4eb25 | ||
|
|
dcaa6e81a3 | ||
|
|
e78155396d | ||
|
|
d3063c8117 | ||
|
|
cd1ed088c3 | ||
|
|
e831debb94 | ||
|
|
8d15a6612f | ||
|
|
9c034f3be6 | ||
|
|
60dd9349a8 | ||
|
|
330b1cbf7d | ||
|
|
9ffa38d54e | ||
|
|
c925727269 | ||
|
|
ac2dc06bd6 | ||
|
|
80b83adb53 | ||
|
|
ddc31ac2bb | ||
|
|
eb7c5d0b2b | ||
|
|
e5ce3cb62d | ||
|
|
7a69692999 | ||
|
|
d00d9d98dc | ||
|
|
1846c5c14c | ||
|
|
0d9db783f7 | ||
|
|
d3a6964d8f | ||
|
|
55e9cabf51 | ||
|
|
5180f2061a | ||
|
|
05154cf6aa | ||
|
|
f61e955945 | ||
|
|
d80605532f | ||
|
|
8d5fb14b50 | ||
|
|
570286c7df | ||
|
|
11e3ee8d90 | ||
|
|
0664c670f7 | ||
|
|
f36f9d412c | ||
|
|
bd734f1960 | ||
|
|
675a0b1a73 | ||
|
|
a2816277bf | ||
|
|
e37f1f914b | ||
|
|
adf7694308 | ||
|
|
c13449c6ad | ||
|
|
f72035210c | ||
|
|
89ef5238ea | ||
|
|
8198f66c1f | ||
|
|
eb5aa4ee44 | ||
|
|
adb09a0efe | ||
|
|
241eb8bed5 | ||
|
|
842a0d6ff3 | ||
|
|
3200917df2 | ||
|
|
12dcf0647d | ||
|
|
22859c9ffa | ||
|
|
29182156df | ||
|
|
357d63f398 | ||
|
|
e594bf208d | ||
|
|
2f0de3520a | ||
|
|
8def68eb02 |
+5
-4
@@ -1,5 +1,6 @@
|
|||||||
commit_message: "[ci skip]"
|
commit_message: '[ci skip]'
|
||||||
escape_special_characters: 0
|
|
||||||
files:
|
files:
|
||||||
- source: /main/ui/src/main/resources/i18n/strings.properties
|
- source: /src/main/resources/i18n/strings.properties
|
||||||
translation: /main/ui/src/main/resources/i18n/strings_%two_letters_code%.properties
|
translation: /src/main/resources/i18n/strings_%two_letters_code%.properties
|
||||||
|
escape_quotes: 0
|
||||||
|
escape_special_characters: 0
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ include:
|
|||||||
|
|
||||||
Examples of unacceptable behavior by participants include:
|
Examples of unacceptable behavior by participants include:
|
||||||
|
|
||||||
* The use of sexualized language or imagery and unwelcome sexual attention or
|
* The use of sexual language or imagery and unwelcome sexual attention or
|
||||||
advances
|
advances
|
||||||
* Trolling, insulting/derogatory comments, and personal or political attacks
|
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||||
* Public or private harassment
|
* Public or private harassment
|
||||||
|
|||||||
@@ -5,14 +5,11 @@ labels: type:bug
|
|||||||
---
|
---
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
|
Please make sure to:
|
||||||
|
- Comply with our code of conduct: https://github.com/cryptomator/cryptomator/blob/develop/.github/CODE_OF_CONDUCT.md
|
||||||
|
- Search for existing similar issues first: https://github.com/cryptomator/cryptomator/issues?q=
|
||||||
|
|
||||||
Do you want to ask a QUESTION? Are you looking for SUPPORT?
|
⚠️ IMPORTANT: If you don't stick to this template, the issue will get closed.
|
||||||
We're happy to help you via our support channels! Please read: https://github.com/cryptomator/cryptomator/blob/develop/SUPPORT.md
|
|
||||||
|
|
||||||
By filing an issue, you are expected to comply with our code of conduct: https://github.com/cryptomator/cryptomator/blob/develop/.github/CODE_OF_CONDUCT.md
|
|
||||||
|
|
||||||
Of course, we also expect you to search for existing similar issues first! ;) https://github.com/cryptomator/cryptomator/issues?q=
|
|
||||||
|
|
||||||
-->
|
-->
|
||||||
|
|
||||||
### Description
|
### Description
|
||||||
@@ -21,9 +18,9 @@ Of course, we also expect you to search for existing similar issues first! ;) ht
|
|||||||
|
|
||||||
### System Setup
|
### System Setup
|
||||||
|
|
||||||
* Operating system and version: [Windows/macOS/Linux + Version]
|
* Operating system and version: [Windows/macOS/Linux + Version ( + Desktop Environment, if Linux)]
|
||||||
* Cryptomator version: [Shown in the settings]
|
* Cryptomator version: [Shown in the settings]
|
||||||
* Drive: [Dokany/FUSE/WebDAV]
|
* Volume type: [Dokany/FUSE/WebDAV, shown in the settings]
|
||||||
|
|
||||||
### Steps to Reproduce
|
### Steps to Reproduce
|
||||||
|
|
||||||
@@ -48,7 +45,6 @@ Of course, we also expect you to search for existing similar issues first! ;) ht
|
|||||||
[Any additional information, log files, screenshots, configuration, or data that might be necessary to reproduce the issue.]
|
[Any additional information, log files, screenshots, configuration, or data that might be necessary to reproduce the issue.]
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
|
|
||||||
If you want to add the log file or screenshots, please add them as attachments. If your log file seems empty and doesn't show any errors, you may enable the debug mode first. Here is how to do that: https://community.cryptomator.org/t/how-do-i-enable-debug-mode/36
|
If you want to add the log file or screenshots, please add them as attachments. If your log file seems empty and doesn't show any errors, you may enable the debug mode first. Here is how to do that: https://community.cryptomator.org/t/how-do-i-enable-debug-mode/36
|
||||||
|
|
||||||
Then reproduce the problem to ensure all important information is contained in there. You may use test data or redact sensitive information from the log file.
|
Then reproduce the problem to ensure all important information is contained in there. You may use test data or redact sensitive information from the log file.
|
||||||
@@ -57,5 +53,4 @@ Log file location:
|
|||||||
- Windows: %appdata%/Cryptomator
|
- Windows: %appdata%/Cryptomator
|
||||||
- macOS: ~/Library/Logs/Cryptomator
|
- macOS: ~/Library/Logs/Cryptomator
|
||||||
- Linux: ~/.local/share/Cryptomator/logs
|
- Linux: ~/.local/share/Cryptomator/logs
|
||||||
|
-->
|
||||||
-->
|
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
blank_issues_enabled: false
|
||||||
|
contact_links:
|
||||||
|
- name: Help & Support
|
||||||
|
url: https://community.cryptomator.org/
|
||||||
|
about: You will find answers in our community forum
|
||||||
|
- name: User Manual
|
||||||
|
url: https://docs.cryptomator.org/
|
||||||
|
about: Read the Cryptomator documentation here
|
||||||
@@ -5,14 +5,9 @@ labels: type:feature-request
|
|||||||
---
|
---
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
|
Please make sure to:
|
||||||
Do you want to ask a QUESTION? Are you looking for SUPPORT?
|
- Comply with our code of conduct: https://github.com/cryptomator/cryptomator/blob/develop/.github/CODE_OF_CONDUCT.md
|
||||||
We're happy to help you via our support channels! Please read: https://github.com/cryptomator/cryptomator/blob/develop/SUPPORT.md
|
- Search for existing similar issues first: https://github.com/cryptomator/cryptomator/issues?q=
|
||||||
|
|
||||||
By filing a feature request, you are expected to comply with our code of conduct: https://github.com/cryptomator/cryptomator/blob/develop/.github/CODE_OF_CONDUCT.md
|
|
||||||
|
|
||||||
Of course, we also expect you to search for existing similar feature requests first! ;)
|
|
||||||
|
|
||||||
-->
|
-->
|
||||||
|
|
||||||
### Summary
|
### Summary
|
||||||
@@ -29,4 +24,4 @@ Of course, we also expect you to search for existing similar feature requests fi
|
|||||||
|
|
||||||
### Additional Context
|
### Additional Context
|
||||||
|
|
||||||
[Add any other context or screenshots about the feature request here.]
|
[Add any other context or screenshots about the feature request here.]
|
||||||
|
|||||||
@@ -14,5 +14,5 @@ For _everything else_, please visit our official [Cryptomator Community](https:/
|
|||||||
- Discussions about the apps
|
- Discussions about the apps
|
||||||
- [Development discussions](https://community.cryptomator.org/c/development)
|
- [Development discussions](https://community.cryptomator.org/c/development)
|
||||||
- General questions
|
- General questions
|
||||||
- Discussions regarding our design decissions
|
- Discussions regarding our design decisions
|
||||||
- Our roadmap
|
- Our roadmap
|
||||||
+55
-19
@@ -7,11 +7,12 @@ jobs:
|
|||||||
build:
|
build:
|
||||||
name: Build and Test
|
name: Build 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@v2
|
- uses: actions/checkout@v2
|
||||||
- uses: actions/setup-java@v1
|
- uses: actions/setup-java@v1
|
||||||
with:
|
with:
|
||||||
java-version: 14
|
java-version: 16
|
||||||
- uses: actions/cache@v1
|
- uses: actions/cache@v1
|
||||||
with:
|
with:
|
||||||
path: ~/.m2/repository
|
path: ~/.m2/repository
|
||||||
@@ -19,44 +20,46 @@ jobs:
|
|||||||
restore-keys: |
|
restore-keys: |
|
||||||
${{ runner.os }}-maven-
|
${{ runner.os }}-maven-
|
||||||
- name: Ensure to use tagged version
|
- name: Ensure to use tagged version
|
||||||
run: mvn versions:set --file main/pom.xml -DnewVersion=${GITHUB_REF##*/} # use shell parameter expansion to strip of 'refs/tags'
|
run: mvn versions:set -DnewVersion=${GITHUB_REF##*/} # use shell parameter expansion to strip of 'refs/tags'
|
||||||
if: startsWith(github.ref, 'refs/tags/')
|
if: startsWith(github.ref, 'refs/tags/')
|
||||||
- name: Build and Test
|
- name: Build and Test
|
||||||
run: mvn -B install --file main/pom.xml -Pcoverage
|
run: mvn -B clean install jacoco:report -Pcoverage,dependency-check
|
||||||
- name: Run Codacy Coverage Reporter
|
- name: Upload code coverage report
|
||||||
run: |
|
id: codacyCoverageReporter
|
||||||
curl -o ~/codacy-coverage-reporter.jar https://repo.maven.apache.org/maven2/com/codacy/codacy-coverage-reporter/7.1.0/codacy-coverage-reporter-7.1.0-assembly.jar
|
run: bash <(curl -Ls https://coverage.codacy.com/get.sh)
|
||||||
$JAVA_HOME/bin/java -jar ~/codacy-coverage-reporter.jar report -l Java -r main/commons/target/site/jacoco/jacoco.xml --partial
|
|
||||||
$JAVA_HOME/bin/java -jar ~/codacy-coverage-reporter.jar report -l Java -r main/keychain/target/site/jacoco/jacoco.xml --partial
|
|
||||||
$JAVA_HOME/bin/java -jar ~/codacy-coverage-reporter.jar report -l Java -r main/ui/target/site/jacoco/jacoco.xml --partial
|
|
||||||
$JAVA_HOME/bin/java -jar ~/codacy-coverage-reporter.jar report -l Java -r main/launcher/target/site/jacoco/jacoco.xml --partial
|
|
||||||
$JAVA_HOME/bin/java -jar ~/codacy-coverage-reporter.jar final
|
|
||||||
env:
|
env:
|
||||||
CODACY_PROJECT_TOKEN: ${{ secrets.CODACY_PROJECT_TOKEN }}
|
CODACY_PROJECT_TOKEN: ${{ secrets.CODACY_PROJECT_TOKEN }}
|
||||||
- name: Assemble Buildkit
|
continue-on-error: true
|
||||||
run: mvn -B package -DskipTests --file main/pom.xml --resume-from=buildkit -Prelease
|
### TODO: move to matrix build:
|
||||||
|
- name: Assemble buildkit-linux.zip
|
||||||
|
run: mvn -B clean package -DskipTests -Plinux
|
||||||
- name: Upload buildkit-linux.zip
|
- name: Upload buildkit-linux.zip
|
||||||
uses: actions/upload-artifact@v1
|
uses: actions/upload-artifact@v1
|
||||||
with:
|
with:
|
||||||
name: buildkit-linux.zip
|
name: buildkit-linux.zip
|
||||||
path: main/buildkit/target/buildkit-linux.zip
|
path: target/buildkit-linux.zip
|
||||||
|
- name: Assemble buildkit-mac.zip
|
||||||
|
run: mvn -B clean package -DskipTests -Pmac
|
||||||
- name: Upload buildkit-mac.zip
|
- name: Upload buildkit-mac.zip
|
||||||
uses: actions/upload-artifact@v1
|
uses: actions/upload-artifact@v1
|
||||||
with:
|
with:
|
||||||
name: buildkit-mac.zip
|
name: buildkit-mac.zip
|
||||||
path: main/buildkit/target/buildkit-mac.zip
|
path: target/buildkit-mac.zip
|
||||||
|
- name: Assemble buildkit-win.zip
|
||||||
|
run: mvn -B clean package -DskipTests -Pwindows
|
||||||
- name: Upload buildkit-win.zip
|
- name: Upload buildkit-win.zip
|
||||||
uses: actions/upload-artifact@v1
|
uses: actions/upload-artifact@v1
|
||||||
with:
|
with:
|
||||||
name: buildkit-win.zip
|
name: buildkit-win.zip
|
||||||
path: main/buildkit/target/buildkit-win.zip
|
path: target/buildkit-win.zip
|
||||||
|
|
||||||
release:
|
release:
|
||||||
name: Draft a Release on GitHub Releases
|
name: Draft a Release on GitHub Releases
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
needs: build
|
needs: build
|
||||||
if: startsWith(github.ref, 'refs/tags/')
|
if: startsWith(github.ref, 'refs/tags/') && github.repository == 'cryptomator/cryptomator'
|
||||||
steps:
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
- name: Download buildkit-linux.zip
|
- name: Download buildkit-linux.zip
|
||||||
uses: actions/download-artifact@v1
|
uses: actions/download-artifact@v1
|
||||||
with:
|
with:
|
||||||
@@ -72,6 +75,15 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
name: buildkit-win.zip
|
name: buildkit-win.zip
|
||||||
path: .
|
path: .
|
||||||
|
- name: Create tarball
|
||||||
|
run: git archive --prefix="cryptomator-${{ github.ref }}/" -o "cryptomator-${{ github.ref }}.tar.gz" ${{ github.ref }}
|
||||||
|
- name: Sign tarball with key 615D449FE6E6A235
|
||||||
|
run: |
|
||||||
|
echo "${GPG_PRIVATE_KEY}" | gpg --batch --quiet --import
|
||||||
|
echo "${GPG_PASSPHRASE}" | gpg --batch --quiet --passphrase-fd 0 --pinentry-mode loopback -u 615D449FE6E6A235 --detach-sign -a "cryptomator-${{ github.ref }}.tar.gz"
|
||||||
|
env:
|
||||||
|
GPG_PRIVATE_KEY: ${{ secrets.RELEASES_GPG_PRIVATE_KEY }}
|
||||||
|
GPG_PASSPHRASE: ${{ secrets.RELEASES_GPG_PASSPHRASE }}
|
||||||
- name: Create Release
|
- name: Create Release
|
||||||
id: create_release
|
id: create_release
|
||||||
uses: actions/create-release@v1
|
uses: actions/create-release@v1
|
||||||
@@ -82,6 +94,21 @@ jobs:
|
|||||||
release_name: ${{ github.ref }}
|
release_name: ${{ github.ref }}
|
||||||
body: |
|
body: |
|
||||||
:construction: Work in Progress
|
:construction: Work in Progress
|
||||||
|
|
||||||
|
TODO:
|
||||||
|
* [ ] add Linux appimage, zsync file and signature file
|
||||||
|
* [ ] add Windows installer and signature file
|
||||||
|
* [ ] add MacOs disk image and signature file
|
||||||
|
|
||||||
|
## What's new
|
||||||
|
|
||||||
|
## Bugfixes
|
||||||
|
|
||||||
|
## Misc
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
:scroll: A complete list of closed issues is available [here](LINK)
|
||||||
draft: true
|
draft: true
|
||||||
prerelease: false
|
prerelease: false
|
||||||
- name: Upload buildkit-linux.zip to GitHub Releases
|
- name: Upload buildkit-linux.zip to GitHub Releases
|
||||||
@@ -110,4 +137,13 @@ jobs:
|
|||||||
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
||||||
asset_path: buildkit-win.zip
|
asset_path: buildkit-win.zip
|
||||||
asset_name: buildkit-win.zip
|
asset_name: buildkit-win.zip
|
||||||
asset_content_type: application/zip
|
asset_content_type: application/zip
|
||||||
|
- name: Upload tarball signature to GitHub Releases
|
||||||
|
uses: actions/upload-release-asset@v1.0.1
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
with:
|
||||||
|
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
||||||
|
asset_path: "cryptomator-${{ github.ref }}.tar.gz.asc"
|
||||||
|
asset_name: "cryptomator-${{ github.ref }}.tar.gz.asc"
|
||||||
|
asset_content_type: application/octet-stream
|
||||||
|
|||||||
@@ -0,0 +1,37 @@
|
|||||||
|
name: Bug Report Triage
|
||||||
|
|
||||||
|
on:
|
||||||
|
issues:
|
||||||
|
types: [opened]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
closeTemplateViolation:
|
||||||
|
name: Validate bug report against issue template
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
if: contains(github.event.issue.labels.*.name, 'type:bug')
|
||||||
|
steps:
|
||||||
|
- name: Check "Description"
|
||||||
|
if: |
|
||||||
|
!contains(github.event.issue.body, env.MUST_CONTAIN)
|
||||||
|
|| contains(toJson(github.event.issue.body), env.MUST_NOT_CONTAIN)
|
||||||
|
run: exit 1
|
||||||
|
env:
|
||||||
|
MUST_CONTAIN: '### Description'
|
||||||
|
MUST_NOT_CONTAIN: '### Description\r\n\r\n[Summarize your problem.]\r\n\r\n### System Setup'
|
||||||
|
- name: Check "Steps to Reproduce"
|
||||||
|
if: |
|
||||||
|
!contains(github.event.issue.body, env.MUST_CONTAIN)
|
||||||
|
|| contains(toJson(github.event.issue.body), env.MUST_NOT_CONTAIN)
|
||||||
|
run: exit 1
|
||||||
|
env:
|
||||||
|
MUST_CONTAIN: '### Steps to Reproduce'
|
||||||
|
MUST_NOT_CONTAIN: '### Steps to Reproduce\r\n\r\n1. [First step]\r\n2. [Second step]\r\n3. [and so on…]\r\n\r\n#### Expected Behavior'
|
||||||
|
- name: Close issue if one of the checks failed
|
||||||
|
if: ${{ failure() }}
|
||||||
|
uses: peter-evans/close-issue@v1
|
||||||
|
with:
|
||||||
|
comment: |
|
||||||
|
This bug report did ignore our issue template. 😞
|
||||||
|
Auto-closing this issue, since it is most likely not useful.
|
||||||
|
|
||||||
|
_This decision was made by a bot. If you think the bot is wrong, let us know and we'll reopen this issue._
|
||||||
+7
-1
@@ -17,6 +17,12 @@ pom.xml.versionsBackup
|
|||||||
# IntelliJ Settings Files (https://intellij-support.jetbrains.com/hc/en-us/articles/206544839-How-to-manage-projects-under-Version-Control-Systems) #
|
# IntelliJ Settings Files (https://intellij-support.jetbrains.com/hc/en-us/articles/206544839-How-to-manage-projects-under-Version-Control-Systems) #
|
||||||
.idea/**/workspace.xml
|
.idea/**/workspace.xml
|
||||||
.idea/**/tasks.xml
|
.idea/**/tasks.xml
|
||||||
.idea/dictionaries
|
.idea/**/shelf
|
||||||
|
.idea/dictionaries/**
|
||||||
|
!.idea/dictionaries/dict_*
|
||||||
|
.idea/compiler.xml
|
||||||
|
.idea/encodings.xml
|
||||||
|
.idea/jarRepositories.xml
|
||||||
|
.idea/uiDesigner.xml
|
||||||
.idea/**/libraries/
|
.idea/**/libraries/
|
||||||
*.iml
|
*.iml
|
||||||
Generated
+28
-1
@@ -9,14 +9,36 @@
|
|||||||
<option name="RIGHT_MARGIN" value="220" />
|
<option name="RIGHT_MARGIN" value="220" />
|
||||||
<option name="FORMATTER_TAGS_ENABLED" value="true" />
|
<option name="FORMATTER_TAGS_ENABLED" value="true" />
|
||||||
<JavaCodeStyleSettings>
|
<JavaCodeStyleSettings>
|
||||||
<option name="CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND" value="30" />
|
<option name="CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND" value="999" />
|
||||||
<option name="NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND" value="10" />
|
<option name="NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND" value="10" />
|
||||||
<option name="PACKAGES_TO_USE_IMPORT_ON_DEMAND">
|
<option name="PACKAGES_TO_USE_IMPORT_ON_DEMAND">
|
||||||
<value />
|
<value />
|
||||||
</option>
|
</option>
|
||||||
|
<option name="IMPORT_LAYOUT_TABLE">
|
||||||
|
<value>
|
||||||
|
<package name="" withSubpackages="true" static="false" />
|
||||||
|
<emptyLine />
|
||||||
|
<package name="javax" withSubpackages="true" static="false" />
|
||||||
|
<package name="javafx" withSubpackages="true" static="false" />
|
||||||
|
<package name="java" withSubpackages="true" static="false" />
|
||||||
|
<emptyLine />
|
||||||
|
<package name="" withSubpackages="true" static="true" />
|
||||||
|
</value>
|
||||||
|
</option>
|
||||||
<option name="JD_ALIGN_PARAM_COMMENTS" value="false" />
|
<option name="JD_ALIGN_PARAM_COMMENTS" value="false" />
|
||||||
<option name="JD_ALIGN_EXCEPTION_COMMENTS" value="false" />
|
<option name="JD_ALIGN_EXCEPTION_COMMENTS" value="false" />
|
||||||
</JavaCodeStyleSettings>
|
</JavaCodeStyleSettings>
|
||||||
|
<Properties>
|
||||||
|
<option name="KEEP_BLANK_LINES" value="true" />
|
||||||
|
</Properties>
|
||||||
|
<XML>
|
||||||
|
<option name="XML_ATTRIBUTE_WRAP" value="0" />
|
||||||
|
</XML>
|
||||||
|
<codeStyleSettings language="CSS">
|
||||||
|
<indentOptions>
|
||||||
|
<option name="USE_TAB_CHARACTER" value="true" />
|
||||||
|
</indentOptions>
|
||||||
|
</codeStyleSettings>
|
||||||
<codeStyleSettings language="Groovy">
|
<codeStyleSettings language="Groovy">
|
||||||
<indentOptions>
|
<indentOptions>
|
||||||
<option name="USE_TAB_CHARACTER" value="true" />
|
<option name="USE_TAB_CHARACTER" value="true" />
|
||||||
@@ -30,12 +52,17 @@
|
|||||||
<codeStyleSettings language="JAVA">
|
<codeStyleSettings language="JAVA">
|
||||||
<option name="KEEP_LINE_BREAKS" value="false" />
|
<option name="KEEP_LINE_BREAKS" value="false" />
|
||||||
<option name="BLANK_LINES_AFTER_CLASS_HEADER" value="1" />
|
<option name="BLANK_LINES_AFTER_CLASS_HEADER" value="1" />
|
||||||
|
<option name="BINARY_OPERATION_SIGN_ON_NEXT_LINE" value="true" />
|
||||||
<option name="KEEP_SIMPLE_BLOCKS_IN_ONE_LINE" value="true" />
|
<option name="KEEP_SIMPLE_BLOCKS_IN_ONE_LINE" value="true" />
|
||||||
<option name="KEEP_SIMPLE_METHODS_IN_ONE_LINE" value="true" />
|
<option name="KEEP_SIMPLE_METHODS_IN_ONE_LINE" value="true" />
|
||||||
<option name="KEEP_SIMPLE_LAMBDAS_IN_ONE_LINE" value="true" />
|
<option name="KEEP_SIMPLE_LAMBDAS_IN_ONE_LINE" value="true" />
|
||||||
|
<option name="ENUM_CONSTANTS_WRAP" value="2" />
|
||||||
<indentOptions>
|
<indentOptions>
|
||||||
<option name="USE_TAB_CHARACTER" value="true" />
|
<option name="USE_TAB_CHARACTER" value="true" />
|
||||||
</indentOptions>
|
</indentOptions>
|
||||||
|
<arrangement>
|
||||||
|
<rules />
|
||||||
|
</arrangement>
|
||||||
</codeStyleSettings>
|
</codeStyleSettings>
|
||||||
<codeStyleSettings language="JSON">
|
<codeStyleSettings language="JSON">
|
||||||
<indentOptions>
|
<indentOptions>
|
||||||
|
|||||||
Generated
-41
@@ -1,41 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="CompilerConfiguration">
|
|
||||||
<annotationProcessing>
|
|
||||||
<profile name="Annotation profile for Cryptomator" enabled="true">
|
|
||||||
<sourceOutputDir name="target/generated-sources/annotations" />
|
|
||||||
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
|
|
||||||
<outputRelativeToContentRoot value="true" />
|
|
||||||
<processorPath useClasspath="false">
|
|
||||||
<entry name="$MAVEN_REPOSITORY$/com/google/dagger/dagger-compiler/2.27/dagger-compiler-2.27.jar" />
|
|
||||||
<entry name="$MAVEN_REPOSITORY$/com/google/dagger/dagger/2.27/dagger-2.27.jar" />
|
|
||||||
<entry name="$MAVEN_REPOSITORY$/javax/inject/javax.inject/1/javax.inject-1.jar" />
|
|
||||||
<entry name="$MAVEN_REPOSITORY$/com/google/dagger/dagger-producers/2.27/dagger-producers-2.27.jar" />
|
|
||||||
<entry name="$MAVEN_REPOSITORY$/com/google/guava/failureaccess/1.0.1/failureaccess-1.0.1.jar" />
|
|
||||||
<entry name="$MAVEN_REPOSITORY$/com/google/guava/guava/27.1-jre/guava-27.1-jre.jar" />
|
|
||||||
<entry name="$MAVEN_REPOSITORY$/com/google/guava/listenablefuture/9999.0-empty-to-avoid-conflict-with-guava/listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar" />
|
|
||||||
<entry name="$MAVEN_REPOSITORY$/com/google/code/findbugs/jsr305/3.0.1/jsr305-3.0.1.jar" />
|
|
||||||
<entry name="$MAVEN_REPOSITORY$/org/checkerframework/checker-qual/2.5.2/checker-qual-2.5.2.jar" />
|
|
||||||
<entry name="$MAVEN_REPOSITORY$/com/google/errorprone/error_prone_annotations/2.2.0/error_prone_annotations-2.2.0.jar" />
|
|
||||||
<entry name="$MAVEN_REPOSITORY$/com/google/j2objc/j2objc-annotations/1.1/j2objc-annotations-1.1.jar" />
|
|
||||||
<entry name="$MAVEN_REPOSITORY$/org/codehaus/mojo/animal-sniffer-annotations/1.17/animal-sniffer-annotations-1.17.jar" />
|
|
||||||
<entry name="$MAVEN_REPOSITORY$/org/checkerframework/checker-compat-qual/2.5.3/checker-compat-qual-2.5.3.jar" />
|
|
||||||
<entry name="$MAVEN_REPOSITORY$/com/google/dagger/dagger-spi/2.27/dagger-spi-2.27.jar" />
|
|
||||||
<entry name="$MAVEN_REPOSITORY$/com/squareup/javapoet/1.11.1/javapoet-1.11.1.jar" />
|
|
||||||
<entry name="$MAVEN_REPOSITORY$/com/google/googlejavaformat/google-java-format/1.5/google-java-format-1.5.jar" />
|
|
||||||
<entry name="$MAVEN_REPOSITORY$/com/google/errorprone/javac-shaded/9-dev-r4023-3/javac-shaded-9-dev-r4023-3.jar" />
|
|
||||||
<entry name="$MAVEN_REPOSITORY$/javax/annotation/jsr250-api/1.0/jsr250-api-1.0.jar" />
|
|
||||||
<entry name="$MAVEN_REPOSITORY$/net/ltgt/gradle/incap/incap/0.2/incap-0.2.jar" />
|
|
||||||
<entry name="$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib/1.3.50/kotlin-stdlib-1.3.50.jar" />
|
|
||||||
<entry name="$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib-common/1.3.50/kotlin-stdlib-common-1.3.50.jar" />
|
|
||||||
<entry name="$MAVEN_REPOSITORY$/org/jetbrains/annotations/13.0/annotations-13.0.jar" />
|
|
||||||
<entry name="$MAVEN_REPOSITORY$/org/jetbrains/kotlinx/kotlinx-metadata-jvm/0.1.0/kotlinx-metadata-jvm-0.1.0.jar" />
|
|
||||||
</processorPath>
|
|
||||||
<module name="keychain" />
|
|
||||||
<module name="launcher" />
|
|
||||||
<module name="commons" />
|
|
||||||
<module name="ui" />
|
|
||||||
</profile>
|
|
||||||
</annotationProcessing>
|
|
||||||
</component>
|
|
||||||
</project>
|
|
||||||
Generated
+15
@@ -0,0 +1,15 @@
|
|||||||
|
<component name="ProjectDictionaryState">
|
||||||
|
<dictionary name="dict_de">
|
||||||
|
<words>
|
||||||
|
<w>tresorinhalt</w>
|
||||||
|
<w>tresorkonfigurationsdatei</w>
|
||||||
|
<w>tresorlaufwerk</w>
|
||||||
|
<w>tresorliste</w>
|
||||||
|
<w>tresorname</w>
|
||||||
|
<w>tresoroptionen</w>
|
||||||
|
<w>tresorstatistik</w>
|
||||||
|
<w>ungespeicherten</w>
|
||||||
|
<w>ungespeicherter</w>
|
||||||
|
</words>
|
||||||
|
</dictionary>
|
||||||
|
</component>
|
||||||
Generated
+106
@@ -0,0 +1,106 @@
|
|||||||
|
<component name="ProjectDictionaryState">
|
||||||
|
<dictionary name="dict_project">
|
||||||
|
<words>
|
||||||
|
<w>addvault</w>
|
||||||
|
<w>addvaultwizard</w>
|
||||||
|
<w>adoptopenjdk</w>
|
||||||
|
<w>affero</w>
|
||||||
|
<w>aquafx</w>
|
||||||
|
<w>autolock</w>
|
||||||
|
<w>autolocked</w>
|
||||||
|
<w>autolocking</w>
|
||||||
|
<w>baos</w>
|
||||||
|
<w>bkup</w>
|
||||||
|
<w>buildkit</w>
|
||||||
|
<w>changepassword</w>
|
||||||
|
<w>checkerframework</w>
|
||||||
|
<w>crit</w>
|
||||||
|
<w>crowdin</w>
|
||||||
|
<w>cryptofs</w>
|
||||||
|
<w>cryptomator</w>
|
||||||
|
<w>cryptomator's</w>
|
||||||
|
<w>cryptor</w>
|
||||||
|
<w>csprng</w>
|
||||||
|
<w>dcryptomator</w>
|
||||||
|
<w>dfuse</w>
|
||||||
|
<w>dirid</w>
|
||||||
|
<w>djdk</w>
|
||||||
|
<w>dokany</w>
|
||||||
|
<w>dragboard</w>
|
||||||
|
<w>easybind</w>
|
||||||
|
<w>encr</w>
|
||||||
|
<w>errorprone</w>
|
||||||
|
<w>failureaccess</w>
|
||||||
|
<w>fbidis</w>
|
||||||
|
<w>fldinst</w>
|
||||||
|
<w>fldrslt</w>
|
||||||
|
<w>fontawesomefx</w>
|
||||||
|
<w>gdrive</w>
|
||||||
|
<w>gvfs</w>
|
||||||
|
<w>hmmss</w>
|
||||||
|
<w>httpcomponents</w>
|
||||||
|
<w>httpcore</w>
|
||||||
|
<w>iclouddrive</w>
|
||||||
|
<w>jensd</w>
|
||||||
|
<w>jffi</w>
|
||||||
|
<w>keyloading</w>
|
||||||
|
<w>kibs</w>
|
||||||
|
<w>listcell</w>
|
||||||
|
<w>listenablefuture</w>
|
||||||
|
<w>lopp</w>
|
||||||
|
<w>mainwindow</w>
|
||||||
|
<w>masterkey</w>
|
||||||
|
<w>masterkeyfile</w>
|
||||||
|
<w>mibs</w>
|
||||||
|
<w>mountpath</w>
|
||||||
|
<w>mpc's</w>
|
||||||
|
<w>needsmigration</w>
|
||||||
|
<w>noncommercially</w>
|
||||||
|
<w>noël</w>
|
||||||
|
<w>nulab</w>
|
||||||
|
<w>oatomic</w>
|
||||||
|
<w>oauto</w>
|
||||||
|
<w>objectgraph</w>
|
||||||
|
<w>odefault</w>
|
||||||
|
<w>ogid</w>
|
||||||
|
<w>onoappledouble</w>
|
||||||
|
<w>ordonly</w>
|
||||||
|
<w>ouid</w>
|
||||||
|
<w>ovolname</w>
|
||||||
|
<w>passthrough</w>
|
||||||
|
<w>patreon</w>
|
||||||
|
<w>pcloud</w>
|
||||||
|
<w>probot</w>
|
||||||
|
<w>recoverykey</w>
|
||||||
|
<w>relicensing</w>
|
||||||
|
<w>removevault</w>
|
||||||
|
<w>revealer</w>
|
||||||
|
<w>serceman</w>
|
||||||
|
<w>setolabs</w>
|
||||||
|
<w>skymatic</w>
|
||||||
|
<w>socio</w>
|
||||||
|
<w>spof</w>
|
||||||
|
<w>stenzel</w>
|
||||||
|
<w>styleclass</w>
|
||||||
|
<w>sublicenses</w>
|
||||||
|
<w>sublicensing</w>
|
||||||
|
<w>systemkeychain</w>
|
||||||
|
<w>tada</w>
|
||||||
|
<w>tidelift</w>
|
||||||
|
<w>tmpmountpoint</w>
|
||||||
|
<w>tobiasdiez</w>
|
||||||
|
<w>toggler</w>
|
||||||
|
<w>traymenu</w>
|
||||||
|
<w>unknownerror</w>
|
||||||
|
<w>unlockable</w>
|
||||||
|
<w>vaultconfig</w>
|
||||||
|
<w>vaultlist</w>
|
||||||
|
<w>vaultname</w>
|
||||||
|
<w>vaultoptions</w>
|
||||||
|
<w>wrongfilealert</w>
|
||||||
|
<w>xattr</w>
|
||||||
|
<w>zillmann</w>
|
||||||
|
<w>zxcvbn</w>
|
||||||
|
</words>
|
||||||
|
</dictionary>
|
||||||
|
</component>
|
||||||
Generated
-13
@@ -1,13 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="Encoding" defaultCharsetForPropertiesFiles="UTF-8">
|
|
||||||
<file url="file://$PROJECT_DIR$/main" charset="UTF-8" />
|
|
||||||
<file url="file://$PROJECT_DIR$/main/commons/src/main/java" charset="UTF-8" />
|
|
||||||
<file url="file://$PROJECT_DIR$/main/keychain/src/main/java" charset="UTF-8" />
|
|
||||||
<file url="file://$PROJECT_DIR$/main/keychain/src/main/resources" charset="UTF-8" />
|
|
||||||
<file url="file://$PROJECT_DIR$/main/launcher/src/main/java" charset="UTF-8" />
|
|
||||||
<file url="file://$PROJECT_DIR$/main/ui/src/main/java" charset="UTF-8" />
|
|
||||||
<file url="file://$PROJECT_DIR$/main/ui/src/main/resources" charset="UTF-8" />
|
|
||||||
<file url="PROJECT" charset="UTF-8" />
|
|
||||||
</component>
|
|
||||||
</project>
|
|
||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
<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="false" level="TYPO" enabled_by_default="false">
|
<inspection_tool class="SpellCheckingInspection" enabled="true" level="TYPO" enabled_by_default="true">
|
||||||
<option name="processCode" value="true" />
|
<option name="processCode" value="true" />
|
||||||
<option name="processLiterals" value="true" />
|
<option name="processLiterals" value="true" />
|
||||||
<option name="processComments" value="true" />
|
<option name="processComments" value="true" />
|
||||||
|
|||||||
Generated
-30
@@ -1,30 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="RemoteRepositoriesConfiguration">
|
|
||||||
<remote-repository>
|
|
||||||
<option name="id" value="bintray" />
|
|
||||||
<option name="name" value="Bintray JCenter" />
|
|
||||||
<option name="url" value="https://jcenter.bintray.com" />
|
|
||||||
</remote-repository>
|
|
||||||
<remote-repository>
|
|
||||||
<option name="id" value="central" />
|
|
||||||
<option name="name" value="Maven Central Repository" />
|
|
||||||
<option name="url" value="https://repo.maven.apache.org/maven2" />
|
|
||||||
</remote-repository>
|
|
||||||
<remote-repository>
|
|
||||||
<option name="id" value="central" />
|
|
||||||
<option name="name" value="Maven Central repository" />
|
|
||||||
<option name="url" value="https://repo1.maven.org/maven2" />
|
|
||||||
</remote-repository>
|
|
||||||
<remote-repository>
|
|
||||||
<option name="id" value="jcenter" />
|
|
||||||
<option name="name" value="jcenter" />
|
|
||||||
<option name="url" value="https://jcenter.bintray.com" />
|
|
||||||
</remote-repository>
|
|
||||||
<remote-repository>
|
|
||||||
<option name="id" value="jboss.community" />
|
|
||||||
<option name="name" value="JBoss Community repository" />
|
|
||||||
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
|
|
||||||
</remote-repository>
|
|
||||||
</component>
|
|
||||||
</project>
|
|
||||||
Generated
+2
-2
@@ -4,11 +4,11 @@
|
|||||||
<component name="MavenProjectsManager">
|
<component name="MavenProjectsManager">
|
||||||
<option name="originalFiles">
|
<option name="originalFiles">
|
||||||
<list>
|
<list>
|
||||||
<option value="$PROJECT_DIR$/main/pom.xml" />
|
<option value="$PROJECT_DIR$/pom.xml" />
|
||||||
</list>
|
</list>
|
||||||
</option>
|
</option>
|
||||||
</component>
|
</component>
|
||||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_14" default="false" project-jdk-name="14" project-jdk-type="JavaSDK">
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_16" project-jdk-name="16" project-jdk-type="JavaSDK">
|
||||||
<output url="file://$PROJECT_DIR$/out" />
|
<output url="file://$PROJECT_DIR$/out" />
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
||||||
Generated
-8
@@ -1,8 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="ProjectModuleManager">
|
|
||||||
<modules>
|
|
||||||
<module fileurl="file://$PROJECT_DIR$/.idea/Desktop.iml" filepath="$PROJECT_DIR$/.idea/Desktop.iml" />
|
|
||||||
</modules>
|
|
||||||
</component>
|
|
||||||
</project>
|
|
||||||
+2
-2
@@ -1,8 +1,8 @@
|
|||||||
<component name="ProjectRunConfigurationManager">
|
<component name="ProjectRunConfigurationManager">
|
||||||
<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="launcher" />
|
<module name="cryptomator" />
|
||||||
<option name="VM_PARAMETERS" value="-Djdk.gtk.version=2 -Duser.language=en -Dcryptomator.settingsPath="~/.config/Cryptomator/settings.json" -Dcryptomator.ipcPortPath="~/.config/Cryptomator/ipcPort.bin" -Dcryptomator.logDir="~/.local/share/Cryptomator/logs" -Dcryptomator.mountPointsDir="~/.local/share/Cryptomator/mnt" -Xss20m -Xmx512m" />
|
<option name="VM_PARAMETERS" value="-Djdk.gtk.version=2 -Duser.language=en -Dcryptomator.settingsPath="~/.config/Cryptomator/settings.json" -Dcryptomator.ipcPortPath="~/.config/Cryptomator/ipcPort.bin" -Dcryptomator.logDir="~/.local/share/Cryptomator/logs" -Dcryptomator.mountPointsDir="~/.local/share/Cryptomator/mnt" -Dcryptomator.showTrayIcon=true -Xss20m -Xmx512m" />
|
||||||
<method v="2">
|
<method v="2">
|
||||||
<option name="Make" enabled="true" />
|
<option name="Make" enabled="true" />
|
||||||
</method>
|
</method>
|
||||||
|
|||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
<component name="ProjectRunConfigurationManager">
|
||||||
|
<configuration default="false" name="Cryptomator Linux Dev" type="Application" factoryName="Application">
|
||||||
|
<option name="MAIN_CLASS_NAME" value="org.cryptomator.launcher.Cryptomator" />
|
||||||
|
<module name="cryptomator" />
|
||||||
|
<option name="VM_PARAMETERS" value="-Djdk.gtk.version=2 -Duser.language=en -Dcryptomator.settingsPath="~/.config/Cryptomator-Dev/settings.json" -Dcryptomator.ipcPortPath="~/.config/Cryptomator-Dev/ipcPort.bin" -Dcryptomator.logDir="~/.local/share/Cryptomator-Dev/logs" -Dcryptomator.mountPointsDir="~/.local/share/Cryptomator-Dev/mnt" -Dcryptomator.showTrayIcon=true -Dfuse.experimental="true" -Xss20m -Xmx512m" />
|
||||||
|
<method v="2">
|
||||||
|
<option name="Make" enabled="true" />
|
||||||
|
</method>
|
||||||
|
</configuration>
|
||||||
|
</component>
|
||||||
+2
-2
@@ -1,8 +1,8 @@
|
|||||||
<component name="ProjectRunConfigurationManager">
|
<component name="ProjectRunConfigurationManager">
|
||||||
<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="launcher" />
|
<module name="cryptomator" />
|
||||||
<option name="VM_PARAMETERS" value="-Duser.language=en -Dcryptomator.settingsPath="~/AppData/Roaming/Cryptomator/settings.json" -Dcryptomator.ipcPortPath="~/AppData/Roaming/Cryptomator/ipcPort.bin" -Dcryptomator.logDir="~/AppData/Roaming/Cryptomator" -Dcryptomator.keychainPath="~/AppData/Roaming/Cryptomator/keychain.json" -Xss2m -Xmx512m" />
|
<option name="VM_PARAMETERS" value="-Duser.language=en -Dcryptomator.settingsPath="~/AppData/Roaming/Cryptomator/settings.json" -Dcryptomator.ipcPortPath="~/AppData/Roaming/Cryptomator/ipcPort.bin" -Dcryptomator.logDir="~/AppData/Roaming/Cryptomator" -Dcryptomator.keychainPath="~/AppData/Roaming/Cryptomator/keychain.json" -Dcryptomator.mountPointsDir="~/Cryptomator" -Dcryptomator.showTrayIcon=true -Xss2m -Xmx512m" />
|
||||||
<method v="2">
|
<method v="2">
|
||||||
<option name="Make" enabled="true" />
|
<option name="Make" enabled="true" />
|
||||||
</method>
|
</method>
|
||||||
|
|||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
<component name="ProjectRunConfigurationManager">
|
||||||
|
<configuration default="false" name="Cryptomator Windows Dev" type="Application" factoryName="Application">
|
||||||
|
<option name="MAIN_CLASS_NAME" value="org.cryptomator.launcher.Cryptomator" />
|
||||||
|
<module name="cryptomator" />
|
||||||
|
<option name="VM_PARAMETERS" value="-Duser.language=en -Dcryptomator.settingsPath="~/AppData/Roaming/Cryptomator-Dev/settings.json" -Dcryptomator.ipcPortPath="~/AppData/Roaming/Cryptomator-Dev/ipcPort.bin" -Dcryptomator.logDir="~/AppData/Roaming/Cryptomator-Dev" -Dcryptomator.keychainPath="~/AppData/Roaming/Cryptomator-Dev/keychain.json" -Dcryptomator.mountPointsDir="~/Cryptomator-Dev" -Dfuse.experimental="true" -Dcryptomator.showTrayIcon=true -Xss2m -Xmx512m" />
|
||||||
|
<method v="2">
|
||||||
|
<option name="Make" enabled="true" />
|
||||||
|
</method>
|
||||||
|
</configuration>
|
||||||
|
</component>
|
||||||
+2
-3
@@ -4,9 +4,8 @@
|
|||||||
<env name="LD_LIBRARY_PATH" value="/usr/local/lib" />
|
<env name="LD_LIBRARY_PATH" value="/usr/local/lib" />
|
||||||
</envs>
|
</envs>
|
||||||
<option name="MAIN_CLASS_NAME" value="org.cryptomator.launcher.Cryptomator" />
|
<option name="MAIN_CLASS_NAME" value="org.cryptomator.launcher.Cryptomator" />
|
||||||
<module name="launcher" />
|
<module name="cryptomator" />
|
||||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
|
<option name="VM_PARAMETERS" value="-Duser.language=en -Dcryptomator.settingsPath="~/Library/Application Support/Cryptomator/settings.json" -Dcryptomator.ipcPortPath="~/Library/Application Support/Cryptomator/ipcPort.bin" -Dcryptomator.logDir="~/Library/Logs/Cryptomator" -Dcryptomator.showTrayIcon=true -Xss2m -Xmx512m -ea" />
|
||||||
<option name="VM_PARAMETERS" value="-Duser.language=en -Dcryptomator.settingsPath="~/Library/Application Support/Cryptomator/settings.json" -Dcryptomator.ipcPortPath="~/Library/Application Support/Cryptomator/ipcPort.bin" -Dcryptomator.logDir="~/Library/Logs/Cryptomator" -Dcryptomator.mountPointsDir="/Volumes/" -Xss2m -Xmx512m -ea" />
|
|
||||||
<method v="2">
|
<method v="2">
|
||||||
<option name="Make" enabled="true" />
|
<option name="Make" enabled="true" />
|
||||||
</method>
|
</method>
|
||||||
|
|||||||
+13
@@ -0,0 +1,13 @@
|
|||||||
|
<component name="ProjectRunConfigurationManager">
|
||||||
|
<configuration default="false" name="Cryptomator macOS Dev" type="Application" factoryName="Application">
|
||||||
|
<envs>
|
||||||
|
<env name="LD_LIBRARY_PATH" value="/usr/local/lib" />
|
||||||
|
</envs>
|
||||||
|
<option name="MAIN_CLASS_NAME" value="org.cryptomator.launcher.Cryptomator" />
|
||||||
|
<module name="cryptomator" />
|
||||||
|
<option name="VM_PARAMETERS" value="-Duser.language=en -Dcryptomator.settingsPath="~/Library/Application Support/Cryptomator-Dev/settings.json" -Dcryptomator.ipcPortPath="~/Library/Application Support/Cryptomator-Dev/ipcPort.bin" -Dcryptomator.logDir="~/Library/Logs/Cryptomator-Dev" -Dcryptomator.showTrayIcon=true -Xss2m -Xmx512m -ea" />
|
||||||
|
<method v="2">
|
||||||
|
<option name="Make" enabled="true" />
|
||||||
|
</method>
|
||||||
|
</configuration>
|
||||||
|
</component>
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
[](https://cryptomator.org/)
|
[](https://cryptomator.org/)
|
||||||
|
|
||||||
[](https://github.com/cryptomator/cryptomator/actions?query=workflow%3ABuild)
|
[](https://github.com/cryptomator/cryptomator/actions?query=workflow%3ABuild)
|
||||||
[](https://snyk.io/test/github/cryptomator/cryptomator?targetFile=main%2Fpom.xml)
|
[](https://snyk.io/test/github/cryptomator/cryptomator)
|
||||||
[](https://www.codacy.com/app/cryptomator/cryptomator?utm_source=github.com&utm_medium=referral&utm_content=cryptomator/cryptomator&utm_campaign=Badge_Grade)
|
[](https://www.codacy.com/gh/cryptomator/cryptomator/dashboard)
|
||||||
[](http://twitter.com/Cryptomator)
|
[](http://twitter.com/Cryptomator)
|
||||||
[](https://translate.cryptomator.org/)
|
[](https://translate.cryptomator.org/)
|
||||||
[](https://github.com/cryptomator/cryptomator/releases/latest)
|
[](https://github.com/cryptomator/cryptomator/releases/latest)
|
||||||
@@ -17,11 +17,26 @@ Cryptomator is provided free of charge as an open-source project despite the hig
|
|||||||
|
|
||||||
### Gold Sponsors
|
### Gold Sponsors
|
||||||
|
|
||||||
[<img src="https://cryptomator.org/img/sponsors/geewhiz.svg" alt="gee-whiz" height="96">](https://www.gee-whiz.de/)
|
<table>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td><a href="https://www.gee-whiz.de/"><img src="https://cryptomator.org/img/sponsors/geewhiz.svg" alt="gee-whiz" height="80"></a></td>
|
||||||
|
<td><a href="https://proxy-hub.com/"><img src="https://cryptomator.org/img/sponsors/proxyhub.svg" alt="Proxy-Hub" height="80"></a></td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
### Silver Sponsors
|
### Silver Sponsors
|
||||||
|
|
||||||
[](https://thebestvpn.com/)
|
<table>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td><a href="https://thebestvpn.com/"><img src="https://cryptomator.org/img/sponsors/thebestvpn@2x.png" alt="TheBestVPN" height="64"></a></td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
- [Jameson Lopp](https://www.lopp.net/)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -33,7 +48,7 @@ Download native binaries of Cryptomator on [cryptomator.org](https://cryptomator
|
|||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
- Works with Dropbox, Google Drive, OneDrive, ownCloud, Nextcloud and any other cloud storage service which synchronizes with a local directory
|
- Works with Dropbox, Google Drive, OneDrive, MEGA, pCloud, ownCloud, Nextcloud and any other cloud storage service which synchronizes with a local directory
|
||||||
- Open Source means: No backdoors, control is better than trust
|
- Open Source means: No backdoors, control is better than trust
|
||||||
- Client-side: No accounts, no data shared with any online service
|
- Client-side: No accounts, no data shared with any online service
|
||||||
- Totally transparent: Just work on the virtual drive as if it were a USB flash drive
|
- Totally transparent: Just work on the virtual drive as if it were a USB flash drive
|
||||||
@@ -65,18 +80,20 @@ For more information on the security details visit [cryptomator.org](https://doc
|
|||||||
|
|
||||||
### Dependencies
|
### Dependencies
|
||||||
|
|
||||||
* JDK 14 (e.g. adoptopenjdk)
|
* JDK 16 (e.g. adoptopenjdk)
|
||||||
* Maven 3
|
* Maven 3
|
||||||
* Optional: OS-dependent build tools for native packaging (see [Windows](https://github.com/cryptomator/cryptomator-win), [OS X](https://github.com/cryptomator/cryptomator-osx), [Linux](https://github.com/cryptomator/builder-containers))
|
* Optional: OS-dependent build tools for native packaging (see [Windows](https://github.com/cryptomator/cryptomator-win), [OS X](https://github.com/cryptomator/cryptomator-osx), [Linux](https://github.com/cryptomator/builder-containers))
|
||||||
|
|
||||||
### Run Maven
|
### Run Maven
|
||||||
|
|
||||||
```
|
```
|
||||||
cd main
|
mvn clean install
|
||||||
mvn clean install -Prelease
|
# or mvn clean install -Pwindows
|
||||||
|
# or mvn clean install -Pmac
|
||||||
|
# or mvn clean install -Plinux
|
||||||
```
|
```
|
||||||
|
|
||||||
This will build all the jars and bundle them together with their OS-specific dependencies under `main/buildkit/target`. This can now be used to build native packages.
|
This will build all the jars and bundle them together with their OS-specific dependencies under `target`. This can now be used to build native packages.
|
||||||
|
|
||||||
### Start Cryptomator
|
### Start Cryptomator
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<assembly xmlns="http://maven.apache.org/ASSEMBLY/2.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
<assembly xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/ASSEMBLY/2.0.0"
|
||||||
xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.0.0 http://maven.apache.org/xsd/assembly-2.0.0.xsd">
|
xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.0.0 http://maven.apache.org/xsd/assembly-2.0.0.xsd">
|
||||||
<id>tarball</id>
|
<id>tarball</id>
|
||||||
<includeBaseDirectory>false</includeBaseDirectory>
|
<includeBaseDirectory>false</includeBaseDirectory>
|
||||||
@@ -14,13 +14,6 @@
|
|||||||
</includes>
|
</includes>
|
||||||
<outputDirectory>libs</outputDirectory>
|
<outputDirectory>libs</outputDirectory>
|
||||||
</fileSet>
|
</fileSet>
|
||||||
<fileSet>
|
|
||||||
<directory>target/</directory>
|
|
||||||
<includes>
|
|
||||||
<include>ffi-version.txt</include>
|
|
||||||
</includes>
|
|
||||||
<outputDirectory>libs</outputDirectory>
|
|
||||||
</fileSet>
|
|
||||||
<fileSet>
|
<fileSet>
|
||||||
<directory>target/</directory>
|
<directory>target/</directory>
|
||||||
<includes>
|
<includes>
|
||||||
@@ -37,14 +30,14 @@
|
|||||||
<fileMode>0755</fileMode>
|
<fileMode>0755</fileMode>
|
||||||
</fileSet>
|
</fileSet>
|
||||||
<fileSet>
|
<fileSet>
|
||||||
<directory>target/libs</directory>
|
<directory>target/</directory>
|
||||||
<includes>
|
<includes>
|
||||||
<include>*.jar</include>
|
<include>cryptomator-*.jar</include>
|
||||||
</includes>
|
</includes>
|
||||||
<outputDirectory>libs</outputDirectory>
|
<outputDirectory>libs</outputDirectory>
|
||||||
</fileSet>
|
</fileSet>
|
||||||
<fileSet>
|
<fileSet>
|
||||||
<directory>target/linux-libs</directory>
|
<directory>target/libs</directory>
|
||||||
<includes>
|
<includes>
|
||||||
<include>*.jar</include>
|
<include>*.jar</include>
|
||||||
</includes>
|
</includes>
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<assembly xmlns="http://maven.apache.org/ASSEMBLY/2.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
<assembly xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/ASSEMBLY/2.0.0"
|
||||||
xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.0.0 http://maven.apache.org/xsd/assembly-2.0.0.xsd">
|
xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.0.0 http://maven.apache.org/xsd/assembly-2.0.0.xsd">
|
||||||
<id>tarball</id>
|
<id>tarball</id>
|
||||||
<includeBaseDirectory>false</includeBaseDirectory>
|
<includeBaseDirectory>false</includeBaseDirectory>
|
||||||
@@ -14,13 +14,6 @@
|
|||||||
</includes>
|
</includes>
|
||||||
<outputDirectory>libs</outputDirectory>
|
<outputDirectory>libs</outputDirectory>
|
||||||
</fileSet>
|
</fileSet>
|
||||||
<fileSet>
|
|
||||||
<directory>target/</directory>
|
|
||||||
<includes>
|
|
||||||
<include>ffi-version.txt</include>
|
|
||||||
</includes>
|
|
||||||
<outputDirectory>libs</outputDirectory>
|
|
||||||
</fileSet>
|
|
||||||
<fileSet>
|
<fileSet>
|
||||||
<directory>target/</directory>
|
<directory>target/</directory>
|
||||||
<includes>
|
<includes>
|
||||||
@@ -37,14 +30,14 @@
|
|||||||
<fileMode>0755</fileMode>
|
<fileMode>0755</fileMode>
|
||||||
</fileSet>
|
</fileSet>
|
||||||
<fileSet>
|
<fileSet>
|
||||||
<directory>target/libs</directory>
|
<directory>target/</directory>
|
||||||
<includes>
|
<includes>
|
||||||
<include>*.jar</include>
|
<include>cryptomator-*.jar</include>
|
||||||
</includes>
|
</includes>
|
||||||
<outputDirectory>libs</outputDirectory>
|
<outputDirectory>libs</outputDirectory>
|
||||||
</fileSet>
|
</fileSet>
|
||||||
<fileSet>
|
<fileSet>
|
||||||
<directory>target/mac-libs</directory>
|
<directory>target/libs</directory>
|
||||||
<includes>
|
<includes>
|
||||||
<include>*.jar</include>
|
<include>*.jar</include>
|
||||||
</includes>
|
</includes>
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<assembly xmlns="http://maven.apache.org/ASSEMBLY/2.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
<assembly xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/ASSEMBLY/2.0.0"
|
||||||
xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.0.0 http://maven.apache.org/xsd/assembly-2.0.0.xsd">
|
xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.0.0 http://maven.apache.org/xsd/assembly-2.0.0.xsd">
|
||||||
<id>tarball</id>
|
<id>tarball</id>
|
||||||
<includeBaseDirectory>false</includeBaseDirectory>
|
<includeBaseDirectory>false</includeBaseDirectory>
|
||||||
@@ -14,13 +14,6 @@
|
|||||||
</includes>
|
</includes>
|
||||||
<outputDirectory>libs</outputDirectory>
|
<outputDirectory>libs</outputDirectory>
|
||||||
</fileSet>
|
</fileSet>
|
||||||
<fileSet>
|
|
||||||
<directory>target/</directory>
|
|
||||||
<includes>
|
|
||||||
<include>ffi-version.txt</include>
|
|
||||||
</includes>
|
|
||||||
<outputDirectory>libs</outputDirectory>
|
|
||||||
</fileSet>
|
|
||||||
<fileSet>
|
<fileSet>
|
||||||
<directory>target/</directory>
|
<directory>target/</directory>
|
||||||
<includes>
|
<includes>
|
||||||
@@ -37,14 +30,14 @@
|
|||||||
<fileMode>0755</fileMode>
|
<fileMode>0755</fileMode>
|
||||||
</fileSet>
|
</fileSet>
|
||||||
<fileSet>
|
<fileSet>
|
||||||
<directory>target/libs</directory>
|
<directory>target/</directory>
|
||||||
<includes>
|
<includes>
|
||||||
<include>*.jar</include>
|
<include>cryptomator-*.jar</include>
|
||||||
</includes>
|
</includes>
|
||||||
<outputDirectory>libs</outputDirectory>
|
<outputDirectory>libs</outputDirectory>
|
||||||
</fileSet>
|
</fileSet>
|
||||||
<fileSet>
|
<fileSet>
|
||||||
<directory>target/win-libs</directory>
|
<directory>target/libs</directory>
|
||||||
<includes>
|
<includes>
|
||||||
<include>*.jar</include>
|
<include>*.jar</include>
|
||||||
</includes>
|
</includes>
|
||||||
@@ -1,174 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
|
||||||
<parent>
|
|
||||||
<groupId>org.cryptomator</groupId>
|
|
||||||
<artifactId>main</artifactId>
|
|
||||||
<version>1.5.4</version>
|
|
||||||
</parent>
|
|
||||||
<artifactId>buildkit</artifactId>
|
|
||||||
<packaging>pom</packaging>
|
|
||||||
<name>Cryptomator Build Kit</name>
|
|
||||||
<description>Builds a package that can be built with Ant locally</description>
|
|
||||||
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.cryptomator</groupId>
|
|
||||||
<artifactId>launcher</artifactId>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
|
|
||||||
<build>
|
|
||||||
<plugins>
|
|
||||||
<!-- copy resources -->
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-resources-plugin</artifactId>
|
|
||||||
<version>3.1.0</version>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<id>copy-resources</id>
|
|
||||||
<phase>prepare-package</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>copy-resources</goal>
|
|
||||||
</goals>
|
|
||||||
<configuration>
|
|
||||||
<outputDirectory>${project.build.directory}</outputDirectory>
|
|
||||||
<resources>
|
|
||||||
<resource>
|
|
||||||
<directory>${project.basedir}/src/main/resources</directory>
|
|
||||||
<includes>
|
|
||||||
<include>version.txt</include>
|
|
||||||
<include>ffi-version.txt</include>
|
|
||||||
<include>launcher-mac.sh</include>
|
|
||||||
<include>launcher-linux.sh</include>
|
|
||||||
<include>launcher-win.bat</include>
|
|
||||||
<include>LICENSE.txt</include>
|
|
||||||
</includes>
|
|
||||||
<filtering>true</filtering>
|
|
||||||
</resource>
|
|
||||||
</resources>
|
|
||||||
</configuration>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
|
|
||||||
<!-- copy libraries to target/libs/: -->
|
|
||||||
<plugin>
|
|
||||||
<artifactId>maven-dependency-plugin</artifactId>
|
|
||||||
<version>3.1.1</version>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<id>copy-libs</id>
|
|
||||||
<phase>prepare-package</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>copy-dependencies</goal>
|
|
||||||
</goals>
|
|
||||||
<configuration>
|
|
||||||
<outputDirectory>${project.build.directory}/libs</outputDirectory>
|
|
||||||
<excludeClassifiers>linux,mac,win</excludeClassifiers>
|
|
||||||
<excludeArtifactIds>dbus-java,secret-service,hkdf,java-utils</excludeArtifactIds>
|
|
||||||
</configuration>
|
|
||||||
</execution>
|
|
||||||
<execution>
|
|
||||||
<id>copy-linux-libs</id>
|
|
||||||
<phase>prepare-package</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>copy-dependencies</goal>
|
|
||||||
</goals>
|
|
||||||
<configuration>
|
|
||||||
<outputDirectory>${project.build.directory}/linux-libs</outputDirectory>
|
|
||||||
<includeGroupIds>org.openjfx</includeGroupIds>
|
|
||||||
<classifier>linux</classifier>
|
|
||||||
</configuration>
|
|
||||||
</execution>
|
|
||||||
<execution>
|
|
||||||
<id>copy-linux-secret-service</id>
|
|
||||||
<phase>prepare-package</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>copy-dependencies</goal>
|
|
||||||
</goals>
|
|
||||||
<configuration>
|
|
||||||
<outputDirectory>${project.build.directory}/linux-libs</outputDirectory>
|
|
||||||
<includeArtifactIds>dbus-java,secret-service,hkdf,java-utils</includeArtifactIds>
|
|
||||||
</configuration>
|
|
||||||
</execution>
|
|
||||||
<execution>
|
|
||||||
<id>copy-mac-libs</id>
|
|
||||||
<phase>prepare-package</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>copy-dependencies</goal>
|
|
||||||
</goals>
|
|
||||||
<configuration>
|
|
||||||
<outputDirectory>${project.build.directory}/mac-libs</outputDirectory>
|
|
||||||
<includeGroupIds>org.openjfx</includeGroupIds>
|
|
||||||
<classifier>mac</classifier>
|
|
||||||
</configuration>
|
|
||||||
</execution>
|
|
||||||
<execution>
|
|
||||||
<id>copy-win-libs</id>
|
|
||||||
<phase>prepare-package</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>copy-dependencies</goal>
|
|
||||||
</goals>
|
|
||||||
<configuration>
|
|
||||||
<outputDirectory>${project.build.directory}/win-libs</outputDirectory>
|
|
||||||
<includeGroupIds>org.openjfx</includeGroupIds>
|
|
||||||
<classifier>win</classifier>
|
|
||||||
</configuration>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
|
|
||||||
<!-- create buildkit.zip: -->
|
|
||||||
<plugin>
|
|
||||||
<artifactId>maven-assembly-plugin</artifactId>
|
|
||||||
<version>3.1.1</version>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<id>assemble-linux</id>
|
|
||||||
<phase>package</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>single</goal>
|
|
||||||
</goals>
|
|
||||||
<configuration>
|
|
||||||
<descriptors>
|
|
||||||
<descriptor>assembly-linux.xml</descriptor>
|
|
||||||
</descriptors>
|
|
||||||
<appendAssemblyId>false</appendAssemblyId>
|
|
||||||
<finalName>buildkit-linux</finalName>
|
|
||||||
</configuration>
|
|
||||||
</execution>
|
|
||||||
<execution>
|
|
||||||
<id>assemble-mac</id>
|
|
||||||
<phase>package</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>single</goal>
|
|
||||||
</goals>
|
|
||||||
<configuration>
|
|
||||||
<descriptors>
|
|
||||||
<descriptor>assembly-mac.xml</descriptor>
|
|
||||||
</descriptors>
|
|
||||||
<appendAssemblyId>false</appendAssemblyId>
|
|
||||||
<finalName>buildkit-mac</finalName>
|
|
||||||
</configuration>
|
|
||||||
</execution>
|
|
||||||
<execution>
|
|
||||||
<id>assemble-win</id>
|
|
||||||
<phase>package</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>single</goal>
|
|
||||||
</goals>
|
|
||||||
<configuration>
|
|
||||||
<descriptors>
|
|
||||||
<descriptor>assembly-win.xml</descriptor>
|
|
||||||
</descriptors>
|
|
||||||
<appendAssemblyId>false</appendAssemblyId>
|
|
||||||
<finalName>buildkit-win</finalName>
|
|
||||||
</configuration>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
|
||||||
</build>
|
|
||||||
</project>
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
${cryptomator.jni.version}
|
|
||||||
@@ -1,86 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
|
||||||
<parent>
|
|
||||||
<groupId>org.cryptomator</groupId>
|
|
||||||
<artifactId>main</artifactId>
|
|
||||||
<version>1.5.4</version>
|
|
||||||
</parent>
|
|
||||||
<artifactId>commons</artifactId>
|
|
||||||
<name>Cryptomator Commons</name>
|
|
||||||
<description>Shared utilities</description>
|
|
||||||
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.cryptomator</groupId>
|
|
||||||
<artifactId>cryptofs</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.cryptomator</groupId>
|
|
||||||
<artifactId>fuse-nio-adapter</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.cryptomator</groupId>
|
|
||||||
<artifactId>dokany-nio-adapter</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.cryptomator</groupId>
|
|
||||||
<artifactId>webdav-nio-adapter</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.cryptomator</groupId>
|
|
||||||
<artifactId>jni</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- JavaFx -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.openjfx</groupId>
|
|
||||||
<artifactId>javafx-base</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.openjfx</groupId>
|
|
||||||
<artifactId>javafx-graphics</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- EasyBind -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.fxmisc.easybind</groupId>
|
|
||||||
<artifactId>easybind</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- JWT -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.auth0</groupId>
|
|
||||||
<artifactId>java-jwt</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- Google -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.google.guava</groupId>
|
|
||||||
<artifactId>guava</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.google.code.gson</groupId>
|
|
||||||
<artifactId>gson</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- Apache Commons -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.commons</groupId>
|
|
||||||
<artifactId>commons-lang3</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- DI -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.google.dagger</groupId>
|
|
||||||
<artifactId>dagger</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- Logging -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.slf4j</groupId>
|
|
||||||
<artifactId>slf4j-simple</artifactId>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
</project>
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
package org.cryptomator.common;
|
|
||||||
|
|
||||||
public interface Constants {
|
|
||||||
|
|
||||||
String MASTERKEY_FILENAME = "masterkey.cryptomator";
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
* Copyright (c) 2019 Skymatic GmbH.
|
|
||||||
* All rights reserved. This program and the accompanying materials
|
|
||||||
* are made available under the terms of the accompanying LICENSE file.
|
|
||||||
*******************************************************************************/
|
|
||||||
package org.cryptomator.common;
|
|
||||||
|
|
||||||
import dagger.Module;
|
|
||||||
import dagger.Provides;
|
|
||||||
import org.cryptomator.jni.JniFunctions;
|
|
||||||
import org.cryptomator.jni.MacFunctions;
|
|
||||||
import org.cryptomator.jni.WinFunctions;
|
|
||||||
|
|
||||||
import javax.inject.Singleton;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
@Module
|
|
||||||
public class JniModule {
|
|
||||||
|
|
||||||
@Provides
|
|
||||||
@Singleton
|
|
||||||
Optional<MacFunctions> provideOptionalMacFunctions() {
|
|
||||||
return JniFunctions.macFunctions();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Provides
|
|
||||||
@Singleton
|
|
||||||
Optional<WinFunctions> provideOptionalWinFunctions() {
|
|
||||||
return JniFunctions.winFunctions();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,79 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
* Copyright (c) 2017 Skymatic UG (haftungsbeschränkt).
|
|
||||||
* All rights reserved. This program and the accompanying materials
|
|
||||||
* are made available under the terms of the accompanying LICENSE file.
|
|
||||||
*******************************************************************************/
|
|
||||||
package org.cryptomator.common;
|
|
||||||
|
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
|
||||||
import java.util.function.Supplier;
|
|
||||||
import java.util.function.UnaryOperator;
|
|
||||||
|
|
||||||
import com.google.common.base.Throwables;
|
|
||||||
|
|
||||||
public final class LazyInitializer {
|
|
||||||
|
|
||||||
private LazyInitializer() {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Same as {@link #initializeLazily(AtomicReference, SupplierThrowingException, Class)} except that no checked exception may be thrown by the factory function.
|
|
||||||
*
|
|
||||||
* @param <T> Type of the value
|
|
||||||
* @param reference A reference to a maybe not yet initialized value.
|
|
||||||
* @param factory A factory providing a value for the reference, if it doesn't exist yet. The factory may be invoked multiple times, but only one result will survive.
|
|
||||||
* @return The initialized value
|
|
||||||
*/
|
|
||||||
public static <T> T initializeLazily(AtomicReference<T> reference, Supplier<T> factory) {
|
|
||||||
SupplierThrowingException<T, RuntimeException> factoryThrowingRuntimeExceptions = () -> factory.get();
|
|
||||||
return initializeLazily(reference, factoryThrowingRuntimeExceptions, RuntimeException.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Threadsafe lazy initialization pattern as proposed on http://stackoverflow.com/a/30247202/4014509
|
|
||||||
*
|
|
||||||
* @param <T> Type of the value
|
|
||||||
* @param <E> Type of the any expected exception that may occur during initialization
|
|
||||||
* @param reference A reference to a maybe not yet initialized value.
|
|
||||||
* @param factory A factory providing a value for the reference, if it doesn't exist yet. The factory may be invoked multiple times, but only one result will survive.
|
|
||||||
* @param exceptionType Expected exception type.
|
|
||||||
* @return The initialized value
|
|
||||||
* @throws E Exception thrown by the factory function.
|
|
||||||
*/
|
|
||||||
public static <T, E extends Exception> T initializeLazily(AtomicReference<T> reference, SupplierThrowingException<T, E> factory, Class<E> exceptionType) throws E {
|
|
||||||
final T existing = reference.get();
|
|
||||||
if (existing != null) {
|
|
||||||
return existing;
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
return reference.updateAndGet(invokeFactoryIfNull(factory));
|
|
||||||
} catch (InitializationException e) {
|
|
||||||
Throwables.throwIfUnchecked(e.getCause());
|
|
||||||
Throwables.throwIfInstanceOf(e.getCause(), exceptionType);
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static <T, E extends Exception> UnaryOperator<T> invokeFactoryIfNull(SupplierThrowingException<T, E> factory) throws InitializationException {
|
|
||||||
return currentValue -> {
|
|
||||||
if (currentValue == null) {
|
|
||||||
try {
|
|
||||||
return factory.get();
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new InitializationException(e);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return currentValue;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class InitializationException extends RuntimeException {
|
|
||||||
|
|
||||||
public InitializationException(Throwable cause) {
|
|
||||||
super(cause);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
package org.cryptomator.common.settings;
|
|
||||||
|
|
||||||
public enum UiTheme {
|
|
||||||
LIGHT("preferences.general.theme.light"),
|
|
||||||
DARK("preferences.general.theme.dark");
|
|
||||||
// CUSTOM("Custom (%s)");
|
|
||||||
|
|
||||||
private String displayName;
|
|
||||||
|
|
||||||
UiTheme(String displayName) {
|
|
||||||
this.displayName = displayName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getDisplayName() {
|
|
||||||
return displayName;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,112 +0,0 @@
|
|||||||
package org.cryptomator.common.vaults;
|
|
||||||
|
|
||||||
import com.google.common.base.Strings;
|
|
||||||
import org.cryptomator.common.settings.VaultSettings;
|
|
||||||
import org.cryptomator.cryptofs.CryptoFileSystem;
|
|
||||||
import org.cryptomator.frontend.dokany.Mount;
|
|
||||||
import org.cryptomator.frontend.dokany.MountFactory;
|
|
||||||
import org.cryptomator.frontend.dokany.MountFailedException;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.nio.file.DirectoryNotEmptyException;
|
|
||||||
import java.nio.file.DirectoryStream;
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.nio.file.NotDirectoryException;
|
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.nio.file.Paths;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.concurrent.ExecutorService;
|
|
||||||
|
|
||||||
public class DokanyVolume implements Volume {
|
|
||||||
|
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(DokanyVolume.class);
|
|
||||||
|
|
||||||
private static final String FS_TYPE_NAME = "Cryptomator File System";
|
|
||||||
|
|
||||||
private final VaultSettings vaultSettings;
|
|
||||||
private final MountFactory mountFactory;
|
|
||||||
private final WindowsDriveLetters windowsDriveLetters;
|
|
||||||
private Mount mount;
|
|
||||||
private Path mountPoint;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
public DokanyVolume(VaultSettings vaultSettings, ExecutorService executorService, WindowsDriveLetters windowsDriveLetters) {
|
|
||||||
this.vaultSettings = vaultSettings;
|
|
||||||
this.mountFactory = new MountFactory(executorService);
|
|
||||||
this.windowsDriveLetters = windowsDriveLetters;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isSupported() {
|
|
||||||
return DokanyVolume.isSupportedStatic();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void mount(CryptoFileSystem fs, String mountFlags) throws VolumeException, IOException {
|
|
||||||
this.mountPoint = determineMountPoint();
|
|
||||||
String mountName = vaultSettings.mountName().get();
|
|
||||||
try {
|
|
||||||
this.mount = mountFactory.mount(fs.getPath("/"), mountPoint, mountName, FS_TYPE_NAME, mountFlags.strip());
|
|
||||||
} catch (MountFailedException e) {
|
|
||||||
if (vaultSettings.getCustomMountPath().isPresent()) {
|
|
||||||
LOG.warn("Failed to mount vault into {}. Is this directory currently accessed by another process (e.g. Windows Explorer)?", mountPoint);
|
|
||||||
}
|
|
||||||
throw new VolumeException("Unable to mount Filesystem", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Path determineMountPoint() throws VolumeException, IOException {
|
|
||||||
Optional<String> optionalCustomMountPoint = vaultSettings.getCustomMountPath();
|
|
||||||
if (optionalCustomMountPoint.isPresent()) {
|
|
||||||
Path customMountPoint = Paths.get(optionalCustomMountPoint.get());
|
|
||||||
checkProvidedMountPoint(customMountPoint);
|
|
||||||
return customMountPoint;
|
|
||||||
} else if (!Strings.isNullOrEmpty(vaultSettings.winDriveLetter().get())) {
|
|
||||||
return Path.of(vaultSettings.winDriveLetter().get().charAt(0) + ":\\");
|
|
||||||
} else {
|
|
||||||
//auto assign drive letter
|
|
||||||
if (!windowsDriveLetters.getAvailableDriveLetters().isEmpty()) {
|
|
||||||
return Path.of(windowsDriveLetters.getAvailableDriveLetters().iterator().next() + ":\\");
|
|
||||||
} else {
|
|
||||||
//TODO: Error Handling
|
|
||||||
throw new VolumeException("No free drive letter available.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void checkProvidedMountPoint(Path mountPoint) throws IOException {
|
|
||||||
if (!Files.isDirectory(mountPoint)) {
|
|
||||||
throw new NotDirectoryException(mountPoint.toString());
|
|
||||||
}
|
|
||||||
try (DirectoryStream<Path> ds = Files.newDirectoryStream(mountPoint)) {
|
|
||||||
if (ds.iterator().hasNext()) {
|
|
||||||
throw new DirectoryNotEmptyException(mountPoint.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void reveal() throws VolumeException {
|
|
||||||
boolean success = mount.reveal();
|
|
||||||
if (!success) {
|
|
||||||
throw new VolumeException("Reveal failed.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void unmount() {
|
|
||||||
mount.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Optional<Path> getMountPoint() {
|
|
||||||
return Optional.ofNullable(mountPoint);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isSupportedStatic() {
|
|
||||||
return MountFactory.isApplicable();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,177 +0,0 @@
|
|||||||
package org.cryptomator.common.vaults;
|
|
||||||
|
|
||||||
import com.google.common.base.Splitter;
|
|
||||||
import org.apache.commons.lang3.SystemUtils;
|
|
||||||
import org.cryptomator.common.Environment;
|
|
||||||
import org.cryptomator.common.settings.VaultSettings;
|
|
||||||
import org.cryptomator.cryptofs.CryptoFileSystem;
|
|
||||||
import org.cryptomator.frontend.fuse.mount.CommandFailedException;
|
|
||||||
import org.cryptomator.frontend.fuse.mount.EnvironmentVariables;
|
|
||||||
import org.cryptomator.frontend.fuse.mount.FuseMountFactory;
|
|
||||||
import org.cryptomator.frontend.fuse.mount.FuseNotSupportedException;
|
|
||||||
import org.cryptomator.frontend.fuse.mount.Mount;
|
|
||||||
import org.cryptomator.frontend.fuse.mount.Mounter;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.nio.file.DirectoryNotEmptyException;
|
|
||||||
import java.nio.file.DirectoryStream;
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.nio.file.NotDirectoryException;
|
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.nio.file.Paths;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
public class FuseVolume implements Volume {
|
|
||||||
|
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(FuseVolume.class);
|
|
||||||
private static final int MAX_TMPMOUNTPOINT_CREATION_RETRIES = 10;
|
|
||||||
private static final boolean IS_MAC = System.getProperty("os.name").toLowerCase().contains("mac");
|
|
||||||
|
|
||||||
private final VaultSettings vaultSettings;
|
|
||||||
private final Environment environment;
|
|
||||||
|
|
||||||
private Mount fuseMnt;
|
|
||||||
private Path mountPoint;
|
|
||||||
private boolean createdTemporaryMountPoint;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
public FuseVolume(VaultSettings vaultSettings, Environment environment) {
|
|
||||||
this.vaultSettings = vaultSettings;
|
|
||||||
this.environment = environment;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void mount(CryptoFileSystem fs, String mountFlags) throws IOException, FuseNotSupportedException, VolumeException {
|
|
||||||
Optional<String> optionalCustomMountPoint = vaultSettings.getCustomMountPath();
|
|
||||||
if (optionalCustomMountPoint.isPresent()) {
|
|
||||||
Path customMountPoint = Paths.get(optionalCustomMountPoint.get());
|
|
||||||
checkProvidedMountPoint(customMountPoint);
|
|
||||||
this.mountPoint = customMountPoint;
|
|
||||||
LOG.debug("Successfully checked custom mount point: {}", mountPoint);
|
|
||||||
} else {
|
|
||||||
this.mountPoint = prepareTemporaryMountPoint();
|
|
||||||
LOG.debug("Successfully created mount point: {}", mountPoint);
|
|
||||||
}
|
|
||||||
mount(fs.getPath("/"), mountFlags);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void checkProvidedMountPoint(Path mountPoint) throws IOException {
|
|
||||||
if (!Files.isDirectory(mountPoint)) {
|
|
||||||
throw new NotDirectoryException(mountPoint.toString());
|
|
||||||
}
|
|
||||||
try (DirectoryStream<Path> ds = Files.newDirectoryStream(mountPoint)) {
|
|
||||||
if (ds.iterator().hasNext()) {
|
|
||||||
throw new DirectoryNotEmptyException(mountPoint.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Path prepareTemporaryMountPoint() throws IOException, VolumeException {
|
|
||||||
Path mountPoint = chooseNonExistingTemporaryMountPoint();
|
|
||||||
// https://github.com/osxfuse/osxfuse/issues/306#issuecomment-245114592:
|
|
||||||
// In order to allow non-admin users to mount FUSE volumes in `/Volumes`,
|
|
||||||
// starting with version 3.5.0, FUSE will create non-existent mount points automatically.
|
|
||||||
if (IS_MAC && mountPoint.getParent().equals(Paths.get("/Volumes"))) {
|
|
||||||
return mountPoint;
|
|
||||||
} else {
|
|
||||||
Files.createDirectories(mountPoint);
|
|
||||||
this.createdTemporaryMountPoint = true;
|
|
||||||
return mountPoint;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Path chooseNonExistingTemporaryMountPoint() throws VolumeException {
|
|
||||||
Path parent = environment.getMountPointsDir().orElseThrow();
|
|
||||||
String basename = vaultSettings.getId();
|
|
||||||
for (int i = 0; i < MAX_TMPMOUNTPOINT_CREATION_RETRIES; i++) {
|
|
||||||
Path mountPoint = parent.resolve(basename + "_" + i);
|
|
||||||
if (Files.notExists(mountPoint)) {
|
|
||||||
return mountPoint;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
LOG.error("Failed to find feasible mountpoint at {}/{}_x. Giving up after {} attempts.", parent, basename, MAX_TMPMOUNTPOINT_CREATION_RETRIES);
|
|
||||||
throw new VolumeException("Did not find feasible mount point.");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void mount(Path root, String mountFlags) throws VolumeException {
|
|
||||||
try {
|
|
||||||
Mounter mounter = FuseMountFactory.getMounter();
|
|
||||||
EnvironmentVariables envVars = EnvironmentVariables.create() //
|
|
||||||
.withFlags(splitFlags(mountFlags)).withMountPoint(mountPoint) //
|
|
||||||
.build();
|
|
||||||
this.fuseMnt = mounter.mount(root, envVars);
|
|
||||||
} catch (CommandFailedException e) {
|
|
||||||
throw new VolumeException("Unable to mount Filesystem", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private String[] splitFlags(String str) {
|
|
||||||
return Splitter.on(' ').splitToList(str).toArray(String[]::new);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void reveal() throws VolumeException {
|
|
||||||
try {
|
|
||||||
fuseMnt.revealInFileManager();
|
|
||||||
} catch (CommandFailedException e) {
|
|
||||||
LOG.debug("Revealing the vault in file manger failed: " + e.getMessage());
|
|
||||||
throw new VolumeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean supportsForcedUnmount() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public synchronized void unmountForced() throws VolumeException {
|
|
||||||
try {
|
|
||||||
fuseMnt.unmountForced();
|
|
||||||
fuseMnt.close();
|
|
||||||
} catch (CommandFailedException e) {
|
|
||||||
throw new VolumeException(e);
|
|
||||||
}
|
|
||||||
cleanupTemporaryMountPoint();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public synchronized void unmount() throws VolumeException {
|
|
||||||
try {
|
|
||||||
fuseMnt.unmount();
|
|
||||||
fuseMnt.close();
|
|
||||||
} catch (CommandFailedException e) {
|
|
||||||
throw new VolumeException(e);
|
|
||||||
}
|
|
||||||
cleanupTemporaryMountPoint();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void cleanupTemporaryMountPoint() {
|
|
||||||
if (createdTemporaryMountPoint) {
|
|
||||||
try {
|
|
||||||
Files.delete(mountPoint);
|
|
||||||
LOG.debug("Successfully deleted mount point: {}", mountPoint);
|
|
||||||
} catch (IOException e) {
|
|
||||||
LOG.warn("Could not delete mount point: {}", e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isSupported() {
|
|
||||||
return FuseVolume.isSupportedStatic();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Optional<Path> getMountPoint() {
|
|
||||||
return Optional.ofNullable(mountPoint);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isSupportedStatic() {
|
|
||||||
return (SystemUtils.IS_OS_MAC_OSX || SystemUtils.IS_OS_LINUX) && FuseMountFactory.isFuseSupported();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
package org.cryptomator.common.vaults;
|
|
||||||
|
|
||||||
public enum VaultState {
|
|
||||||
/**
|
|
||||||
* No vault found at the provided path
|
|
||||||
*/
|
|
||||||
MISSING,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Vault requires migration to a newer vault format
|
|
||||||
*/
|
|
||||||
NEEDS_MIGRATION,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Vault ready to be unlocked
|
|
||||||
*/
|
|
||||||
LOCKED,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Vault in transition between two other states
|
|
||||||
*/
|
|
||||||
PROCESSING,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Vault is unlocked
|
|
||||||
*/
|
|
||||||
UNLOCKED,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Unknown state due to preceeding unrecoverable exceptions.
|
|
||||||
*/
|
|
||||||
ERROR;
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,97 +0,0 @@
|
|||||||
package org.cryptomator.common.vaults;
|
|
||||||
|
|
||||||
import javafx.application.Platform;
|
|
||||||
import javafx.beans.Observable;
|
|
||||||
import javafx.beans.property.LongProperty;
|
|
||||||
import javafx.beans.property.ObjectProperty;
|
|
||||||
import javafx.beans.property.SimpleLongProperty;
|
|
||||||
import javafx.concurrent.ScheduledService;
|
|
||||||
import javafx.concurrent.Task;
|
|
||||||
import javafx.util.Duration;
|
|
||||||
import org.cryptomator.cryptofs.CryptoFileSystem;
|
|
||||||
import org.cryptomator.cryptofs.CryptoFileSystemStats;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.concurrent.ExecutorService;
|
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
|
||||||
|
|
||||||
@PerVault
|
|
||||||
public class VaultStats {
|
|
||||||
|
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(VaultStats.class);
|
|
||||||
|
|
||||||
private final AtomicReference<CryptoFileSystem> fs;
|
|
||||||
private final ObjectProperty<VaultState> state;
|
|
||||||
private final ScheduledService<Optional<CryptoFileSystemStats>> updateService;
|
|
||||||
private final LongProperty bytesPerSecondRead = new SimpleLongProperty();
|
|
||||||
private final LongProperty bytesPerSecondWritten = new SimpleLongProperty();
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
VaultStats(AtomicReference<CryptoFileSystem> fs, ObjectProperty<VaultState> state, ExecutorService executor) {
|
|
||||||
this.fs = fs;
|
|
||||||
this.state = state;
|
|
||||||
this.updateService = new UpdateStatsService();
|
|
||||||
updateService.setExecutor(executor);
|
|
||||||
updateService.setPeriod(Duration.seconds(1));
|
|
||||||
|
|
||||||
state.addListener(this::vaultStateChanged);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void vaultStateChanged(@SuppressWarnings("unused") Observable observable) {
|
|
||||||
if (VaultState.UNLOCKED.equals(state.get())) {
|
|
||||||
assert fs.get() != null;
|
|
||||||
LOG.debug("start recording stats");
|
|
||||||
updateService.restart();
|
|
||||||
} else {
|
|
||||||
LOG.debug("stop recording stats");
|
|
||||||
updateService.cancel();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateStats(Optional<CryptoFileSystemStats> stats) {
|
|
||||||
assert Platform.isFxApplicationThread();
|
|
||||||
bytesPerSecondRead.set(stats.map(CryptoFileSystemStats::pollBytesRead).orElse(0l));
|
|
||||||
bytesPerSecondWritten.set(stats.map(CryptoFileSystemStats::pollBytesWritten).orElse(0l));
|
|
||||||
}
|
|
||||||
|
|
||||||
private class UpdateStatsService extends ScheduledService<Optional<CryptoFileSystemStats>> {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Task<Optional<CryptoFileSystemStats>> createTask() {
|
|
||||||
return new Task<>() {
|
|
||||||
@Override
|
|
||||||
protected Optional<CryptoFileSystemStats> call() {
|
|
||||||
return Optional.ofNullable(fs.get()).map(CryptoFileSystem::getStats);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void succeeded() {
|
|
||||||
assert getValue() != null;
|
|
||||||
updateStats(getValue());
|
|
||||||
super.succeeded();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Observables */
|
|
||||||
|
|
||||||
public LongProperty bytesPerSecondReadProperty() {
|
|
||||||
return bytesPerSecondRead;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getBytesPerSecondRead() {
|
|
||||||
return bytesPerSecondRead.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
public LongProperty bytesPerSecondWrittenProperty() {
|
|
||||||
return bytesPerSecondWritten;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getBytesPerSecondWritten() {
|
|
||||||
return bytesPerSecondWritten.get();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-62
@@ -1,62 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
* Copyright (c) 2017 Skymatic UG (haftungsbeschränkt).
|
|
||||||
* All rights reserved. This program and the accompanying materials
|
|
||||||
* are made available under the terms of the accompanying LICENSE file.
|
|
||||||
*******************************************************************************/
|
|
||||||
package org.cryptomator.common.settings;
|
|
||||||
|
|
||||||
import com.google.gson.stream.JsonReader;
|
|
||||||
import com.google.gson.stream.JsonWriter;
|
|
||||||
import org.hamcrest.CoreMatchers;
|
|
||||||
import org.hamcrest.MatcherAssert;
|
|
||||||
import org.junit.jupiter.api.Assertions;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.StringReader;
|
|
||||||
import java.io.StringWriter;
|
|
||||||
import java.nio.file.Paths;
|
|
||||||
|
|
||||||
public class VaultSettingsJsonAdapterTest {
|
|
||||||
|
|
||||||
private final VaultSettingsJsonAdapter adapter = new VaultSettingsJsonAdapter();
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testDeserialize() throws IOException {
|
|
||||||
String json = "{\"id\": \"foo\", \"path\": \"/foo/bar\", \"mountName\": \"test\", \"winDriveLetter\": \"X\", \"shouldBeIgnored\": true, \"individualMountPath\": \"/home/test/crypto\", \"mountFlags\":\"--foo --bar\"}";
|
|
||||||
JsonReader jsonReader = new JsonReader(new StringReader(json));
|
|
||||||
|
|
||||||
VaultSettings vaultSettings = adapter.read(jsonReader);
|
|
||||||
Assertions.assertEquals("foo", vaultSettings.getId());
|
|
||||||
Assertions.assertEquals(Paths.get("/foo/bar"), vaultSettings.path().get());
|
|
||||||
Assertions.assertEquals("test", vaultSettings.mountName().get());
|
|
||||||
Assertions.assertEquals("X", vaultSettings.winDriveLetter().get());
|
|
||||||
Assertions.assertEquals("/home/test/crypto", vaultSettings.customMountPath().get());
|
|
||||||
Assertions.assertEquals("--foo --bar", vaultSettings.mountFlags().get());
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testSerialize() throws IOException {
|
|
||||||
VaultSettings vaultSettings = new VaultSettings("test");
|
|
||||||
vaultSettings.path().set(Paths.get("/foo/bar"));
|
|
||||||
vaultSettings.mountName().set("mountyMcMountFace");
|
|
||||||
vaultSettings.mountFlags().set("--foo --bar");
|
|
||||||
|
|
||||||
StringWriter buf = new StringWriter();
|
|
||||||
JsonWriter jsonWriter = new JsonWriter(buf);
|
|
||||||
adapter.write(jsonWriter, vaultSettings);
|
|
||||||
String result = buf.toString();
|
|
||||||
|
|
||||||
MatcherAssert.assertThat(result, CoreMatchers.containsString("\"id\":\"test\""));
|
|
||||||
if(System.getProperty("os.name").contains("Windows")){
|
|
||||||
MatcherAssert.assertThat(result, CoreMatchers.containsString("\"path\":\"\\\\foo\\\\bar\""));
|
|
||||||
} else {
|
|
||||||
MatcherAssert.assertThat(result, CoreMatchers.containsString("\"path\":\"/foo/bar\""));
|
|
||||||
}
|
|
||||||
MatcherAssert.assertThat(result, CoreMatchers.containsString("\"mountName\":\"mountyMcMountFace\""));
|
|
||||||
MatcherAssert.assertThat(result, CoreMatchers.containsString("\"mountFlags\":\"--foo --bar\""));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,52 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
|
||||||
<parent>
|
|
||||||
<groupId>org.cryptomator</groupId>
|
|
||||||
<artifactId>main</artifactId>
|
|
||||||
<version>1.5.4</version>
|
|
||||||
</parent>
|
|
||||||
<artifactId>keychain</artifactId>
|
|
||||||
<name>System Keychain Access</name>
|
|
||||||
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.cryptomator</groupId>
|
|
||||||
<artifactId>commons</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.commons</groupId>
|
|
||||||
<artifactId>commons-lang3</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.google.code.gson</groupId>
|
|
||||||
<artifactId>gson</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- Google -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.google.guava</groupId>
|
|
||||||
<artifactId>guava</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- DI -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.google.dagger</groupId>
|
|
||||||
<artifactId>dagger</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- secret-service lib -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>de.swiesend</groupId>
|
|
||||||
<artifactId>secret-service</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- Logging -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.slf4j</groupId>
|
|
||||||
<artifactId>slf4j-simple</artifactId>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
</project>
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
* Copyright (c) 2017 Skymatic UG (haftungsbeschränkt).
|
|
||||||
* All rights reserved. This program and the accompanying materials
|
|
||||||
* are made available under the terms of the accompanying LICENSE file.
|
|
||||||
*******************************************************************************/
|
|
||||||
package org.cryptomator.keychain;
|
|
||||||
|
|
||||||
public interface KeychainAccess {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Associates a passphrase with a given key.
|
|
||||||
*
|
|
||||||
* @param key Key used to retrieve the passphrase via {@link #loadPassphrase(String)}.
|
|
||||||
* @param passphrase The secret to store in this keychain.
|
|
||||||
*/
|
|
||||||
void storePassphrase(String key, CharSequence passphrase) throws KeychainAccessException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param key Unique key previously used while {@link #storePassphrase(String, CharSequence) storing a passphrase}.
|
|
||||||
* @return The stored passphrase for the given key or <code>null</code> if no value for the given key could be found.
|
|
||||||
*/
|
|
||||||
char[] loadPassphrase(String key) throws KeychainAccessException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Deletes a passphrase with a given key.
|
|
||||||
*
|
|
||||||
* @param key Unique key previously used while {@link #storePassphrase(String, CharSequence) storing a passphrase}.
|
|
||||||
*/
|
|
||||||
void deletePassphrase(String key) throws KeychainAccessException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Updates a passphrase with a given key.
|
|
||||||
*
|
|
||||||
* @param key Unique key previously used while {@link #storePassphrase(String, CharSequence) storing a passphrase}.
|
|
||||||
* @param passphrase The secret to be updated in this keychain.
|
|
||||||
*/
|
|
||||||
void changePassphrase(String key, CharSequence passphrase) throws KeychainAccessException;
|
|
||||||
}
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
package org.cryptomator.keychain;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Indicates an error during communication with the operating system's keychain.
|
|
||||||
*/
|
|
||||||
public class KeychainAccessException extends Exception {
|
|
||||||
|
|
||||||
KeychainAccessException(Throwable cause) {
|
|
||||||
super(cause);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
* Copyright (c) 2017 Skymatic UG (haftungsbeschränkt).
|
|
||||||
* All rights reserved. This program and the accompanying materials
|
|
||||||
* are made available under the terms of the accompanying LICENSE file.
|
|
||||||
*******************************************************************************/
|
|
||||||
package org.cryptomator.keychain;
|
|
||||||
|
|
||||||
interface KeychainAccessStrategy extends KeychainAccess {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return <code>true</code> if this KeychainAccessStrategy works on the current machine.
|
|
||||||
* @implNote This method must not throw any exceptions and should fail fast
|
|
||||||
* returning <code>false</code> if it can't determine availability of the checked strategy
|
|
||||||
*/
|
|
||||||
boolean isSupported();
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
* Copyright (c) 2017 Skymatic UG (haftungsbeschränkt).
|
|
||||||
* All rights reserved. This program and the accompanying materials
|
|
||||||
* are made available under the terms of the accompanying LICENSE file.
|
|
||||||
*******************************************************************************/
|
|
||||||
package org.cryptomator.keychain;
|
|
||||||
|
|
||||||
import com.google.common.collect.Sets;
|
|
||||||
import dagger.Module;
|
|
||||||
import dagger.Provides;
|
|
||||||
import dagger.multibindings.ElementsIntoSet;
|
|
||||||
import org.cryptomator.common.JniModule;
|
|
||||||
|
|
||||||
import javax.inject.Singleton;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
@Module(includes = {JniModule.class})
|
|
||||||
public class KeychainModule {
|
|
||||||
|
|
||||||
@Provides
|
|
||||||
@ElementsIntoSet
|
|
||||||
Set<KeychainAccessStrategy> provideKeychainAccessStrategies(MacSystemKeychainAccess macKeychain, WindowsProtectedKeychainAccess winKeychain, LinuxSecretServiceKeychainAccess linKeychain) {
|
|
||||||
return Sets.newHashSet(macKeychain, winKeychain, linKeychain);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Provides
|
|
||||||
@Singleton
|
|
||||||
public Optional<KeychainAccess> provideSupportedKeychain(Set<KeychainAccessStrategy> keychainAccessStrategies) {
|
|
||||||
return keychainAccessStrategies.stream().filter(KeychainAccessStrategy::isSupported).map(KeychainAccess.class::cast).findFirst();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
-56
@@ -1,56 +0,0 @@
|
|||||||
package org.cryptomator.keychain;
|
|
||||||
|
|
||||||
import org.apache.commons.lang3.SystemUtils;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A facade to LinuxSecretServiceKeychainAccessImpl that doesn't depend on libraries that are unavailable on Mac and Windows.
|
|
||||||
*/
|
|
||||||
public class LinuxSecretServiceKeychainAccess implements KeychainAccessStrategy {
|
|
||||||
|
|
||||||
// the actual implementation is hidden in this delegate object which is loaded via reflection,
|
|
||||||
// as it depends on libraries that aren't necessarily available:
|
|
||||||
private final Optional<KeychainAccessStrategy> delegate;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
public LinuxSecretServiceKeychainAccess() {
|
|
||||||
this.delegate = constructGnomeKeyringKeychainAccess();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Optional<KeychainAccessStrategy> constructGnomeKeyringKeychainAccess() {
|
|
||||||
try {
|
|
||||||
Class<?> clazz = Class.forName("org.cryptomator.keychain.LinuxSecretServiceKeychainAccessImpl");
|
|
||||||
KeychainAccessStrategy instance = (KeychainAccessStrategy) clazz.getDeclaredConstructor().newInstance();
|
|
||||||
return Optional.of(instance);
|
|
||||||
} catch (Exception e) {
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isSupported() {
|
|
||||||
return SystemUtils.IS_OS_LINUX && delegate.map(KeychainAccessStrategy::isSupported).orElse(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void storePassphrase(String key, CharSequence passphrase) throws KeychainAccessException {
|
|
||||||
delegate.orElseThrow(IllegalStateException::new).storePassphrase(key, passphrase);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public char[] loadPassphrase(String key) throws KeychainAccessException {
|
|
||||||
return delegate.orElseThrow(IllegalStateException::new).loadPassphrase(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void deletePassphrase(String key) throws KeychainAccessException {
|
|
||||||
delegate.orElseThrow(IllegalStateException::new).deletePassphrase(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void changePassphrase(String key, CharSequence passphrase) throws KeychainAccessException {
|
|
||||||
delegate.orElseThrow(IllegalStateException::new).changePassphrase(key, passphrase);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-79
@@ -1,79 +0,0 @@
|
|||||||
package org.cryptomator.keychain;
|
|
||||||
|
|
||||||
import org.freedesktop.secret.simple.SimpleCollection;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
class LinuxSecretServiceKeychainAccessImpl implements KeychainAccessStrategy {
|
|
||||||
|
|
||||||
private final String LABEL_FOR_SECRET_IN_KEYRING = "Cryptomator";
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isSupported() {
|
|
||||||
try (@SuppressWarnings("unused") SimpleCollection keyring = new SimpleCollection()) {
|
|
||||||
// seems like we're able to access the keyring.
|
|
||||||
return true;
|
|
||||||
} catch (IOException | RuntimeException e) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void storePassphrase(String key, CharSequence passphrase) throws KeychainAccessException {
|
|
||||||
try (SimpleCollection keyring = new SimpleCollection()) {
|
|
||||||
List<String> list = keyring.getItems(createAttributes(key));
|
|
||||||
if (list == null) {
|
|
||||||
keyring.createItem(LABEL_FOR_SECRET_IN_KEYRING, passphrase, createAttributes(key));
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new KeychainAccessException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public char[] loadPassphrase(String key) throws KeychainAccessException {
|
|
||||||
try (SimpleCollection keyring = new SimpleCollection()) {
|
|
||||||
List<String> list = keyring.getItems(createAttributes(key));
|
|
||||||
if (list != null) {
|
|
||||||
return keyring.getSecret(list.get(0));
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new KeychainAccessException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void deletePassphrase(String key) throws KeychainAccessException {
|
|
||||||
try (SimpleCollection keyring = new SimpleCollection()) {
|
|
||||||
List<String> list = keyring.getItems(createAttributes(key));
|
|
||||||
if (list != null) {
|
|
||||||
keyring.deleteItem(list.get(0));
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new KeychainAccessException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void changePassphrase(String key, CharSequence passphrase) throws KeychainAccessException {
|
|
||||||
try (SimpleCollection keyring = new SimpleCollection()) {
|
|
||||||
List<String> list = keyring.getItems(createAttributes(key));
|
|
||||||
if (list != null) {
|
|
||||||
keyring.updateItem(list.get(0), LABEL_FOR_SECRET_IN_KEYRING, passphrase, createAttributes(key));
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new KeychainAccessException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Map<String, String> createAttributes(String key) {
|
|
||||||
Map<String, String> attributes = new HashMap();
|
|
||||||
attributes.put("Vault", key);
|
|
||||||
return attributes;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
* Copyright (c) 2017 Skymatic UG (haftungsbeschränkt).
|
|
||||||
* All rights reserved. This program and the accompanying materials
|
|
||||||
* are made available under the terms of the accompanying LICENSE file.
|
|
||||||
*******************************************************************************/
|
|
||||||
package org.cryptomator.keychain;
|
|
||||||
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
|
|
||||||
import org.apache.commons.lang3.SystemUtils;
|
|
||||||
import org.cryptomator.jni.MacFunctions;
|
|
||||||
import org.cryptomator.jni.MacKeychainAccess;
|
|
||||||
|
|
||||||
class MacSystemKeychainAccess implements KeychainAccessStrategy {
|
|
||||||
|
|
||||||
private final Optional<MacFunctions> macFunctions;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
public MacSystemKeychainAccess(Optional<MacFunctions> macFunctions) {
|
|
||||||
this.macFunctions = macFunctions;
|
|
||||||
}
|
|
||||||
|
|
||||||
private MacKeychainAccess keychain() {
|
|
||||||
return macFunctions.orElseThrow(IllegalStateException::new).keychainAccess();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void storePassphrase(String key, CharSequence passphrase) {
|
|
||||||
keychain().storePassword(key, passphrase);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public char[] loadPassphrase(String key) {
|
|
||||||
return keychain().loadPassword(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isSupported() {
|
|
||||||
return SystemUtils.IS_OS_MAC_OSX && macFunctions.isPresent();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void deletePassphrase(String key) {
|
|
||||||
keychain().deletePassword(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void changePassphrase(String key, CharSequence passphrase) throws KeychainAccessException {
|
|
||||||
storePassphrase(key, passphrase);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
-204
@@ -1,204 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
* Copyright (c) 2017 Skymatic UG (haftungsbeschränkt).
|
|
||||||
* All rights reserved. This program and the accompanying materials
|
|
||||||
* are made available under the terms of the accompanying LICENSE file.
|
|
||||||
*******************************************************************************/
|
|
||||||
package org.cryptomator.keychain;
|
|
||||||
|
|
||||||
import com.google.common.io.BaseEncoding;
|
|
||||||
import com.google.gson.Gson;
|
|
||||||
import com.google.gson.GsonBuilder;
|
|
||||||
import com.google.gson.JsonDeserializationContext;
|
|
||||||
import com.google.gson.JsonDeserializer;
|
|
||||||
import com.google.gson.JsonElement;
|
|
||||||
import com.google.gson.JsonParseException;
|
|
||||||
import com.google.gson.JsonPrimitive;
|
|
||||||
import com.google.gson.JsonSerializationContext;
|
|
||||||
import com.google.gson.JsonSerializer;
|
|
||||||
import com.google.gson.annotations.SerializedName;
|
|
||||||
import com.google.gson.reflect.TypeToken;
|
|
||||||
import org.apache.commons.lang3.SystemUtils;
|
|
||||||
import org.cryptomator.common.Environment;
|
|
||||||
import org.cryptomator.jni.WinDataProtection;
|
|
||||||
import org.cryptomator.jni.WinFunctions;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.io.OutputStreamWriter;
|
|
||||||
import java.io.Reader;
|
|
||||||
import java.io.UncheckedIOException;
|
|
||||||
import java.io.Writer;
|
|
||||||
import java.lang.reflect.Type;
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
import java.nio.CharBuffer;
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.nio.file.NoSuchFileException;
|
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.nio.file.StandardOpenOption;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.UUID;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
|
||||||
|
|
||||||
class WindowsProtectedKeychainAccess implements KeychainAccessStrategy {
|
|
||||||
|
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(WindowsProtectedKeychainAccess.class);
|
|
||||||
private static final Gson GSON = new GsonBuilder().setPrettyPrinting() //
|
|
||||||
.registerTypeHierarchyAdapter(byte[].class, new ByteArrayJsonAdapter()) //
|
|
||||||
.disableHtmlEscaping().create();
|
|
||||||
|
|
||||||
private final Optional<WinFunctions> winFunctions;
|
|
||||||
private final List<Path> keychainPaths;
|
|
||||||
private Map<String, KeychainEntry> keychainEntries;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
public WindowsProtectedKeychainAccess(Optional<WinFunctions> winFunctions, Environment environment) {
|
|
||||||
this.winFunctions = winFunctions;
|
|
||||||
this.keychainPaths = environment.getKeychainPath().collect(Collectors.toList());
|
|
||||||
}
|
|
||||||
|
|
||||||
private WinDataProtection dataProtection() {
|
|
||||||
return winFunctions.orElseThrow(IllegalStateException::new).dataProtection();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void storePassphrase(String key, CharSequence passphrase) {
|
|
||||||
loadKeychainEntriesIfNeeded();
|
|
||||||
ByteBuffer buf = UTF_8.encode(CharBuffer.wrap(passphrase));
|
|
||||||
byte[] cleartext = new byte[buf.remaining()];
|
|
||||||
buf.get(cleartext);
|
|
||||||
KeychainEntry entry = new KeychainEntry();
|
|
||||||
entry.salt = generateSalt();
|
|
||||||
entry.ciphertext = dataProtection().protect(cleartext, entry.salt);
|
|
||||||
Arrays.fill(buf.array(), (byte) 0x00);
|
|
||||||
Arrays.fill(cleartext, (byte) 0x00);
|
|
||||||
keychainEntries.put(key, entry);
|
|
||||||
saveKeychainEntries();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public char[] loadPassphrase(String key) {
|
|
||||||
loadKeychainEntriesIfNeeded();
|
|
||||||
KeychainEntry entry = keychainEntries.get(key);
|
|
||||||
if (entry == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
byte[] cleartext = dataProtection().unprotect(entry.ciphertext, entry.salt);
|
|
||||||
if (cleartext == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
CharBuffer buf = UTF_8.decode(ByteBuffer.wrap(cleartext));
|
|
||||||
char[] passphrase = new char[buf.remaining()];
|
|
||||||
buf.get(passphrase);
|
|
||||||
Arrays.fill(cleartext, (byte) 0x00);
|
|
||||||
Arrays.fill(buf.array(), (char) 0x00);
|
|
||||||
return passphrase;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void deletePassphrase(String key) {
|
|
||||||
loadKeychainEntriesIfNeeded();
|
|
||||||
keychainEntries.remove(key);
|
|
||||||
saveKeychainEntries();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void changePassphrase(String key, CharSequence passphrase) throws KeychainAccessException {
|
|
||||||
storePassphrase(key, passphrase);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isSupported() {
|
|
||||||
return SystemUtils.IS_OS_WINDOWS && winFunctions.isPresent() && !keychainPaths.isEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
private byte[] generateSalt() {
|
|
||||||
byte[] result = new byte[2 * Long.BYTES];
|
|
||||||
UUID uuid = UUID.randomUUID();
|
|
||||||
ByteBuffer buf = ByteBuffer.wrap(result);
|
|
||||||
buf.putLong(uuid.getMostSignificantBits());
|
|
||||||
buf.putLong(uuid.getLeastSignificantBits());
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void loadKeychainEntriesIfNeeded() {
|
|
||||||
if (keychainEntries == null) {
|
|
||||||
for (Path keychainPath : keychainPaths) {
|
|
||||||
Optional<Map<String, KeychainEntry>> keychain = loadKeychainEntries(keychainPath);
|
|
||||||
if (keychain.isPresent()) {
|
|
||||||
keychainEntries = keychain.get();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (keychainEntries == null) {
|
|
||||||
LOG.info("Unable to load existing keychain file, creating new keychain.");
|
|
||||||
keychainEntries = new HashMap<>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Optional<Map<String, KeychainEntry>> loadKeychainEntries(Path keychainPath) {
|
|
||||||
LOG.debug("Attempting to load keychain from {}", keychainPath);
|
|
||||||
Type type = new TypeToken<Map<String, KeychainEntry>>() {
|
|
||||||
}.getType();
|
|
||||||
try (InputStream in = Files.newInputStream(keychainPath, StandardOpenOption.READ); //
|
|
||||||
Reader reader = new InputStreamReader(in, UTF_8)) {
|
|
||||||
return Optional.of(GSON.fromJson(reader, type));
|
|
||||||
} catch (NoSuchFileException | JsonParseException e) {
|
|
||||||
return Optional.empty();
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new UncheckedIOException("Could not read keychain from path " + keychainPath, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void saveKeychainEntries() {
|
|
||||||
if (keychainPaths.isEmpty()) {
|
|
||||||
throw new IllegalStateException("Can't save keychain if no keychain path is specified.");
|
|
||||||
}
|
|
||||||
saveKeychainEntries(keychainPaths.get(0));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void saveKeychainEntries(Path keychainPath) {
|
|
||||||
try (OutputStream out = Files.newOutputStream(keychainPath, StandardOpenOption.WRITE, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING); //
|
|
||||||
Writer writer = new OutputStreamWriter(out, UTF_8)) {
|
|
||||||
GSON.toJson(keychainEntries, writer);
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new UncheckedIOException("Could not read keychain from path " + keychainPath, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class KeychainEntry {
|
|
||||||
|
|
||||||
@SerializedName("ciphertext")
|
|
||||||
byte[] ciphertext;
|
|
||||||
@SerializedName("salt")
|
|
||||||
byte[] salt;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class ByteArrayJsonAdapter implements JsonSerializer<byte[]>, JsonDeserializer<byte[]> {
|
|
||||||
|
|
||||||
private static final BaseEncoding BASE64 = BaseEncoding.base64();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public byte[] deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
|
|
||||||
return BASE64.decode(json.getAsString());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public JsonElement serialize(byte[] src, Type typeOfSrc, JsonSerializationContext context) {
|
|
||||||
return new JsonPrimitive(BASE64.encode(src));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
* Copyright (c) 2017 Skymatic UG (haftungsbeschränkt).
|
|
||||||
* All rights reserved. This program and the accompanying materials
|
|
||||||
* are made available under the terms of the accompanying LICENSE file.
|
|
||||||
*******************************************************************************/
|
|
||||||
package org.cryptomator.keychain;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.Assertions;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
public class KeychainModuleTest {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testGetKeychain() throws KeychainAccessException {
|
|
||||||
Optional<KeychainAccess> keychainAccess = DaggerTestKeychainComponent.builder().keychainModule(new TestKeychainModule()).build().keychainAccess();
|
|
||||||
Assertions.assertTrue(keychainAccess.isPresent());
|
|
||||||
Assertions.assertTrue(keychainAccess.get() instanceof MapKeychainAccess);
|
|
||||||
keychainAccess.get().storePassphrase("test", "asd");
|
|
||||||
Assertions.assertArrayEquals("asd".toCharArray(), keychainAccess.get().loadPassphrase("test"));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
* Copyright (c) 2017 Skymatic UG (haftungsbeschränkt).
|
|
||||||
* All rights reserved. This program and the accompanying materials
|
|
||||||
* are made available under the terms of the accompanying LICENSE file.
|
|
||||||
*******************************************************************************/
|
|
||||||
package org.cryptomator.keychain;
|
|
||||||
|
|
||||||
import dagger.Component;
|
|
||||||
|
|
||||||
import javax.inject.Singleton;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
@Singleton
|
|
||||||
@Component(modules = KeychainModule.class)
|
|
||||||
interface TestKeychainComponent {
|
|
||||||
|
|
||||||
Optional<KeychainAccess> keychainAccess();
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
* Copyright (c) 2017 Skymatic UG (haftungsbeschränkt).
|
|
||||||
* All rights reserved. This program and the accompanying materials
|
|
||||||
* are made available under the terms of the accompanying LICENSE file.
|
|
||||||
*******************************************************************************/
|
|
||||||
package org.cryptomator.keychain;
|
|
||||||
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
public class TestKeychainModule extends KeychainModule {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
Set<KeychainAccessStrategy> provideKeychainAccessStrategies(MacSystemKeychainAccess macKeychain, WindowsProtectedKeychainAccess winKeychain, LinuxSecretServiceKeychainAccess linKeychain) {
|
|
||||||
return Set.of(new MapKeychainAccess());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
-56
@@ -1,56 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
* Copyright (c) 2017 Skymatic UG (haftungsbeschränkt).
|
|
||||||
* All rights reserved. This program and the accompanying materials
|
|
||||||
* are made available under the terms of the accompanying LICENSE file.
|
|
||||||
*******************************************************************************/
|
|
||||||
package org.cryptomator.keychain;
|
|
||||||
|
|
||||||
import org.cryptomator.common.Environment;
|
|
||||||
import org.cryptomator.jni.WinDataProtection;
|
|
||||||
import org.cryptomator.jni.WinFunctions;
|
|
||||||
import org.junit.jupiter.api.Assertions;
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.junit.jupiter.api.io.TempDir;
|
|
||||||
import org.mockito.Mockito;
|
|
||||||
import org.mockito.stubbing.Answer;
|
|
||||||
|
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.stream.Stream;
|
|
||||||
|
|
||||||
public class WindowsProtectedKeychainAccessTest {
|
|
||||||
|
|
||||||
private WindowsProtectedKeychainAccess keychain;
|
|
||||||
|
|
||||||
@BeforeEach
|
|
||||||
public void setup(@TempDir Path tempDir) {
|
|
||||||
Path keychainPath = tempDir.resolve("keychainfile.tmp");
|
|
||||||
Environment env = Mockito.mock(Environment.class);
|
|
||||||
Mockito.when(env.getKeychainPath()).thenReturn(Stream.of(keychainPath));
|
|
||||||
WinFunctions winFunctions = Mockito.mock(WinFunctions.class);
|
|
||||||
WinDataProtection winDataProtection = Mockito.mock(WinDataProtection.class);
|
|
||||||
Mockito.when(winFunctions.dataProtection()).thenReturn(winDataProtection);
|
|
||||||
Answer<byte[]> answerReturningFirstArg = invocation -> ((byte[]) invocation.getArgument(0)).clone();
|
|
||||||
Mockito.when(winDataProtection.protect(Mockito.any(), Mockito.any())).thenAnswer(answerReturningFirstArg);
|
|
||||||
Mockito.when(winDataProtection.unprotect(Mockito.any(), Mockito.any())).thenAnswer(answerReturningFirstArg);
|
|
||||||
keychain = new WindowsProtectedKeychainAccess(Optional.of(winFunctions), env);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testStoreAndLoad() {
|
|
||||||
String storedPw1 = "topSecret";
|
|
||||||
String storedPw2 = "bottomSecret";
|
|
||||||
keychain.storePassphrase("myPassword", storedPw1);
|
|
||||||
keychain.storePassphrase("myOtherPassword", storedPw2);
|
|
||||||
String loadedPw1 = new String(keychain.loadPassphrase("myPassword"));
|
|
||||||
String loadedPw2 = new String(keychain.loadPassphrase("myOtherPassword"));
|
|
||||||
Assertions.assertEquals(storedPw1, loadedPw1);
|
|
||||||
Assertions.assertEquals(storedPw2, loadedPw2);
|
|
||||||
keychain.deletePassphrase("myPassword");
|
|
||||||
Assertions.assertNull(keychain.loadPassphrase("myPassword"));
|
|
||||||
Assertions.assertNotNull(keychain.loadPassphrase("myOtherPassword"));
|
|
||||||
Assertions.assertNull(keychain.loadPassphrase("nonExistingPassword"));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" ?>
|
|
||||||
<!--
|
|
||||||
Copyright (c) 2014 Markus Kreusch
|
|
||||||
This file is licensed under the terms of the MIT license.
|
|
||||||
See the LICENSE.txt file for more info.
|
|
||||||
|
|
||||||
Contributors:
|
|
||||||
Sebastian Stenzel - log4j config for WebDAV unit tests
|
|
||||||
-->
|
|
||||||
<Configuration status="WARN">
|
|
||||||
|
|
||||||
<Appenders>
|
|
||||||
<Console name="Console" target="SYSTEM_OUT">
|
|
||||||
<PatternLayout pattern="%16d %-5p [%c{1}:%L] %m%n" />
|
|
||||||
<ThresholdFilter level="WARN" onMatch="DENY" onMismatch="ACCEPT" />
|
|
||||||
</Console>
|
|
||||||
<Console name="StdErr" target="SYSTEM_ERR">
|
|
||||||
<PatternLayout pattern="%16d %-5p [%c{1}:%L] %m%n" />
|
|
||||||
<ThresholdFilter level="WARN" onMatch="ACCEPT" onMismatch="DENY" />
|
|
||||||
</Console>
|
|
||||||
</Appenders>
|
|
||||||
|
|
||||||
<Loggers>
|
|
||||||
<!-- show our own debug messages: -->
|
|
||||||
<Logger name="org.cryptomator" level="DEBUG" />
|
|
||||||
<!-- mute dependencies: -->
|
|
||||||
<Root level="INFO">
|
|
||||||
<AppenderRef ref="Console" />
|
|
||||||
<AppenderRef ref="StdErr" />
|
|
||||||
</Root>
|
|
||||||
</Loggers>
|
|
||||||
|
|
||||||
</Configuration>
|
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
|
||||||
<parent>
|
|
||||||
<groupId>org.cryptomator</groupId>
|
|
||||||
<artifactId>main</artifactId>
|
|
||||||
<version>1.5.4</version>
|
|
||||||
</parent>
|
|
||||||
<artifactId>launcher</artifactId>
|
|
||||||
<name>Cryptomator Launcher</name>
|
|
||||||
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.cryptomator</groupId>
|
|
||||||
<artifactId>commons</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.cryptomator</groupId>
|
|
||||||
<artifactId>ui</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- Libs -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.google.guava</groupId>
|
|
||||||
<artifactId>guava</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.commons</groupId>
|
|
||||||
<artifactId>commons-lang3</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- DI -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.google.dagger</groupId>
|
|
||||||
<artifactId>dagger</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- Logging -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>ch.qos.logback</groupId>
|
|
||||||
<artifactId>logback-core</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>ch.qos.logback</groupId>
|
|
||||||
<artifactId>logback-classic</artifactId>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
</project>
|
|
||||||
-365
@@ -1,365 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
|
||||||
<groupId>org.cryptomator</groupId>
|
|
||||||
<artifactId>main</artifactId>
|
|
||||||
<version>1.5.4</version>
|
|
||||||
<packaging>pom</packaging>
|
|
||||||
<name>Cryptomator</name>
|
|
||||||
|
|
||||||
<organization>
|
|
||||||
<name>cryptomator.org</name>
|
|
||||||
<url>https://cryptomator.org</url>
|
|
||||||
</organization>
|
|
||||||
|
|
||||||
<developers>
|
|
||||||
<developer>
|
|
||||||
<name>Sebastian Stenzel</name>
|
|
||||||
<email>sebastian.stenzel@gmail.com</email>
|
|
||||||
<timezone>+1</timezone>
|
|
||||||
</developer>
|
|
||||||
</developers>
|
|
||||||
|
|
||||||
<properties>
|
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
|
||||||
|
|
||||||
<!-- cryptomator dependencies -->
|
|
||||||
<cryptomator.cryptofs.version>1.9.10</cryptomator.cryptofs.version>
|
|
||||||
<cryptomator.jni.version>2.2.2</cryptomator.jni.version>
|
|
||||||
<cryptomator.fuse.version>1.2.3</cryptomator.fuse.version>
|
|
||||||
<cryptomator.dokany.version>1.1.15</cryptomator.dokany.version>
|
|
||||||
<cryptomator.webdav.version>1.0.11</cryptomator.webdav.version>
|
|
||||||
|
|
||||||
<!-- 3rd party dependencies -->
|
|
||||||
<javafx.version>14</javafx.version>
|
|
||||||
<commons-lang3.version>3.9</commons-lang3.version>
|
|
||||||
<secret-service.version>1.0.0</secret-service.version>
|
|
||||||
<jwt.version>3.10.2</jwt.version>
|
|
||||||
<easybind.version>1.0.3</easybind.version>
|
|
||||||
<guava.version>28.2-jre</guava.version>
|
|
||||||
<dagger.version>2.27</dagger.version>
|
|
||||||
<gson.version>2.8.6</gson.version>
|
|
||||||
<slf4j.version>1.7.30</slf4j.version>
|
|
||||||
<logback.version>1.2.3</logback.version>
|
|
||||||
|
|
||||||
<!-- test dependencies -->
|
|
||||||
<junit.jupiter.version>5.6.1</junit.jupiter.version>
|
|
||||||
<mockito.version>3.3.3</mockito.version>
|
|
||||||
<hamcrest.version>2.2</hamcrest.version>
|
|
||||||
</properties>
|
|
||||||
|
|
||||||
<repositories>
|
|
||||||
<repository>
|
|
||||||
<id>jcenter</id>
|
|
||||||
<url>https://jcenter.bintray.com</url>
|
|
||||||
</repository>
|
|
||||||
</repositories>
|
|
||||||
|
|
||||||
<dependencyManagement>
|
|
||||||
<dependencies>
|
|
||||||
<!-- modules -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.cryptomator</groupId>
|
|
||||||
<artifactId>commons</artifactId>
|
|
||||||
<version>${project.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.cryptomator</groupId>
|
|
||||||
<artifactId>keychain</artifactId>
|
|
||||||
<version>${project.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.cryptomator</groupId>
|
|
||||||
<artifactId>ui</artifactId>
|
|
||||||
<version>${project.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.cryptomator</groupId>
|
|
||||||
<artifactId>launcher</artifactId>
|
|
||||||
<version>${project.version}</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- Cryptomator Libs -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.cryptomator</groupId>
|
|
||||||
<artifactId>siv-mode</artifactId>
|
|
||||||
<version>1.4.0</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.cryptomator</groupId>
|
|
||||||
<artifactId>cryptofs</artifactId>
|
|
||||||
<version>${cryptomator.cryptofs.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.cryptomator</groupId>
|
|
||||||
<artifactId>fuse-nio-adapter</artifactId>
|
|
||||||
<version>${cryptomator.fuse.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.cryptomator</groupId>
|
|
||||||
<artifactId>dokany-nio-adapter</artifactId>
|
|
||||||
<version>${cryptomator.dokany.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.cryptomator</groupId>
|
|
||||||
<artifactId>webdav-nio-adapter</artifactId>
|
|
||||||
<version>${cryptomator.webdav.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.cryptomator</groupId>
|
|
||||||
<artifactId>jni</artifactId>
|
|
||||||
<version>${cryptomator.jni.version}</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- JavaFX -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.openjfx</groupId>
|
|
||||||
<artifactId>javafx-base</artifactId>
|
|
||||||
<version>${javafx.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.openjfx</groupId>
|
|
||||||
<artifactId>javafx-graphics</artifactId>
|
|
||||||
<version>${javafx.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.openjfx</groupId>
|
|
||||||
<artifactId>javafx-controls</artifactId>
|
|
||||||
<version>${javafx.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.openjfx</groupId>
|
|
||||||
<artifactId>javafx-fxml</artifactId>
|
|
||||||
<version>${javafx.version}</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- Logging -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.slf4j</groupId>
|
|
||||||
<artifactId>slf4j-api</artifactId>
|
|
||||||
<version>${slf4j.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.slf4j</groupId>
|
|
||||||
<artifactId>slf4j-simple</artifactId>
|
|
||||||
<version>${slf4j.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>ch.qos.logback</groupId>
|
|
||||||
<artifactId>logback-core</artifactId>
|
|
||||||
<version>${logback.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>ch.qos.logback</groupId>
|
|
||||||
<artifactId>logback-classic</artifactId>
|
|
||||||
<version>${logback.version}</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- Apache Commons -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.commons</groupId>
|
|
||||||
<artifactId>commons-lang3</artifactId>
|
|
||||||
<version>${commons-lang3.version}</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- Linux System Keychain -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>de.swiesend</groupId>
|
|
||||||
<artifactId>secret-service</artifactId>
|
|
||||||
<version>${secret-service.version}</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- JWT -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.auth0</groupId>
|
|
||||||
<artifactId>java-jwt</artifactId>
|
|
||||||
<version>${jwt.version}</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- EasyBind -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.fxmisc.easybind</groupId>
|
|
||||||
<artifactId>easybind</artifactId>
|
|
||||||
<version>${easybind.version}</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- Google -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.google.guava</groupId>
|
|
||||||
<artifactId>guava</artifactId>
|
|
||||||
<version>${guava.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.google.dagger</groupId>
|
|
||||||
<artifactId>dagger</artifactId>
|
|
||||||
<version>${dagger.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.google.code.gson</groupId>
|
|
||||||
<artifactId>gson</artifactId>
|
|
||||||
<version>${gson.version}</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- JUnit / Mockito / Hamcrest -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.junit.jupiter</groupId>
|
|
||||||
<artifactId>junit-jupiter</artifactId>
|
|
||||||
<version>${junit.jupiter.version}</version>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.mockito</groupId>
|
|
||||||
<artifactId>mockito-core</artifactId>
|
|
||||||
<version>${mockito.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.hamcrest</groupId>
|
|
||||||
<artifactId>hamcrest</artifactId>
|
|
||||||
<version>${hamcrest.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.openjfx</groupId>
|
|
||||||
<artifactId>javafx-swing</artifactId>
|
|
||||||
<version>${javafx.version}</version>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
</dependencyManagement>
|
|
||||||
|
|
||||||
<dependencies>
|
|
||||||
<!-- common dependencies for all modules -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.slf4j</groupId>
|
|
||||||
<artifactId>slf4j-api</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.junit.jupiter</groupId>
|
|
||||||
<artifactId>junit-jupiter</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.hamcrest</groupId>
|
|
||||||
<artifactId>hamcrest</artifactId>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.mockito</groupId>
|
|
||||||
<artifactId>mockito-core</artifactId>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
|
|
||||||
<modules>
|
|
||||||
<module>commons</module>
|
|
||||||
<module>keychain</module>
|
|
||||||
<module>ui</module>
|
|
||||||
<module>launcher</module>
|
|
||||||
</modules>
|
|
||||||
|
|
||||||
<profiles>
|
|
||||||
<profile>
|
|
||||||
<id>release</id>
|
|
||||||
<modules>
|
|
||||||
<module>buildkit</module>
|
|
||||||
</modules>
|
|
||||||
</profile>
|
|
||||||
<profile>
|
|
||||||
<id>coverage</id>
|
|
||||||
<build>
|
|
||||||
<plugins>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.jacoco</groupId>
|
|
||||||
<artifactId>jacoco-maven-plugin</artifactId>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
|
||||||
</build>
|
|
||||||
</profile>
|
|
||||||
</profiles>
|
|
||||||
|
|
||||||
<build>
|
|
||||||
<pluginManagement>
|
|
||||||
<plugins>
|
|
||||||
<plugin>
|
|
||||||
<artifactId>maven-dependency-plugin</artifactId>
|
|
||||||
<version>3.1.2</version>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<id>copy-libs</id>
|
|
||||||
<goals>
|
|
||||||
<goal>copy-dependencies</goal>
|
|
||||||
</goals>
|
|
||||||
<configuration>
|
|
||||||
<outputDirectory>${project.build.directory}/libs</outputDirectory>
|
|
||||||
<includeScope>runtime</includeScope>
|
|
||||||
</configuration>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.codehaus.mojo</groupId>
|
|
||||||
<artifactId>license-maven-plugin</artifactId>
|
|
||||||
<version>2.0.0</version>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-jar-plugin</artifactId>
|
|
||||||
<version>3.2.0</version>
|
|
||||||
<configuration>
|
|
||||||
<archive>
|
|
||||||
<manifest>
|
|
||||||
<!-- adds Implementation-Version which can be read during runtime -->
|
|
||||||
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
|
|
||||||
</manifest>
|
|
||||||
</archive>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.jacoco</groupId>
|
|
||||||
<artifactId>jacoco-maven-plugin</artifactId>
|
|
||||||
<version>0.8.5</version>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<id>prepare-agent</id>
|
|
||||||
<goals>
|
|
||||||
<goal>prepare-agent</goal>
|
|
||||||
</goals>
|
|
||||||
</execution>
|
|
||||||
<execution>
|
|
||||||
<id>report</id>
|
|
||||||
<goals>
|
|
||||||
<goal>report</goal>
|
|
||||||
</goals>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
<configuration>
|
|
||||||
<excludes>
|
|
||||||
<exclude>**/*_*</exclude>
|
|
||||||
<exclude>**/Dagger*</exclude>
|
|
||||||
</excludes>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
|
||||||
</pluginManagement>
|
|
||||||
<plugins>
|
|
||||||
<plugin>
|
|
||||||
<artifactId>maven-compiler-plugin</artifactId>
|
|
||||||
<version>3.8.1</version>
|
|
||||||
<configuration>
|
|
||||||
<release>14</release>
|
|
||||||
<annotationProcessorPaths>
|
|
||||||
<path>
|
|
||||||
<groupId>com.google.dagger</groupId>
|
|
||||||
<artifactId>dagger-compiler</artifactId>
|
|
||||||
<version>${dagger.version}</version>
|
|
||||||
</path>
|
|
||||||
</annotationProcessorPaths>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-surefire-plugin</artifactId>
|
|
||||||
<version>2.22.2</version>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
|
||||||
</build>
|
|
||||||
|
|
||||||
</project>
|
|
||||||
-123
@@ -1,123 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
|
||||||
<parent>
|
|
||||||
<groupId>org.cryptomator</groupId>
|
|
||||||
<artifactId>main</artifactId>
|
|
||||||
<version>1.5.4</version>
|
|
||||||
</parent>
|
|
||||||
<artifactId>ui</artifactId>
|
|
||||||
<name>Cryptomator GUI</name>
|
|
||||||
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.cryptomator</groupId>
|
|
||||||
<artifactId>keychain</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.cryptomator</groupId>
|
|
||||||
<artifactId>commons</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.cryptomator</groupId>
|
|
||||||
<artifactId>jni</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- JavaFx -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.openjfx</groupId>
|
|
||||||
<artifactId>javafx-controls</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.openjfx</groupId>
|
|
||||||
<artifactId>javafx-fxml</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- EasyBind -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.fxmisc.easybind</groupId>
|
|
||||||
<artifactId>easybind</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- Google -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.google.guava</groupId>
|
|
||||||
<artifactId>guava</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.google.code.gson</groupId>
|
|
||||||
<artifactId>gson</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- Apache Commons -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.commons</groupId>
|
|
||||||
<artifactId>commons-lang3</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- DI -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.google.dagger</groupId>
|
|
||||||
<artifactId>dagger</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- Zxcvbn -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.nulab-inc</groupId>
|
|
||||||
<artifactId>zxcvbn</artifactId>
|
|
||||||
<version>1.3.0</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- Logging -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.slf4j</groupId>
|
|
||||||
<artifactId>slf4j-simple</artifactId>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- Testing -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.google.jimfs</groupId>
|
|
||||||
<artifactId>jimfs</artifactId>
|
|
||||||
<version>1.1</version>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.openjfx</groupId>
|
|
||||||
<artifactId>javafx-swing</artifactId>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
|
|
||||||
<build>
|
|
||||||
<plugins>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.codehaus.mojo</groupId>
|
|
||||||
<artifactId>license-maven-plugin</artifactId>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<id>add-third-party</id>
|
|
||||||
<goals>
|
|
||||||
<goal>add-third-party</goal>
|
|
||||||
</goals>
|
|
||||||
<phase>generate-resources</phase>
|
|
||||||
<configuration>
|
|
||||||
<outputDirectory>${project.basedir}/src/main/resources/license</outputDirectory>
|
|
||||||
<thirdPartyFilename>THIRD-PARTY.txt</thirdPartyFilename>
|
|
||||||
<includedScopes>compile</includedScopes>
|
|
||||||
<excludedGroups>org\.cryptomator</excludedGroups>
|
|
||||||
<licenseMerges>
|
|
||||||
<licenseMerge>Apache License v2.0|Apache License, Version 2.0|The Apache Software License, Version 2.0|Apache 2.0|Apache Software License - Version 2.0</licenseMerge>
|
|
||||||
<licenseMerge>MIT License|The MIT License (MIT)|The MIT License|MIT license</licenseMerge>
|
|
||||||
<licenseMerge>LGPL 2.1|LGPL, version 2.1|GNU Lesser/Library General Public License version 2|GNU Lesser General Public License Version 2.1</licenseMerge>
|
|
||||||
<licenseMerge>GPLv2|GNU General Public License Version 2</licenseMerge>
|
|
||||||
<licenseMerge>GPLv2+CE|CDDL + GPLv2 with classpath exception</licenseMerge>
|
|
||||||
</licenseMerges>
|
|
||||||
<fileTemplate>${project.basedir}/src/license/template.ftl</fileTemplate>
|
|
||||||
</configuration>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
|
||||||
</build>
|
|
||||||
</project>
|
|
||||||
-100
@@ -1,100 +0,0 @@
|
|||||||
package org.cryptomator.ui.changepassword;
|
|
||||||
|
|
||||||
import javafx.beans.binding.Bindings;
|
|
||||||
import javafx.beans.binding.BooleanBinding;
|
|
||||||
import javafx.beans.property.ObjectProperty;
|
|
||||||
import javafx.fxml.FXML;
|
|
||||||
import javafx.scene.control.Button;
|
|
||||||
import javafx.scene.control.CheckBox;
|
|
||||||
import javafx.stage.Stage;
|
|
||||||
import org.cryptomator.common.vaults.Vault;
|
|
||||||
import org.cryptomator.cryptofs.CryptoFileSystemProvider;
|
|
||||||
import org.cryptomator.cryptolib.api.InvalidPassphraseException;
|
|
||||||
import org.cryptomator.keychain.KeychainAccess;
|
|
||||||
import org.cryptomator.keychain.KeychainAccessException;
|
|
||||||
import org.cryptomator.ui.common.Animations;
|
|
||||||
import org.cryptomator.ui.common.ErrorComponent;
|
|
||||||
import org.cryptomator.ui.common.FxController;
|
|
||||||
import org.cryptomator.ui.controls.NiceSecurePasswordField;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
import javax.inject.Named;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.nio.CharBuffer;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
import static org.cryptomator.common.Constants.MASTERKEY_FILENAME;
|
|
||||||
|
|
||||||
@ChangePasswordScoped
|
|
||||||
public class ChangePasswordController implements FxController {
|
|
||||||
|
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(ChangePasswordController.class);
|
|
||||||
|
|
||||||
private final Stage window;
|
|
||||||
private final Vault vault;
|
|
||||||
private final ObjectProperty<CharSequence> newPassword;
|
|
||||||
private final ErrorComponent.Builder errorComponent;
|
|
||||||
private final Optional<KeychainAccess> keychain;
|
|
||||||
|
|
||||||
public NiceSecurePasswordField oldPasswordField;
|
|
||||||
public CheckBox finalConfirmationCheckbox;
|
|
||||||
public Button finishButton;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
public ChangePasswordController(@ChangePasswordWindow Stage window, @ChangePasswordWindow Vault vault, @Named("newPassword") ObjectProperty<CharSequence> newPassword, ErrorComponent.Builder errorComponent, Optional<KeychainAccess> keychain) {
|
|
||||||
this.window = window;
|
|
||||||
this.vault = vault;
|
|
||||||
this.newPassword = newPassword;
|
|
||||||
this.errorComponent = errorComponent;
|
|
||||||
this.keychain = keychain;
|
|
||||||
}
|
|
||||||
|
|
||||||
@FXML
|
|
||||||
public void initialize() {
|
|
||||||
BooleanBinding hasNotConfirmedCheckbox = finalConfirmationCheckbox.selectedProperty().not();
|
|
||||||
BooleanBinding isInvalidNewPassword = Bindings.createBooleanBinding(() -> newPassword.get() == null || newPassword.get().length() == 0, newPassword);
|
|
||||||
finishButton.disableProperty().bind(hasNotConfirmedCheckbox.or(isInvalidNewPassword));
|
|
||||||
}
|
|
||||||
|
|
||||||
@FXML
|
|
||||||
public void cancel() {
|
|
||||||
window.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
@FXML
|
|
||||||
public void finish() {
|
|
||||||
try {
|
|
||||||
CryptoFileSystemProvider.changePassphrase(vault.getPath(), MASTERKEY_FILENAME, oldPasswordField.getCharacters(), newPassword.get());
|
|
||||||
LOG.info("Successfully changed password for {}", vault.getDisplayableName());
|
|
||||||
window.close();
|
|
||||||
updatePasswordInSystemkeychain();
|
|
||||||
} catch (IOException e) {
|
|
||||||
LOG.error("IO error occured during password change. Unable to perform operation.", e);
|
|
||||||
errorComponent.cause(e).window(window).returnToScene(window.getScene()).build().showErrorScene();
|
|
||||||
} catch (InvalidPassphraseException e) {
|
|
||||||
Animations.createShakeWindowAnimation(window).play();
|
|
||||||
oldPasswordField.selectAll();
|
|
||||||
oldPasswordField.requestFocus();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updatePasswordInSystemkeychain() {
|
|
||||||
if (keychain.isPresent()) {
|
|
||||||
try {
|
|
||||||
keychain.get().changePassphrase(vault.getId(), CharBuffer.wrap(newPassword.get()));
|
|
||||||
LOG.info("Successfully updated password in system keychain for {}", vault.getDisplayableName());
|
|
||||||
} catch (KeychainAccessException e) {
|
|
||||||
LOG.error("Failed to update password in system keychain.", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Getter/Setter */
|
|
||||||
|
|
||||||
public Vault getVault() {
|
|
||||||
return vault;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,135 +0,0 @@
|
|||||||
package org.cryptomator.ui.fxapp;
|
|
||||||
|
|
||||||
import dagger.Lazy;
|
|
||||||
import javafx.application.Application;
|
|
||||||
import javafx.application.Platform;
|
|
||||||
import javafx.beans.binding.Bindings;
|
|
||||||
import javafx.beans.binding.BooleanBinding;
|
|
||||||
import javafx.beans.value.ObservableValue;
|
|
||||||
import javafx.collections.FXCollections;
|
|
||||||
import javafx.collections.ObservableSet;
|
|
||||||
import javafx.stage.Stage;
|
|
||||||
import org.cryptomator.common.LicenseHolder;
|
|
||||||
import org.cryptomator.common.settings.Settings;
|
|
||||||
import org.cryptomator.common.settings.UiTheme;
|
|
||||||
import org.cryptomator.common.vaults.Vault;
|
|
||||||
import org.cryptomator.jni.JniException;
|
|
||||||
import org.cryptomator.jni.MacApplicationUiAppearance;
|
|
||||||
import org.cryptomator.jni.MacApplicationUiState;
|
|
||||||
import org.cryptomator.jni.MacFunctions;
|
|
||||||
import org.cryptomator.ui.common.VaultService;
|
|
||||||
import org.cryptomator.ui.mainwindow.MainWindowComponent;
|
|
||||||
import org.cryptomator.ui.preferences.PreferencesComponent;
|
|
||||||
import org.cryptomator.ui.preferences.SelectedPreferencesTab;
|
|
||||||
import org.cryptomator.ui.quit.QuitComponent;
|
|
||||||
import org.cryptomator.ui.unlock.UnlockComponent;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
import javax.inject.Provider;
|
|
||||||
import java.awt.desktop.QuitResponse;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
@FxApplicationScoped
|
|
||||||
public class FxApplication extends Application {
|
|
||||||
|
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(FxApplication.class);
|
|
||||||
|
|
||||||
private final Settings settings;
|
|
||||||
private final Lazy<MainWindowComponent> mainWindow;
|
|
||||||
private final Lazy<PreferencesComponent> preferencesWindow;
|
|
||||||
private final Provider<UnlockComponent.Builder> unlockWindowBuilderProvider;
|
|
||||||
private final Provider<QuitComponent.Builder> quitWindowBuilderProvider;
|
|
||||||
private final Optional<MacFunctions> macFunctions;
|
|
||||||
private final VaultService vaultService;
|
|
||||||
private final LicenseHolder licenseHolder;
|
|
||||||
private final BooleanBinding hasVisibleStages;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
FxApplication(Settings settings, Lazy<MainWindowComponent> mainWindow, Lazy<PreferencesComponent> preferencesWindow, Provider<UnlockComponent.Builder> unlockWindowBuilderProvider, Provider<QuitComponent.Builder> quitWindowBuilderProvider, Optional<MacFunctions> macFunctions, VaultService vaultService, LicenseHolder licenseHolder, ObservableSet<Stage> visibleStages) {
|
|
||||||
this.settings = settings;
|
|
||||||
this.mainWindow = mainWindow;
|
|
||||||
this.preferencesWindow = preferencesWindow;
|
|
||||||
this.unlockWindowBuilderProvider = unlockWindowBuilderProvider;
|
|
||||||
this.quitWindowBuilderProvider = quitWindowBuilderProvider;
|
|
||||||
this.macFunctions = macFunctions;
|
|
||||||
this.vaultService = vaultService;
|
|
||||||
this.licenseHolder = licenseHolder;
|
|
||||||
this.hasVisibleStages = Bindings.isNotEmpty(visibleStages);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void start() {
|
|
||||||
LOG.trace("FxApplication.start()");
|
|
||||||
Platform.setImplicitExit(false);
|
|
||||||
|
|
||||||
hasVisibleStages.addListener(this::hasVisibleStagesChanged);
|
|
||||||
|
|
||||||
settings.theme().addListener(this::themeChanged);
|
|
||||||
loadSelectedStyleSheet(settings.theme().get());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void start(Stage stage) {
|
|
||||||
throw new UnsupportedOperationException("Use start() instead.");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void hasVisibleStagesChanged(@SuppressWarnings("unused") ObservableValue<? extends Boolean> observableValue, @SuppressWarnings("unused") boolean oldValue, boolean newValue) {
|
|
||||||
if (newValue) {
|
|
||||||
macFunctions.map(MacFunctions::uiState).ifPresent(MacApplicationUiState::transformToForegroundApplication);
|
|
||||||
} else {
|
|
||||||
macFunctions.map(MacFunctions::uiState).ifPresent(MacApplicationUiState::transformToAgentApplication);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void showPreferencesWindow(SelectedPreferencesTab selectedTab) {
|
|
||||||
Platform.runLater(() -> {
|
|
||||||
preferencesWindow.get().showPreferencesWindow(selectedTab);
|
|
||||||
LOG.debug("Showing Preferences");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public void showMainWindow() {
|
|
||||||
Platform.runLater(() -> {
|
|
||||||
mainWindow.get().showMainWindow();
|
|
||||||
LOG.debug("Showing MainWindow");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public void startUnlockWorkflow(Vault vault) {
|
|
||||||
Platform.runLater(() -> {
|
|
||||||
unlockWindowBuilderProvider.get().vault(vault).build().startUnlockWorkflow();
|
|
||||||
LOG.debug("Showing UnlockWindow for {}", vault.getDisplayableName());
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public void showQuitWindow(QuitResponse response) {
|
|
||||||
Platform.runLater(() -> {
|
|
||||||
quitWindowBuilderProvider.get().quitResponse(response).build().showQuitWindow();
|
|
||||||
LOG.debug("Showing QuitWindow");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public VaultService getVaultService() {
|
|
||||||
return vaultService;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void themeChanged(@SuppressWarnings("unused") ObservableValue<? extends UiTheme> observable, @SuppressWarnings("unused") UiTheme oldValue, UiTheme newValue) {
|
|
||||||
loadSelectedStyleSheet(newValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void loadSelectedStyleSheet(UiTheme desiredTheme) {
|
|
||||||
UiTheme theme = licenseHolder.isValidLicense() ? desiredTheme : UiTheme.LIGHT;
|
|
||||||
switch (theme) {
|
|
||||||
case DARK -> {
|
|
||||||
Application.setUserAgentStylesheet(getClass().getResource("/css/dark_theme.css").toString());
|
|
||||||
macFunctions.map(MacFunctions::uiAppearance).ifPresent(JniException.ignore(MacApplicationUiAppearance::setToDarkAqua));
|
|
||||||
}
|
|
||||||
case LIGHT -> {
|
|
||||||
Application.setUserAgentStylesheet(getClass().getResource("/css/light_theme.css").toString());
|
|
||||||
macFunctions.map(MacFunctions::uiAppearance).ifPresent(JniException.ignore(MacApplicationUiAppearance::setToAqua));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,81 +0,0 @@
|
|||||||
package org.cryptomator.ui.launcher;
|
|
||||||
|
|
||||||
import javafx.collections.ObservableList;
|
|
||||||
import org.cryptomator.common.settings.Settings;
|
|
||||||
import org.cryptomator.common.vaults.Vault;
|
|
||||||
import org.cryptomator.jni.JniException;
|
|
||||||
import org.cryptomator.jni.MacApplicationUiState;
|
|
||||||
import org.cryptomator.jni.MacFunctions;
|
|
||||||
import org.cryptomator.ui.fxapp.FxApplication;
|
|
||||||
import org.cryptomator.ui.traymenu.TrayMenuComponent;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
import javax.inject.Singleton;
|
|
||||||
import java.awt.Desktop;
|
|
||||||
import java.awt.SystemTray;
|
|
||||||
import java.awt.desktop.AppReopenedListener;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
@Singleton
|
|
||||||
public class UiLauncher {
|
|
||||||
|
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(UiLauncher.class);
|
|
||||||
|
|
||||||
private final Settings settings;
|
|
||||||
private final ObservableList<Vault> vaults;
|
|
||||||
private final TrayMenuComponent.Builder trayComponent;
|
|
||||||
private final FxApplicationStarter fxApplicationStarter;
|
|
||||||
private final AppLaunchEventHandler launchEventHandler;
|
|
||||||
private final Optional<MacFunctions> macFunctions;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
public UiLauncher(Settings settings, ObservableList<Vault> vaults, TrayMenuComponent.Builder trayComponent, FxApplicationStarter fxApplicationStarter, AppLaunchEventHandler launchEventHandler, Optional<MacFunctions> macFunctions) {
|
|
||||||
this.settings = settings;
|
|
||||||
this.vaults = vaults;
|
|
||||||
this.trayComponent = trayComponent;
|
|
||||||
this.fxApplicationStarter = fxApplicationStarter;
|
|
||||||
this.launchEventHandler = launchEventHandler;
|
|
||||||
this.macFunctions = macFunctions;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void launch() {
|
|
||||||
final boolean hasTrayIcon;
|
|
||||||
if (SystemTray.isSupported()) {
|
|
||||||
trayComponent.build().addIconToSystemTray();
|
|
||||||
hasTrayIcon = true;
|
|
||||||
} else {
|
|
||||||
hasTrayIcon = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// show window on start?
|
|
||||||
if (hasTrayIcon && settings.startHidden().get()) {
|
|
||||||
LOG.debug("Hiding application...");
|
|
||||||
macFunctions.map(MacFunctions::uiState).ifPresent(JniException.ignore(MacApplicationUiState::transformToAgentApplication));
|
|
||||||
} else {
|
|
||||||
showMainWindowAsync(hasTrayIcon);
|
|
||||||
}
|
|
||||||
|
|
||||||
// register app reopen listener
|
|
||||||
Desktop.getDesktop().addAppEventListener((AppReopenedListener) e -> showMainWindowAsync(hasTrayIcon));
|
|
||||||
|
|
||||||
// auto unlock
|
|
||||||
Collection<Vault> vaultsWithAutoUnlockEnabled = vaults.filtered(v -> v.getVaultSettings().unlockAfterStartup().get());
|
|
||||||
if (!vaultsWithAutoUnlockEnabled.isEmpty()) {
|
|
||||||
fxApplicationStarter.get(hasTrayIcon).thenAccept(app -> {
|
|
||||||
for (Vault vault : vaultsWithAutoUnlockEnabled){
|
|
||||||
app.startUnlockWorkflow(vault);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
launchEventHandler.startHandlingLaunchEvents(hasTrayIcon);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void showMainWindowAsync(boolean hasTrayIcon) {
|
|
||||||
fxApplicationStarter.get(hasTrayIcon).thenAccept(FxApplication::showMainWindow);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
package org.cryptomator.ui.launcher;
|
|
||||||
|
|
||||||
import dagger.Module;
|
|
||||||
import dagger.Provides;
|
|
||||||
import org.cryptomator.common.JniModule;
|
|
||||||
import org.cryptomator.keychain.KeychainModule;
|
|
||||||
import org.cryptomator.ui.fxapp.FxApplicationComponent;
|
|
||||||
import org.cryptomator.ui.traymenu.TrayMenuComponent;
|
|
||||||
|
|
||||||
import javax.inject.Named;
|
|
||||||
import javax.inject.Singleton;
|
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.ResourceBundle;
|
|
||||||
import java.util.concurrent.ArrayBlockingQueue;
|
|
||||||
import java.util.concurrent.BlockingQueue;
|
|
||||||
|
|
||||||
@Module(includes = {JniModule.class, KeychainModule.class}, subcomponents = {TrayMenuComponent.class, FxApplicationComponent.class})
|
|
||||||
public abstract class UiLauncherModule {
|
|
||||||
|
|
||||||
@Provides
|
|
||||||
@Singleton
|
|
||||||
static ResourceBundle provideLocalization() {
|
|
||||||
return ResourceBundle.getBundle("i18n.strings");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Provides
|
|
||||||
@Singleton
|
|
||||||
@Named("launchEventQueue")
|
|
||||||
static BlockingQueue<AppLaunchEvent> provideFileOpenRequests() {
|
|
||||||
return new ArrayBlockingQueue<>(10);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
package org.cryptomator.ui.mainwindow;
|
|
||||||
|
|
||||||
import javafx.beans.property.ObjectProperty;
|
|
||||||
import javafx.beans.property.ReadOnlyObjectProperty;
|
|
||||||
import javafx.fxml.FXML;
|
|
||||||
import org.cryptomator.common.vaults.Vault;
|
|
||||||
import org.cryptomator.ui.common.FxController;
|
|
||||||
import org.cryptomator.ui.fxapp.FxApplication;
|
|
||||||
import org.cryptomator.ui.vaultoptions.VaultOptionsComponent;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
|
|
||||||
@MainWindowScoped
|
|
||||||
public class VaultDetailLockedController implements FxController {
|
|
||||||
|
|
||||||
private final ReadOnlyObjectProperty<Vault> vault;
|
|
||||||
private final FxApplication application;
|
|
||||||
private final VaultOptionsComponent.Builder vaultOptionsWindow;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
VaultDetailLockedController(ObjectProperty<Vault> vault, FxApplication application, VaultOptionsComponent.Builder vaultOptionsWindow) {
|
|
||||||
this.vault = vault;
|
|
||||||
this.application = application;
|
|
||||||
this.vaultOptionsWindow = vaultOptionsWindow;
|
|
||||||
}
|
|
||||||
|
|
||||||
@FXML
|
|
||||||
public void unlock() {
|
|
||||||
application.startUnlockWorkflow(vault.get());
|
|
||||||
}
|
|
||||||
|
|
||||||
@FXML
|
|
||||||
public void showVaultOptions() {
|
|
||||||
vaultOptionsWindow.vault(vault.get()).build().showVaultOptionsWindow();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Getter/Setter */
|
|
||||||
|
|
||||||
public ReadOnlyObjectProperty<Vault> vaultProperty() {
|
|
||||||
return vault;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Vault getVault() {
|
|
||||||
return vault.get();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-20
@@ -1,20 +0,0 @@
|
|||||||
package org.cryptomator.ui.mainwindow;
|
|
||||||
|
|
||||||
import javafx.beans.property.ObjectProperty;
|
|
||||||
import javafx.beans.property.ReadOnlyObjectProperty;
|
|
||||||
import org.cryptomator.common.vaults.Vault;
|
|
||||||
import org.cryptomator.ui.common.FxController;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
|
|
||||||
@MainWindowScoped
|
|
||||||
public class VaultDetailMissingVaultController implements FxController {
|
|
||||||
|
|
||||||
private final ReadOnlyObjectProperty<Vault> vault;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
public VaultDetailMissingVaultController(ObjectProperty<Vault> vault) {
|
|
||||||
this.vault = vault;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
-45
@@ -1,45 +0,0 @@
|
|||||||
package org.cryptomator.ui.mainwindow;
|
|
||||||
|
|
||||||
import javafx.beans.property.ObjectProperty;
|
|
||||||
import javafx.beans.property.ReadOnlyObjectProperty;
|
|
||||||
import javafx.fxml.FXML;
|
|
||||||
import org.cryptomator.common.vaults.Vault;
|
|
||||||
import org.cryptomator.ui.common.FxController;
|
|
||||||
import org.cryptomator.ui.common.VaultService;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
|
|
||||||
@MainWindowScoped
|
|
||||||
public class VaultDetailUnlockedController implements FxController {
|
|
||||||
|
|
||||||
private final ReadOnlyObjectProperty<Vault> vault;
|
|
||||||
private final VaultService vaultService;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
public VaultDetailUnlockedController(ObjectProperty<Vault> vault, VaultService vaultService) {
|
|
||||||
this.vault = vault;
|
|
||||||
this.vaultService = vaultService;
|
|
||||||
}
|
|
||||||
|
|
||||||
@FXML
|
|
||||||
public void revealAccessLocation() {
|
|
||||||
vaultService.reveal(vault.get());
|
|
||||||
}
|
|
||||||
|
|
||||||
@FXML
|
|
||||||
public void lock() {
|
|
||||||
vaultService.lock(vault.get(), false);
|
|
||||||
// TODO count lock attempts, and allow forced lock
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Getter/Setter */
|
|
||||||
|
|
||||||
public ReadOnlyObjectProperty<Vault> vaultProperty() {
|
|
||||||
return vault;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Vault getVault() {
|
|
||||||
return vault.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,102 +0,0 @@
|
|||||||
package org.cryptomator.ui.mainwindow;
|
|
||||||
|
|
||||||
import javafx.beans.binding.Bindings;
|
|
||||||
import javafx.beans.binding.BooleanBinding;
|
|
||||||
import javafx.beans.property.ObjectProperty;
|
|
||||||
import javafx.beans.value.ObservableValue;
|
|
||||||
import javafx.collections.ListChangeListener;
|
|
||||||
import javafx.collections.ObservableList;
|
|
||||||
import javafx.fxml.FXML;
|
|
||||||
import javafx.scene.control.ListView;
|
|
||||||
import org.cryptomator.common.vaults.Vault;
|
|
||||||
import org.cryptomator.common.vaults.VaultListManager;
|
|
||||||
import org.cryptomator.common.vaults.VaultState;
|
|
||||||
import org.cryptomator.ui.addvaultwizard.AddVaultWizardComponent;
|
|
||||||
import org.cryptomator.ui.common.FxController;
|
|
||||||
import org.cryptomator.ui.removevault.RemoveVaultComponent;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
@MainWindowScoped
|
|
||||||
public class VaultListController implements FxController {
|
|
||||||
|
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(VaultListController.class);
|
|
||||||
|
|
||||||
private final ObservableList<Vault> vaults;
|
|
||||||
private final ObjectProperty<Vault> selectedVault;
|
|
||||||
private final VaultListCellFactory cellFactory;
|
|
||||||
private final AddVaultWizardComponent.Builder addVaultWizard;
|
|
||||||
private final RemoveVaultComponent.Builder removeVault;
|
|
||||||
private final BooleanBinding noVaultSelected;
|
|
||||||
private final BooleanBinding emptyVaultList;
|
|
||||||
public ListView<Vault> vaultList;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
VaultListController(ObservableList<Vault> vaults, ObjectProperty<Vault> selectedVault, VaultListCellFactory cellFactory, AddVaultWizardComponent.Builder addVaultWizard, RemoveVaultComponent.Builder removeVault) {
|
|
||||||
this.vaults = vaults;
|
|
||||||
this.selectedVault = selectedVault;
|
|
||||||
this.cellFactory = cellFactory;
|
|
||||||
this.addVaultWizard = addVaultWizard;
|
|
||||||
this.removeVault = removeVault;
|
|
||||||
this.noVaultSelected = selectedVault.isNull();
|
|
||||||
this.emptyVaultList = Bindings.isEmpty(vaults);
|
|
||||||
selectedVault.addListener(this::selectedVaultDidChange);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void initialize() {
|
|
||||||
vaultList.setItems(vaults);
|
|
||||||
vaultList.setCellFactory(cellFactory);
|
|
||||||
selectedVault.bind(vaultList.getSelectionModel().selectedItemProperty());
|
|
||||||
vaults.addListener((ListChangeListener.Change<? extends Vault> c) -> {
|
|
||||||
while (c.next()) {
|
|
||||||
if (c.wasAdded()) {
|
|
||||||
Vault anyAddedVault = c.getAddedSubList().get(0);
|
|
||||||
vaultList.getSelectionModel().select(anyAddedVault);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void selectedVaultDidChange(@SuppressWarnings("unused") ObservableValue<? extends Vault> observableValue, @SuppressWarnings("unused") Vault oldValue, Vault newValue) {
|
|
||||||
if (newValue == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
VaultListManager.redetermineVaultState(newValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
@FXML
|
|
||||||
public void didClickAddVault() {
|
|
||||||
addVaultWizard.build().showAddVaultWizard();
|
|
||||||
}
|
|
||||||
|
|
||||||
@FXML
|
|
||||||
public void didClickRemoveVault() {
|
|
||||||
Vault v = selectedVault.get();
|
|
||||||
if (v != null) {
|
|
||||||
removeVault.vault(v).build().showRemoveVault();
|
|
||||||
} else {
|
|
||||||
LOG.debug("Cannot remove a vault if none is selected.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Getter and Setter
|
|
||||||
|
|
||||||
public BooleanBinding emptyVaultListProperty() {
|
|
||||||
return emptyVaultList;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isEmptyVaultList() {
|
|
||||||
return emptyVaultList.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
public BooleanBinding noVaultSelectedProperty() {
|
|
||||||
return noVaultSelected;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isNoVaultSelected() {
|
|
||||||
return noVaultSelected.get();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
package org.cryptomator.ui.preferences;
|
|
||||||
|
|
||||||
import org.cryptomator.jni.MacFunctions;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
|
||||||
import java.util.concurrent.CompletionStage;
|
|
||||||
|
|
||||||
class AutoStartMacStrategy implements AutoStartStrategy {
|
|
||||||
|
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(AutoStartMacStrategy.class);
|
|
||||||
|
|
||||||
private final MacFunctions macFunctions;
|
|
||||||
|
|
||||||
public AutoStartMacStrategy(MacFunctions macFunctions) {
|
|
||||||
this.macFunctions = macFunctions;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CompletionStage<Boolean> isAutoStartEnabled() {
|
|
||||||
boolean enabled = macFunctions.launchServices().isLoginItemEnabled();
|
|
||||||
return CompletableFuture.completedFuture(enabled);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void enableAutoStart() throws TogglingAutoStartFailedException {
|
|
||||||
if (macFunctions.launchServices().enableLoginItem()) {
|
|
||||||
LOG.debug("Added login item.");
|
|
||||||
} else {
|
|
||||||
throw new TogglingAutoStartFailedException("Failed to add login item.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void disableAutoStart() throws TogglingAutoStartFailedException {
|
|
||||||
if (macFunctions.launchServices().disableLoginItem()) {
|
|
||||||
LOG.debug("Removed login item.");
|
|
||||||
} else {
|
|
||||||
throw new TogglingAutoStartFailedException("Failed to remove login item.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
package org.cryptomator.ui.preferences;
|
|
||||||
|
|
||||||
import dagger.Module;
|
|
||||||
import dagger.Provides;
|
|
||||||
import org.apache.commons.lang3.SystemUtils;
|
|
||||||
import org.cryptomator.jni.MacFunctions;
|
|
||||||
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
@Module
|
|
||||||
abstract class AutoStartModule {
|
|
||||||
|
|
||||||
@Provides
|
|
||||||
@PreferencesScoped
|
|
||||||
public static Optional<AutoStartStrategy> provideAutoStartStrategy(Optional<MacFunctions> macFunctions) {
|
|
||||||
if (SystemUtils.IS_OS_MAC_OSX && macFunctions.isPresent()) {
|
|
||||||
return Optional.of(new AutoStartMacStrategy(macFunctions.get()));
|
|
||||||
} else if (SystemUtils.IS_OS_WINDOWS) {
|
|
||||||
Optional<String> exeName = ProcessHandle.current().info().command();
|
|
||||||
return exeName.map(AutoStartWinStrategy::new);
|
|
||||||
} else {
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
package org.cryptomator.ui.preferences;
|
|
||||||
|
|
||||||
import java.util.concurrent.CompletionStage;
|
|
||||||
|
|
||||||
public interface AutoStartStrategy {
|
|
||||||
|
|
||||||
CompletionStage<Boolean> isAutoStartEnabled();
|
|
||||||
|
|
||||||
void enableAutoStart() throws TogglingAutoStartFailedException;
|
|
||||||
|
|
||||||
void disableAutoStart() throws TogglingAutoStartFailedException;
|
|
||||||
|
|
||||||
class TogglingAutoStartFailedException extends Exception {
|
|
||||||
|
|
||||||
public TogglingAutoStartFailedException(String message) {
|
|
||||||
super(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
public TogglingAutoStartFailedException(String message, Throwable cause) {
|
|
||||||
super(message, cause);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,91 +0,0 @@
|
|||||||
package org.cryptomator.ui.preferences;
|
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
|
||||||
import java.util.concurrent.CompletionStage;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
class AutoStartWinStrategy implements AutoStartStrategy {
|
|
||||||
|
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(AutoStartWinStrategy.class);
|
|
||||||
private static final String HKCU_AUTOSTART_KEY = "\"HKCU\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run\"";
|
|
||||||
private static final String AUTOSTART_VALUE = "Cryptomator";
|
|
||||||
private final String exePath;
|
|
||||||
|
|
||||||
public AutoStartWinStrategy(String exePath) {
|
|
||||||
this.exePath = exePath;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CompletionStage<Boolean> isAutoStartEnabled() {
|
|
||||||
ProcessBuilder regQuery = new ProcessBuilder("reg", "query", HKCU_AUTOSTART_KEY, //
|
|
||||||
"/v", AUTOSTART_VALUE);
|
|
||||||
try {
|
|
||||||
Process proc = regQuery.start();
|
|
||||||
return proc.onExit().thenApply(p -> p.exitValue() == 0);
|
|
||||||
} catch (IOException e) {
|
|
||||||
LOG.warn("Failed to query {} from registry key {}", AUTOSTART_VALUE, HKCU_AUTOSTART_KEY);
|
|
||||||
return CompletableFuture.completedFuture(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void enableAutoStart() throws TogglingAutoStartFailedException {
|
|
||||||
ProcessBuilder regAdd = new ProcessBuilder("reg", "add", HKCU_AUTOSTART_KEY, //
|
|
||||||
"/v", AUTOSTART_VALUE, //
|
|
||||||
"/t", "REG_SZ", //
|
|
||||||
"/d", "\"" + exePath + "\"", //
|
|
||||||
"/f");
|
|
||||||
String command = regAdd.command().stream().collect(Collectors.joining(" "));
|
|
||||||
try {
|
|
||||||
Process proc = regAdd.start();
|
|
||||||
boolean finishedInTime = waitForProcess(proc, 5, TimeUnit.SECONDS);
|
|
||||||
if (finishedInTime) {
|
|
||||||
LOG.debug("Added {} to registry key {}.", AUTOSTART_VALUE, HKCU_AUTOSTART_KEY);
|
|
||||||
} else {
|
|
||||||
throw new TogglingAutoStartFailedException("Adding registry value failed.");
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new TogglingAutoStartFailedException("Adding registry value failed. " + command, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void disableAutoStart() throws TogglingAutoStartFailedException {
|
|
||||||
ProcessBuilder regRemove = new ProcessBuilder("reg", "delete", HKCU_AUTOSTART_KEY, //
|
|
||||||
"/v", AUTOSTART_VALUE, //
|
|
||||||
"/f");
|
|
||||||
String command = regRemove.command().stream().collect(Collectors.joining(" "));
|
|
||||||
try {
|
|
||||||
Process proc = regRemove.start();
|
|
||||||
boolean finishedInTime = waitForProcess(proc, 5, TimeUnit.SECONDS);
|
|
||||||
if (finishedInTime) {
|
|
||||||
LOG.debug("Removed {} from registry key {}.", AUTOSTART_VALUE, HKCU_AUTOSTART_KEY);
|
|
||||||
} else {
|
|
||||||
throw new TogglingAutoStartFailedException("Removing registry value failed.");
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new TogglingAutoStartFailedException("Removing registry value failed. " + command, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean waitForProcess(Process proc, int timeout, TimeUnit timeUnit) {
|
|
||||||
boolean finishedInTime = false;
|
|
||||||
try {
|
|
||||||
finishedInTime = proc.waitFor(timeout, timeUnit);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
LOG.error("Timeout while reading registry", e);
|
|
||||||
Thread.currentThread().interrupt();
|
|
||||||
} finally {
|
|
||||||
if (!finishedInTime) {
|
|
||||||
proc.destroyForcibly();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return finishedInTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
-45
@@ -1,45 +0,0 @@
|
|||||||
package org.cryptomator.ui.preferences;
|
|
||||||
|
|
||||||
import javafx.application.Application;
|
|
||||||
import javafx.beans.value.ObservableValue;
|
|
||||||
import javafx.fxml.FXML;
|
|
||||||
import javafx.scene.control.TextArea;
|
|
||||||
import org.cryptomator.common.LicenseHolder;
|
|
||||||
import org.cryptomator.ui.common.FxController;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
|
|
||||||
@PreferencesScoped
|
|
||||||
public class DonationKeyPreferencesController implements FxController {
|
|
||||||
|
|
||||||
private static final String DONATION_URI = "https://store.cryptomator.org/desktop";
|
|
||||||
|
|
||||||
private final Application application;
|
|
||||||
private final LicenseHolder licenseHolder;
|
|
||||||
public TextArea donationKeyField;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
DonationKeyPreferencesController(Application application, LicenseHolder licenseHolder) {
|
|
||||||
this.application = application;
|
|
||||||
this.licenseHolder = licenseHolder;
|
|
||||||
}
|
|
||||||
|
|
||||||
@FXML
|
|
||||||
public void initialize() {
|
|
||||||
donationKeyField.setText(licenseHolder.getLicenseKey().orElse(null));
|
|
||||||
donationKeyField.textProperty().addListener(this::registrationKeyChanged);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void registrationKeyChanged(@SuppressWarnings("unused") ObservableValue<? extends String> observable, @SuppressWarnings("unused") String oldValue, String newValue) {
|
|
||||||
licenseHolder.validateAndStoreLicense(newValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
@FXML
|
|
||||||
public void getDonationKey() {
|
|
||||||
application.getHostServices().showDocument(DONATION_URI);
|
|
||||||
}
|
|
||||||
|
|
||||||
public LicenseHolder getLicenseHolder() {
|
|
||||||
return licenseHolder;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-171
@@ -1,171 +0,0 @@
|
|||||||
package org.cryptomator.ui.preferences;
|
|
||||||
|
|
||||||
import javafx.application.Platform;
|
|
||||||
import javafx.beans.property.ObjectProperty;
|
|
||||||
import javafx.beans.value.ObservableValue;
|
|
||||||
import javafx.concurrent.Task;
|
|
||||||
import javafx.fxml.FXML;
|
|
||||||
import javafx.geometry.NodeOrientation;
|
|
||||||
import javafx.scene.control.CheckBox;
|
|
||||||
import javafx.scene.control.ChoiceBox;
|
|
||||||
import javafx.scene.control.RadioButton;
|
|
||||||
import javafx.scene.control.Toggle;
|
|
||||||
import javafx.scene.control.ToggleGroup;
|
|
||||||
import javafx.util.StringConverter;
|
|
||||||
import javafx.application.Application;
|
|
||||||
import org.cryptomator.common.LicenseHolder;
|
|
||||||
import org.cryptomator.common.settings.Settings;
|
|
||||||
import org.cryptomator.common.settings.UiTheme;
|
|
||||||
import org.cryptomator.common.Environment;
|
|
||||||
import org.cryptomator.ui.common.FxController;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
import javax.inject.Named;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.ResourceBundle;
|
|
||||||
import java.util.concurrent.ExecutorService;
|
|
||||||
|
|
||||||
@PreferencesScoped
|
|
||||||
public class GeneralPreferencesController implements FxController {
|
|
||||||
|
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(GeneralPreferencesController.class);
|
|
||||||
|
|
||||||
private final Settings settings;
|
|
||||||
private final boolean trayMenuSupported;
|
|
||||||
private final Optional<AutoStartStrategy> autoStartStrategy;
|
|
||||||
private final ObjectProperty<SelectedPreferencesTab> selectedTabProperty;
|
|
||||||
private final LicenseHolder licenseHolder;
|
|
||||||
private final ExecutorService executor;
|
|
||||||
private final ResourceBundle resourceBundle;
|
|
||||||
private final Application application;
|
|
||||||
private final Environment environment;
|
|
||||||
public ChoiceBox<UiTheme> themeChoiceBox;
|
|
||||||
public CheckBox startHiddenCheckbox;
|
|
||||||
public CheckBox debugModeCheckbox;
|
|
||||||
public CheckBox autoStartCheckbox;
|
|
||||||
public ToggleGroup nodeOrientation;
|
|
||||||
public RadioButton nodeOrientationLtr;
|
|
||||||
public RadioButton nodeOrientationRtl;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
GeneralPreferencesController(Settings settings, @Named("trayMenuSupported") boolean trayMenuSupported, Optional<AutoStartStrategy> autoStartStrategy, ObjectProperty<SelectedPreferencesTab> selectedTabProperty, LicenseHolder licenseHolder, ExecutorService executor, ResourceBundle resourceBundle, Application application, Environment environment) {
|
|
||||||
this.settings = settings;
|
|
||||||
this.trayMenuSupported = trayMenuSupported;
|
|
||||||
this.autoStartStrategy = autoStartStrategy;
|
|
||||||
this.selectedTabProperty = selectedTabProperty;
|
|
||||||
this.licenseHolder = licenseHolder;
|
|
||||||
this.executor = executor;
|
|
||||||
this.resourceBundle = resourceBundle;
|
|
||||||
this.application = application;
|
|
||||||
this.environment = environment;
|
|
||||||
}
|
|
||||||
|
|
||||||
@FXML
|
|
||||||
public void initialize() {
|
|
||||||
themeChoiceBox.getItems().addAll(UiTheme.values());
|
|
||||||
themeChoiceBox.valueProperty().bindBidirectional(settings.theme());
|
|
||||||
themeChoiceBox.setConverter(new UiThemeConverter(resourceBundle));
|
|
||||||
|
|
||||||
startHiddenCheckbox.selectedProperty().bindBidirectional(settings.startHidden());
|
|
||||||
|
|
||||||
debugModeCheckbox.selectedProperty().bindBidirectional(settings.debugMode());
|
|
||||||
|
|
||||||
autoStartStrategy.ifPresent(autoStart -> {
|
|
||||||
autoStart.isAutoStartEnabled().thenAccept(enabled -> {
|
|
||||||
Platform.runLater(() -> autoStartCheckbox.setSelected(enabled));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
nodeOrientationLtr.setSelected(settings.userInterfaceOrientation().get() == NodeOrientation.LEFT_TO_RIGHT);
|
|
||||||
nodeOrientationRtl.setSelected(settings.userInterfaceOrientation().get() == NodeOrientation.RIGHT_TO_LEFT);
|
|
||||||
nodeOrientation.selectedToggleProperty().addListener(this::toggleNodeOrientation);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isTrayMenuSupported() {
|
|
||||||
return this.trayMenuSupported;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isAutoStartSupported() {
|
|
||||||
return autoStartStrategy.isPresent();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void toggleNodeOrientation(@SuppressWarnings("unused") ObservableValue<? extends Toggle> observable, @SuppressWarnings("unused") Toggle oldValue, Toggle newValue) {
|
|
||||||
if (nodeOrientationLtr.equals(newValue)) {
|
|
||||||
settings.userInterfaceOrientation().set(NodeOrientation.LEFT_TO_RIGHT);
|
|
||||||
} else if (nodeOrientationRtl.equals(newValue)) {
|
|
||||||
settings.userInterfaceOrientation().set(NodeOrientation.RIGHT_TO_LEFT);
|
|
||||||
} else {
|
|
||||||
LOG.warn("Unexpected toggle option {}", newValue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@FXML
|
|
||||||
public void toggleAutoStart() {
|
|
||||||
autoStartStrategy.ifPresent(autoStart -> {
|
|
||||||
boolean enableAutoStart = autoStartCheckbox.isSelected();
|
|
||||||
Task<Void> toggleTask = new ToggleAutoStartTask(autoStart, enableAutoStart);
|
|
||||||
toggleTask.setOnFailed(evt -> autoStartCheckbox.setSelected(!enableAutoStart)); // restore previous state
|
|
||||||
executor.execute(toggleTask);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public LicenseHolder getLicenseHolder() {
|
|
||||||
return licenseHolder;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@FXML
|
|
||||||
public void showDonationTab() {
|
|
||||||
selectedTabProperty.set(SelectedPreferencesTab.DONATION_KEY);
|
|
||||||
}
|
|
||||||
|
|
||||||
@FXML
|
|
||||||
public void showLogfileDirectory(){
|
|
||||||
environment.getLogDir().ifPresent(logDirPath -> application.getHostServices().showDocument(logDirPath.toUri().toString()));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Helper classes */
|
|
||||||
|
|
||||||
private static class UiThemeConverter extends StringConverter<UiTheme> {
|
|
||||||
|
|
||||||
private final ResourceBundle resourceBundle;
|
|
||||||
|
|
||||||
UiThemeConverter(ResourceBundle resourceBundle) {
|
|
||||||
this.resourceBundle = resourceBundle;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString(UiTheme impl) {
|
|
||||||
return resourceBundle.getString(impl.getDisplayName());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public UiTheme fromString(String string) {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class ToggleAutoStartTask extends Task<Void> {
|
|
||||||
|
|
||||||
private final AutoStartStrategy autoStart;
|
|
||||||
private final boolean enable;
|
|
||||||
|
|
||||||
public ToggleAutoStartTask(AutoStartStrategy autoStart, boolean enable) {
|
|
||||||
this.autoStart = autoStart;
|
|
||||||
this.enable = enable;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Void call() throws Exception {
|
|
||||||
if (enable) {
|
|
||||||
autoStart.enableAutoStart();
|
|
||||||
} else {
|
|
||||||
autoStart.disableAutoStart();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
package org.cryptomator.ui.traymenu;
|
|
||||||
|
|
||||||
import org.apache.commons.lang3.SystemUtils;
|
|
||||||
import org.cryptomator.jni.MacApplicationUiAppearance;
|
|
||||||
import org.cryptomator.jni.MacApplicationUiInterfaceStyle;
|
|
||||||
import org.cryptomator.jni.MacFunctions;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
import java.awt.Image;
|
|
||||||
import java.awt.Toolkit;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
@TrayMenuScoped
|
|
||||||
class TrayImageFactory {
|
|
||||||
|
|
||||||
private final Optional<MacFunctions> macFunctions;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
TrayImageFactory(Optional<MacFunctions> macFunctions) {
|
|
||||||
this.macFunctions = macFunctions;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Image loadImage() {
|
|
||||||
String resourceName = SystemUtils.IS_OS_MAC_OSX ? getMacResourceName() : getWinOrLinuxResourceName();
|
|
||||||
return Toolkit.getDefaultToolkit().getImage(getClass().getResource(resourceName));
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getMacResourceName() {
|
|
||||||
MacApplicationUiInterfaceStyle interfaceStyle = macFunctions.map(MacFunctions::uiAppearance) //
|
|
||||||
.map(MacApplicationUiAppearance::getCurrentInterfaceStyle) //
|
|
||||||
.orElse(MacApplicationUiInterfaceStyle.LIGHT);
|
|
||||||
return switch (interfaceStyle) {
|
|
||||||
case DARK -> "/tray_icon_mac_white.png";
|
|
||||||
case LIGHT -> "/tray_icon_mac_black.png";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getWinOrLinuxResourceName() {
|
|
||||||
return "/tray_icon.png";
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
* Copyright (c) 2017 Skymatic UG (haftungsbeschränkt).
|
|
||||||
* All rights reserved. This program and the accompanying materials
|
|
||||||
* are made available under the terms of the accompanying LICENSE file.
|
|
||||||
*******************************************************************************/
|
|
||||||
package org.cryptomator.ui.traymenu;
|
|
||||||
|
|
||||||
import dagger.Subcomponent;
|
|
||||||
|
|
||||||
import java.awt.SystemTray;
|
|
||||||
|
|
||||||
@TrayMenuScoped
|
|
||||||
@Subcomponent
|
|
||||||
public interface TrayMenuComponent {
|
|
||||||
|
|
||||||
TrayIconController trayIconController();
|
|
||||||
|
|
||||||
default void addIconToSystemTray() {
|
|
||||||
assert SystemTray.isSupported();
|
|
||||||
trayIconController().initializeTrayIcon();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Subcomponent.Builder
|
|
||||||
interface Builder {
|
|
||||||
|
|
||||||
TrayMenuComponent build();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,136 +0,0 @@
|
|||||||
package org.cryptomator.ui.unlock;
|
|
||||||
|
|
||||||
import javafx.beans.binding.Bindings;
|
|
||||||
import javafx.beans.binding.BooleanBinding;
|
|
||||||
import javafx.beans.binding.ObjectBinding;
|
|
||||||
import javafx.beans.property.BooleanProperty;
|
|
||||||
import javafx.beans.property.ReadOnlyBooleanProperty;
|
|
||||||
import javafx.beans.property.SimpleBooleanProperty;
|
|
||||||
import javafx.fxml.FXML;
|
|
||||||
import javafx.scene.control.CheckBox;
|
|
||||||
import javafx.scene.control.ContentDisplay;
|
|
||||||
import javafx.stage.Stage;
|
|
||||||
import org.cryptomator.common.vaults.Vault;
|
|
||||||
import org.cryptomator.keychain.KeychainAccess;
|
|
||||||
import org.cryptomator.ui.common.FxController;
|
|
||||||
import org.cryptomator.ui.common.UserInteractionLock;
|
|
||||||
import org.cryptomator.ui.controls.NiceSecurePasswordField;
|
|
||||||
import org.cryptomator.ui.forgetPassword.ForgetPasswordComponent;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
import javax.inject.Named;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
|
||||||
|
|
||||||
@UnlockScoped
|
|
||||||
public class UnlockController implements FxController {
|
|
||||||
|
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(UnlockController.class);
|
|
||||||
|
|
||||||
private final Stage window;
|
|
||||||
private final Vault vault;
|
|
||||||
private final AtomicReference<char[]> password;
|
|
||||||
private final AtomicBoolean savePassword;
|
|
||||||
private final Optional<char[]> savedPassword;
|
|
||||||
private final UserInteractionLock<UnlockModule.PasswordEntry> passwordEntryLock;
|
|
||||||
private final ForgetPasswordComponent.Builder forgetPassword;
|
|
||||||
private final Optional<KeychainAccess> keychainAccess;
|
|
||||||
private final ObjectBinding<ContentDisplay> unlockButtonContentDisplay;
|
|
||||||
private final BooleanBinding userInteractionDisabled;
|
|
||||||
private final BooleanProperty unlockButtonDisabled;
|
|
||||||
public NiceSecurePasswordField passwordField;
|
|
||||||
public CheckBox savePasswordCheckbox;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
public UnlockController(@UnlockWindow Stage window, @UnlockWindow Vault vault, AtomicReference<char[]> password, @Named("savePassword") AtomicBoolean savePassword, @Named("savedPassword") Optional<char[]> savedPassword, UserInteractionLock<UnlockModule.PasswordEntry> passwordEntryLock, ForgetPasswordComponent.Builder forgetPassword, Optional<KeychainAccess> keychainAccess) {
|
|
||||||
this.window = window;
|
|
||||||
this.vault = vault;
|
|
||||||
this.password = password;
|
|
||||||
this.savePassword = savePassword;
|
|
||||||
this.savedPassword = savedPassword;
|
|
||||||
this.passwordEntryLock = passwordEntryLock;
|
|
||||||
this.forgetPassword = forgetPassword;
|
|
||||||
this.keychainAccess = keychainAccess;
|
|
||||||
this.unlockButtonContentDisplay = Bindings.createObjectBinding(this::getUnlockButtonContentDisplay, passwordEntryLock.awaitingInteraction());
|
|
||||||
this.userInteractionDisabled = passwordEntryLock.awaitingInteraction().not();
|
|
||||||
this.unlockButtonDisabled = new SimpleBooleanProperty();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void initialize() {
|
|
||||||
savePasswordCheckbox.setSelected(savedPassword.isPresent());
|
|
||||||
if (password.get() != null) {
|
|
||||||
passwordField.setPassword(password.get());
|
|
||||||
}
|
|
||||||
unlockButtonDisabled.bind(userInteractionDisabled.or(passwordField.textProperty().isEmpty()));
|
|
||||||
}
|
|
||||||
|
|
||||||
@FXML
|
|
||||||
public void cancel() {
|
|
||||||
LOG.debug("Unlock canceled by user.");
|
|
||||||
window.close();
|
|
||||||
passwordEntryLock.interacted(UnlockModule.PasswordEntry.CANCELED);
|
|
||||||
}
|
|
||||||
|
|
||||||
@FXML
|
|
||||||
public void unlock() {
|
|
||||||
LOG.trace("UnlockController.unlock()");
|
|
||||||
CharSequence pwFieldContents = passwordField.getCharacters();
|
|
||||||
char[] newPw = new char[pwFieldContents.length()];
|
|
||||||
for (int i = 0; i < pwFieldContents.length(); i++) {
|
|
||||||
newPw[i] = pwFieldContents.charAt(i);
|
|
||||||
}
|
|
||||||
char[] oldPw = password.getAndSet(newPw);
|
|
||||||
if (oldPw != null) {
|
|
||||||
Arrays.fill(oldPw, ' ');
|
|
||||||
}
|
|
||||||
passwordEntryLock.interacted(UnlockModule.PasswordEntry.PASSWORD_ENTERED);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Save Password */
|
|
||||||
|
|
||||||
@FXML
|
|
||||||
private void didClickSavePasswordCheckbox() {
|
|
||||||
savePassword.set(savePasswordCheckbox.isSelected());
|
|
||||||
if (!savePasswordCheckbox.isSelected() && savedPassword.isPresent()) {
|
|
||||||
forgetPassword.vault(vault).owner(window).build().showForgetPassword().thenAccept(forgotten -> savePasswordCheckbox.setSelected(!forgotten));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Getter/Setter */
|
|
||||||
|
|
||||||
public Vault getVault() {
|
|
||||||
return vault;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ObjectBinding<ContentDisplay> unlockButtonContentDisplayProperty() {
|
|
||||||
return unlockButtonContentDisplay;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ContentDisplay getUnlockButtonContentDisplay() {
|
|
||||||
return passwordEntryLock.awaitingInteraction().get() ? ContentDisplay.TEXT_ONLY : ContentDisplay.LEFT;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BooleanBinding userInteractionDisabledProperty() {
|
|
||||||
return userInteractionDisabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isUserInteractionDisabled() {
|
|
||||||
return userInteractionDisabled.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
public ReadOnlyBooleanProperty unlockButtonDisabledProperty() {
|
|
||||||
return unlockButtonDisabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isUnlockButtonDisabled() {
|
|
||||||
return unlockButtonDisabled.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isKeychainAccessAvailable() {
|
|
||||||
return keychainAccess.isPresent();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-39
@@ -1,39 +0,0 @@
|
|||||||
package org.cryptomator.ui.unlock;
|
|
||||||
|
|
||||||
import dagger.Lazy;
|
|
||||||
import javafx.fxml.FXML;
|
|
||||||
import javafx.scene.Scene;
|
|
||||||
import javafx.stage.Stage;
|
|
||||||
import org.cryptomator.common.vaults.Vault;
|
|
||||||
import org.cryptomator.ui.common.FxController;
|
|
||||||
import org.cryptomator.ui.common.FxmlFile;
|
|
||||||
import org.cryptomator.ui.common.FxmlScene;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
|
|
||||||
@UnlockScoped
|
|
||||||
public class UnlockInvalidMountPointController implements FxController {
|
|
||||||
|
|
||||||
private final Stage window;
|
|
||||||
private final Lazy<Scene> unlockScene;
|
|
||||||
private final Vault vault;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
UnlockInvalidMountPointController(@UnlockWindow Stage window, @FxmlScene(FxmlFile.UNLOCK) Lazy<Scene> unlockScene, @UnlockWindow Vault vault) {
|
|
||||||
this.window = window;
|
|
||||||
this.unlockScene = unlockScene;
|
|
||||||
this.vault = vault;
|
|
||||||
}
|
|
||||||
|
|
||||||
@FXML
|
|
||||||
public void back() {
|
|
||||||
window.setScene(unlockScene.get());
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Getter/Setter */
|
|
||||||
|
|
||||||
public String getMountPoint() {
|
|
||||||
return vault.getVaultSettings().getCustomMountPath().orElse("AUTO");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,135 +0,0 @@
|
|||||||
package org.cryptomator.ui.unlock;
|
|
||||||
|
|
||||||
import dagger.Binds;
|
|
||||||
import dagger.Module;
|
|
||||||
import dagger.Provides;
|
|
||||||
import dagger.multibindings.IntoMap;
|
|
||||||
import javafx.scene.Scene;
|
|
||||||
import javafx.scene.image.Image;
|
|
||||||
import javafx.stage.Modality;
|
|
||||||
import javafx.stage.Stage;
|
|
||||||
import org.cryptomator.common.vaults.Vault;
|
|
||||||
import org.cryptomator.keychain.KeychainAccess;
|
|
||||||
import org.cryptomator.keychain.KeychainAccessException;
|
|
||||||
import org.cryptomator.ui.common.DefaultSceneFactory;
|
|
||||||
import org.cryptomator.ui.common.FXMLLoaderFactory;
|
|
||||||
import org.cryptomator.ui.common.FxController;
|
|
||||||
import org.cryptomator.ui.common.FxControllerKey;
|
|
||||||
import org.cryptomator.ui.common.FxmlFile;
|
|
||||||
import org.cryptomator.ui.common.FxmlScene;
|
|
||||||
import org.cryptomator.ui.common.StageFactory;
|
|
||||||
import org.cryptomator.ui.common.UserInteractionLock;
|
|
||||||
import org.cryptomator.ui.forgetPassword.ForgetPasswordComponent;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import javax.inject.Named;
|
|
||||||
import javax.inject.Provider;
|
|
||||||
import java.nio.CharBuffer;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.ResourceBundle;
|
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
|
||||||
import java.util.concurrent.locks.Condition;
|
|
||||||
import java.util.concurrent.locks.Lock;
|
|
||||||
import java.util.concurrent.locks.ReentrantLock;
|
|
||||||
|
|
||||||
@Module(subcomponents = {ForgetPasswordComponent.class})
|
|
||||||
abstract class UnlockModule {
|
|
||||||
|
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(UnlockModule.class);
|
|
||||||
|
|
||||||
public enum PasswordEntry {PASSWORD_ENTERED, CANCELED}
|
|
||||||
|
|
||||||
@Provides
|
|
||||||
@UnlockScoped
|
|
||||||
static UserInteractionLock<PasswordEntry> providePasswordEntryLock() {
|
|
||||||
return new UserInteractionLock<>(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Provides
|
|
||||||
@Named("savedPassword")
|
|
||||||
@UnlockScoped
|
|
||||||
static Optional<char[]> provideStoredPassword(Optional<KeychainAccess> keychainAccess, @UnlockWindow Vault vault) {
|
|
||||||
return keychainAccess.map(k -> {
|
|
||||||
try {
|
|
||||||
return k.loadPassphrase(vault.getId());
|
|
||||||
} catch (KeychainAccessException e) {
|
|
||||||
LOG.error("Failed to load entry from system keychain.", e);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Provides
|
|
||||||
@UnlockScoped
|
|
||||||
static AtomicReference<char[]> providePassword(@Named("savedPassword") Optional<char[]> storedPassword) {
|
|
||||||
return new AtomicReference(storedPassword.orElse(null));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Provides
|
|
||||||
@Named("savePassword")
|
|
||||||
@UnlockScoped
|
|
||||||
static AtomicBoolean provideSavePasswordFlag(@Named("savedPassword") Optional<char[]> storedPassword) {
|
|
||||||
return new AtomicBoolean(storedPassword.isPresent());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Provides
|
|
||||||
@UnlockWindow
|
|
||||||
@UnlockScoped
|
|
||||||
static FXMLLoaderFactory provideFxmlLoaderFactory(Map<Class<? extends FxController>, Provider<FxController>> factories, DefaultSceneFactory sceneFactory, ResourceBundle resourceBundle) {
|
|
||||||
return new FXMLLoaderFactory(factories, sceneFactory, resourceBundle);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Provides
|
|
||||||
@UnlockWindow
|
|
||||||
@UnlockScoped
|
|
||||||
static Stage provideStage(StageFactory factory, @UnlockWindow Vault vault) {
|
|
||||||
Stage stage = factory.create();
|
|
||||||
stage.setTitle(vault.getDisplayableName());
|
|
||||||
stage.setResizable(false);
|
|
||||||
stage.initModality(Modality.APPLICATION_MODAL);
|
|
||||||
return stage;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Provides
|
|
||||||
@FxmlScene(FxmlFile.UNLOCK)
|
|
||||||
@UnlockScoped
|
|
||||||
static Scene provideUnlockScene(@UnlockWindow FXMLLoaderFactory fxmlLoaders) {
|
|
||||||
return fxmlLoaders.createScene("/fxml/unlock.fxml");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Provides
|
|
||||||
@FxmlScene(FxmlFile.UNLOCK_SUCCESS)
|
|
||||||
@UnlockScoped
|
|
||||||
static Scene provideUnlockSuccessScene(@UnlockWindow FXMLLoaderFactory fxmlLoaders) {
|
|
||||||
return fxmlLoaders.createScene("/fxml/unlock_success.fxml");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Provides
|
|
||||||
@FxmlScene(FxmlFile.UNLOCK_INVALID_MOUNT_POINT)
|
|
||||||
@UnlockScoped
|
|
||||||
static Scene provideInvalidMountPointScene(@UnlockWindow FXMLLoaderFactory fxmlLoaders) {
|
|
||||||
return fxmlLoaders.createScene("/fxml/unlock_invalid_mount_point.fxml");
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------
|
|
||||||
|
|
||||||
@Binds
|
|
||||||
@IntoMap
|
|
||||||
@FxControllerKey(UnlockController.class)
|
|
||||||
abstract FxController bindUnlockController(UnlockController controller);
|
|
||||||
|
|
||||||
@Binds
|
|
||||||
@IntoMap
|
|
||||||
@FxControllerKey(UnlockSuccessController.class)
|
|
||||||
abstract FxController bindUnlockSuccessController(UnlockSuccessController controller);
|
|
||||||
|
|
||||||
@Binds
|
|
||||||
@IntoMap
|
|
||||||
@FxControllerKey(UnlockInvalidMountPointController.class)
|
|
||||||
abstract FxController bindUnlockInvalidMountPointController(UnlockInvalidMountPointController controller);
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,190 +0,0 @@
|
|||||||
package org.cryptomator.ui.unlock;
|
|
||||||
|
|
||||||
import dagger.Lazy;
|
|
||||||
import javafx.application.Platform;
|
|
||||||
import javafx.concurrent.Task;
|
|
||||||
import javafx.scene.Scene;
|
|
||||||
import javafx.stage.Stage;
|
|
||||||
import org.cryptomator.common.vaults.Vault;
|
|
||||||
import org.cryptomator.common.vaults.VaultState;
|
|
||||||
import org.cryptomator.common.vaults.Volume;
|
|
||||||
import org.cryptomator.cryptolib.api.CryptoException;
|
|
||||||
import org.cryptomator.cryptolib.api.InvalidPassphraseException;
|
|
||||||
import org.cryptomator.keychain.KeychainAccess;
|
|
||||||
import org.cryptomator.keychain.KeychainAccessException;
|
|
||||||
import org.cryptomator.ui.common.Animations;
|
|
||||||
import org.cryptomator.ui.common.ErrorComponent;
|
|
||||||
import org.cryptomator.ui.common.FxmlFile;
|
|
||||||
import org.cryptomator.ui.common.FxmlScene;
|
|
||||||
import org.cryptomator.ui.common.UserInteractionLock;
|
|
||||||
import org.cryptomator.ui.common.VaultService;
|
|
||||||
import org.cryptomator.ui.unlock.UnlockModule.PasswordEntry;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
import javax.inject.Named;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.nio.CharBuffer;
|
|
||||||
import java.nio.file.DirectoryNotEmptyException;
|
|
||||||
import java.nio.file.FileSystemException;
|
|
||||||
import java.nio.file.NotDirectoryException;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A multi-step task that consists of background activities as well as user interaction.
|
|
||||||
* <p>
|
|
||||||
* This class runs the unlock process and controls when to display which UI.
|
|
||||||
*/
|
|
||||||
@UnlockScoped
|
|
||||||
public class UnlockWorkflow extends Task<Boolean> {
|
|
||||||
|
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(UnlockWorkflow.class);
|
|
||||||
|
|
||||||
private final Stage window;
|
|
||||||
private final Vault vault;
|
|
||||||
private final VaultService vaultService;
|
|
||||||
private final AtomicReference<char[]> password;
|
|
||||||
private final AtomicBoolean savePassword;
|
|
||||||
private final Optional<char[]> savedPassword;
|
|
||||||
private final UserInteractionLock<PasswordEntry> passwordEntryLock;
|
|
||||||
private final Optional<KeychainAccess> keychain;
|
|
||||||
private final Lazy<Scene> unlockScene;
|
|
||||||
private final Lazy<Scene> successScene;
|
|
||||||
private final Lazy<Scene> invalidMountPointScene;
|
|
||||||
private final ErrorComponent.Builder errorComponent;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
UnlockWorkflow(@UnlockWindow Stage window, @UnlockWindow Vault vault, VaultService vaultService, AtomicReference<char[]> password, @Named("savePassword") AtomicBoolean savePassword, @Named("savedPassword") Optional<char[]> savedPassword, UserInteractionLock<PasswordEntry> passwordEntryLock, Optional<KeychainAccess> keychain, @FxmlScene(FxmlFile.UNLOCK) Lazy<Scene> unlockScene, @FxmlScene(FxmlFile.UNLOCK_SUCCESS) Lazy<Scene> successScene, @FxmlScene(FxmlFile.UNLOCK_INVALID_MOUNT_POINT) Lazy<Scene> invalidMountPointScene, ErrorComponent.Builder errorComponent) {
|
|
||||||
this.window = window;
|
|
||||||
this.vault = vault;
|
|
||||||
this.vaultService = vaultService;
|
|
||||||
this.password = password;
|
|
||||||
this.savePassword = savePassword;
|
|
||||||
this.savedPassword = savedPassword;
|
|
||||||
this.passwordEntryLock = passwordEntryLock;
|
|
||||||
this.keychain = keychain;
|
|
||||||
this.unlockScene = unlockScene;
|
|
||||||
this.successScene = successScene;
|
|
||||||
this.invalidMountPointScene = invalidMountPointScene;
|
|
||||||
this.errorComponent = errorComponent;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Boolean call() throws InterruptedException, IOException, Volume.VolumeException {
|
|
||||||
try {
|
|
||||||
if (attemptUnlock()) {
|
|
||||||
handleSuccess();
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
cancel(false); // set Tasks state to cancelled
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} catch (NotDirectoryException | DirectoryNotEmptyException e) {
|
|
||||||
handleInvalidMountPoint(e);
|
|
||||||
throw e; // rethrow to trigger correct exception handling in Task
|
|
||||||
} catch (CryptoException | Volume.VolumeException | IOException e) {
|
|
||||||
handleGenericError(e);
|
|
||||||
throw e; // rethrow to trigger correct exception handling in Task
|
|
||||||
} finally {
|
|
||||||
wipePassword(password.get());
|
|
||||||
wipePassword(savedPassword.orElse(null));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean attemptUnlock() throws InterruptedException, IOException, Volume.VolumeException {
|
|
||||||
boolean proceed = password.get() != null || askForPassword(false) == PasswordEntry.PASSWORD_ENTERED;
|
|
||||||
while (proceed) {
|
|
||||||
try {
|
|
||||||
vault.unlock(CharBuffer.wrap(password.get()));
|
|
||||||
return true;
|
|
||||||
} catch (InvalidPassphraseException e) {
|
|
||||||
proceed = askForPassword(true) == PasswordEntry.PASSWORD_ENTERED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private PasswordEntry askForPassword(boolean animateShake) throws InterruptedException {
|
|
||||||
Platform.runLater(() -> {
|
|
||||||
window.setScene(unlockScene.get());
|
|
||||||
window.show();
|
|
||||||
if (animateShake) {
|
|
||||||
Animations.createShakeWindowAnimation(window).play();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return passwordEntryLock.awaitInteraction();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void handleSuccess() {
|
|
||||||
LOG.info("Unlock of '{}' succeeded.", vault.getDisplayableName());
|
|
||||||
if (savePassword.get()) {
|
|
||||||
savePasswordToSystemkeychain();
|
|
||||||
}
|
|
||||||
switch (vault.getVaultSettings().actionAfterUnlock().get()) {
|
|
||||||
case ASK -> Platform.runLater(() -> {
|
|
||||||
window.setScene(successScene.get());
|
|
||||||
window.show();
|
|
||||||
});
|
|
||||||
case REVEAL -> {
|
|
||||||
Platform.runLater(window::close);
|
|
||||||
vaultService.reveal(vault);
|
|
||||||
}
|
|
||||||
case IGNORE -> Platform.runLater(window::close);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void savePasswordToSystemkeychain() {
|
|
||||||
if (keychain.isPresent()) {
|
|
||||||
try {
|
|
||||||
keychain.get().storePassphrase(vault.getId(), CharBuffer.wrap(password.get()));
|
|
||||||
} catch (KeychainAccessException e) {
|
|
||||||
LOG.error("Failed to store passphrase in system keychain.", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void handleInvalidMountPoint(FileSystemException e) {
|
|
||||||
LOG.error("Unlock failed. Mount point not an empty directory: {}", e.getMessage());
|
|
||||||
Platform.runLater(() -> {
|
|
||||||
window.setScene(invalidMountPointScene.get());
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void handleGenericError(Exception e) {
|
|
||||||
LOG.error("Unlock failed for technical reasons.", e);
|
|
||||||
Platform.runLater(() -> {
|
|
||||||
errorComponent.cause(e).window(window).returnToScene(window.getScene()).build().showErrorScene();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void wipePassword(char[] pw) {
|
|
||||||
if (pw != null) {
|
|
||||||
Arrays.fill(pw, ' ');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void scheduled() {
|
|
||||||
vault.setState(VaultState.PROCESSING);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void succeeded() {
|
|
||||||
vault.setState(VaultState.UNLOCKED);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void failed() {
|
|
||||||
vault.setState(VaultState.LOCKED);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void cancelled() {
|
|
||||||
vault.setState(VaultState.LOCKED);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
-57
@@ -1,57 +0,0 @@
|
|||||||
package org.cryptomator.ui.vaultoptions;
|
|
||||||
|
|
||||||
import javafx.fxml.FXML;
|
|
||||||
import javafx.scene.control.CheckBox;
|
|
||||||
import javafx.scene.control.ChoiceBox;
|
|
||||||
import javafx.util.StringConverter;
|
|
||||||
import org.cryptomator.common.settings.UiTheme;
|
|
||||||
import org.cryptomator.common.settings.WhenUnlocked;
|
|
||||||
import org.cryptomator.common.vaults.Vault;
|
|
||||||
import org.cryptomator.ui.common.FxController;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
import java.util.ResourceBundle;
|
|
||||||
|
|
||||||
@VaultOptionsScoped
|
|
||||||
public class GeneralVaultOptionsController implements FxController {
|
|
||||||
|
|
||||||
private final Vault vault;
|
|
||||||
private final ResourceBundle resourceBundle;
|
|
||||||
|
|
||||||
public CheckBox unlockOnStartupCheckbox;
|
|
||||||
public ChoiceBox<WhenUnlocked> actionAfterUnlockChoiceBox;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
GeneralVaultOptionsController(@VaultOptionsWindow Vault vault, ResourceBundle resourceBundle) {
|
|
||||||
this.vault = vault;
|
|
||||||
this.resourceBundle = resourceBundle;
|
|
||||||
}
|
|
||||||
|
|
||||||
@FXML
|
|
||||||
public void initialize() {
|
|
||||||
unlockOnStartupCheckbox.selectedProperty().bindBidirectional(vault.getVaultSettings().unlockAfterStartup());
|
|
||||||
actionAfterUnlockChoiceBox.getItems().addAll(WhenUnlocked.values());
|
|
||||||
actionAfterUnlockChoiceBox.valueProperty().bindBidirectional(vault.getVaultSettings().actionAfterUnlock());
|
|
||||||
actionAfterUnlockChoiceBox.setConverter(new WhenUnlockedConverter(resourceBundle));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class WhenUnlockedConverter extends StringConverter<WhenUnlocked> {
|
|
||||||
|
|
||||||
private final ResourceBundle resourceBundle;
|
|
||||||
|
|
||||||
public WhenUnlockedConverter(ResourceBundle resourceBundle) {
|
|
||||||
this.resourceBundle = resourceBundle;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString(WhenUnlocked obj) {
|
|
||||||
return resourceBundle.getString(obj.getDisplayName());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public WhenUnlocked fromString(String string) {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
package org.cryptomator.ui.vaultoptions;
|
|
||||||
|
|
||||||
import javafx.fxml.FXML;
|
|
||||||
import javafx.stage.Stage;
|
|
||||||
import org.cryptomator.common.vaults.Vault;
|
|
||||||
import org.cryptomator.ui.changepassword.ChangePasswordComponent;
|
|
||||||
import org.cryptomator.ui.common.FxController;
|
|
||||||
import org.cryptomator.ui.recoverykey.RecoveryKeyComponent;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
|
|
||||||
@VaultOptionsScoped
|
|
||||||
public class MasterkeyOptionsController implements FxController {
|
|
||||||
|
|
||||||
private final Vault vault;
|
|
||||||
private final Stage window;
|
|
||||||
private final ChangePasswordComponent.Builder changePasswordWindow;
|
|
||||||
private final RecoveryKeyComponent.Builder recoveryKeyWindow;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
MasterkeyOptionsController(@VaultOptionsWindow Vault vault, @VaultOptionsWindow Stage window, ChangePasswordComponent.Builder changePasswordWindow, RecoveryKeyComponent.Builder recoveryKeyWindow) {
|
|
||||||
this.vault = vault;
|
|
||||||
this.window = window;
|
|
||||||
this.changePasswordWindow = changePasswordWindow;
|
|
||||||
this.recoveryKeyWindow = recoveryKeyWindow;
|
|
||||||
}
|
|
||||||
|
|
||||||
@FXML
|
|
||||||
public void changePassword() {
|
|
||||||
changePasswordWindow.vault(vault).owner(window).build().showChangePasswordWindow();
|
|
||||||
}
|
|
||||||
|
|
||||||
@FXML
|
|
||||||
public void showRecoveryKey() {
|
|
||||||
recoveryKeyWindow.vault(vault).owner(window).build().showRecoveryKeyCreationWindow();
|
|
||||||
}
|
|
||||||
|
|
||||||
@FXML
|
|
||||||
public void showRecoverVaultDialogue() {
|
|
||||||
recoveryKeyWindow.vault(vault).owner(window).build().showRecoveryKeyRecoverWindow();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
package org.cryptomator.ui.vaultoptions;
|
|
||||||
|
|
||||||
import org.cryptomator.ui.common.FxController;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
|
|
||||||
@VaultOptionsScoped
|
|
||||||
public class VaultOptionsController implements FxController {
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
VaultOptionsController() {}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
|
|
||||||
<?import javafx.geometry.Insets?>
|
|
||||||
<?import javafx.scene.control.Button?>
|
|
||||||
<?import javafx.scene.control.ButtonBar?>
|
|
||||||
<?import javafx.scene.control.CheckBox?>
|
|
||||||
<?import javafx.scene.control.ProgressIndicator?>
|
|
||||||
<?import javafx.scene.layout.VBox?>
|
|
||||||
<?import org.cryptomator.ui.controls.FormattedLabel?>
|
|
||||||
<?import org.cryptomator.ui.controls.NiceSecurePasswordField?>
|
|
||||||
<VBox xmlns="http://javafx.com/javafx"
|
|
||||||
xmlns:fx="http://javafx.com/fxml"
|
|
||||||
fx:controller="org.cryptomator.ui.unlock.UnlockController"
|
|
||||||
minWidth="400"
|
|
||||||
maxWidth="400"
|
|
||||||
minHeight="145"
|
|
||||||
spacing="12">
|
|
||||||
<padding>
|
|
||||||
<Insets topRightBottomLeft="12"/>
|
|
||||||
</padding>
|
|
||||||
<children>
|
|
||||||
<VBox spacing="6">
|
|
||||||
<FormattedLabel format="%unlock.passwordPrompt" arg1="${controller.vault.displayableName}" wrapText="true"/>
|
|
||||||
<NiceSecurePasswordField fx:id="passwordField" disable="${controller.userInteractionDisabled}"/>
|
|
||||||
<CheckBox fx:id="savePasswordCheckbox" text="%unlock.savePassword" onAction="#didClickSavePasswordCheckbox" disable="${controller.userInteractionDisabled}" visible="${controller.keychainAccessAvailable}"/>
|
|
||||||
</VBox>
|
|
||||||
|
|
||||||
<VBox alignment="BOTTOM_CENTER" VBox.vgrow="ALWAYS">
|
|
||||||
<ButtonBar buttonMinWidth="120" buttonOrder="+CI">
|
|
||||||
<buttons>
|
|
||||||
<Button text="%generic.button.cancel" ButtonBar.buttonData="CANCEL_CLOSE" cancelButton="true" onAction="#cancel" disable="${controller.userInteractionDisabled}"/>
|
|
||||||
<Button text="%unlock.unlockBtn" ButtonBar.buttonData="FINISH" defaultButton="true" onAction="#unlock" contentDisplay="${controller.unlockButtonContentDisplay}" disable="${controller.unlockButtonDisabled}">
|
|
||||||
<graphic>
|
|
||||||
<ProgressIndicator progress="-1" prefWidth="12" prefHeight="12"/>
|
|
||||||
</graphic>
|
|
||||||
</Button>
|
|
||||||
</buttons>
|
|
||||||
</ButtonBar>
|
|
||||||
</VBox>
|
|
||||||
</children>
|
|
||||||
</VBox>
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
|
|
||||||
<?import javafx.geometry.Insets?>
|
|
||||||
<?import javafx.scene.control.Button?>
|
|
||||||
<?import javafx.scene.control.Hyperlink?>
|
|
||||||
<?import javafx.scene.layout.VBox?>
|
|
||||||
<?import org.cryptomator.ui.controls.FontAwesome5IconView?>
|
|
||||||
<VBox xmlns="http://javafx.com/javafx"
|
|
||||||
xmlns:fx="http://javafx.com/fxml"
|
|
||||||
fx:controller="org.cryptomator.ui.mainwindow.VaultDetailLockedController"
|
|
||||||
alignment="TOP_CENTER"
|
|
||||||
spacing="9">
|
|
||||||
<padding>
|
|
||||||
<Insets topRightBottomLeft="24"/>
|
|
||||||
</padding>
|
|
||||||
<children>
|
|
||||||
<Button styleClass="button-large" text="%main.vaultDetail.unlockBtn" minWidth="120" onAction="#unlock" defaultButton="${controller.vault.locked}">
|
|
||||||
<graphic>
|
|
||||||
<FontAwesome5IconView glyph="KEY" glyphSize="15"/>
|
|
||||||
</graphic>
|
|
||||||
</Button>
|
|
||||||
<Hyperlink text="%main.vaultDetail.optionsBtn" onAction="#showVaultOptions">
|
|
||||||
<graphic>
|
|
||||||
<FontAwesome5IconView glyph="COG"/>
|
|
||||||
</graphic>
|
|
||||||
</Hyperlink>
|
|
||||||
</children>
|
|
||||||
</VBox>
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
<?import javafx.geometry.Insets?>
|
|
||||||
<?import javafx.scene.control.Label?>
|
|
||||||
<?import javafx.scene.layout.StackPane?>
|
|
||||||
<?import javafx.scene.layout.VBox?>
|
|
||||||
<?import javafx.scene.shape.Circle?>
|
|
||||||
<?import org.cryptomator.ui.controls.FontAwesome5IconView?>
|
|
||||||
<VBox xmlns="http://javafx.com/javafx"
|
|
||||||
xmlns:fx="http://javafx.com/fxml"
|
|
||||||
fx:controller="org.cryptomator.ui.mainwindow.VaultDetailMissingVaultController"
|
|
||||||
alignment="TOP_CENTER"
|
|
||||||
spacing="9">
|
|
||||||
<padding>
|
|
||||||
<Insets topRightBottomLeft="24"/>
|
|
||||||
</padding>
|
|
||||||
<children>
|
|
||||||
<StackPane alignment="CENTER">
|
|
||||||
<Circle styleClass="glyph-icon-primary" radius="48"/>
|
|
||||||
<FontAwesome5IconView styleClass="glyph-icon-white" glyph="FILE" glyphSize="48"/>
|
|
||||||
<FontAwesome5IconView styleClass="glyph-icon-primary" glyph="SEARCH" glyphSize="24">
|
|
||||||
<StackPane.margin>
|
|
||||||
<Insets top="12"/>
|
|
||||||
</StackPane.margin>
|
|
||||||
</FontAwesome5IconView>
|
|
||||||
</StackPane>
|
|
||||||
|
|
||||||
<Label text="%main.vaultDetail.missing.info" wrapText="true"/>
|
|
||||||
</children>
|
|
||||||
</VBox>
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
|
|
||||||
<?import javafx.geometry.Insets?>
|
|
||||||
<?import javafx.scene.control.CheckBox?>
|
|
||||||
<?import javafx.scene.layout.VBox?>
|
|
||||||
<?import javafx.scene.control.ChoiceBox?>
|
|
||||||
<?import javafx.scene.layout.HBox?>
|
|
||||||
<?import javafx.scene.control.Label?>
|
|
||||||
<VBox xmlns="http://javafx.com/javafx"
|
|
||||||
xmlns:fx="http://javafx.com/fxml"
|
|
||||||
fx:controller="org.cryptomator.ui.vaultoptions.GeneralVaultOptionsController"
|
|
||||||
spacing="6">
|
|
||||||
<padding>
|
|
||||||
<Insets topRightBottomLeft="12"/>
|
|
||||||
</padding>
|
|
||||||
<children>
|
|
||||||
<CheckBox text="%vaultOptions.general.unlockAfterStartup" fx:id="unlockOnStartupCheckbox"/>
|
|
||||||
|
|
||||||
<HBox spacing="6" alignment="CENTER_LEFT">
|
|
||||||
<Label text="%vaultOptions.general.actionAfterUnlock"/>
|
|
||||||
<ChoiceBox fx:id="actionAfterUnlockChoiceBox"/>
|
|
||||||
</HBox>
|
|
||||||
</children>
|
|
||||||
</VBox>
|
|
||||||
@@ -1,64 +0,0 @@
|
|||||||
# Locale Specific CSS files such as CJK, RTL,...
|
|
||||||
|
|
||||||
# Generics
|
|
||||||
## Button
|
|
||||||
## Error
|
|
||||||
|
|
||||||
# Tray Menu
|
|
||||||
|
|
||||||
# Add Vault Wizard
|
|
||||||
## Welcome
|
|
||||||
## New
|
|
||||||
### Name
|
|
||||||
### Location
|
|
||||||
### Password
|
|
||||||
### Information
|
|
||||||
## Existing
|
|
||||||
## Success
|
|
||||||
|
|
||||||
# Remove Vault
|
|
||||||
|
|
||||||
# Change Password
|
|
||||||
|
|
||||||
# Forget Password
|
|
||||||
|
|
||||||
# Unlock
|
|
||||||
## Success
|
|
||||||
## Invalid Mount Point
|
|
||||||
|
|
||||||
# Migration
|
|
||||||
## Start
|
|
||||||
## Run
|
|
||||||
## Sucess
|
|
||||||
## Missing file system capabilities
|
|
||||||
## Impossible
|
|
||||||
|
|
||||||
# Preferences
|
|
||||||
## General
|
|
||||||
## Volume
|
|
||||||
## Updates
|
|
||||||
## Donation Key
|
|
||||||
## About
|
|
||||||
|
|
||||||
# Main Window
|
|
||||||
## Drag 'n' Drop
|
|
||||||
## Vault List
|
|
||||||
## Vault Detail
|
|
||||||
### Welcome
|
|
||||||
### Locked
|
|
||||||
### Unlocked
|
|
||||||
### Missing
|
|
||||||
### Needs Migration
|
|
||||||
|
|
||||||
# Wrong File Alert
|
|
||||||
|
|
||||||
# Vault Options
|
|
||||||
## General
|
|
||||||
## Mount
|
|
||||||
## Master Key
|
|
||||||
|
|
||||||
# Recovery Key
|
|
||||||
|
|
||||||
# New Password
|
|
||||||
|
|
||||||
# Quit
|
|
||||||
@@ -1,256 +0,0 @@
|
|||||||
# Locale Specific CSS files such as CJK, RTL,...
|
|
||||||
|
|
||||||
# Generics
|
|
||||||
## Button
|
|
||||||
generic.button.apply=Применить
|
|
||||||
generic.button.back=Назад
|
|
||||||
generic.button.cancel=Отмена
|
|
||||||
generic.button.change=Изменить
|
|
||||||
generic.button.close=Закрыть
|
|
||||||
generic.button.copy=Скопировать
|
|
||||||
generic.button.copied=Скопировано!
|
|
||||||
generic.button.done=Готово
|
|
||||||
generic.button.next=Далее
|
|
||||||
generic.button.print=Распечатать
|
|
||||||
## Error
|
|
||||||
generic.error.title=Произошла непредвиденная ошибка
|
|
||||||
generic.error.instruction=Этого не должно было произойти. Пожалуйста, создайте отчет об ошибке ниже и опишите, какие шаги к ней привели.
|
|
||||||
|
|
||||||
# Tray Menu
|
|
||||||
traymenu.showMainWindow=Показать
|
|
||||||
traymenu.showPreferencesWindow=Настройки
|
|
||||||
traymenu.lockAllVaults=Заблокировать все
|
|
||||||
traymenu.quitApplication=Выход
|
|
||||||
traymenu.vault.unlock=Разблокировать
|
|
||||||
traymenu.vault.lock=Заблокировать
|
|
||||||
traymenu.vault.reveal=Показать
|
|
||||||
|
|
||||||
# Add Vault Wizard
|
|
||||||
addvaultwizard.title=Добавить хранилище
|
|
||||||
## Welcome
|
|
||||||
addvaultwizard.welcome.newButton=Создать хранилище
|
|
||||||
addvaultwizard.welcome.existingButton=Открыть существующее хранилище
|
|
||||||
## New
|
|
||||||
### Name
|
|
||||||
addvaultwizard.new.nameInstruction=Выберите имя для хранилища
|
|
||||||
addvaultwizard.new.namePrompt=Название хранилища
|
|
||||||
### Location
|
|
||||||
addvaultwizard.new.locationInstruction=Где Cryptomator должен хранить зашифрованные файлы вашего хранилища?
|
|
||||||
addvaultwizard.new.locationLabel=Расположение хранилища
|
|
||||||
addvaultwizard.new.locationPrompt=…
|
|
||||||
addvaultwizard.new.directoryPickerLabel=Своё расположение
|
|
||||||
addvaultwizard.new.directoryPickerButton=Выбрать…
|
|
||||||
addvaultwizard.new.directoryPickerTitle=Выберите каталог
|
|
||||||
addvaultwizard.new.fileAlreadyExists=Хранилище не может быть создано по этому пути, потому что некоторые объекты уже существуют.
|
|
||||||
addvaultwizard.new.invalidName=Недопустимое название хранилища. Пожалуйста, выберите корректное название каталога.
|
|
||||||
### Password
|
|
||||||
addvaultwizard.new.createVaultBtn=Создать хранилище
|
|
||||||
addvaultwizard.new.generateRecoveryKeyChoice=Вы не сможете получить доступ к своим данным без пароля. Хотите создать ключ для восстановления на случай потери пароля?
|
|
||||||
addvaultwizard.new.generateRecoveryKeyChoice.yes=Да, пожалуй, лучше так, чем потом сожалеть
|
|
||||||
addvaultwizard.new.generateRecoveryKeyChoice.no=Нет, спасибо, я не потеряю свой пароль
|
|
||||||
### Information
|
|
||||||
addvault.new.readme.storageLocation.fileName=ВАЖНО.rtf
|
|
||||||
addvault.new.readme.storageLocation.1=⚠️ ФАЙЛЫ ХРАНИЛИЩА ⚠️
|
|
||||||
addvault.new.readme.storageLocation.2=Это место расположения вашего хранилища.
|
|
||||||
addvault.new.readme.storageLocation.3=НЕТ
|
|
||||||
addvault.new.readme.storageLocation.4=• изменяйте любые файлы в этой папке или
|
|
||||||
addvault.new.readme.storageLocation.5=• добавляйте в эту папку любые файлы для шифрования.
|
|
||||||
addvault.new.readme.storageLocation.6=Если вы хотите зашифровать файлы и просмотреть содержимое хранилища, сделайте следующее:
|
|
||||||
addvault.new.readme.storageLocation.7=1. Добавьте это хранилище в Cryptomator.
|
|
||||||
addvault.new.readme.storageLocation.8=2. Разблокируйте хранилище в Cryptomator.
|
|
||||||
addvault.new.readme.storageLocation.9=3. Откройте место доступа, нажав кнопку "Показать".
|
|
||||||
addvault.new.readme.storageLocation.10=Если вам нужна помощь, ознакомьтесь с документацией: %s
|
|
||||||
addvault.new.readme.accessLocation.fileName=ПРИВЕТСТВИЕ.rtf
|
|
||||||
addvault.new.readme.accessLocation.1=🔐️ ЗАШИФРОВАННЫЙ ТОМ 🔐️
|
|
||||||
addvault.new.readme.accessLocation.2=Это место доступа к вашему хранилищу.
|
|
||||||
addvault.new.readme.accessLocation.3=Любые файлы, добавленные в этот том, будут зашифрованы Cryptomator. Вы можете работать с ним, как с любым другим диском/папкой. Здесь отображается только расшифрованное содержимое тома, ваши файлы остаются зашифрованными на жестком диске постоянно.
|
|
||||||
addvault.new.readme.accessLocation.4=Этот файл можно удалить.
|
|
||||||
## Existing
|
|
||||||
addvaultwizard.existing.instruction=Выберите файл "masterkey.cryptomator" от существующего хранилища.
|
|
||||||
addvaultwizard.existing.chooseBtn=Выбрать…
|
|
||||||
addvaultwizard.existing.filePickerTitle=Выберите файл MasterKey
|
|
||||||
## Success
|
|
||||||
addvaultwizard.success.nextStepsInstructions=Добавлено хранилище "%s".\nДля добавления данных или доступа к содержимому нужно разблокировать хранилище. Его можно разблокировать и позже.
|
|
||||||
addvaultwizard.success.unlockNow=Разблокировать
|
|
||||||
|
|
||||||
# Remove Vault
|
|
||||||
removeVault.title=Удалить хранилище
|
|
||||||
removeVault.information=Cryptomator просто забудет это хранилище. Вы можете добавить его снова позже. Зашифрованные файлы не будут удалены с жесткого диска.
|
|
||||||
removeVault.confirmBtn=Удалить хранилище
|
|
||||||
|
|
||||||
# Change Password
|
|
||||||
changepassword.title=Изменить пароль
|
|
||||||
changepassword.enterOldPassword=Введите текущий пароль для "%s"
|
|
||||||
changepassword.finalConfirmation=Я понимаю, что не смогу получить доступ к своим данным, если забуду пароль
|
|
||||||
|
|
||||||
# Forget Password
|
|
||||||
forgetPassword.title=Не помню пароль
|
|
||||||
forgetPassword.information=Сохранённый пароль от этого хранилища будет удалён из вашей связки ключей.
|
|
||||||
forgetPassword.confirmBtn=Не помню пароль
|
|
||||||
|
|
||||||
# Unlock
|
|
||||||
unlock.title=Разблокировать хранилище
|
|
||||||
unlock.passwordPrompt=Введите пароль для "%s"
|
|
||||||
unlock.savePassword=Сохранить пароль
|
|
||||||
unlock.unlockBtn=Разблокировать
|
|
||||||
## Success
|
|
||||||
unlock.success.message=Разблокировка "%s" успешно выполнена! Доступ в хранилище открыт.
|
|
||||||
unlock.success.rememberChoice=Запомнить выбор и больше не спрашивать
|
|
||||||
unlock.success.revealBtn=Показать хранилище
|
|
||||||
## Invalid Mount Point
|
|
||||||
unlock.error.invalidMountPoint=Точка монтирования - не пустая папка: %s
|
|
||||||
|
|
||||||
# Migration
|
|
||||||
migration.title=Обновить хранилище
|
|
||||||
## Start
|
|
||||||
migration.start.prompt=Ваше хранилище "%s" должно быть обновлено до более нового формата. Перед тем, как продолжить, убедитесь в отсутствии отложенной синхронизации, которая может повлиять на хранилище.
|
|
||||||
migration.start.confirm=Да, моё хранилище полностью синхронизировано
|
|
||||||
## Run
|
|
||||||
migration.run.enterPassword=Введите пароль для "%s"
|
|
||||||
migration.run.startMigrationBtn=Перенести хранилище
|
|
||||||
migration.run.progressHint=Это может занять некоторое время…
|
|
||||||
## Sucess
|
|
||||||
migration.success.nextStepsInstructions="%s" перенесено успешно.\nТеперь вы можете разблокировать хранилище.
|
|
||||||
migration.success.unlockNow=Разблокировать
|
|
||||||
## Missing file system capabilities
|
|
||||||
migration.error.missingFileSystemCapabilities.title=Неподдерживаемая файловая система
|
|
||||||
migration.error.missingFileSystemCapabilities.description=Миграция не была запущена, так как ваше хранилище расположено в неподходящей файловой системе.
|
|
||||||
migration.error.missingFileSystemCapabilities.reason.LONG_FILENAMES=Файловая система не поддерживает длинные имена файлов.
|
|
||||||
migration.error.missingFileSystemCapabilities.reason.LONG_PATHS=Файловая система не поддерживает длинные пути.
|
|
||||||
migration.error.missingFileSystemCapabilities.reason.READ_ACCESS=Файловая система не разрешает чтение.
|
|
||||||
migration.error.missingFileSystemCapabilities.reason.WRITE_ACCESS=Файловая система не разрешает запись.
|
|
||||||
## Impossible
|
|
||||||
migration.impossible.heading=Невозможно перенести хранилище
|
|
||||||
migration.impossible.reason=Хранилище не может быть перенесено автоматически из-за несовместимости его расположения или точки доступа.
|
|
||||||
migration.impossible.moreInfo=Хранилище по-прежнему можно открыть в более старой версии. Чтобы узнать, как вручную перенести хранилище, посетите
|
|
||||||
|
|
||||||
# Preferences
|
|
||||||
preferences.title=Настройки
|
|
||||||
## General
|
|
||||||
preferences.general=Общие
|
|
||||||
preferences.general.theme=Внешний вид
|
|
||||||
preferences.general.theme.light=Светлая
|
|
||||||
preferences.general.theme.dark=Тёмная
|
|
||||||
preferences.general.unlockThemes=Разблокировать темный режим
|
|
||||||
preferences.general.startHidden=Скрывать окно при запуске Cryptomator
|
|
||||||
preferences.general.debugLogging=Включить ведение журнала отладки
|
|
||||||
preferences.general.debugDirectory=Показать файлы журнала
|
|
||||||
preferences.general.autoStart=Запускать Cryptomator при старте системы
|
|
||||||
preferences.general.interfaceOrientation=Ориентация интерфейса
|
|
||||||
preferences.general.interfaceOrientation.ltr=Слева направо
|
|
||||||
preferences.general.interfaceOrientation.rtl=Справа налево
|
|
||||||
## Volume
|
|
||||||
preferences.volume=Виртуальный диск
|
|
||||||
preferences.volume.type=Тип тома
|
|
||||||
preferences.volume.webdav.port=Порт WebDAV
|
|
||||||
preferences.volume.webdav.scheme=Схема WebDAV
|
|
||||||
## Updates
|
|
||||||
preferences.updates=Обновления
|
|
||||||
preferences.updates.currentVersion=Текущая версия: %s
|
|
||||||
preferences.updates.autoUpdateCheck=Автоматически проверять наличие обновлений
|
|
||||||
preferences.updates.checkNowBtn=Проверить сейчас
|
|
||||||
preferences.updates.updateAvailable=Доступно обновление до версии %s.
|
|
||||||
## Donation Key
|
|
||||||
preferences.donationKey=Пожертвование
|
|
||||||
preferences.donationKey.registeredFor=Зарегистрировано: %s
|
|
||||||
preferences.donationKey.noDonationKey=Не найден ключ пожертвования. Он напоминает лицензионный ключ, но для удивительных людей, использующих свободное ПО ;-)
|
|
||||||
preferences.donationKey.getDonationKey=Получить ключ пожертвования
|
|
||||||
## About
|
|
||||||
preferences.about=О программе
|
|
||||||
|
|
||||||
# Main Window
|
|
||||||
main.closeBtn.tooltip=Закрыть
|
|
||||||
main.minimizeBtn.tooltip=Свернуть
|
|
||||||
main.preferencesBtn.tooltip=Настройки
|
|
||||||
main.donationKeyMissing.tooltip=Мы будем рады финансовой помощи
|
|
||||||
## Drag 'n' Drop
|
|
||||||
main.dropZone.dropVault=Добавить это хранилище
|
|
||||||
main.dropZone.unknownDragboardContent=Если вы хотите добавить хранилище, перетащите его в это окно
|
|
||||||
## Vault List
|
|
||||||
main.vaultlist.emptyList.onboardingInstruction=Нажмите здесь для добавления хранилища
|
|
||||||
main.vaultlist.contextMenu.remove=Удалить хранилище
|
|
||||||
main.vaultlist.addVaultBtn=Добавить хранилище
|
|
||||||
## Vault Detail
|
|
||||||
### Welcome
|
|
||||||
main.vaultDetail.welcomeOnboarding=Спасибо, что выбрали Cryptomator для защиты ваших файлов. Если вам нужна помощь, ознакомьтесь с нашими руководствами по началу работы:
|
|
||||||
### Locked
|
|
||||||
main.vaultDetail.lockedStatus=ЗАБЛОКИРОВАНО
|
|
||||||
main.vaultDetail.unlockBtn=Разблокировать
|
|
||||||
main.vaultDetail.optionsBtn=Параметры хранилища
|
|
||||||
### Unlocked
|
|
||||||
main.vaultDetail.unlockedStatus=РАЗБЛОКИРОВАНО
|
|
||||||
main.vaultDetail.accessLocation=Содержимое вашего хранилища доступно здесь:
|
|
||||||
main.vaultDetail.revealBtn=Показать диск
|
|
||||||
main.vaultDetail.lockBtn=Заблокировать
|
|
||||||
main.vaultDetail.bytesPerSecondRead=чтение:
|
|
||||||
main.vaultDetail.bytesPerSecondWritten=запись:
|
|
||||||
main.vaultDetail.throughput.idle=бездействие
|
|
||||||
main.vaultDetail.throughput.kbps=%.1f КиБ/с
|
|
||||||
main.vaultDetail.throughput.mbps=%.1f МиБ/с
|
|
||||||
### Missing
|
|
||||||
main.vaultDetail.missing.info=Cryptomator не смог найти хранилище по этому пути.
|
|
||||||
### Needs Migration
|
|
||||||
main.vaultDetail.migrateButton=Обновить хранилище
|
|
||||||
main.vaultDetail.migratePrompt=Чтобы получить доступ к хранилищу, его нужно преобразовать в новый формат
|
|
||||||
|
|
||||||
# Wrong File Alert
|
|
||||||
wrongFileAlert.title=Как шифровать файлы
|
|
||||||
wrongFileAlert.header.title=Вы пытались зашифровать эти файлы?
|
|
||||||
wrongFileAlert.header.lead=Для этого Cryptomator создает том в системном файловом менеджере.
|
|
||||||
wrongFileAlert.instruction.0=Чтобы зашифровать файлы, выполните следующее:
|
|
||||||
wrongFileAlert.instruction.1=1. Разблокируйте ваше хранилище.
|
|
||||||
wrongFileAlert.instruction.2=2. Нажмите кнопку "Показать", чтобы открыть том в диспетчере файлов.
|
|
||||||
wrongFileAlert.instruction.3=3. Добавьте файлы в этот том.
|
|
||||||
wrongFileAlert.link=Если нужна помощь, посетите
|
|
||||||
|
|
||||||
# Vault Options
|
|
||||||
## General
|
|
||||||
vaultOptions.general=Общие
|
|
||||||
vaultOptions.general.unlockAfterStartup=Разблокировать хранилище при запуске Cryptomator
|
|
||||||
vaultOptions.general.actionAfterUnlock=После успешной разблокировки
|
|
||||||
vaultOptions.general.actionAfterUnlock.ignore=Ничего не делать
|
|
||||||
vaultOptions.general.actionAfterUnlock.reveal=Показать диск
|
|
||||||
vaultOptions.general.actionAfterUnlock.ask=Спрашивать
|
|
||||||
## Mount
|
|
||||||
vaultOptions.mount=Монтирование
|
|
||||||
vaultOptions.mount.readonly=Только чтение
|
|
||||||
vaultOptions.mount.driveName=Имя диска
|
|
||||||
vaultOptions.mount.customMountFlags=Пользовательские флаги монтирования
|
|
||||||
vaultOptions.mount.winDriveLetterOccupied=занято
|
|
||||||
vaultOptions.mount.mountPoint=Точка монтирования
|
|
||||||
vaultOptions.mount.mountPoint.auto=Автоматически выбирать подходящую
|
|
||||||
vaultOptions.mount.mountPoint.driveLetter=Использовать назначенную букву диска
|
|
||||||
vaultOptions.mount.mountPoint.custom=Свой путь
|
|
||||||
vaultOptions.mount.mountPoint.directoryPickerButton=Выбрать…
|
|
||||||
vaultOptions.mount.mountPoint.directoryPickerTitle=Выберите пустой каталог
|
|
||||||
## Master Key
|
|
||||||
vaultOptions.masterkey=Пароль
|
|
||||||
vaultOptions.masterkey.changePasswordBtn=Изменить пароль
|
|
||||||
vaultOptions.masterkey.recoveryKeyExpanation=Ключ восстановления - это единственный способ восстановить доступ к хранилищу в случае утери пароля.
|
|
||||||
vaultOptions.masterkey.showRecoveryKeyBtn=Показать ключ восстановления
|
|
||||||
vaultOptions.masterkey.recoverPasswordBtn=Восстановить пароль
|
|
||||||
|
|
||||||
# Recovery Key
|
|
||||||
recoveryKey.title=Ключ восстановления
|
|
||||||
recoveryKey.enterPassword.prompt=Введите пароль для отображения ключа восстановления для "%s":
|
|
||||||
recoveryKey.display.message=Следующий ключ восстановления можно использовать для восстановления доступа к "%s":
|
|
||||||
recoveryKey.display.StorageHints=Храните его в надежном месте, например:\n • в менеджере паролей\n • на флэш-накопителе USB\n • распечатайте на бумаге
|
|
||||||
recoveryKey.recover.prompt=Введите ваш ключ восстановления для "%s":
|
|
||||||
recoveryKey.recover.validKey=Это действительный ключ восстановления
|
|
||||||
recoveryKey.printout.heading=Ключ восстановления Cryptomator\n"%s"\n
|
|
||||||
|
|
||||||
# New Password
|
|
||||||
newPassword.promptText=Введите новый пароль
|
|
||||||
newPassword.reenterPassword=Подтвердите новый пароль
|
|
||||||
newPassword.passwordsMatch=Пароли совпадают!
|
|
||||||
newPassword.passwordsDoNotMatch=Пароли не совпадают
|
|
||||||
passwordStrength.messageLabel.tooShort=Минимум символов: %d
|
|
||||||
passwordStrength.messageLabel.0=Очень слабый
|
|
||||||
passwordStrength.messageLabel.1=Слабый
|
|
||||||
passwordStrength.messageLabel.2=Хороший
|
|
||||||
passwordStrength.messageLabel.3=Сильный
|
|
||||||
passwordStrength.messageLabel.4=Очень сильный
|
|
||||||
|
|
||||||
# Quit
|
|
||||||
quit.prompt=Выйти из приложения? Есть разблокированные хранилища.
|
|
||||||
quit.lockAndQuit=Заблокировать и выйти
|
|
||||||
@@ -1,144 +0,0 @@
|
|||||||
# Locale Specific CSS files such as CJK, RTL,...
|
|
||||||
|
|
||||||
# Generics
|
|
||||||
## Button
|
|
||||||
generic.button.apply=Použiť
|
|
||||||
generic.button.back=Späť
|
|
||||||
generic.button.cancel=Zrušiť
|
|
||||||
generic.button.change=Zmeniť
|
|
||||||
generic.button.close=Zavrieť
|
|
||||||
generic.button.copy=Kopírovať
|
|
||||||
generic.button.copied=Skopírované!
|
|
||||||
generic.button.done=Hotovo
|
|
||||||
generic.button.next=Ďalej
|
|
||||||
generic.button.print=Tlač
|
|
||||||
## Error
|
|
||||||
generic.error.title=Vyskytla sa neočakávaná chyba
|
|
||||||
generic.error.instruction=Toto sa nemalo stať. Nahláste text chyby uvedený nižšie a uveďte popis krokov, ktoré viedli k tejto chybe.
|
|
||||||
|
|
||||||
# Tray Menu
|
|
||||||
traymenu.showMainWindow=Zobraziť
|
|
||||||
traymenu.showPreferencesWindow=Predvoľby
|
|
||||||
traymenu.lockAllVaults=Zamknúť všetky
|
|
||||||
traymenu.quitApplication=Ukončiť
|
|
||||||
traymenu.vault.unlock=Odomknúť
|
|
||||||
traymenu.vault.lock=Uzamknúť
|
|
||||||
traymenu.vault.reveal=Odkryť
|
|
||||||
|
|
||||||
# Add Vault Wizard
|
|
||||||
addvaultwizard.title=Pridať trezor
|
|
||||||
## Welcome
|
|
||||||
addvaultwizard.welcome.newButton=Vytvoriť nový trezor
|
|
||||||
addvaultwizard.welcome.existingButton=Otvoriť existujúci trezor
|
|
||||||
## New
|
|
||||||
### Name
|
|
||||||
addvaultwizard.new.nameInstruction=Zvoľte názov pre trezor
|
|
||||||
addvaultwizard.new.namePrompt=Názov trezoru
|
|
||||||
### Location
|
|
||||||
addvaultwizard.new.locationInstruction=Kde by mal Cryptomator uchovávať šifrované súbory vášho trezoru?
|
|
||||||
addvaultwizard.new.locationLabel=Umiestnenie úložiska
|
|
||||||
addvaultwizard.new.directoryPickerLabel=Vlastné umiestnenie
|
|
||||||
addvaultwizard.new.directoryPickerButton=Vybrať…
|
|
||||||
addvaultwizard.new.directoryPickerTitle=Vybrať adresár
|
|
||||||
addvaultwizard.new.fileAlreadyExists=Na tejto ceste nie je možné vytvoriť trezor, pretože niektorý objekt už existuje.
|
|
||||||
addvaultwizard.new.invalidName=Neplatný názov trezoru. Zvážte bežný názov adresára.
|
|
||||||
### Password
|
|
||||||
addvaultwizard.new.createVaultBtn=Vytvoriť trezor
|
|
||||||
addvaultwizard.new.generateRecoveryKeyChoice=Bez hesla nebudete mať prístup k svojim údajom. Chcete obnovovací kľúč pre prípad straty hesla?
|
|
||||||
addvaultwizard.new.generateRecoveryKeyChoice.yes=Áno, prosím, istota je istota
|
|
||||||
addvaultwizard.new.generateRecoveryKeyChoice.no=Nie, ďakujem, nestratím svoje heslo
|
|
||||||
### Information
|
|
||||||
addvault.new.readme.storageLocation.fileName=Dôležité.rtf
|
|
||||||
addvault.new.readme.storageLocation.1=⚠️ SÚBORY TREZORU ⚠️
|
|
||||||
addvault.new.readme.storageLocation.2=Toto je umiestnenie úložiska vášho trezoru.
|
|
||||||
addvault.new.readme.storageLocation.3=NEVYKONÁVAJTE
|
|
||||||
addvault.new.readme.storageLocation.4=zmeniť akékoľvek súbory v tomto adresári alebo
|
|
||||||
addvault.new.readme.storageLocation.5=vložiť do tohto adresára akékoľvek súbory na šifrovanie.
|
|
||||||
addvault.new.readme.storageLocation.6=Ak chcete šifrovať súbory a zobraziť obsah trezoru, postupujte takto:
|
|
||||||
addvault.new.readme.storageLocation.7=1. Pridajte tento trezor do Cryptomatoru.
|
|
||||||
addvault.new.readme.storageLocation.8=2. Odomknite trezor v Cryptomatore.
|
|
||||||
addvault.new.readme.storageLocation.9=3. Otvorte prístupové miesto kliknutím na tlačidlo „Odkryť“.
|
|
||||||
addvault.new.readme.storageLocation.10=Ak potrebujete pomoc, navštívte dokumentáciu: %s
|
|
||||||
addvault.new.readme.accessLocation.fileName=VITAJTE.rtf
|
|
||||||
addvault.new.readme.accessLocation.1=🔐️ ZAŠIFROVANÝ ZVÄZOK 🔐️
|
|
||||||
addvault.new.readme.accessLocation.2=Toto je prístupové miesto vášho trezoru.
|
|
||||||
addvault.new.readme.accessLocation.3=Všetky súbory pridané do tohto zväzku budú šifrované programom Cryptomator. Môžete na tom pracovať ako na akomkoľvek inom disku / priečinku. Toto je iba dešifrované zobrazenie jeho obsahu, vaše súbory zostávajú stále šifrované na pevnom disku.
|
|
||||||
addvault.new.readme.accessLocation.4=Tento súbor môžete kedykoľvek odstrániť.
|
|
||||||
## Existing
|
|
||||||
addvaultwizard.existing.instruction=Vyberte súbor „masterkey.cryptomator“ existujúceho trezoru.
|
|
||||||
addvaultwizard.existing.chooseBtn=Vybrať…
|
|
||||||
## Success
|
|
||||||
addvaultwizard.success.nextStepsInstructions=Pridaný trezor "%s".\nAk chcete získať prístup alebo pridať obsah, musíte tento trezor odomknúť. Prípadne ju môžete odomknúť kedykoľvek neskôr.
|
|
||||||
addvaultwizard.success.unlockNow=Odomknúť teraz
|
|
||||||
|
|
||||||
# Remove Vault
|
|
||||||
removeVault.title=Odstrániť trezor
|
|
||||||
removeVault.information=To spôsobí, že Cryptomator iba zabudne na tento trezor. Môžete ho pridať znova neskôr. Z pevného disku sa neodstránia žiadne šifrované súbory.
|
|
||||||
removeVault.confirmBtn=Odstrániť trezor
|
|
||||||
|
|
||||||
# Change Password
|
|
||||||
changepassword.title=Zmeniť heslo
|
|
||||||
changepassword.enterOldPassword=Zadaj aktuálne heslo pre "%s"
|
|
||||||
changepassword.finalConfirmation=Chápem, že ak zabudnem svoje heslo, nebudem mať prístup k svojim údajom
|
|
||||||
|
|
||||||
# Forget Password
|
|
||||||
forgetPassword.title=Zabudnuté heslo
|
|
||||||
forgetPassword.information=Týmto vymažete uložené heslo tohto trezoru z vášho systému kľúčov.
|
|
||||||
forgetPassword.confirmBtn=Zabudnuté heslo
|
|
||||||
|
|
||||||
# Unlock
|
|
||||||
unlock.title=Odomknúť trezor
|
|
||||||
unlock.passwordPrompt=Zadajte heslo pre "%s":
|
|
||||||
unlock.savePassword=Uložiť heslo
|
|
||||||
unlock.unlockBtn=Odomknúť
|
|
||||||
## Success
|
|
||||||
unlock.success.message=Úspešne sa odomkol "%s"! Váš trezor je teraz prístupný.
|
|
||||||
unlock.success.revealBtn=Odhaliť trezor
|
|
||||||
## Invalid Mount Point
|
|
||||||
|
|
||||||
# Migration
|
|
||||||
## Start
|
|
||||||
## Run
|
|
||||||
## Sucess
|
|
||||||
migration.success.unlockNow=Odomknúť teraz
|
|
||||||
## Missing file system capabilities
|
|
||||||
## Impossible
|
|
||||||
|
|
||||||
# Preferences
|
|
||||||
preferences.title=Predvoľby
|
|
||||||
## General
|
|
||||||
## Volume
|
|
||||||
## Updates
|
|
||||||
## Donation Key
|
|
||||||
## About
|
|
||||||
|
|
||||||
# Main Window
|
|
||||||
main.closeBtn.tooltip=Zavrieť
|
|
||||||
main.preferencesBtn.tooltip=Predvoľby
|
|
||||||
## Drag 'n' Drop
|
|
||||||
## Vault List
|
|
||||||
main.vaultlist.contextMenu.remove=Odstrániť trezor
|
|
||||||
main.vaultlist.addVaultBtn=Pridať trezor
|
|
||||||
## Vault Detail
|
|
||||||
### Welcome
|
|
||||||
### Locked
|
|
||||||
main.vaultDetail.unlockBtn=Odomknúť
|
|
||||||
### Unlocked
|
|
||||||
main.vaultDetail.lockBtn=Uzamknúť
|
|
||||||
### Missing
|
|
||||||
### Needs Migration
|
|
||||||
|
|
||||||
# Wrong File Alert
|
|
||||||
|
|
||||||
# Vault Options
|
|
||||||
## General
|
|
||||||
## Mount
|
|
||||||
vaultOptions.mount.mountPoint.directoryPickerButton=Vybrať…
|
|
||||||
## Master Key
|
|
||||||
vaultOptions.masterkey.changePasswordBtn=Zmeniť heslo
|
|
||||||
|
|
||||||
# Recovery Key
|
|
||||||
|
|
||||||
# New Password
|
|
||||||
|
|
||||||
# Quit
|
|
||||||
@@ -1,91 +0,0 @@
|
|||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see http://www.gnu.org/licenses/.
|
|
||||||
|
|
||||||
Cryptomator uses 52 third-party dependencies under the following licenses:
|
|
||||||
Apache License v2.0:
|
|
||||||
- HKDF-RFC5869 (at.favre.lib:hkdf:1.1.0 - https://github.com/patrickfav/hkdf)
|
|
||||||
- jffi (com.github.jnr:jffi:1.2.23 - http://github.com/jnr/jffi)
|
|
||||||
- jnr-a64asm (com.github.jnr:jnr-a64asm:1.0.0 - http://nexus.sonatype.org/oss-repository-hosting.html/jnr-a64asm)
|
|
||||||
- jnr-constants (com.github.jnr:jnr-constants:0.9.15 - http://github.com/jnr/jnr-constants)
|
|
||||||
- jnr-enxio (com.github.jnr:jnr-enxio:0.21 - http://github.com/jnr/jnr-enxio)
|
|
||||||
- jnr-ffi (com.github.jnr:jnr-ffi:2.1.12 - http://github.com/jnr/jnr-ffi)
|
|
||||||
- jnr-unixsocket (com.github.jnr:jnr-unixsocket:0.23 - http://github.com/jnr/jnr-unixsocket)
|
|
||||||
- FindBugs-jsr305 (com.google.code.findbugs:jsr305:3.0.2 - http://findbugs.sourceforge.net/)
|
|
||||||
- Gson (com.google.code.gson:gson:2.8.6 - https://github.com/google/gson/gson)
|
|
||||||
- Dagger (com.google.dagger:dagger:2.27 - https://github.com/google/dagger)
|
|
||||||
- error-prone annotations (com.google.errorprone:error_prone_annotations:2.3.4 - http://nexus.sonatype.org/oss-repository-hosting.html/error_prone_parent/error_prone_annotations)
|
|
||||||
- Guava InternalFutureFailureAccess and InternalFutures (com.google.guava:failureaccess:1.0.1 - https://github.com/google/guava/failureaccess)
|
|
||||||
- Guava: Google Core Libraries for Java (com.google.guava:guava:28.2-jre - https://github.com/google/guava/guava)
|
|
||||||
- Guava ListenableFuture only (com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava - https://github.com/google/guava/listenablefuture)
|
|
||||||
- J2ObjC Annotations (com.google.j2objc:j2objc-annotations:1.3 - https://github.com/google/j2objc/)
|
|
||||||
- Apache Commons CLI (commons-cli:commons-cli:1.4 - http://commons.apache.org/proper/commons-cli/)
|
|
||||||
- Apache Commons IO (commons-io:commons-io:2.6 - http://commons.apache.org/proper/commons-io/)
|
|
||||||
- javax.inject (javax.inject:javax.inject:1 - http://code.google.com/p/atinject/)
|
|
||||||
- Java Native Access (net.java.dev.jna:jna:5.1.0 - https://github.com/java-native-access/jna)
|
|
||||||
- Java Native Access Platform (net.java.dev.jna:jna-platform:5.1.0 - https://github.com/java-native-access/jna)
|
|
||||||
- Apache Commons Lang (org.apache.commons:commons-lang3:3.9 - http://commons.apache.org/proper/commons-lang/)
|
|
||||||
- Apache HttpCore (org.apache.httpcomponents:httpcore:4.4.13 - http://hc.apache.org/httpcomponents-core-ga)
|
|
||||||
- Jackrabbit WebDAV Library (org.apache.jackrabbit:jackrabbit-webdav:2.21.0 - http://jackrabbit.apache.org/jackrabbit-webdav/)
|
|
||||||
- Jetty :: Http Utility (org.eclipse.jetty:jetty-http:9.4.28.v20200408 - http://www.eclipse.org/jetty)
|
|
||||||
- Jetty :: IO Utility (org.eclipse.jetty:jetty-io:9.4.28.v20200408 - http://www.eclipse.org/jetty)
|
|
||||||
- Jetty :: Security (org.eclipse.jetty:jetty-security:9.4.28.v20200408 - http://www.eclipse.org/jetty)
|
|
||||||
- Jetty :: Server Core (org.eclipse.jetty:jetty-server:9.4.28.v20200408 - http://www.eclipse.org/jetty)
|
|
||||||
- Jetty :: Servlet Handling (org.eclipse.jetty:jetty-servlet:9.4.28.v20200408 - http://www.eclipse.org/jetty)
|
|
||||||
- Jetty :: Utilities (org.eclipse.jetty:jetty-util:9.4.28.v20200408 - http://www.eclipse.org/jetty)
|
|
||||||
- Jetty :: Webapp Application Support (org.eclipse.jetty:jetty-webapp:9.4.28.v20200408 - http://www.eclipse.org/jetty)
|
|
||||||
- Jetty :: XML utilities (org.eclipse.jetty:jetty-xml:9.4.28.v20200408 - http://www.eclipse.org/jetty)
|
|
||||||
BSD:
|
|
||||||
- asm (org.ow2.asm:asm:7.1 - http://asm.ow2.org/)
|
|
||||||
- asm-analysis (org.ow2.asm:asm-analysis:7.1 - http://asm.ow2.org/)
|
|
||||||
- asm-commons (org.ow2.asm:asm-commons:7.1 - http://asm.ow2.org/)
|
|
||||||
- asm-tree (org.ow2.asm:asm-tree:7.1 - http://asm.ow2.org/)
|
|
||||||
- asm-util (org.ow2.asm:asm-util:7.1 - http://asm.ow2.org/)
|
|
||||||
Eclipse Public License - Version 1.0:
|
|
||||||
- Jetty :: Http Utility (org.eclipse.jetty:jetty-http:9.4.28.v20200408 - http://www.eclipse.org/jetty)
|
|
||||||
- Jetty :: IO Utility (org.eclipse.jetty:jetty-io:9.4.28.v20200408 - http://www.eclipse.org/jetty)
|
|
||||||
- Jetty :: Security (org.eclipse.jetty:jetty-security:9.4.28.v20200408 - http://www.eclipse.org/jetty)
|
|
||||||
- Jetty :: Server Core (org.eclipse.jetty:jetty-server:9.4.28.v20200408 - http://www.eclipse.org/jetty)
|
|
||||||
- Jetty :: Servlet Handling (org.eclipse.jetty:jetty-servlet:9.4.28.v20200408 - http://www.eclipse.org/jetty)
|
|
||||||
- Jetty :: Utilities (org.eclipse.jetty:jetty-util:9.4.28.v20200408 - http://www.eclipse.org/jetty)
|
|
||||||
- Jetty :: Webapp Application Support (org.eclipse.jetty:jetty-webapp:9.4.28.v20200408 - http://www.eclipse.org/jetty)
|
|
||||||
- Jetty :: XML utilities (org.eclipse.jetty:jetty-xml:9.4.28.v20200408 - http://www.eclipse.org/jetty)
|
|
||||||
Eclipse Public License - v 2.0:
|
|
||||||
- jnr-posix (com.github.jnr:jnr-posix:3.0.54 - http://nexus.sonatype.org/oss-repository-hosting.html/jnr-posix)
|
|
||||||
GPLv2:
|
|
||||||
- jnr-posix (com.github.jnr:jnr-posix:3.0.54 - http://nexus.sonatype.org/oss-repository-hosting.html/jnr-posix)
|
|
||||||
GPLv2+CE:
|
|
||||||
- Java Servlet API (javax.servlet:javax.servlet-api:3.1.0 - http://servlet-spec.java.net)
|
|
||||||
- javafx-base (org.openjfx:javafx-base:14 - https://openjdk.java.net/projects/openjfx/javafx-base/)
|
|
||||||
- javafx-controls (org.openjfx:javafx-controls:14 - https://openjdk.java.net/projects/openjfx/javafx-controls/)
|
|
||||||
- javafx-fxml (org.openjfx:javafx-fxml:14 - https://openjdk.java.net/projects/openjfx/javafx-fxml/)
|
|
||||||
- javafx-graphics (org.openjfx:javafx-graphics:14 - https://openjdk.java.net/projects/openjfx/javafx-graphics/)
|
|
||||||
LGPL 2.1:
|
|
||||||
- dbus-java (com.github.hypfvieh:dbus-java:3.2.1 - https://github.com/hypfvieh/dbus-java/dbus-java)
|
|
||||||
- jnr-posix (com.github.jnr:jnr-posix:3.0.54 - http://nexus.sonatype.org/oss-repository-hosting.html/jnr-posix)
|
|
||||||
- Java Native Access (net.java.dev.jna:jna:5.1.0 - https://github.com/java-native-access/jna)
|
|
||||||
- Java Native Access Platform (net.java.dev.jna:jna-platform:5.1.0 - https://github.com/java-native-access/jna)
|
|
||||||
MIT License:
|
|
||||||
- java jwt (com.auth0:java-jwt:3.10.2 - https://github.com/auth0/java-jwt)
|
|
||||||
- java-utils (com.github.hypfvieh:java-utils:1.0.6 - https://github.com/hypfvieh/java-utils)
|
|
||||||
- jnr-x86asm (com.github.jnr:jnr-x86asm:1.0.2 - http://github.com/jnr/jnr-x86asm)
|
|
||||||
- jnr-fuse (com.github.serceman:jnr-fuse:0.5.4 - no url defined)
|
|
||||||
- zxcvbn4j (com.nulab-inc:zxcvbn:1.3.0 - https://github.com/nulab/zxcvbn4j)
|
|
||||||
- secret-service (de.swiesend:secret-service:1.0.0 - https://github.com/swiesend/secret-service)
|
|
||||||
- Checker Qual (org.checkerframework:checker-qual:2.10.0 - https://checkerframework.org)
|
|
||||||
- SLF4J API Module (org.slf4j:slf4j-api:1.7.30 - http://www.slf4j.org)
|
|
||||||
The BSD 2-Clause License:
|
|
||||||
- EasyBind (org.fxmisc.easybind:easybind:1.0.3 - http://www.fxmisc.org/easybind/)
|
|
||||||
|
|
||||||
Cryptomator uses other third-party assets under the following licenses:
|
|
||||||
SIL OFL 1.1 License:
|
|
||||||
- Font Awesome 5.12.0 (https://fontawesome.com/)
|
|
||||||
@@ -0,0 +1,601 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<groupId>org.cryptomator</groupId>
|
||||||
|
<artifactId>cryptomator</artifactId>
|
||||||
|
<version>1.6.0-SNAPSHOT</version>
|
||||||
|
<name>Cryptomator Desktop App</name>
|
||||||
|
|
||||||
|
<organization>
|
||||||
|
<name>cryptomator.org</name>
|
||||||
|
<url>https://cryptomator.org</url>
|
||||||
|
</organization>
|
||||||
|
|
||||||
|
<developers>
|
||||||
|
<developer>
|
||||||
|
<name>Sebastian Stenzel</name>
|
||||||
|
<email>sebastian.stenzel@gmail.com</email>
|
||||||
|
<timezone>+1</timezone>
|
||||||
|
</developer>
|
||||||
|
</developers>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
<project.jdk.version>16</project.jdk.version>
|
||||||
|
|
||||||
|
<!-- cryptomator dependencies -->
|
||||||
|
<cryptomator.cryptofs.version>2.1.0-beta8</cryptomator.cryptofs.version>
|
||||||
|
<cryptomator.integrations.version>1.0.0-rc1</cryptomator.integrations.version>
|
||||||
|
<cryptomator.integrations.win.version>1.0.0-beta2</cryptomator.integrations.win.version>
|
||||||
|
<cryptomator.integrations.mac.version>1.0.0-beta2</cryptomator.integrations.mac.version>
|
||||||
|
<cryptomator.integrations.linux.version>1.0.0-beta1</cryptomator.integrations.linux.version>
|
||||||
|
<cryptomator.fuse.version>1.3.1</cryptomator.fuse.version>
|
||||||
|
<cryptomator.dokany.version>1.3.1</cryptomator.dokany.version>
|
||||||
|
<cryptomator.webdav.version>1.2.4</cryptomator.webdav.version>
|
||||||
|
|
||||||
|
<!-- 3rd party dependencies -->
|
||||||
|
<javafx.version>16</javafx.version>
|
||||||
|
<commons-lang3.version>3.12.0</commons-lang3.version>
|
||||||
|
<jwt.version>3.17.0</jwt.version>
|
||||||
|
<easybind.version>2.2</easybind.version>
|
||||||
|
<guava.version>30.1.1-jre</guava.version>
|
||||||
|
<dagger.version>2.37</dagger.version>
|
||||||
|
<gson.version>2.8.6</gson.version>
|
||||||
|
<slf4j.version>1.7.31</slf4j.version>
|
||||||
|
<logback.version>1.2.3</logback.version>
|
||||||
|
|
||||||
|
<!-- test dependencies -->
|
||||||
|
<junit.jupiter.version>5.7.2</junit.jupiter.version>
|
||||||
|
<mockito.version>3.11.2</mockito.version>
|
||||||
|
<hamcrest.version>2.2</hamcrest.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<!-- Cryptomator Libs -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.cryptomator</groupId>
|
||||||
|
<artifactId>cryptofs</artifactId>
|
||||||
|
<version>${cryptomator.cryptofs.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.cryptomator</groupId>
|
||||||
|
<artifactId>fuse-nio-adapter</artifactId>
|
||||||
|
<version>${cryptomator.fuse.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.cryptomator</groupId>
|
||||||
|
<artifactId>dokany-nio-adapter</artifactId>
|
||||||
|
<version>${cryptomator.dokany.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.cryptomator</groupId>
|
||||||
|
<artifactId>webdav-nio-adapter</artifactId>
|
||||||
|
<version>${cryptomator.webdav.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.cryptomator</groupId>
|
||||||
|
<artifactId>integrations-api</artifactId>
|
||||||
|
<version>${cryptomator.integrations.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- JavaFX -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.openjfx</groupId>
|
||||||
|
<artifactId>javafx-base</artifactId>
|
||||||
|
<version>${javafx.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.openjfx</groupId>
|
||||||
|
<artifactId>javafx-graphics</artifactId>
|
||||||
|
<version>${javafx.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.openjfx</groupId>
|
||||||
|
<artifactId>javafx-controls</artifactId>
|
||||||
|
<version>${javafx.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.openjfx</groupId>
|
||||||
|
<artifactId>javafx-fxml</artifactId>
|
||||||
|
<version>${javafx.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Logging -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.slf4j</groupId>
|
||||||
|
<artifactId>slf4j-api</artifactId>
|
||||||
|
<version>${slf4j.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>ch.qos.logback</groupId>
|
||||||
|
<artifactId>logback-core</artifactId>
|
||||||
|
<version>${logback.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>ch.qos.logback</groupId>
|
||||||
|
<artifactId>logback-classic</artifactId>
|
||||||
|
<version>${logback.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Apache Commons -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.commons</groupId>
|
||||||
|
<artifactId>commons-lang3</artifactId>
|
||||||
|
<version>${commons-lang3.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- JWT -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.auth0</groupId>
|
||||||
|
<artifactId>java-jwt</artifactId>
|
||||||
|
<version>${jwt.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- EasyBind -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.tobiasdiez</groupId>
|
||||||
|
<artifactId>easybind</artifactId>
|
||||||
|
<version>${easybind.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Zxcvbn -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.nulab-inc</groupId>
|
||||||
|
<artifactId>zxcvbn</artifactId>
|
||||||
|
<version>1.3.0</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Google -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.guava</groupId>
|
||||||
|
<artifactId>guava</artifactId>
|
||||||
|
<version>${guava.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.dagger</groupId>
|
||||||
|
<artifactId>dagger</artifactId>
|
||||||
|
<version>${dagger.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.code.gson</groupId>
|
||||||
|
<artifactId>gson</artifactId>
|
||||||
|
<version>${gson.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- JUnit / Mockito / Hamcrest -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.junit.jupiter</groupId>
|
||||||
|
<artifactId>junit-jupiter</artifactId>
|
||||||
|
<version>${junit.jupiter.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.mockito</groupId>
|
||||||
|
<artifactId>mockito-core</artifactId>
|
||||||
|
<version>${mockito.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.hamcrest</groupId>
|
||||||
|
<artifactId>hamcrest</artifactId>
|
||||||
|
<version>${hamcrest.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.openjfx</groupId>
|
||||||
|
<artifactId>javafx-swing</artifactId>
|
||||||
|
<version>${javafx.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.jimfs</groupId>
|
||||||
|
<artifactId>jimfs</artifactId>
|
||||||
|
<version>1.1</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<pluginManagement>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>3.8.1</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-resources-plugin</artifactId>
|
||||||
|
<version>3.2.0</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-dependency-plugin</artifactId>
|
||||||
|
<version>3.1.2</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-assembly-plugin</artifactId>
|
||||||
|
<version>3.3.0</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
<version>2.22.2</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.codehaus.mojo</groupId>
|
||||||
|
<artifactId>license-maven-plugin</artifactId>
|
||||||
|
<version>2.0.0</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-jar-plugin</artifactId>
|
||||||
|
<version>3.2.0</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.jacoco</groupId>
|
||||||
|
<artifactId>jacoco-maven-plugin</artifactId>
|
||||||
|
<version>0.8.6</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.owasp</groupId>
|
||||||
|
<artifactId>dependency-check-maven</artifactId>
|
||||||
|
<version>6.0.3</version>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</pluginManagement>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<release>${project.jdk.version}</release>
|
||||||
|
<annotationProcessorPaths>
|
||||||
|
<path>
|
||||||
|
<groupId>com.google.dagger</groupId>
|
||||||
|
<artifactId>dagger-compiler</artifactId>
|
||||||
|
<version>${dagger.version}</version>
|
||||||
|
</path>
|
||||||
|
</annotationProcessorPaths>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-jar-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<archive>
|
||||||
|
<manifest>
|
||||||
|
<!-- adds Implementation-Version which can be read during runtime -->
|
||||||
|
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
|
||||||
|
</manifest>
|
||||||
|
</archive>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-resources-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>copy-resources</id>
|
||||||
|
<phase>prepare-package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>copy-resources</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<outputDirectory>${project.build.directory}</outputDirectory>
|
||||||
|
<resources>
|
||||||
|
<resource>
|
||||||
|
<directory>${project.basedir}/src/package</directory>
|
||||||
|
<includes>
|
||||||
|
<include>version.txt</include>
|
||||||
|
<include>ffi-version.txt</include>
|
||||||
|
<include>launcher-mac.sh</include>
|
||||||
|
<include>launcher-linux.sh</include>
|
||||||
|
<include>launcher-win.bat</include>
|
||||||
|
<include>LICENSE.txt</include>
|
||||||
|
</includes>
|
||||||
|
<filtering>true</filtering>
|
||||||
|
</resource>
|
||||||
|
</resources>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-dependency-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>copy-libs</id>
|
||||||
|
<phase>prepare-package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>copy-dependencies</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<includeScope>runtime</includeScope>
|
||||||
|
<outputDirectory>${project.build.directory}/libs</outputDirectory>
|
||||||
|
<excludeClassifiers>linux,mac,win</excludeClassifiers>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.codehaus.mojo</groupId>
|
||||||
|
<artifactId>license-maven-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>add-third-party</id>
|
||||||
|
<goals>
|
||||||
|
<goal>add-third-party</goal>
|
||||||
|
</goals>
|
||||||
|
<phase>generate-resources</phase>
|
||||||
|
<configuration>
|
||||||
|
<outputDirectory>${project.basedir}/src/main/resources/license</outputDirectory>
|
||||||
|
<thirdPartyFilename>THIRD-PARTY.txt</thirdPartyFilename>
|
||||||
|
<includedScopes>compile</includedScopes>
|
||||||
|
<excludedGroups>org\.cryptomator</excludedGroups>
|
||||||
|
<licenseMerges>
|
||||||
|
<licenseMerge>Apache License v2.0|Apache License, Version 2.0|The Apache Software License, Version 2.0|Apache 2.0|Apache Software License - Version 2.0</licenseMerge>
|
||||||
|
<licenseMerge>MIT License|The MIT License (MIT)|The MIT License|MIT license</licenseMerge>
|
||||||
|
<licenseMerge>LGPL 2.1|LGPL, version 2.1|GNU Lesser/Library General Public License version 2|GNU Lesser General Public License Version 2.1</licenseMerge>
|
||||||
|
<licenseMerge>GPLv2|GNU General Public License Version 2</licenseMerge>
|
||||||
|
<licenseMerge>GPLv2+CE|CDDL + GPLv2 with classpath exception</licenseMerge>
|
||||||
|
</licenseMerges>
|
||||||
|
<fileTemplate>${project.basedir}/src/license/template.ftl</fileTemplate>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
<profiles>
|
||||||
|
<profile>
|
||||||
|
<id>coverage</id>
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.jacoco</groupId>
|
||||||
|
<artifactId>jacoco-maven-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>prepare-agent</id>
|
||||||
|
<goals>
|
||||||
|
<goal>prepare-agent</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
<execution>
|
||||||
|
<id>report</id>
|
||||||
|
<goals>
|
||||||
|
<goal>report</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
<configuration>
|
||||||
|
<excludes>
|
||||||
|
<exclude>**/*_*</exclude>
|
||||||
|
<exclude>**/Dagger*</exclude>
|
||||||
|
</excludes>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</profile>
|
||||||
|
|
||||||
|
<profile>
|
||||||
|
<id>dependency-check</id>
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.owasp</groupId>
|
||||||
|
<artifactId>dependency-check-maven</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<cveValidForHours>24</cveValidForHours>
|
||||||
|
<failBuildOnCVSS>0</failBuildOnCVSS>
|
||||||
|
<skipTestScope>true</skipTestScope>
|
||||||
|
<detail>true</detail>
|
||||||
|
<suppressionFile>suppression.xml</suppressionFile>
|
||||||
|
</configuration>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<goals>
|
||||||
|
<goal>check</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</profile>
|
||||||
|
|
||||||
|
<profile>
|
||||||
|
<id>mac</id>
|
||||||
|
<activation>
|
||||||
|
<os>
|
||||||
|
<family>mac</family>
|
||||||
|
</os>
|
||||||
|
<property>
|
||||||
|
<name>idea.version</name>
|
||||||
|
</property>
|
||||||
|
</activation>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.cryptomator</groupId>
|
||||||
|
<artifactId>integrations-mac</artifactId>
|
||||||
|
<version>${cryptomator.integrations.mac.version}</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-assembly-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>assemble-mac</id>
|
||||||
|
<phase>package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>single</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<descriptors>
|
||||||
|
<descriptor>assembly-mac.xml</descriptor>
|
||||||
|
</descriptors>
|
||||||
|
<appendAssemblyId>false</appendAssemblyId>
|
||||||
|
<finalName>buildkit-mac</finalName>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-dependency-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>copy-mac-libs</id>
|
||||||
|
<phase>prepare-package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>copy-dependencies</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<outputDirectory>${project.build.directory}/libs</outputDirectory>
|
||||||
|
<includeGroupIds>org.openjfx</includeGroupIds>
|
||||||
|
<classifier>mac</classifier>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</profile>
|
||||||
|
|
||||||
|
<profile>
|
||||||
|
<id>linux</id>
|
||||||
|
<activation>
|
||||||
|
<os>
|
||||||
|
<family>unix</family>
|
||||||
|
<name>Linux</name>
|
||||||
|
</os>
|
||||||
|
<property>
|
||||||
|
<name>idea.version</name>
|
||||||
|
</property>
|
||||||
|
</activation>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.cryptomator</groupId>
|
||||||
|
<artifactId>integrations-linux</artifactId>
|
||||||
|
<version>${cryptomator.integrations.linux.version}</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-assembly-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>assemble-linux</id>
|
||||||
|
<phase>package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>single</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<descriptors>
|
||||||
|
<descriptor>assembly-linux.xml</descriptor>
|
||||||
|
</descriptors>
|
||||||
|
<appendAssemblyId>false</appendAssemblyId>
|
||||||
|
<finalName>buildkit-linux</finalName>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-dependency-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>copy-linux-libs</id>
|
||||||
|
<phase>prepare-package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>copy-dependencies</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<outputDirectory>${project.build.directory}/libs</outputDirectory>
|
||||||
|
<includeGroupIds>org.openjfx</includeGroupIds>
|
||||||
|
<classifier>linux</classifier>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</profile>
|
||||||
|
|
||||||
|
<profile>
|
||||||
|
<id>windows</id>
|
||||||
|
<activation>
|
||||||
|
<os>
|
||||||
|
<family>windows</family>
|
||||||
|
</os>
|
||||||
|
<property>
|
||||||
|
<name>idea.version</name>
|
||||||
|
</property>
|
||||||
|
</activation>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.cryptomator</groupId>
|
||||||
|
<artifactId>integrations-win</artifactId>
|
||||||
|
<version>${cryptomator.integrations.win.version}</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-assembly-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>assemble-win</id>
|
||||||
|
<phase>package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>single</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<descriptors>
|
||||||
|
<descriptor>assembly-win.xml</descriptor>
|
||||||
|
</descriptors>
|
||||||
|
<appendAssemblyId>false</appendAssemblyId>
|
||||||
|
<finalName>buildkit-win</finalName>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-dependency-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>copy-win-libs</id>
|
||||||
|
<phase>prepare-package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>copy-dependencies</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<outputDirectory>${project.build.directory}/libs</outputDirectory>
|
||||||
|
<includeGroupIds>org.openjfx</includeGroupIds>
|
||||||
|
<classifier>win</classifier>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</profile>
|
||||||
|
</profiles>
|
||||||
|
|
||||||
|
</project>
|
||||||
@@ -20,16 +20,16 @@ along with this program. If not, see http://www.gnu.org/licenses/.
|
|||||||
|
|
||||||
Cryptomator uses ${dependencyMap?size} third-party dependencies under the following licenses:
|
Cryptomator uses ${dependencyMap?size} third-party dependencies under the following licenses:
|
||||||
<#list licenseMap as e>
|
<#list licenseMap as e>
|
||||||
<#assign license = e.getKey()/>
|
<#assign license = e.getKey()/>
|
||||||
<#assign projects = e.getValue()/>
|
<#assign projects = e.getValue()/>
|
||||||
<#if projects?size > 0>
|
<#if projects?size > 0>
|
||||||
${license}:
|
${license}:
|
||||||
<#list projects as project>
|
<#list projects as project>
|
||||||
- ${artifactFormat(project)}
|
- ${artifactFormat(project)}
|
||||||
</#list>
|
</#list>
|
||||||
</#if>
|
</#if>
|
||||||
</#list>
|
</#list>
|
||||||
|
|
||||||
Cryptomator uses other third-party assets under the following licenses:
|
Cryptomator uses other third-party assets under the following licenses:
|
||||||
SIL OFL 1.1 License:
|
SIL OFL 1.1 License:
|
||||||
- Font Awesome 5.12.0 (https://fontawesome.com/)
|
- Font Awesome 5.12.0 (https://fontawesome.com/)
|
||||||
+33
-15
@@ -5,25 +5,30 @@
|
|||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.cryptomator.common;
|
package org.cryptomator.common;
|
||||||
|
|
||||||
|
import com.tobiasdiez.easybind.EasyBind;
|
||||||
import dagger.Module;
|
import dagger.Module;
|
||||||
import dagger.Provides;
|
import dagger.Provides;
|
||||||
import javafx.beans.binding.Binding;
|
|
||||||
import javafx.beans.binding.Bindings;
|
|
||||||
import javafx.collections.ObservableList;
|
|
||||||
import org.apache.commons.lang3.SystemUtils;
|
import org.apache.commons.lang3.SystemUtils;
|
||||||
|
import org.cryptomator.common.keychain.KeychainModule;
|
||||||
import org.cryptomator.common.settings.Settings;
|
import org.cryptomator.common.settings.Settings;
|
||||||
import org.cryptomator.common.settings.SettingsProvider;
|
import org.cryptomator.common.settings.SettingsProvider;
|
||||||
import org.cryptomator.common.vaults.Vault;
|
import org.cryptomator.common.vaults.Vault;
|
||||||
import org.cryptomator.common.vaults.VaultComponent;
|
import org.cryptomator.common.vaults.VaultComponent;
|
||||||
import org.cryptomator.common.vaults.VaultListManager;
|
import org.cryptomator.common.vaults.VaultListManager;
|
||||||
|
import org.cryptomator.common.vaults.VaultListModule;
|
||||||
|
import org.cryptomator.cryptolib.common.MasterkeyFileAccess;
|
||||||
import org.cryptomator.frontend.webdav.WebDavServer;
|
import org.cryptomator.frontend.webdav.WebDavServer;
|
||||||
import org.fxmisc.easybind.EasyBind;
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
import javafx.beans.binding.Binding;
|
||||||
|
import javafx.beans.binding.Bindings;
|
||||||
|
import javafx.collections.ObservableList;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.security.SecureRandom;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
@@ -33,7 +38,7 @@ import java.util.concurrent.ThreadPoolExecutor;
|
|||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
@Module(subcomponents = {VaultComponent.class})
|
@Module(subcomponents = {VaultComponent.class}, includes = {VaultListModule.class, KeychainModule.class})
|
||||||
public abstract class CommonsModule {
|
public abstract class CommonsModule {
|
||||||
|
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(CommonsModule.class);
|
private static final Logger LOG = LoggerFactory.getLogger(CommonsModule.class);
|
||||||
@@ -41,15 +46,34 @@ public abstract class CommonsModule {
|
|||||||
private static final int NUM_CORE_BG_THREADS = 6;
|
private static final int NUM_CORE_BG_THREADS = 6;
|
||||||
private static final long BG_THREAD_KEEPALIVE_SECONDS = 60l;
|
private static final long BG_THREAD_KEEPALIVE_SECONDS = 60l;
|
||||||
|
|
||||||
|
@SuppressWarnings("SpellCheckingInspection")
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
@Named("licensePublicKey")
|
@Named("licensePublicKey")
|
||||||
static String provideLicensePublicKey() {
|
static String provideLicensePublicKey() {
|
||||||
// in PEM format without the dash-escaped begin/end lines
|
// in PEM format without the dash-escaped begin/end lines
|
||||||
return "MIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQB7NfnqiZbg2KTmoflmZ71PbXru7oW" //
|
return """
|
||||||
+ "fmnV2yv3eDjlDfGruBrqz9TtXBZV/eYWt31xu1osIqaT12lKBvZ511aaAkIBeOEV" //
|
MIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQB7NfnqiZbg2KTmoflmZ71PbXru7oW\
|
||||||
+ "gwcBIlJr6kUw7NKzeJt7r2rrsOyQoOG2nWc/Of/NBqA3mIZRHk5Aq1YupFdD26QE" //
|
fmnV2yv3eDjlDfGruBrqz9TtXBZV/eYWt31xu1osIqaT12lKBvZ511aaAkIBeOEV\
|
||||||
+ "r0DzRyj4ixPIt38CQB8=";
|
gwcBIlJr6kUw7NKzeJt7r2rrsOyQoOG2nWc/Of/NBqA3mIZRHk5Aq1YupFdD26QE\
|
||||||
|
r0DzRyj4ixPIt38CQB8=\
|
||||||
|
""";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
static SecureRandom provideCSPRNG() {
|
||||||
|
try {
|
||||||
|
return SecureRandom.getInstanceStrong();
|
||||||
|
} catch (NoSuchAlgorithmException e) {
|
||||||
|
throw new IllegalStateException("A strong algorithm must exist in every Java platform.", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
static MasterkeyFileAccess provideMasterkeyFileAccess(SecureRandom csprng) {
|
||||||
|
return new MasterkeyFileAccess(Constants.PEPPER, csprng);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@@ -65,12 +89,6 @@ public abstract class CommonsModule {
|
|||||||
return settingsProvider.get();
|
return settingsProvider.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
|
||||||
@Singleton
|
|
||||||
static ObservableList<Vault> provideVaultList(VaultListManager vaultListManager) {
|
|
||||||
return vaultListManager.getVaultList();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
static ScheduledExecutorService provideScheduledExecutorService(ShutdownHook shutdownHook) {
|
static ScheduledExecutorService provideScheduledExecutorService(ShutdownHook shutdownHook) {
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package org.cryptomator.common;
|
||||||
|
|
||||||
|
public interface Constants {
|
||||||
|
|
||||||
|
String MASTERKEY_FILENAME = "masterkey.cryptomator";
|
||||||
|
String MASTERKEY_BACKUP_SUFFIX = ".bkup";
|
||||||
|
String VAULTCONFIG_FILENAME = "vault.cryptomator";
|
||||||
|
byte[] PEPPER = new byte[0];
|
||||||
|
|
||||||
|
}
|
||||||
+22
-7
@@ -21,14 +21,13 @@ import java.util.stream.StreamSupport;
|
|||||||
public class Environment {
|
public class Environment {
|
||||||
|
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(Environment.class);
|
private static final Logger LOG = LoggerFactory.getLogger(Environment.class);
|
||||||
private static final String USER_HOME = System.getProperty("user.home");
|
|
||||||
private static final Path RELATIVE_HOME_DIR = Paths.get("~");
|
private static final Path RELATIVE_HOME_DIR = Paths.get("~");
|
||||||
private static final Path ABSOLUTE_HOME_DIR = Paths.get(USER_HOME);
|
|
||||||
private static final char PATH_LIST_SEP = ':';
|
private static final char PATH_LIST_SEP = ':';
|
||||||
private static final int DEFAULT_MIN_PW_LENGTH = 8;
|
private static final int DEFAULT_MIN_PW_LENGTH = 8;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public Environment() {
|
public Environment() {
|
||||||
|
LOG.debug("user.home: {}", System.getProperty("user.home"));
|
||||||
LOG.debug("java.library.path: {}", System.getProperty("java.library.path"));
|
LOG.debug("java.library.path: {}", System.getProperty("java.library.path"));
|
||||||
LOG.debug("user.language: {}", System.getProperty("user.language"));
|
LOG.debug("user.language: {}", System.getProperty("user.language"));
|
||||||
LOG.debug("user.region: {}", System.getProperty("user.region"));
|
LOG.debug("user.region: {}", System.getProperty("user.region"));
|
||||||
@@ -40,6 +39,8 @@ public class Environment {
|
|||||||
LOG.debug("cryptomator.mountPointsDir: {}", System.getProperty("cryptomator.mountPointsDir"));
|
LOG.debug("cryptomator.mountPointsDir: {}", System.getProperty("cryptomator.mountPointsDir"));
|
||||||
LOG.debug("cryptomator.minPwLength: {}", System.getProperty("cryptomator.minPwLength"));
|
LOG.debug("cryptomator.minPwLength: {}", System.getProperty("cryptomator.minPwLength"));
|
||||||
LOG.debug("cryptomator.buildNumber: {}", System.getProperty("cryptomator.buildNumber"));
|
LOG.debug("cryptomator.buildNumber: {}", System.getProperty("cryptomator.buildNumber"));
|
||||||
|
LOG.debug("cryptomator.showTrayIcon: {}", System.getProperty("cryptomator.showTrayIcon"));
|
||||||
|
LOG.debug("fuse.experimental: {}", Boolean.getBoolean("fuse.experimental"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean useCustomLogbackConfig() {
|
public boolean useCustomLogbackConfig() {
|
||||||
@@ -74,6 +75,15 @@ public class Environment {
|
|||||||
return getInt("cryptomator.minPwLength", DEFAULT_MIN_PW_LENGTH);
|
return getInt("cryptomator.minPwLength", DEFAULT_MIN_PW_LENGTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean showTrayIcon() {
|
||||||
|
return Boolean.getBoolean("cryptomator.showTrayIcon");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated // TODO: remove as soon as custom mount path works properly on Win+Fuse
|
||||||
|
public boolean useExperimentalFuse() {
|
||||||
|
return Boolean.getBoolean("fuse.experimental");
|
||||||
|
}
|
||||||
|
|
||||||
private int getInt(String propertyName, int defaultValue) {
|
private int getInt(String propertyName, int defaultValue) {
|
||||||
String value = System.getProperty(propertyName);
|
String value = System.getProperty(propertyName);
|
||||||
try {
|
try {
|
||||||
@@ -87,16 +97,21 @@ public class Environment {
|
|||||||
String value = System.getProperty(propertyName);
|
String value = System.getProperty(propertyName);
|
||||||
return Optional.ofNullable(value).map(Paths::get);
|
return Optional.ofNullable(value).map(Paths::get);
|
||||||
}
|
}
|
||||||
// visible for testing
|
|
||||||
|
|
||||||
Stream<Path> getPaths(String propertyName) {
|
// visible for testing
|
||||||
|
public Path getHomeDir() {
|
||||||
|
return getPath("user.home").orElseThrow();
|
||||||
|
}
|
||||||
|
|
||||||
|
// visible for testing
|
||||||
|
public Stream<Path> getPaths(String propertyName) {
|
||||||
Stream<String> rawSettingsPaths = getRawList(propertyName, PATH_LIST_SEP);
|
Stream<String> rawSettingsPaths = getRawList(propertyName, PATH_LIST_SEP);
|
||||||
return rawSettingsPaths.filter(Predicate.not(Strings::isNullOrEmpty)).map(Paths::get).map(this::replaceHomeDir);
|
return rawSettingsPaths.filter(Predicate.not(Strings::isNullOrEmpty)).map(Paths::get).map(this::replaceHomeDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Path replaceHomeDir(Path path) {
|
private Path replaceHomeDir(Path path) {
|
||||||
if (path.startsWith(RELATIVE_HOME_DIR)) {
|
if (path.startsWith(RELATIVE_HOME_DIR)) {
|
||||||
return ABSOLUTE_HOME_DIR.resolve(RELATIVE_HOME_DIR.relativize(path));
|
return getHomeDir().resolve(RELATIVE_HOME_DIR.relativize(path));
|
||||||
} else {
|
} else {
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
@@ -108,8 +123,8 @@ public class Environment {
|
|||||||
return Stream.empty();
|
return Stream.empty();
|
||||||
} else {
|
} else {
|
||||||
Iterable<String> iter = Splitter.on(separator).split(value);
|
Iterable<String> iter = Splitter.on(separator).split(value);
|
||||||
Spliterator<String> spliter = Spliterators.spliteratorUnknownSize(iter.iterator(), Spliterator.ORDERED | Spliterator.IMMUTABLE);
|
Spliterator<String> spliterator = Spliterators.spliteratorUnknownSize(iter.iterator(), Spliterator.ORDERED | Spliterator.IMMUTABLE);
|
||||||
return StreamSupport.stream(spliter, false);
|
return StreamSupport.stream(spliterator, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+2
-2
@@ -33,8 +33,8 @@ class LicenseChecker {
|
|||||||
try {
|
try {
|
||||||
byte[] keyBytes = BaseEncoding.base64().decode(pemEncodedPublicKey);
|
byte[] keyBytes = BaseEncoding.base64().decode(pemEncodedPublicKey);
|
||||||
PublicKey key = KeyFactory.getInstance("EC").generatePublic(new X509EncodedKeySpec(keyBytes));
|
PublicKey key = KeyFactory.getInstance("EC").generatePublic(new X509EncodedKeySpec(keyBytes));
|
||||||
if (key instanceof ECPublicKey) {
|
if (key instanceof ECPublicKey k) {
|
||||||
return (ECPublicKey) key;
|
return k;
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalStateException("Key not an EC public key.");
|
throw new IllegalStateException("Key not an EC public key.");
|
||||||
}
|
}
|
||||||
+4
-4
@@ -1,15 +1,15 @@
|
|||||||
package org.cryptomator.common;
|
package org.cryptomator.common;
|
||||||
|
|
||||||
import com.auth0.jwt.interfaces.DecodedJWT;
|
import com.auth0.jwt.interfaces.DecodedJWT;
|
||||||
|
import org.cryptomator.common.settings.Settings;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Singleton;
|
||||||
import javafx.beans.binding.Bindings;
|
import javafx.beans.binding.Bindings;
|
||||||
import javafx.beans.binding.BooleanBinding;
|
import javafx.beans.binding.BooleanBinding;
|
||||||
import javafx.beans.binding.StringBinding;
|
import javafx.beans.binding.StringBinding;
|
||||||
import javafx.beans.property.ObjectProperty;
|
import javafx.beans.property.ObjectProperty;
|
||||||
import javafx.beans.property.SimpleObjectProperty;
|
import javafx.beans.property.SimpleObjectProperty;
|
||||||
import org.cryptomator.common.settings.Settings;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
import javax.inject.Singleton;
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
+7
-7
@@ -8,10 +8,10 @@
|
|||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.cryptomator.common;
|
package org.cryptomator.common;
|
||||||
|
|
||||||
import java.util.Comparator;
|
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
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>.
|
* Compares version strings according to <a href="http://semver.org/spec/v2.0.0.html">SemVer 2.0.0</a>.
|
||||||
*/
|
*/
|
||||||
@@ -60,17 +60,17 @@ public class SemVerComparator implements Comparator<String> {
|
|||||||
final int commonCompCount = Math.min(vComps1.length, vComps2.length);
|
final int commonCompCount = Math.min(vComps1.length, vComps2.length);
|
||||||
|
|
||||||
for (int i = 0; i < commonCompCount; i++) {
|
for (int i = 0; i < commonCompCount; i++) {
|
||||||
int subversionComparisionResult = 0;
|
int subversionComparisonResult = 0;
|
||||||
try {
|
try {
|
||||||
final int v1 = Integer.parseInt(vComps1[i]);
|
final int v1 = Integer.parseInt(vComps1[i]);
|
||||||
final int v2 = Integer.parseInt(vComps2[i]);
|
final int v2 = Integer.parseInt(vComps2[i]);
|
||||||
subversionComparisionResult = v1 - v2;
|
subversionComparisonResult = v1 - v2;
|
||||||
} catch (NumberFormatException ex) {
|
} catch (NumberFormatException ex) {
|
||||||
// ok, lets compare this fragment lexicographically
|
// ok, lets compare this fragment lexicographically
|
||||||
subversionComparisionResult = vComps1[i].compareTo(vComps2[i]);
|
subversionComparisonResult = vComps1[i].compareTo(vComps2[i]);
|
||||||
}
|
}
|
||||||
if (subversionComparisionResult != 0) {
|
if (subversionComparisonResult != 0) {
|
||||||
return subversionComparisionResult;
|
return subversionComparisonResult;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user