Compare commits
592 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b0028bb41a | ||
|
|
e581e1f6e4 | ||
|
|
dd9e03843a | ||
|
|
e38ce53ed5 | ||
|
|
0c21bcf847 | ||
|
|
1c6b94e640 | ||
|
|
ef1c47ab19 | ||
|
|
64ff16e895 | ||
|
|
89860d6770 | ||
|
|
91ff43a17f | ||
|
|
0f19ebc928 | ||
|
|
b48a1d5856 | ||
|
|
7776009a31 | ||
|
|
ff816035ce | ||
|
|
fe384b14f0 | ||
|
|
adeb84f44e | ||
|
|
dc2e17c5db | ||
|
|
f3d8b39ac5 | ||
|
|
3be1f2eac6 | ||
|
|
1146c8f5bf | ||
|
|
910bfb945d | ||
|
|
4e886c1c15 | ||
|
|
a4b85f1e30 | ||
|
|
7c85c9fddd | ||
|
|
68c964acaa | ||
|
|
1be64836f4 | ||
|
|
f2389189a3 | ||
|
|
bb4be6022b | ||
|
|
f85a0c5ea5 | ||
|
|
5afae04b1d | ||
|
|
d1b182d20b | ||
|
|
9e3d1caee4 | ||
|
|
9a78956b23 | ||
|
|
822655b944 | ||
|
|
6dfbe505d9 | ||
|
|
0809c2c104 | ||
|
|
e30000bd00 | ||
|
|
90a7601960 | ||
|
|
8a800c6d33 | ||
|
|
d0021c9306 | ||
|
|
97673c84da | ||
|
|
771a182235 | ||
|
|
857d725a77 | ||
|
|
25b3e0f691 | ||
|
|
d2ba7631b5 | ||
|
|
a893c78c74 | ||
|
|
5ff041aa7b | ||
|
|
096196fcd5 | ||
|
|
225073aa33 | ||
|
|
f8b26d82d8 | ||
|
|
6b98a46b94 | ||
|
|
13572b94ee | ||
|
|
999b790557 | ||
|
|
7c93d59a42 | ||
|
|
9bec2aa2f0 | ||
|
|
240e1d5813 | ||
|
|
d82f4d90c1 | ||
|
|
abc68e8ef9 | ||
|
|
660ee538ce | ||
|
|
a96144d6dc | ||
|
|
e43d192007 | ||
|
|
74a018edb8 | ||
|
|
07d0049183 | ||
|
|
5f5358ea0f | ||
|
|
36cc6552bf | ||
|
|
05b5fd2eb4 | ||
|
|
95f1e86509 | ||
|
|
378dd06274 | ||
|
|
314adeb164 | ||
|
|
cc4f8c9f8d | ||
|
|
35b0e81beb | ||
|
|
9136e3936b | ||
|
|
35aead6c0e | ||
|
|
615f3b82db | ||
|
|
baa441cb90 | ||
|
|
9ad683ca09 | ||
|
|
c2d1d12cd2 | ||
|
|
3b6bac7668 | ||
|
|
2be879548d | ||
|
|
033c346042 | ||
|
|
32a8e65fe8 | ||
|
|
b2d4d80181 | ||
|
|
56c1cb23a0 | ||
|
|
ba26f70d1a | ||
|
|
e5589e7664 | ||
|
|
4e82486784 | ||
|
|
bb1cdebaf4 | ||
|
|
01405f47c9 | ||
|
|
5e64dc9262 | ||
|
|
9c7cd943b3 | ||
|
|
7cf3166169 | ||
|
|
9bdb77a573 | ||
|
|
3b8ee5ec0d | ||
|
|
6e7e09064f | ||
|
|
dfcb450a8a | ||
|
|
b192c34c15 | ||
|
|
f813dbb690 | ||
|
|
16deafca76 | ||
|
|
647b087fa7 | ||
|
|
4bd1387b83 | ||
|
|
4e098462dc | ||
|
|
0b1c2ae72a | ||
|
|
5d3fa0a0d2 | ||
|
|
6097bca063 | ||
|
|
a6aafe7593 | ||
|
|
56d05af07a | ||
|
|
0d17345600 | ||
|
|
5df62b7422 | ||
|
|
868914feb1 | ||
|
|
1a9555d4af | ||
|
|
33c8f15e45 | ||
|
|
ed8dd01dbd | ||
|
|
2296e37e8f | ||
|
|
a0f33c7bdc | ||
|
|
f6b249836e | ||
|
|
0c92a97054 | ||
|
|
24ab152559 | ||
|
|
5f9f09d77c | ||
|
|
4d27d9e48d | ||
|
|
0b624b972a | ||
|
|
1889e12bac | ||
|
|
7648f73072 | ||
|
|
75d346ed85 | ||
|
|
dabfe7907d | ||
|
|
965976223f | ||
|
|
410f00c213 | ||
|
|
0d8b942ad4 | ||
|
|
5371015a58 | ||
|
|
2ead70e434 | ||
|
|
ffca14cb5f | ||
|
|
090d5e82df | ||
|
|
8893ddf0f7 | ||
|
|
997ec5a699 | ||
|
|
762818ee39 | ||
|
|
61c6ba8189 | ||
|
|
9cfa646bcb | ||
|
|
b4301c7d41 | ||
|
|
71b5f6a38a | ||
|
|
1c0052fe30 | ||
|
|
35862acb73 | ||
|
|
11cf64fcc7 | ||
|
|
2ab37b45cf | ||
|
|
7096fc830b | ||
|
|
39806b7d96 | ||
|
|
7a16b8cb0e | ||
|
|
2583068dbd | ||
|
|
e5d0b3a372 | ||
|
|
9a1caf1e7e | ||
|
|
af0e41e26c | ||
|
|
d3049164a9 | ||
|
|
bdfda6775d | ||
|
|
72e6e74a42 | ||
|
|
75832fbed9 | ||
|
|
811b3adb51 | ||
|
|
e710df3ba7 | ||
|
|
4ee0c3ccba | ||
|
|
036b934119 | ||
|
|
4bfd43bf4c | ||
|
|
55722d3c04 | ||
|
|
77043d8d66 | ||
|
|
002117a6e5 | ||
|
|
5aa8097cfd | ||
|
|
19e1049566 | ||
|
|
87bdc88e22 | ||
|
|
950e3ae91e | ||
|
|
a37532e1ad | ||
|
|
21ff5f311b | ||
|
|
7dd12cf0cb | ||
|
|
6f8df7a690 | ||
|
|
1ff0ef1f90 | ||
|
|
196fc10d80 | ||
|
|
7496de4cc6 | ||
|
|
02a6adf6a2 | ||
|
|
6c95575a8f | ||
|
|
39755e89a8 | ||
|
|
c5d3ca218e | ||
|
|
87a2a2a0e4 | ||
|
|
5904da2eb1 | ||
|
|
1ac0c81661 | ||
|
|
955711714d | ||
|
|
5848553a4b | ||
|
|
38758caac4 | ||
|
|
b41a1bdbf4 | ||
|
|
a400ab7f7d | ||
|
|
e5d0405882 | ||
|
|
f2137c02f7 | ||
|
|
4c61f465a3 | ||
|
|
6d22041eab | ||
|
|
752e26db6d | ||
|
|
094ec23f04 | ||
|
|
af8ff2901e | ||
|
|
628689c990 | ||
|
|
ab37221182 | ||
|
|
626892473f | ||
|
|
c621677852 | ||
|
|
6650b4848d | ||
|
|
c07c56f89b | ||
|
|
294590882f | ||
|
|
9151b9c2d6 | ||
|
|
5817468d09 | ||
|
|
31dd20999c | ||
|
|
4eb9c9bd4d | ||
|
|
150164534f | ||
|
|
2b2d8a9fab | ||
|
|
fb122cbbdb | ||
|
|
0b37857d29 | ||
|
|
15c1876687 | ||
|
|
473a6e391d | ||
|
|
13ad64e6f3 | ||
|
|
04e278249e | ||
|
|
e12c4ea1e2 | ||
|
|
acfa8632af | ||
|
|
f53c1f5605 | ||
|
|
f0f7f89ea8 | ||
|
|
059ff0647a | ||
|
|
d94e5b0620 | ||
|
|
3840bce6d7 | ||
|
|
71cd11eedf | ||
|
|
ecea04bc08 | ||
|
|
0575ee5507 | ||
|
|
8b2fa8405b | ||
|
|
7d36a50687 | ||
|
|
f7dd9d8d5b | ||
|
|
379b4f4612 | ||
|
|
4652668e1b | ||
|
|
4e02a8571e | ||
|
|
bc927a65ac | ||
|
|
90f1a1c115 | ||
|
|
c48acf6038 | ||
|
|
2640e8c890 | ||
|
|
094ec55e7f | ||
|
|
fe39bdac42 | ||
|
|
2c98d50c43 | ||
|
|
d374cff51c | ||
|
|
d9e7256804 | ||
|
|
0ef2d1523e | ||
|
|
05bad6f671 | ||
|
|
5a62cfcda1 | ||
|
|
634d38510d | ||
|
|
bf27872973 | ||
|
|
20bb5a4926 | ||
|
|
f63fb3ffa0 | ||
|
|
f11c32c606 | ||
|
|
0b4e22a952 | ||
|
|
a85dbff3a5 | ||
|
|
d2835dd577 | ||
|
|
62abc99b61 | ||
|
|
20de62cc79 | ||
|
|
731614279f | ||
|
|
2be751dc8e | ||
|
|
e0409941a3 | ||
|
|
e6a5a3c8c1 | ||
|
|
3f3590a223 | ||
|
|
c1f64d7b82 | ||
|
|
f90611c96f | ||
|
|
630e21f7c1 | ||
|
|
2e81642c0e | ||
|
|
39514b9550 | ||
|
|
2da82d5610 | ||
|
|
69f33a08b6 | ||
|
|
a05e9c7746 | ||
|
|
d8031e4f49 | ||
|
|
e6aa07ba5c | ||
|
|
173129014a | ||
|
|
8d4baa6d31 | ||
|
|
20463ce653 | ||
|
|
2617f96710 | ||
|
|
53b0614faf | ||
|
|
a01db9c448 | ||
|
|
84dc8e3696 | ||
|
|
e7b988c042 | ||
|
|
a06212af1a | ||
|
|
b217ac9456 | ||
|
|
ff8422d6c1 | ||
|
|
b51d279ba6 | ||
|
|
78e4601413 | ||
|
|
5900db10eb | ||
|
|
c9bd853032 | ||
|
|
976fcad098 | ||
|
|
5d8193c348 | ||
|
|
cc09b26818 | ||
|
|
b0247caa4c | ||
|
|
38316abeae | ||
|
|
0991dfa6bd | ||
|
|
88029663e9 | ||
|
|
3f5cb10db6 | ||
|
|
1c927722f0 | ||
|
|
c04354ba1c | ||
|
|
3335659c8d | ||
|
|
f0282b33f0 | ||
|
|
f69d461463 | ||
|
|
bcf16562fe | ||
|
|
d7412410f2 | ||
|
|
d5907477df | ||
|
|
9acfaff361 | ||
|
|
737274da59 | ||
|
|
7a0e0e6915 | ||
|
|
25847b9c83 | ||
|
|
07dd7bb93e | ||
|
|
bc9936bd92 | ||
|
|
e4428e3387 | ||
|
|
30ef0ce140 | ||
|
|
38c461ebe0 | ||
|
|
ead1776f90 | ||
|
|
0e944b2442 | ||
|
|
3bbd503308 | ||
|
|
a7b13b168e | ||
|
|
1cf8ae1bdf | ||
|
|
7da3c8e252 | ||
|
|
2edf3fb68d | ||
|
|
1e698ba81b | ||
|
|
e9034ea6fe | ||
|
|
08ebc1ce16 | ||
|
|
a80c95e1cf | ||
|
|
c3ab785d66 | ||
|
|
baef6210c1 | ||
|
|
74d4a6fa72 | ||
|
|
770e41a657 | ||
|
|
d04eb03b3c | ||
|
|
9a8224a8d6 | ||
|
|
bd072b727c | ||
|
|
93cedec32c | ||
|
|
3d8933e5f0 | ||
|
|
790f5a5f2f | ||
|
|
36bb24d580 | ||
|
|
3e08ba95cf | ||
|
|
e50f82175b | ||
|
|
5907c8b5ce | ||
|
|
9f9b5beff9 | ||
|
|
71dbd31477 | ||
|
|
9e4d17cc7c | ||
|
|
2ae14913cc | ||
|
|
a4e23eee83 | ||
|
|
0bc406b332 | ||
|
|
76a6b2407e | ||
|
|
f371067d56 | ||
|
|
d1507dffca | ||
|
|
c11cc0b979 | ||
|
|
7cc941cc84 | ||
|
|
a847339d72 | ||
|
|
46827cdaa0 | ||
|
|
183b54f9b8 | ||
|
|
e51a70f7b9 | ||
|
|
f83e97abfc | ||
|
|
92a566e73e | ||
|
|
59ade0d2ba | ||
|
|
7da368d555 | ||
|
|
e00fd648a6 | ||
|
|
f74c8420fb | ||
|
|
d2fbb8aba9 | ||
|
|
ba8aee2148 | ||
|
|
018dfd8865 | ||
|
|
be40ee3100 | ||
|
|
35f9b5ed17 | ||
|
|
8c4450246b | ||
|
|
537e7d10e6 | ||
|
|
124c7288b9 | ||
|
|
3224648bc7 | ||
|
|
9b8a11b65e | ||
|
|
6b9d72f4a2 | ||
|
|
8d50697345 | ||
|
|
f8e9d2b73a | ||
|
|
99ed78a2e6 | ||
|
|
346dab2c26 | ||
|
|
28582b2b0c | ||
|
|
2bda7e5f65 | ||
|
|
8849f6c513 | ||
|
|
6d50856c07 | ||
|
|
bdec0f9493 | ||
|
|
ab31beb1ae | ||
|
|
014d995284 | ||
|
|
69783d3606 | ||
|
|
55a0078332 | ||
|
|
346e0194d4 | ||
|
|
512f222819 | ||
|
|
006c6b3312 | ||
|
|
8c80a52ce2 | ||
|
|
5d8bf54f2f | ||
|
|
70c1eb0623 | ||
|
|
447b674469 | ||
|
|
7cb2147569 | ||
|
|
327de4d714 | ||
|
|
9b57955d72 | ||
|
|
e63198e130 | ||
|
|
03eac9006f | ||
|
|
d3402cca5e | ||
|
|
076b320e70 | ||
|
|
44180f95a5 | ||
|
|
e23ebf13b7 | ||
|
|
e0fd1a2e93 | ||
|
|
c39986b37c | ||
|
|
1e0029dc15 | ||
|
|
63bc5e4161 | ||
|
|
8c8b4da595 | ||
|
|
1a7536270a | ||
|
|
d92e3c8d7b | ||
|
|
c30aedf491 | ||
|
|
0e96a462ee | ||
|
|
3ef60cb3a0 | ||
|
|
34b7638e11 | ||
|
|
63ef932469 | ||
|
|
e09163fc72 | ||
|
|
6a737f6d7d | ||
|
|
ccc7b7b213 | ||
|
|
1e98bc6430 | ||
|
|
c63a945057 | ||
|
|
a13d9fa00f | ||
|
|
1518d5eafc | ||
|
|
c74800fd8c | ||
|
|
9e282efe28 | ||
|
|
26efc9158d | ||
|
|
e2d3d35d71 | ||
|
|
c115bf84f0 | ||
|
|
5b56d32492 | ||
|
|
2fe294ad8a | ||
|
|
1343897fa9 | ||
|
|
9b2b0e4ea6 | ||
|
|
489e775b08 | ||
|
|
0d76a45181 | ||
|
|
4787f9a462 | ||
|
|
b228e12c81 | ||
|
|
0e28100ec6 | ||
|
|
d2c1697144 | ||
|
|
b924ea8dd1 | ||
|
|
30936d3ad1 | ||
|
|
289589dce9 | ||
|
|
48734b8109 | ||
|
|
2e69a41943 | ||
|
|
f414a3ac0a | ||
|
|
81833b134c | ||
|
|
5a5b74a0d5 | ||
|
|
5a7a230193 | ||
|
|
bc5ab6252e | ||
|
|
0e4d5e0973 | ||
|
|
08e254e34c | ||
|
|
2c20796ea1 | ||
|
|
8b9d7a7e2e | ||
|
|
1a0709b02c | ||
|
|
0f386ee8d2 | ||
|
|
c0b41155e9 | ||
|
|
ddd1165728 | ||
|
|
651dbe59c8 | ||
|
|
aeb6f28f9a | ||
|
|
012eefad4e | ||
|
|
b05346d4a3 | ||
|
|
854e6e84fe | ||
|
|
20436bf07d | ||
|
|
4110e4b8cb | ||
|
|
e179edc2e0 | ||
|
|
133ef7eb16 | ||
|
|
5a98982fc2 | ||
|
|
f6e92bf597 | ||
|
|
af4a8d5ae8 | ||
|
|
c3704bbb67 | ||
|
|
8620f2f80d | ||
|
|
e0124474cf | ||
|
|
ac21b78225 | ||
|
|
dca69a5428 | ||
|
|
6b1fa0f50c | ||
|
|
3ab35dc4e0 | ||
|
|
2aa1fc1acb | ||
|
|
e6643fa4cb | ||
|
|
4848dd8502 | ||
|
|
4b08d7b4b2 | ||
|
|
839189c772 | ||
|
|
a06ff45c21 | ||
|
|
c598efcb9f | ||
|
|
878476d195 | ||
|
|
82e599fc13 | ||
|
|
79b76687a0 | ||
|
|
af5349c4cb | ||
|
|
3de35b481e | ||
|
|
008bb308e7 | ||
|
|
9b44fc4a35 | ||
|
|
3d374fc792 | ||
|
|
b51c842d18 | ||
|
|
95b595d5bf | ||
|
|
445c3f220a | ||
|
|
9644d95b9b | ||
|
|
eef9f151ef | ||
|
|
6c05a4ec25 | ||
|
|
2ea71e1feb | ||
|
|
294404750d | ||
|
|
ada957c7a3 | ||
|
|
cda747a1f5 | ||
|
|
3f9db95eba | ||
|
|
18d77f5ff5 | ||
|
|
e7e8cfe8da | ||
|
|
7abc791050 | ||
|
|
913098916e | ||
|
|
cbf1f3bd9f | ||
|
|
a0a1fe6737 | ||
|
|
cb2a702829 | ||
|
|
65f171bde0 | ||
|
|
85531e2133 | ||
|
|
17e058dce2 | ||
|
|
566f187a3d | ||
|
|
85c528ce27 | ||
|
|
9a87c8bffb | ||
|
|
ae931b2dde | ||
|
|
183be70d44 | ||
|
|
eb6e5d7a75 | ||
|
|
e1101bdd62 | ||
|
|
954cf2c0ff | ||
|
|
17c7806850 | ||
|
|
2594773a12 | ||
|
|
a0025e933a | ||
|
|
aea11afb5a | ||
|
|
e40ee1e3a8 | ||
|
|
1632af3e22 | ||
|
|
fd3793d3d7 | ||
|
|
fef65c5209 | ||
|
|
173ab8cf91 | ||
|
|
9d6cb6e044 | ||
|
|
27c5909d7f | ||
|
|
91b0943a8b | ||
|
|
a8b741bb22 | ||
|
|
4cd1a8a6a0 | ||
|
|
db501f9f72 | ||
|
|
95d98181fc | ||
|
|
3981cb95fc | ||
|
|
c80fa93515 | ||
|
|
5e2895ce33 | ||
|
|
9c5e0df719 | ||
|
|
da73fcd973 | ||
|
|
f8ae050556 | ||
|
|
d53c1211cf | ||
|
|
905ebd76ae | ||
|
|
179687490c | ||
|
|
85aff3e75a | ||
|
|
388a69fe4e | ||
|
|
4e9086a042 | ||
|
|
d6707488c8 | ||
|
|
bbcc65f149 | ||
|
|
e74b99ec65 | ||
|
|
125de3e35e | ||
|
|
9689a63bdc | ||
|
|
89b468e443 | ||
|
|
db6b6fe8fa | ||
|
|
e5718dd742 | ||
|
|
39622fe263 | ||
|
|
1d723000a9 | ||
|
|
36101fd7dd | ||
|
|
b8bb6cb55c | ||
|
|
995249e421 | ||
|
|
4533dd72ae | ||
|
|
f5c12d9ea6 | ||
|
|
ce8d58199a | ||
|
|
5556a57685 | ||
|
|
39f760e135 | ||
|
|
e8351c3246 | ||
|
|
35bf1f0f77 | ||
|
|
87039fa784 | ||
|
|
dea8e48895 | ||
|
|
4145de7662 | ||
|
|
2800c2f077 | ||
|
|
e7787ea95c | ||
|
|
e7809b405d | ||
|
|
b04b3ef924 | ||
|
|
6876b905cd | ||
|
|
371101bf69 | ||
|
|
e17ecf967d | ||
|
|
b0705a911d | ||
|
|
99c7f619e0 | ||
|
|
c4a37b2a85 | ||
|
|
c12f40ecf7 | ||
|
|
fe6055c402 | ||
|
|
d2b36c4d23 | ||
|
|
fdd29190a4 | ||
|
|
6d31d0a60e | ||
|
|
a4cb908390 | ||
|
|
b8d3c35e34 | ||
|
|
48bde677bc | ||
|
|
cafb7da93e | ||
|
|
ad6c3cb132 | ||
|
|
e1e532ed91 | ||
|
|
2afbeb1c10 | ||
|
|
598db5c83b | ||
|
|
ceddb83d2d | ||
|
|
4e70378b46 | ||
|
|
5cd7f3568e | ||
|
|
2c2f1921c1 | ||
|
|
1e5e28e2b6 | ||
|
|
41f8263a7c | ||
|
|
818a4db96e | ||
|
|
51ab260fe6 | ||
|
|
be393f7a63 | ||
|
|
28c0509886 | ||
|
|
835c9f9cac | ||
|
|
6e4e78c30e | ||
|
|
7d3ea444f4 | ||
|
|
fef8bd1e00 |
15
.editorconfig
Normal file
@@ -0,0 +1,15 @@
|
||||
# EditorConfig is awesome: http://EditorConfig.org
|
||||
|
||||
# top-most EditorConfig file
|
||||
root = true
|
||||
|
||||
# Unix-style newlines with a newline ending every file
|
||||
[*]
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
|
||||
# Set default charset
|
||||
[*.{js,ts,scss,html}]
|
||||
charset = utf-8
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
9
.eslintignore
Normal file
@@ -0,0 +1,9 @@
|
||||
dist
|
||||
build
|
||||
build-cli
|
||||
jslib
|
||||
webpack.cli.js
|
||||
webpack.main.js
|
||||
webpack.renderer.js
|
||||
|
||||
**/node_modules
|
||||
32
.eslintrc.json
Normal file
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"root": true,
|
||||
"env": {
|
||||
"browser": true,
|
||||
"node": true
|
||||
},
|
||||
"extends": ["./jslib/shared/eslintrc.json"],
|
||||
"rules": {
|
||||
"import/order": [
|
||||
"error",
|
||||
{
|
||||
"alphabetize": {
|
||||
"order": "asc"
|
||||
},
|
||||
"newlines-between": "always",
|
||||
"pathGroups": [
|
||||
{
|
||||
"pattern": "jslib-*/**",
|
||||
"group": "external",
|
||||
"position": "after"
|
||||
},
|
||||
{
|
||||
"pattern": "src/**/*",
|
||||
"group": "parent",
|
||||
"position": "before"
|
||||
}
|
||||
],
|
||||
"pathGroupsExcludedImportTypes": ["builtin"]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
2
.git-blame-ignore-revs
Normal file
@@ -0,0 +1,2 @@
|
||||
# Apply Prettier https://github.com/bitwarden/directory-connector/pull/194
|
||||
096196fcd512944d1c3d9c007647a1319b032639
|
||||
33
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
## Type of change
|
||||
|
||||
- [ ] Bug fix
|
||||
- [ ] New feature development
|
||||
- [ ] Tech debt (refactoring, code cleanup, dependency upgrades, etc)
|
||||
- [ ] Build/deploy pipeline (DevOps)
|
||||
- [ ] Other
|
||||
|
||||
## Objective
|
||||
|
||||
<!--Describe what the purpose of this PR is. For example: what bug you're fixing or what new feature you're adding-->
|
||||
|
||||
## Code changes
|
||||
|
||||
<!--Explain the changes you've made to each file or major component. This should help the reviewer understand your changes-->
|
||||
<!--Also refer to any related changes or PRs in other repositories-->
|
||||
|
||||
- **file.ext:** Description of what was changed and why
|
||||
|
||||
## Screenshots
|
||||
|
||||
<!--Required for any UI changes. Delete if not applicable-->
|
||||
|
||||
## Testing requirements
|
||||
|
||||
<!--What functionality requires testing by QA? This includes testing new behavior and regression testing-->
|
||||
|
||||
## Before you submit
|
||||
|
||||
- [ ] I have checked for **linting** errors (`npm run lint`) (required)
|
||||
- [ ] I have added **unit tests** where it makes sense to do so (encouraged but not required)
|
||||
- [ ] This change requires a **documentation update** (notify the documentation team)
|
||||
- [ ] This change has particular **deployment requirements** (notify the DevOps team)
|
||||
BIN
.github/secrets/devid-app-cert.p12.gpg
vendored
Normal file
BIN
.github/secrets/devid-installer-cert.p12.gpg
vendored
Normal file
BIN
.github/secrets/macdev-cert.p12.gpg
vendored
Normal file
690
.github/workflows/build.yml
vendored
Normal file
@@ -0,0 +1,690 @@
|
||||
---
|
||||
name: Build
|
||||
|
||||
on:
|
||||
push:
|
||||
branches-ignore:
|
||||
- 'l10n_master'
|
||||
paths-ignore:
|
||||
- '.github/workflows/**'
|
||||
|
||||
|
||||
jobs:
|
||||
cloc:
|
||||
name: CLOC
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f # v2.3.4
|
||||
|
||||
- name: Set up CLOC
|
||||
run: |
|
||||
sudo apt update
|
||||
sudo apt -y install cloc
|
||||
|
||||
- name: Print lines of code
|
||||
run: cloc --include-lang TypeScript,JavaScript,HTML,Sass,CSS --vcs git
|
||||
|
||||
|
||||
setup:
|
||||
name: Setup
|
||||
runs-on: ubuntu-20.04
|
||||
outputs:
|
||||
package_version: ${{ steps.retrieve-version.outputs.package_version }}
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f # v2.3.4
|
||||
|
||||
- name: Get Package Version
|
||||
id: retrieve-version
|
||||
run: |
|
||||
PKG_VERSION=$(jq -r .version src/package.json)
|
||||
echo "::set-output name=package_version::$PKG_VERSION"
|
||||
|
||||
|
||||
linux-cli:
|
||||
name: Build Linux CLI
|
||||
runs-on: ubuntu-20.04
|
||||
needs: setup
|
||||
env:
|
||||
_PACKAGE_VERSION: ${{ needs.setup.outputs.package_version }}
|
||||
_PKG_FETCH_NODE_VERSION: 16.13.0
|
||||
_PKG_FETCH_VERSION: 3.2
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f # v2.3.4
|
||||
|
||||
- name: Set up Node
|
||||
uses: actions/setup-node@46071b5c7a2e0c34e49c3cb8a0e792e86e18d5ea
|
||||
with:
|
||||
node-version: '16'
|
||||
|
||||
- name: Update NPM
|
||||
run: |
|
||||
npm install -g node-gyp
|
||||
node-gyp install $(node -v)
|
||||
|
||||
- name: Get pkg-fetch
|
||||
run: |
|
||||
cd $HOME
|
||||
fetchedUrl="https://github.com/vercel/pkg-fetch/releases/download/v$_PKG_FETCH_VERSION/node-v$_PKG_FETCH_NODE_VERSION-linux-x64"
|
||||
|
||||
mkdir -p .pkg-cache/v$_PKG_FETCH_VERSION
|
||||
wget $fetchedUrl -O "./.pkg-cache/v$_PKG_FETCH_VERSION/fetched-v$_PKG_FETCH_NODE_VERSION-linux-x64"
|
||||
|
||||
- name: Keytar
|
||||
run: |
|
||||
keytarVersion=$(cat src/package.json | jq -r '.dependencies.keytar')
|
||||
keytarTar="keytar-v$keytarVersion-napi-v3-linux-x64.tar"
|
||||
|
||||
keytarTarGz="$keytarTar.gz"
|
||||
keytarUrl="https://github.com/atom/node-keytar/releases/download/v$keytarVersion/$keytarTarGz"
|
||||
|
||||
mkdir -p ./keytar/linux
|
||||
wget $keytarUrl -O ./keytar/linux/$keytarTarGz
|
||||
tar -xvf ./keytar/linux/$keytarTarGz -C ./keytar/linux
|
||||
|
||||
- name: Install
|
||||
run: npm install
|
||||
|
||||
- name: Package CLI
|
||||
run: npm run dist:cli:lin
|
||||
|
||||
- name: Zip
|
||||
run: |
|
||||
zip -j ./dist-cli/bwdc-linux-$_PACKAGE_VERSION.zip ./dist-cli/linux/bwdc ./keytar/linux/build/Release/keytar.node
|
||||
|
||||
- name: Create checksums
|
||||
run: |
|
||||
sha256sum ./dist-cli/bwdc-linux-$_PACKAGE_VERSION.zip | cut -d " " -f 1 > ./dist-cli/bwdc-linux-sha256-$_PACKAGE_VERSION.txt
|
||||
|
||||
- name: Version Test
|
||||
run: |
|
||||
sudo apt install libsecret-1-0 dbus-x11 gnome-keyring
|
||||
eval $(dbus-launch --sh-syntax)
|
||||
|
||||
eval $(echo -n "" | /usr/bin/gnome-keyring-daemon --login)
|
||||
eval $(/usr/bin/gnome-keyring-daemon --components=secrets --start)
|
||||
|
||||
mkdir -p test/linux
|
||||
unzip ./dist-cli/bwdc-linux-$_PACKAGE_VERSION.zip -d ./test/linux
|
||||
|
||||
testVersion=$(./test/linux/bwdc -v)
|
||||
|
||||
echo "version: $_PACKAGE_VERSION"
|
||||
echo "testVersion: $testVersion"
|
||||
|
||||
if [ "$testVersion" != "$_PACKAGE_VERSION" ]; then
|
||||
echo "Version test failed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Upload Linux Zip to GitHub
|
||||
uses: actions/upload-artifact@ee69f02b3dfdecd58bb31b4d133da38ba6fe3700 # v2.2.3
|
||||
with:
|
||||
name: bwdc-linux-${{ env._PACKAGE_VERSION }}.zip
|
||||
path: ./dist-cli/bwdc-linux-${{ env._PACKAGE_VERSION }}.zip
|
||||
if-no-files-found: error
|
||||
|
||||
- name: Upload Linux checksum to GitHub
|
||||
uses: actions/upload-artifact@ee69f02b3dfdecd58bb31b4d133da38ba6fe3700 # v2.2.3
|
||||
with:
|
||||
name: bwdc-linux-sha256-${{ env._PACKAGE_VERSION }}.txt
|
||||
path: ./dist-cli/bwdc-linux-sha256-${{ env._PACKAGE_VERSION }}.txt
|
||||
if-no-files-found: error
|
||||
|
||||
|
||||
macos-cli:
|
||||
name: Build Mac CLI
|
||||
runs-on: macos-11
|
||||
needs: setup
|
||||
env:
|
||||
_PACKAGE_VERSION: ${{ needs.setup.outputs.package_version }}
|
||||
_PKG_FETCH_NODE_VERSION: 16.13.0
|
||||
_PKG_FETCH_VERSION: 3.2
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f # v2.3.4
|
||||
|
||||
- name: Set up Node
|
||||
uses: actions/setup-node@46071b5c7a2e0c34e49c3cb8a0e792e86e18d5ea
|
||||
with:
|
||||
node-version: '16'
|
||||
|
||||
- name: Update NPM
|
||||
run: |
|
||||
npm install -g node-gyp
|
||||
node-gyp install $(node -v)
|
||||
|
||||
- name: Get pkg-fetch
|
||||
run: |
|
||||
cd $HOME
|
||||
fetchedUrl="https://github.com/vercel/pkg-fetch/releases/download/v$_PKG_FETCH_VERSION/node-v$_PKG_FETCH_NODE_VERSION-macos-x64"
|
||||
|
||||
mkdir -p .pkg-cache/v$_PKG_FETCH_VERSION
|
||||
wget $fetchedUrl -O "./.pkg-cache/v$_PKG_FETCH_VERSION/fetched-v$_PKG_FETCH_NODE_VERSION-macos-x64"
|
||||
|
||||
- name: Keytar
|
||||
run: |
|
||||
keytarVersion=$(cat src/package.json | jq -r '.dependencies.keytar')
|
||||
keytarTar="keytar-v$keytarVersion-napi-v3-darwin-x64.tar"
|
||||
|
||||
keytarTarGz="$keytarTar.gz"
|
||||
keytarUrl="https://github.com/atom/node-keytar/releases/download/v$keytarVersion/$keytarTarGz"
|
||||
|
||||
mkdir -p ./keytar/macos
|
||||
wget $keytarUrl -O ./keytar/macos/$keytarTarGz
|
||||
tar -xvf ./keytar/macos/$keytarTarGz -C ./keytar/macos
|
||||
|
||||
- name: Install
|
||||
run: npm install
|
||||
|
||||
- name: Package CLI
|
||||
run: npm run dist:cli:mac
|
||||
|
||||
- name: Zip
|
||||
run: |
|
||||
zip -j ./dist-cli/bwdc-macos-$_PACKAGE_VERSION.zip ./dist-cli/macos/bwdc ./keytar/macos/build/Release/keytar.node
|
||||
|
||||
- name: Create checksums
|
||||
run: |
|
||||
sha256sum ./dist-cli/bwdc-macos-$_PACKAGE_VERSION.zip | cut -d " " -f 1 > ./dist-cli/bwdc-macos-sha256-$_PACKAGE_VERSION.txt
|
||||
|
||||
- name: Version Test
|
||||
run: |
|
||||
mkdir -p test/macos
|
||||
unzip ./dist-cli/bwdc-macos-$_PACKAGE_VERSION.zip -d ./test/macos
|
||||
|
||||
testVersion=$(./test/macos/bwdc -v)
|
||||
|
||||
echo "version: $_PACKAGE_VERSION"
|
||||
echo "testVersion: $testVersion"
|
||||
|
||||
if [ "$testVersion" != "$_PACKAGE_VERSION" ]; then
|
||||
echo "Version test failed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Upload Mac Zip to GitHub
|
||||
uses: actions/upload-artifact@ee69f02b3dfdecd58bb31b4d133da38ba6fe3700 # v2.2.3
|
||||
with:
|
||||
name: bwdc-macos-${{ env._PACKAGE_VERSION }}.zip
|
||||
path: ./dist-cli/bwdc-macos-${{ env._PACKAGE_VERSION }}.zip
|
||||
if-no-files-found: error
|
||||
|
||||
- name: Upload Mac checksum to GitHub
|
||||
uses: actions/upload-artifact@ee69f02b3dfdecd58bb31b4d133da38ba6fe3700 # v2.2.3
|
||||
with:
|
||||
name: bwdc-macos-sha256-${{ env._PACKAGE_VERSION }}.txt
|
||||
path: ./dist-cli/bwdc-macos-sha256-${{ env._PACKAGE_VERSION }}.txt
|
||||
if-no-files-found: error
|
||||
|
||||
|
||||
windows-cli:
|
||||
name: Build Windows CLI
|
||||
runs-on: windows-2019
|
||||
needs: setup
|
||||
env:
|
||||
_PACKAGE_VERSION: ${{ needs.setup.outputs.package_version }}
|
||||
_WIN_PKG_FETCH_VERSION: 16.13.0
|
||||
_WIN_PKG_VERSION: 3.2
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f # v2.3.4
|
||||
|
||||
- name: Setup Windows builder
|
||||
run: |
|
||||
choco install checksum --no-progress
|
||||
choco install reshack --no-progress
|
||||
|
||||
- name: Set up Node
|
||||
uses: actions/setup-node@46071b5c7a2e0c34e49c3cb8a0e792e86e18d5ea
|
||||
with:
|
||||
node-version: '16'
|
||||
|
||||
- name: Update NPM
|
||||
run: |
|
||||
npm install -g node-gyp
|
||||
node-gyp install $(node -v)
|
||||
|
||||
- name: Get pkg-fetch
|
||||
shell: pwsh
|
||||
run: |
|
||||
cd $HOME
|
||||
$fetchedUrl = "https://github.com/vercel/pkg-fetch/releases/download/v$env:_WIN_PKG_VERSION/node-v$env:_WIN_PKG_FETCH_VERSION-win-x64"
|
||||
|
||||
New-Item -ItemType directory -Path ./.pkg-cache
|
||||
New-Item -ItemType directory -Path ./.pkg-cache/v$env:_WIN_PKG_VERSION
|
||||
Invoke-RestMethod -Uri $fetchedUrl `
|
||||
-OutFile "./.pkg-cache/v$env:_WIN_PKG_VERSION/fetched-v$env:_WIN_PKG_FETCH_VERSION-win-x64"
|
||||
|
||||
- name: Keytar
|
||||
shell: pwsh
|
||||
run: |
|
||||
$keytarVersion = (Get-Content -Raw -Path ./src/package.json | ConvertFrom-Json).dependencies.keytar
|
||||
$keytarTar = "keytar-v${keytarVersion}-napi-v3-{0}-x64.tar"
|
||||
$keytarTarGz = "${keytarTar}.gz"
|
||||
$keytarUrl = "https://github.com/atom/node-keytar/releases/download/v${keytarVersion}/${keytarTarGz}"
|
||||
|
||||
New-Item -ItemType directory -Path ./keytar/windows | Out-Null
|
||||
|
||||
Invoke-RestMethod -Uri $($keytarUrl -f "win32") -OutFile "./keytar/windows/$($keytarTarGz -f "win32")"
|
||||
|
||||
7z e "./keytar/windows/$($keytarTarGz -f "win32")" -o"./keytar/windows"
|
||||
|
||||
7z e "./keytar/windows/$($keytarTar -f "win32")" -o"./keytar/windows"
|
||||
|
||||
- name: Setup Version Info
|
||||
shell: pwsh
|
||||
run: |
|
||||
$major, $minor, $patch = $env:_PACKAGE_VERSION.split('.')
|
||||
|
||||
$versionInfo = @"
|
||||
|
||||
1 VERSIONINFO
|
||||
FILEVERSION $major,$minor,$patch,0
|
||||
PRODUCTVERSION $major,$minor,$patch,0
|
||||
FILEOS 0x40004
|
||||
FILETYPE 0x1
|
||||
{
|
||||
BLOCK "StringFileInfo"
|
||||
{
|
||||
BLOCK "040904b0"
|
||||
{
|
||||
VALUE "CompanyName", "Bitwarden Inc."
|
||||
VALUE "ProductName", "Bitwarden"
|
||||
VALUE "FileDescription", "Bitwarden Directory Connector CLI"
|
||||
VALUE "FileVersion", "$env:_PACKAGE_VERSION"
|
||||
VALUE "ProductVersion", "$env:_PACKAGE_VERSION"
|
||||
VALUE "OriginalFilename", "bwdc.exe"
|
||||
VALUE "InternalName", "bwdc"
|
||||
VALUE "LegalCopyright", "Copyright Bitwarden Inc."
|
||||
}
|
||||
}
|
||||
|
||||
BLOCK "VarFileInfo"
|
||||
{
|
||||
VALUE "Translation", 0x0409 0x04B0
|
||||
}
|
||||
}
|
||||
"@
|
||||
|
||||
$versionInfo | Out-File ./version-info.rc
|
||||
|
||||
- name: Resource Hacker
|
||||
shell: cmd
|
||||
run: |
|
||||
set PATH=%PATH%;C:\Program Files (x86)\Resource Hacker
|
||||
set WIN_PKG=C:\Users\runneradmin\.pkg-cache\v%_WIN_PKG_VERSION%\fetched-v%_WIN_PKG_FETCH_VERSION%-win-x64
|
||||
set WIN_PKG_BUILT=C:\Users\runneradmin\.pkg-cache\v%_WIN_PKG_VERSION%\built-v%_WIN_PKG_FETCH_VERSION%-win-x64
|
||||
|
||||
ResourceHacker -open %WIN_PKG% -save %WIN_PKG% -action delete -mask ICONGROUP,1,
|
||||
ResourceHacker -open version-info.rc -save version-info.res -action compile
|
||||
ResourceHacker -open %WIN_PKG% -save %WIN_PKG% -action addoverwrite -resource version-info.res
|
||||
|
||||
- name: Install
|
||||
run: npm install
|
||||
|
||||
- name: Package CLI
|
||||
run: npm run dist:cli:win
|
||||
|
||||
- name: Zip
|
||||
shell: cmd
|
||||
run: |
|
||||
7z a ./dist-cli/bwdc-windows-%_PACKAGE_VERSION%.zip ./dist-cli/windows/bwdc.exe ./keytar/windows/keytar.node
|
||||
|
||||
- name: Version Test
|
||||
run: |
|
||||
Expand-Archive -Path "./dist-cli/bwdc-windows-${env:_PACKAGE_VERSION}.zip" -DestinationPath "./test/windows"
|
||||
$testVersion = Invoke-Expression '& ./test/windows/bwdc.exe -v'
|
||||
echo "version: $env:_PACKAGE_VERSION"
|
||||
echo "testVersion: $testVersion"
|
||||
if($testVersion -ne $env:_PACKAGE_VERSION) {
|
||||
Throw "Version test failed."
|
||||
}
|
||||
|
||||
- name: Create checksums
|
||||
run: |
|
||||
checksum -f="./dist-cli/bwdc-windows-${env:_PACKAGE_VERSION}.zip" `
|
||||
-t sha256 | Out-File ./dist-cli/bwdc-windows-sha256-${env:_PACKAGE_VERSION}.txt
|
||||
|
||||
- name: Upload Windows Zip to GitHub
|
||||
uses: actions/upload-artifact@ee69f02b3dfdecd58bb31b4d133da38ba6fe3700 # v2.2.3
|
||||
with:
|
||||
name: bwdc-windows-${{ env._PACKAGE_VERSION }}.zip
|
||||
path: ./dist-cli/bwdc-windows-${{ env._PACKAGE_VERSION }}.zip
|
||||
if-no-files-found: error
|
||||
|
||||
- name: Upload Windows checksum to GitHub
|
||||
uses: actions/upload-artifact@ee69f02b3dfdecd58bb31b4d133da38ba6fe3700 # v2.2.3
|
||||
with:
|
||||
name: bwdc-windows-sha256-${{ env._PACKAGE_VERSION }}.txt
|
||||
path: ./dist-cli/bwdc-windows-sha256-${{ env._PACKAGE_VERSION }}.txt
|
||||
if-no-files-found: error
|
||||
|
||||
|
||||
windows-gui:
|
||||
name: Build Windows GUI
|
||||
runs-on: windows-2019
|
||||
needs: setup
|
||||
env:
|
||||
_PACKAGE_VERSION: ${{ needs.setup.outputs.package_version }}
|
||||
steps:
|
||||
- name: Set up .NET
|
||||
uses: actions/setup-dotnet@a71d1eb2c86af85faa8c772c03fb365e377e45ea
|
||||
with:
|
||||
dotnet-version: "3.1.x"
|
||||
|
||||
- name: Set up Node
|
||||
uses: actions/setup-node@46071b5c7a2e0c34e49c3cb8a0e792e86e18d5ea
|
||||
with:
|
||||
node-version: '16'
|
||||
|
||||
- name: Update NPM
|
||||
run: |
|
||||
npm install -g node-gyp
|
||||
node-gyp install $(node -v)
|
||||
|
||||
- name: Set Node options
|
||||
run: echo "NODE_OPTIONS=--max_old_space_size=4096" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
|
||||
shell: pwsh
|
||||
|
||||
- name: Print environment
|
||||
run: |
|
||||
node --version
|
||||
npm --version
|
||||
dotnet --version
|
||||
|
||||
- name: Install AST
|
||||
uses: bitwarden/gh-actions/install-ast@f135c42c8596cb535c5bcb7523c0b2eef89709ac
|
||||
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f # v2.3.4
|
||||
|
||||
- name: Install Node dependencies
|
||||
run: npm install
|
||||
|
||||
# - name: Run linter
|
||||
# run: npm run lint
|
||||
|
||||
- name: Build & Sign
|
||||
run: npm run dist:win
|
||||
env:
|
||||
ELECTRON_BUILDER_SIGN: 1
|
||||
SIGNING_VAULT_URL: ${{ secrets.SIGNING_VAULT_URL }}
|
||||
SIGNING_CLIENT_ID: ${{ secrets.SIGNING_CLIENT_ID }}
|
||||
SIGNING_TENANT_ID: ${{ secrets.SIGNING_TENANT_ID }}
|
||||
SIGNING_CLIENT_SECRET: ${{ secrets.SIGNING_CLIENT_SECRET }}
|
||||
SIGNING_CERT_NAME: ${{ secrets.SIGNING_CERT_NAME }}
|
||||
|
||||
- name: Upload Portable Executable to GitHub
|
||||
uses: actions/upload-artifact@ee69f02b3dfdecd58bb31b4d133da38ba6fe3700 # v2.2.3
|
||||
with:
|
||||
name: Bitwarden-Connector-Portable-${{ env._PACKAGE_VERSION }}.exe
|
||||
path: ./dist/Bitwarden-Connector-Portable-${{ env._PACKAGE_VERSION }}.exe
|
||||
if-no-files-found: error
|
||||
|
||||
- name: Upload Installer Executable to GitHub
|
||||
uses: actions/upload-artifact@ee69f02b3dfdecd58bb31b4d133da38ba6fe3700 # v2.2.3
|
||||
with:
|
||||
name: Bitwarden-Connector-Installer-${{ env._PACKAGE_VERSION }}.exe
|
||||
path: ./dist/Bitwarden-Connector-Installer-${{ env._PACKAGE_VERSION }}.exe
|
||||
if-no-files-found: error
|
||||
|
||||
- name: Upload Installer Executable Blockmap to GitHub
|
||||
uses: actions/upload-artifact@ee69f02b3dfdecd58bb31b4d133da38ba6fe3700 # v2.2.3
|
||||
with:
|
||||
name: Bitwarden-Connector-Installer-${{ env._PACKAGE_VERSION }}.exe.blockmap
|
||||
path: ./dist/Bitwarden-Connector-Installer-${{ env._PACKAGE_VERSION }}.exe.blockmap
|
||||
if-no-files-found: error
|
||||
|
||||
- name: Upload latest auto-update artifact
|
||||
uses: actions/upload-artifact@ee69f02b3dfdecd58bb31b4d133da38ba6fe3700 # v2.2.3
|
||||
with:
|
||||
name: latest.yml
|
||||
path: ./dist/latest.yml
|
||||
if-no-files-found: error
|
||||
|
||||
|
||||
linux-gui:
|
||||
name: Build Linux GUI
|
||||
runs-on: ubuntu-20.04
|
||||
needs: setup
|
||||
env:
|
||||
_PACKAGE_VERSION: ${{ needs.setup.outputs.package_version }}
|
||||
steps:
|
||||
- name: Set up Node
|
||||
uses: actions/setup-node@46071b5c7a2e0c34e49c3cb8a0e792e86e18d5ea
|
||||
with:
|
||||
node-version: '16'
|
||||
|
||||
- name: Update NPM
|
||||
run: |
|
||||
npm install -g node-gyp
|
||||
node-gyp install $(node -v)
|
||||
|
||||
- name: Set Node options
|
||||
run: echo "NODE_OPTIONS=--max_old_space_size=4096" >> $GITHUB_ENV
|
||||
|
||||
- name: Set up environment
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get -y install pkg-config libxss-dev libsecret-1-dev
|
||||
sudo apt-get -y install rpm
|
||||
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f # v2.3.4
|
||||
|
||||
- name: NPM Install
|
||||
run: npm install
|
||||
|
||||
- name: NPM Rebuild
|
||||
run: npm run rebuild
|
||||
|
||||
- name: NPM Package
|
||||
run: npm run dist:lin
|
||||
|
||||
- name: Upload AppImage
|
||||
uses: actions/upload-artifact@ee69f02b3dfdecd58bb31b4d133da38ba6fe3700 # v2.2.3
|
||||
with:
|
||||
name: Bitwarden-Connector-${{ env._PACKAGE_VERSION }}-x86_64.AppImage
|
||||
path: ./dist/Bitwarden-Connector-${{ env._PACKAGE_VERSION }}-x86_64.AppImage
|
||||
if-no-files-found: error
|
||||
|
||||
- name: Upload latest auto-update artifact
|
||||
uses: actions/upload-artifact@ee69f02b3dfdecd58bb31b4d133da38ba6fe3700 # v2.2.3
|
||||
with:
|
||||
name: latest-linux.yml
|
||||
path: ./dist/latest-linux.yml
|
||||
if-no-files-found: error
|
||||
|
||||
|
||||
macos-gui:
|
||||
name: Build MacOS GUI
|
||||
runs-on: macos-11
|
||||
needs: setup
|
||||
env:
|
||||
_PACKAGE_VERSION: ${{ needs.setup.outputs.package_version }}
|
||||
steps:
|
||||
- name: Set up Node
|
||||
uses: actions/setup-node@46071b5c7a2e0c34e49c3cb8a0e792e86e18d5ea
|
||||
with:
|
||||
node-version: '16'
|
||||
|
||||
- name: Update NPM
|
||||
run: |
|
||||
npm install -g node-gyp
|
||||
node-gyp install $(node -v)
|
||||
|
||||
- name: Set Node options
|
||||
run: echo "NODE_OPTIONS=--max_old_space_size=4096" >> $GITHUB_ENV
|
||||
|
||||
- name: Print environment
|
||||
run: |
|
||||
node --version
|
||||
npm --version
|
||||
echo "GitHub ref: $GITHUB_REF"
|
||||
echo "GitHub event: $GITHUB_EVENT"
|
||||
shell: bash
|
||||
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f # v2.3.4
|
||||
|
||||
- name: Decrypt secrets
|
||||
env:
|
||||
DECRYPT_FILE_PASSWORD: ${{ secrets.DECRYPT_FILE_PASSWORD }}
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir -p $HOME/secrets
|
||||
|
||||
gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \
|
||||
--output "$HOME/secrets/devid-app-cert.p12" \
|
||||
"$GITHUB_WORKSPACE/.github/secrets/devid-app-cert.p12.gpg"
|
||||
|
||||
gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \
|
||||
--output "$HOME/secrets/devid-installer-cert.p12" \
|
||||
"$GITHUB_WORKSPACE/.github/secrets/devid-installer-cert.p12.gpg"
|
||||
|
||||
gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \
|
||||
--output "$HOME/secrets/macdev-cert.p12" \
|
||||
"$GITHUB_WORKSPACE/.github/secrets/macdev-cert.p12.gpg"
|
||||
|
||||
- name: Set up keychain
|
||||
env:
|
||||
KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }}
|
||||
DEVID_CERT_PASSWORD: ${{ secrets.DEVID_CERT_PASSWORD }}
|
||||
MACDEV_CERT_PASSWORD: ${{ secrets.MACDEV_CERT_PASSWORD }}
|
||||
shell: bash
|
||||
run: |
|
||||
security create-keychain -p $KEYCHAIN_PASSWORD build.keychain
|
||||
security default-keychain -s build.keychain
|
||||
security unlock-keychain -p $KEYCHAIN_PASSWORD build.keychain
|
||||
security set-keychain-settings -lut 1200 build.keychain
|
||||
security import "$HOME/secrets/devid-app-cert.p12" -k build.keychain -P $DEVID_CERT_PASSWORD \
|
||||
-T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild
|
||||
security import "$HOME/secrets/devid-installer-cert.p12" -k build.keychain -P $DEVID_CERT_PASSWORD \
|
||||
-T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild
|
||||
security import "$HOME/secrets/macdev-cert.p12" -k build.keychain -P $MACDEV_CERT_PASSWORD \
|
||||
-T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild
|
||||
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k $KEYCHAIN_PASSWORD build.keychain
|
||||
|
||||
- name: Load package version
|
||||
run: |
|
||||
$rootPath = $env:GITHUB_WORKSPACE;
|
||||
$packageVersion = (Get-Content -Raw -Path $rootPath\src\package.json | ConvertFrom-Json).version;
|
||||
|
||||
Write-Output "Setting package version to $packageVersion";
|
||||
Write-Output "PACKAGE_VERSION=$packageVersion" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append;
|
||||
shell: pwsh
|
||||
|
||||
- name: Install Node dependencies
|
||||
run: npm install
|
||||
|
||||
# - name: Run linter
|
||||
# run: npm run lint
|
||||
|
||||
- name: Build application
|
||||
run: npm run dist:mac
|
||||
env:
|
||||
APPLE_ID_USERNAME: ${{ secrets.APPLE_ID_USERNAME }}
|
||||
APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }}
|
||||
|
||||
- name: Rename Zip Artifact
|
||||
run: |
|
||||
cd dist
|
||||
mv "Bitwarden Directory Connector-${{ env._PACKAGE_VERSION }}-mac.zip" \
|
||||
"Bitwarden-Connector-${{ env._PACKAGE_VERSION }}-mac.zip"
|
||||
|
||||
- name: Upload .zip artifact
|
||||
uses: actions/upload-artifact@ee69f02b3dfdecd58bb31b4d133da38ba6fe3700 # v2.2.3
|
||||
with:
|
||||
name: Bitwarden-Connector-${{ env._PACKAGE_VERSION }}-mac.zip
|
||||
path: ./dist/Bitwarden-Connector-${{ env._PACKAGE_VERSION }}-mac.zip
|
||||
if-no-files-found: error
|
||||
|
||||
- name: Upload .dmg artifact
|
||||
uses: actions/upload-artifact@ee69f02b3dfdecd58bb31b4d133da38ba6fe3700 # v2.2.3
|
||||
with:
|
||||
name: Bitwarden-Connector-${{ env._PACKAGE_VERSION }}.dmg
|
||||
path: ./dist/Bitwarden-Connector-${{ env._PACKAGE_VERSION }}.dmg
|
||||
if-no-files-found: error
|
||||
|
||||
- name: Upload .dmg Blockmap artifact
|
||||
uses: actions/upload-artifact@ee69f02b3dfdecd58bb31b4d133da38ba6fe3700 # v2.2.3
|
||||
with:
|
||||
name: Bitwarden-Connector-${{ env._PACKAGE_VERSION }}.dmg.blockmap
|
||||
path: ./dist/Bitwarden-Connector-${{ env._PACKAGE_VERSION }}.dmg.blockmap
|
||||
if-no-files-found: error
|
||||
|
||||
- name: Upload latest auto-update artifact
|
||||
uses: actions/upload-artifact@ee69f02b3dfdecd58bb31b4d133da38ba6fe3700 # v2.2.3
|
||||
with:
|
||||
name: latest-mac.yml
|
||||
path: ./dist/latest-mac.yml
|
||||
if-no-files-found: error
|
||||
|
||||
|
||||
check-failures:
|
||||
name: Check for failures
|
||||
runs-on: ubuntu-20.04
|
||||
needs:
|
||||
- cloc
|
||||
- setup
|
||||
- linux-cli
|
||||
- macos-cli
|
||||
- windows-cli
|
||||
- windows-gui
|
||||
- linux-gui
|
||||
- macos-gui
|
||||
steps:
|
||||
- name: Check if any job failed
|
||||
if: ${{ (github.ref == 'refs/heads/master') || (github.ref == 'refs/heads/rc') }}
|
||||
env:
|
||||
CLOC_STATUS: ${{ needs.cloc.result }}
|
||||
SETUP_STATUS: ${{ needs.setup.result }}
|
||||
LINUX_CLI_STATUS: ${{ needs.linux-cli.result }}
|
||||
MACOS_CLI_STATUS: ${{ needs.macos-cli.result }}
|
||||
WINDOWS_CLI_STATUS: ${{ needs.windows-cli.result }}
|
||||
WINDOWS_GUI_STATUS: ${{ needs.windows-gui.result }}
|
||||
LINUX_GUI_STATUS: ${{ needs.linux-gui.result }}
|
||||
MACOS_GUI_STATUS: ${{ needs.macos-gui.result }}
|
||||
run: |
|
||||
if [ "$CLOC_STATUS" = "failure" ]; then
|
||||
exit 1
|
||||
elif [ "$SETUP_STATUS" = "failure" ]; then
|
||||
exit 1
|
||||
elif [ "$LINUX_CLI_STATUS" = "failure" ]; then
|
||||
exit 1
|
||||
elif [ "$MACOS_CLI_STATUS" = "failure" ]; then
|
||||
exit 1
|
||||
elif [ "$WINDOWS_CLI_STATUS" = "failure" ]; then
|
||||
exit 1
|
||||
elif [ "$WINDOWS_GUI_STATUS" = "failure" ]; then
|
||||
exit 1
|
||||
elif [ "$LINUX_GUI_STATUS" = "failure" ]; then
|
||||
exit 1
|
||||
elif [ "$MACOS_GUI_STATUS" = "failure" ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Login to Azure - Prod Subscription
|
||||
uses: Azure/login@77f1b2e3fb80c0e8645114159d17008b8a2e475a
|
||||
if: failure()
|
||||
with:
|
||||
creds: ${{ secrets.AZURE_PROD_KV_CREDENTIALS }}
|
||||
|
||||
- name: Retrieve secrets
|
||||
id: retrieve-secrets
|
||||
uses: Azure/get-keyvault-secrets@80ccd3fafe5662407cc2e55f202ee34bfff8c403
|
||||
if: failure()
|
||||
with:
|
||||
keyvault: "bitwarden-prod-kv"
|
||||
secrets: "devops-alerts-slack-webhook-url"
|
||||
|
||||
- name: Notify Slack on failure
|
||||
uses: act10ns/slack@e4e71685b9b239384b0f676a63c32367f59c2522 # v1.2.2
|
||||
if: failure()
|
||||
env:
|
||||
SLACK_WEBHOOK_URL: ${{ steps.retrieve-secrets.outputs.devops-alerts-slack-webhook-url }}
|
||||
with:
|
||||
status: ${{ job.status }}
|
||||
16
.github/workflows/enforce-labels.yml
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
---
|
||||
name: Enforce PR labels
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [labeled, unlabeled, opened, edited, synchronize]
|
||||
jobs:
|
||||
enforce-label:
|
||||
name: EnforceLabel
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- name: Enforce Label
|
||||
uses: yogevbd/enforce-label-action@8d1e1709b1011e6d90400a0e6cf7c0b77aa5efeb
|
||||
with:
|
||||
BANNED_LABELS: "hold"
|
||||
BANNED_LABELS_DESCRIPTION: "PRs on hold cannot be merged"
|
||||
97
.github/workflows/release.yml
vendored
Normal file
@@ -0,0 +1,97 @@
|
||||
---
|
||||
name: Release
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
release_type:
|
||||
description: 'Release Options'
|
||||
required: true
|
||||
default: 'Initial Release'
|
||||
type: choice
|
||||
options:
|
||||
- Initial Release
|
||||
- Redeploy
|
||||
- Dry Run
|
||||
|
||||
jobs:
|
||||
setup:
|
||||
name: Setup
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- name: Branch check
|
||||
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
|
||||
run: |
|
||||
if [[ "$GITHUB_REF" != "refs/heads/rc" ]] && [[ "$GITHUB_REF" != "refs/heads/hotfix-rc" ]]; then
|
||||
echo "==================================="
|
||||
echo "[!] Can only release from the 'rc' or 'hotfix-rc' branches"
|
||||
echo "==================================="
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
|
||||
|
||||
- name: Retrieve Directory Connector release version
|
||||
id: retrieve-version
|
||||
run: |
|
||||
PKG_VERSION=$(jq -r .version src/package.json)
|
||||
echo "::set-output name=package_version::$PKG_VERSION"
|
||||
|
||||
- name: Check to make sure Mobile release version has been bumped
|
||||
if: ${{ github.event.inputs.release_type == 'Initial Release' }}
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
latest_ver=$(hub release -L 1 -f '%T')
|
||||
latest_ver=${latest_ver:1}
|
||||
echo "Latest version: $latest_ver"
|
||||
ver=${{ steps.retrieve-version.outputs.package_version }}
|
||||
echo "Version: $ver"
|
||||
if [ "$latest_ver" = "$ver" ]; then
|
||||
echo "Version has not been bumped!"
|
||||
exit 1
|
||||
fi
|
||||
shell: bash
|
||||
|
||||
- name: Get branch name
|
||||
id: branch
|
||||
run: |
|
||||
BRANCH_NAME=$(basename ${{ github.ref }})
|
||||
echo "::set-output name=branch-name::$BRANCH_NAME"
|
||||
|
||||
- name: Download all artifacts
|
||||
uses: bitwarden/gh-actions/download-artifacts@23433be15ed6fd046ce12b6889c5184a8d9c8783
|
||||
with:
|
||||
workflow: build.yml
|
||||
workflow_conclusion: success
|
||||
branch: ${{ steps.branch.outputs.branch-name }}
|
||||
|
||||
- name: Create release
|
||||
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
|
||||
uses: ncipollo/release-action@40bb172bd05f266cf9ba4ff965cb61e9ee5f6d01 # v1.9.0
|
||||
env:
|
||||
PKG_VERSION: ${{ steps.retrieve-version.outputs.package_version }}
|
||||
with:
|
||||
artifacts: "./bwdc-windows-${{ env.PKG_VERSION }}.zip,
|
||||
./bwdc-macos-${{ env.PKG_VERSION }}.zip,
|
||||
./bwdc-linux-${{ env.PKG_VERSION }}.zip,
|
||||
./bwdc-windows-sha256-${{ env.PKG_VERSION }}.txt,
|
||||
./bwdc-macos-sha256-${{ env.PKG_VERSION }}.txt,
|
||||
./bwdc-linux-sha256-${{ env.PKG_VERSION }}.txt,
|
||||
./Bitwarden-Connector-Portable-${{ env.PKG_VERSION }}.exe,
|
||||
./Bitwarden-Connector-Installer-${{ env.PKG_VERSION }}.exe,
|
||||
./Bitwarden-Connector-Installer-${{ env.PKG_VERSION }}.exe.blockmap,
|
||||
./Bitwarden-Connector-${{ env.PKG_VERSION }}-x86_64.AppImage,
|
||||
./Bitwarden-Connector-${{ env.PKG_VERSION }}-mac.zip,
|
||||
./Bitwarden-Connector-${{ env.PKG_VERSION }}.dmg,
|
||||
./Bitwarden-Connector-${{ env.PKG_VERSION }}.dmg.blockmap,
|
||||
./latest-linux.yml,
|
||||
./latest-mac.yml,
|
||||
./latest.yml"
|
||||
commit: ${{ github.sha }}
|
||||
tag: v${{ env.PKG_VERSION }}
|
||||
name: Version ${{ env.PKG_VERSION }}
|
||||
body: "<insert release notes here>"
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
draft: true
|
||||
65
.github/workflows/version-bump.yml
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
---
|
||||
name: Version Bump
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
version_number:
|
||||
description: "New Version"
|
||||
required: true
|
||||
|
||||
jobs:
|
||||
bump_version:
|
||||
name: "Create version_bump_${{ github.event.inputs.version_number }} branch"
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- name: Checkout Branch
|
||||
uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
|
||||
|
||||
- name: Create Version Branch
|
||||
run: |
|
||||
git switch -c version_bump_${{ github.event.inputs.version_number }}
|
||||
git push -u origin version_bump_${{ github.event.inputs.version_number }}
|
||||
|
||||
- name: Checkout Version Branch
|
||||
uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
|
||||
with:
|
||||
ref: version_bump_${{ github.event.inputs.version_number }}
|
||||
|
||||
- name: Bump Version - Package
|
||||
uses: bitwarden/gh-actions/version-bump@03ad9a873c39cdc95dd8d77dbbda67f84db43945
|
||||
with:
|
||||
version: ${{ github.event.inputs.version_number }}
|
||||
file_path: "./src/package.json"
|
||||
|
||||
- name: Commit files
|
||||
run: |
|
||||
git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
||||
git config --local user.name "github-actions[bot]"
|
||||
git commit -m "Bumped version to ${{ github.event.inputs.version_number }}" -a
|
||||
|
||||
- name: Push changes
|
||||
run: git push -u origin version_bump_${{ github.event.inputs.version_number }}
|
||||
|
||||
- name: Create Version PR
|
||||
env:
|
||||
PR_BRANCH: "version_bump_${{ github.event.inputs.version_number }}"
|
||||
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
|
||||
BASE_BRANCH: master
|
||||
TITLE: "Bump version to ${{ github.event.inputs.version_number }}"
|
||||
run: |
|
||||
gh pr create --title "$TITLE" \
|
||||
--base "$BASE" \
|
||||
--head "$PR_BRANCH" \
|
||||
--label "version update" \
|
||||
--label "automated pr" \
|
||||
--body "
|
||||
## Type of change
|
||||
- [ ] Bug fix
|
||||
- [ ] New feature development
|
||||
- [ ] Tech debt (refactoring, code cleanup, dependency upgrades, etc)
|
||||
- [ ] Build/deploy pipeline (DevOps)
|
||||
- [X] Other
|
||||
|
||||
## Objective
|
||||
Automated version bump to ${{ github.event.inputs.version_number }}"
|
||||
11
.github/workflows/workflow-linter.yml
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
---
|
||||
name: Workflow Linter
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- .github/workflows/**
|
||||
|
||||
jobs:
|
||||
call-workflow:
|
||||
uses: bitwarden/gh-actions/.github/workflows/workflow-linter.yml@master
|
||||
276
.gitignore
vendored
@@ -1,261 +1,17 @@
|
||||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
|
||||
# User-specific files
|
||||
*.suo
|
||||
*.user
|
||||
*.userosscache
|
||||
*.sln.docstates
|
||||
|
||||
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||
*.userprefs
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Dd]ebugPublic/
|
||||
[Rr]elease/
|
||||
[Rr]eleases/
|
||||
x64/
|
||||
x86/
|
||||
bld/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
[Ll]og/
|
||||
|
||||
# Visual Studio 2015 cache/options directory
|
||||
.vs/
|
||||
# Uncomment if you have tasks that create the project's static files in wwwroot
|
||||
#wwwroot/
|
||||
|
||||
# MSTest test Results
|
||||
[Tt]est[Rr]esult*/
|
||||
[Bb]uild[Ll]og.*
|
||||
|
||||
# NUNIT
|
||||
*.VisualState.xml
|
||||
TestResult.xml
|
||||
|
||||
# Build Results of an ATL Project
|
||||
[Dd]ebugPS/
|
||||
[Rr]eleasePS/
|
||||
dlldata.c
|
||||
|
||||
# DNX
|
||||
project.lock.json
|
||||
project.fragment.lock.json
|
||||
artifacts/
|
||||
|
||||
*_i.c
|
||||
*_p.c
|
||||
*_i.h
|
||||
*.ilk
|
||||
*.meta
|
||||
*.obj
|
||||
*.pch
|
||||
*.pdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
*.sbr
|
||||
*.tlb
|
||||
*.tli
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.tmp_proj
|
||||
*.log
|
||||
*.vspscc
|
||||
*.vssscc
|
||||
.builds
|
||||
*.pidb
|
||||
*.svclog
|
||||
*.scc
|
||||
|
||||
# Chutzpah Test files
|
||||
_Chutzpah*
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opendb
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.cachefile
|
||||
*.VC.db
|
||||
*.VC.VC.opendb
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
*.vsp
|
||||
*.vspx
|
||||
*.sap
|
||||
|
||||
# TFS 2012 Local Workspace
|
||||
$tf/
|
||||
|
||||
# Guidance Automation Toolkit
|
||||
*.gpState
|
||||
|
||||
# ReSharper is a .NET coding add-in
|
||||
_ReSharper*/
|
||||
*.[Rr]e[Ss]harper
|
||||
*.DotSettings.user
|
||||
|
||||
# JustCode is a .NET coding add-in
|
||||
.JustCode
|
||||
|
||||
# TeamCity is a build add-in
|
||||
_TeamCity*
|
||||
|
||||
# DotCover is a Code Coverage Tool
|
||||
*.dotCover
|
||||
|
||||
# NCrunch
|
||||
_NCrunch_*
|
||||
.*crunch*.local.xml
|
||||
nCrunchTemp_*
|
||||
|
||||
# MightyMoose
|
||||
*.mm.*
|
||||
AutoTest.Net/
|
||||
|
||||
# Web workbench (sass)
|
||||
.sass-cache/
|
||||
|
||||
# Installshield output folder
|
||||
[Ee]xpress/
|
||||
|
||||
# DocProject is a documentation generator add-in
|
||||
DocProject/buildhelp/
|
||||
DocProject/Help/*.HxT
|
||||
DocProject/Help/*.HxC
|
||||
DocProject/Help/*.hhc
|
||||
DocProject/Help/*.hhk
|
||||
DocProject/Help/*.hhp
|
||||
DocProject/Help/Html2
|
||||
DocProject/Help/html
|
||||
|
||||
# Click-Once directory
|
||||
publish/
|
||||
|
||||
# Publish Web Output
|
||||
*.[Pp]ublish.xml
|
||||
*.azurePubxml
|
||||
# TODO: Comment the next line if you want to checkin your web deploy settings
|
||||
# but database connection strings (with potential passwords) will be unencrypted
|
||||
#*.pubxml
|
||||
*.publishproj
|
||||
|
||||
# Microsoft Azure Web App publish settings. Comment the next line if you want to
|
||||
# checkin your Azure Web App publish settings, but sensitive information contained
|
||||
# in these scripts will be unencrypted
|
||||
PublishScripts/
|
||||
|
||||
# NuGet Packages
|
||||
.vs
|
||||
.idea
|
||||
node_modules
|
||||
npm-debug.log
|
||||
vwd.webinfo
|
||||
dist/
|
||||
dist-cli/
|
||||
css/
|
||||
*.crx
|
||||
*.pem
|
||||
build-cli/
|
||||
build/
|
||||
yarn-error.log
|
||||
.DS_Store
|
||||
*.nupkg
|
||||
# The packages folder can be ignored because of Package Restore
|
||||
**/packages/*
|
||||
# except build/, which is used as an MSBuild target.
|
||||
!**/packages/build/
|
||||
# Uncomment if necessary however generally it will be regenerated when needed
|
||||
#!**/packages/repositories.config
|
||||
# NuGet v3's project.json files produces more ignoreable files
|
||||
*.nuget.props
|
||||
*.nuget.targets
|
||||
|
||||
# Microsoft Azure Build Output
|
||||
csx/
|
||||
*.build.csdef
|
||||
|
||||
# Microsoft Azure Emulator
|
||||
ecf/
|
||||
rcf/
|
||||
|
||||
# Windows Store app package directories and files
|
||||
AppPackages/
|
||||
BundleArtifacts/
|
||||
Package.StoreAssociation.xml
|
||||
_pkginfo.txt
|
||||
|
||||
# Visual Studio cache files
|
||||
# files ending in .cache can be ignored
|
||||
*.[Cc]ache
|
||||
# but keep track of directories ending in .cache
|
||||
!*.[Cc]ache/
|
||||
|
||||
# Others
|
||||
ClientBin/
|
||||
~$*
|
||||
*~
|
||||
*.dbmdl
|
||||
*.dbproj.schemaview
|
||||
*.jfm
|
||||
*.pfx
|
||||
*.publishsettings
|
||||
node_modules/
|
||||
orleans.codegen.cs
|
||||
|
||||
# Since there are multiple workflows, uncomment next line to ignore bower_components
|
||||
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
|
||||
#bower_components/
|
||||
|
||||
# RIA/Silverlight projects
|
||||
Generated_Code/
|
||||
|
||||
# Backup & report files from converting an old project file
|
||||
# to a newer Visual Studio version. Backup files are not needed,
|
||||
# because we have git ;-)
|
||||
_UpgradeReport_Files/
|
||||
Backup*/
|
||||
UpgradeLog*.XML
|
||||
UpgradeLog*.htm
|
||||
|
||||
# SQL Server files
|
||||
*.mdf
|
||||
*.ldf
|
||||
|
||||
# Business Intelligence projects
|
||||
*.rdl.data
|
||||
*.bim.layout
|
||||
*.bim_*.settings
|
||||
|
||||
# Microsoft Fakes
|
||||
FakesAssemblies/
|
||||
|
||||
# GhostDoc plugin setting file
|
||||
*.GhostDoc.xml
|
||||
|
||||
# Node.js Tools for Visual Studio
|
||||
.ntvs_analysis.dat
|
||||
|
||||
# Visual Studio 6 build log
|
||||
*.plg
|
||||
|
||||
# Visual Studio 6 workspace options file
|
||||
*.opt
|
||||
|
||||
# Visual Studio LightSwitch build output
|
||||
**/*.HTMLClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/ModelManifest.xml
|
||||
**/*.Server/GeneratedArtifacts
|
||||
**/*.Server/ModelManifest.xml
|
||||
_Pvt_Extensions
|
||||
|
||||
# Paket dependency manager
|
||||
.paket/paket.exe
|
||||
paket-files/
|
||||
|
||||
# FAKE - F# Make
|
||||
.fake/
|
||||
|
||||
# JetBrains Rider
|
||||
.idea/
|
||||
*.sln.iml
|
||||
|
||||
# CodeRush
|
||||
.cr/
|
||||
|
||||
# Python Tools for Visual Studio (PTVS)
|
||||
__pycache__/
|
||||
*.pyc
|
||||
*.provisionprofile
|
||||
*.env
|
||||
|
||||
4
.gitmodules
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
[submodule "jslib"]
|
||||
path = jslib
|
||||
url = https://github.com/bitwarden/jslib.git
|
||||
branch = master
|
||||
1
.husky/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
_
|
||||
4
.husky/pre-commit
Executable file
@@ -0,0 +1,4 @@
|
||||
#!/bin/sh
|
||||
. "$(dirname "$0")/_/husky.sh"
|
||||
|
||||
npx lint-staged
|
||||
12
.prettierignore
Normal file
@@ -0,0 +1,12 @@
|
||||
# Build directories
|
||||
build
|
||||
build-cli
|
||||
dist
|
||||
|
||||
jslib
|
||||
|
||||
# External libraries / auto synced locales
|
||||
src/locales
|
||||
|
||||
# Github Workflows
|
||||
.github/workflows
|
||||
3
.prettierrc.json
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"printWidth": 100
|
||||
}
|
||||
40
.vscode/launch.json
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "Electron: Main",
|
||||
"protocol": "inspector",
|
||||
"cwd": "${workspaceRoot}/build",
|
||||
"runtimeArgs": ["--remote-debugging-port=9223", "."],
|
||||
"windows": {
|
||||
"runtimeExecutable": "${workspaceFolder}/node_modules/.bin/electron.cmd"
|
||||
},
|
||||
"sourceMaps": true
|
||||
},
|
||||
{
|
||||
"name": "Electron: Renderer",
|
||||
"type": "chrome",
|
||||
"request": "attach",
|
||||
"port": 9223,
|
||||
"webRoot": "${workspaceFolder}/build",
|
||||
"sourceMaps": true
|
||||
},
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "Debug CLI",
|
||||
"protocol": "inspector",
|
||||
"cwd": "${workspaceFolder}",
|
||||
"program": "${workspaceFolder}/build-cli/bwdc.js",
|
||||
"args": ["sync"]
|
||||
}
|
||||
],
|
||||
"compounds": [
|
||||
{
|
||||
"name": "Electron: All",
|
||||
"configurations": ["Electron: Main", "Electron: Renderer"]
|
||||
}
|
||||
]
|
||||
}
|
||||
13
CONTRIBUTING.md
Normal file
@@ -0,0 +1,13 @@
|
||||
Code contributions are welcome! Please commit any pull requests against the `master` branch.
|
||||
|
||||
# Localization (l10n)
|
||||
|
||||
[](https://crowdin.com/project/bitwarden-desktop)
|
||||
|
||||
We use a translation tool called [Crowdin](https://crowdin.com) to help manage our localization efforts across many different languages.
|
||||
|
||||
If you are interested in helping translate the Bitwarden desktop app into another language (or make a translation correction), please register an account at Crowdin and join our project here: https://crowdin.com/project/bitwarden-desktop
|
||||
|
||||
If the language that you are interested in translating is not already listed, create a new account on Crowdin, join the project, and contact the project owner (https://crowdin.com/mail/compose/kspearrin).
|
||||
|
||||
You can read Crowdin's getting started guide for translators here: https://support.crowdin.com/crowdin-intro/
|
||||
5
ISSUE_TEMPLATE.md
Normal file
@@ -0,0 +1,5 @@
|
||||
<!--
|
||||
Please do not submit feature requests. The [Community Forums][1] has a
|
||||
section for submitting, voting for, and discussing product feature requests.
|
||||
[1]: https://community.bitwarden.com
|
||||
-->
|
||||
@@ -1,5 +1,5 @@
|
||||
GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
Version 3, 19 November 2007
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
@@ -7,15 +7,17 @@
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU Affero General Public License is a free, copyleft license for
|
||||
software and other kinds of works, specifically designed to ensure
|
||||
cooperation with the community in the case of network server software.
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
our General Public Licenses are intended to guarantee your freedom to
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users.
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
@@ -24,34 +26,44 @@ them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
Developers that use our General Public Licenses protect your rights
|
||||
with two steps: (1) assert copyright on the software, and (2) offer
|
||||
you this License which gives you legal permission to copy, distribute
|
||||
and/or modify the software.
|
||||
To protect your rights, we need to prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
|
||||
A secondary benefit of defending all users' freedom is that
|
||||
improvements made in alternate versions of the program, if they
|
||||
receive widespread use, become available for other developers to
|
||||
incorporate. Many developers of free software are heartened and
|
||||
encouraged by the resulting cooperation. However, in the case of
|
||||
software used on network servers, this result may fail to come about.
|
||||
The GNU General Public License permits making a modified version and
|
||||
letting the public access it on a server without ever releasing its
|
||||
source code to the public.
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. You must make sure that they, too, receive
|
||||
or can get the source code. And you must show them these terms so they
|
||||
know their rights.
|
||||
|
||||
The GNU Affero General Public License is designed specifically to
|
||||
ensure that, in such cases, the modified source code becomes available
|
||||
to the community. It requires the operator of a network server to
|
||||
provide the source code of the modified version running there to the
|
||||
users of that server. Therefore, public use of a modified version, on
|
||||
a publicly accessible server, gives the public access to the source
|
||||
code of the modified version.
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
|
||||
An older license, called the Affero General Public License and
|
||||
published by Affero, was designed to accomplish similar goals. This is
|
||||
a different license, not a version of the Affero GPL, but Affero has
|
||||
released a new version of the Affero GPL which permits relicensing under
|
||||
this license.
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
@@ -60,7 +72,7 @@ modification follow.
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU Affero General Public License.
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
@@ -537,45 +549,35 @@ to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Remote Network Interaction; Use with the GNU General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, if you modify the
|
||||
Program, your modified version must prominently offer all users
|
||||
interacting with it remotely through a computer network (if your version
|
||||
supports such interaction) an opportunity to receive the Corresponding
|
||||
Source of your version by providing access to the Corresponding Source
|
||||
from a network server at no charge, through some standard or customary
|
||||
means of facilitating copying of software. This Corresponding Source
|
||||
shall include the Corresponding Source for any work covered by version 3
|
||||
of the GNU General Public License that is incorporated pursuant to the
|
||||
following paragraph.
|
||||
13. Use with the GNU Affero General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU General Public License into a single
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the work with which it is combined will remain governed by version
|
||||
3 of the GNU General Public License.
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU Affero General Public License from time to time. Such new versions
|
||||
will be similar in spirit to the present version, but may differ in detail to
|
||||
the GNU General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU Affero General
|
||||
Program specifies that a certain numbered version of the GNU General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU Affero General Public License, you may choose any version ever published
|
||||
GNU General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU Affero General Public License can be used, that proxy's
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
@@ -629,33 +631,44 @@ to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
{one line to give the program's name and a brief idea of what it does.}
|
||||
Copyright (C) {year} {name of author}
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published
|
||||
by the Free Software Foundation, either version 3 of the License, or
|
||||
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 Affero General Public License for more details.
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If your software can interact with users remotely through a computer
|
||||
network, you should also make sure that it provides a way for users to
|
||||
get its source. For example, if your program is a web application, its
|
||||
interface could display a "Source" link that leads users to an archive
|
||||
of the code. There are many ways you could offer source, and different
|
||||
solutions will be better for different programs; see section 13 for the
|
||||
specific requirements.
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
{project} Copyright (C) {year} {fullname}
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, your program's commands
|
||||
might be different; for a GUI interface, you would use an "about box".
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU AGPL, see
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
|
||||
The GNU General Public License does not permit incorporating your program
|
||||
into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
||||
100
README.md
@@ -1,29 +1,105 @@
|
||||
[](https://ci.appveyor.com/project/bitwarden/directory-connector)
|
||||

|
||||
[](https://gitter.im/bitwarden/Lobby)
|
||||
|
||||
# bitwarden Directory Connector
|
||||
# Bitwarden Directory Connector
|
||||
|
||||
The bitwarden Directory Connector is a command line application used to connect your bitwarden enterprise organization to an existing directory of users and groups.
|
||||
It is written in C# with the .NET Framework. It consists of a console application and an optional windows service to run syncs in the background on a specified interval.
|
||||
The Bitwarden Directory Connector is a a desktop application used to sync your Bitwarden enterprise organization to an existing directory of users and groups.
|
||||
|
||||
Supported directories:
|
||||
|
||||
- Active Directory
|
||||
- Azure Active Directory
|
||||
- GSuite (Google)
|
||||
- Any other LDAP-based directory
|
||||
- Azure Active Directory
|
||||
- G Suite (Google)
|
||||
- Okta
|
||||
|
||||
<img src="https://i.imgur.com/IdqS0se.png" alt="" width="680" height="479" />
|
||||
The application is written using Electron with Angular and installs on Windows, macOS, and Linux distributions.
|
||||
|
||||
# Build/Run
|
||||
[](https://bitwarden.com/help/directory-sync/#download-and-install)
|
||||
|
||||

|
||||
|
||||
## Command-line Interface
|
||||
|
||||
A command-line interface tool is also available for the Bitwarden Directory Connector. The Directory Connector CLI (`bwdc`) is written with TypeScript and Node.js and can also be run on Windows, macOS, and Linux distributions.
|
||||
|
||||
## CLI Documentation
|
||||
|
||||
The Bitwarden Directory Connector CLI is self-documented with `--help` content and examples for every command. You should start exploring the CLI by using the global `--help` option:
|
||||
|
||||
```bash
|
||||
bwdc --help
|
||||
```
|
||||
|
||||
This option will list all available commands that you can use with the Directory Connector CLI.
|
||||
|
||||
Additionally, you can run the `--help` option on a specific command to learn more about it:
|
||||
|
||||
```
|
||||
bwdc test --help
|
||||
bwdc config --help
|
||||
```
|
||||
|
||||
**Detailed Documentation**
|
||||
|
||||
We provide detailed documentation and examples for using the Directory Connector CLI in our help center at https://bitwarden.com/help/directory-sync-cli/.
|
||||
|
||||
## Build/Run
|
||||
|
||||
**Requirements**
|
||||
|
||||
- [Visual Studio](https://www.visualstudio.com/)
|
||||
- [Node.js](https://nodejs.org) v16.13.1 (LTS)
|
||||
- Windows users: To compile the native node modules used in the app you will need the Visual C++ toolset, available through the standard Visual Studio installer (recommended) or by installing [`windows-build-tools`](https://github.com/felixrieseberg/windows-build-tools) through `npm`. See more at [Compiling native Addon modules](https://github.com/Microsoft/nodejs-guidelines/blob/master/windows-environment.md#compiling-native-addon-modules).
|
||||
|
||||
Open `bitwarden-directory-connector.sln` or `bitwarden-directory-connector-noinstaller.sln`. After restoring the nuget packages, you can build and run the application.
|
||||
**Run the app**
|
||||
|
||||
# Contribute
|
||||
```bash
|
||||
npm install
|
||||
npm run reset # Only necessary if you have previously run the CLI app
|
||||
npm run rebuild
|
||||
npm run electron
|
||||
```
|
||||
|
||||
Code contributions are welcome! Visual Studio is required to work on this project. Please commit any pull requests against the `master` branch.
|
||||
**Run the CLI**
|
||||
|
||||
```bash
|
||||
npm install
|
||||
npm run reset # Only necessary if you have previously run the desktop app
|
||||
npm run build:cli:watch
|
||||
```
|
||||
|
||||
You can then run commands from the `./build-cli` folder:
|
||||
|
||||
```bash
|
||||
node ./build-cli/bwdc.js --help
|
||||
```
|
||||
|
||||
## We're Hiring!
|
||||
|
||||
Interested in contributing in a big way? Consider joining our team! We're hiring for many positions. Please take a look at our [Careers page](https://bitwarden.com/careers/) to see what opportunities are currently open as well as what it's like to work at Bitwarden.
|
||||
|
||||
## Contribute
|
||||
|
||||
Code contributions are welcome! Please commit any pull requests against the `master` branch. Learn more about how to contribute by reading the [`CONTRIBUTING.md`](CONTRIBUTING.md) file.
|
||||
|
||||
Security audits and feedback are welcome. Please open an issue or email us privately if the report is sensitive in nature. You can read our security policy in the [`SECURITY.md`](SECURITY.md) file.
|
||||
|
||||
### Prettier
|
||||
|
||||
We recently migrated to using Prettier as code formatter. All previous branches will need to updated to avoid large merge conflicts using the following steps:
|
||||
|
||||
1. Check out your local Branch
|
||||
2. Run `git merge 225073aa335d33ad905877b68336a9288e89ea10`
|
||||
3. Resolve any merge conflicts, commit.
|
||||
4. Run `npm run prettier`
|
||||
5. Commit
|
||||
6. Run `git merge -Xours 096196fcd512944d1c3d9c007647a1319b032639`
|
||||
7. Push
|
||||
|
||||
#### Git blame
|
||||
|
||||
We also recommend that you configure git to ignore the prettier revision using:
|
||||
|
||||
```bash
|
||||
git config blame.ignoreRevsFile .git-blame-ignore-revs
|
||||
```
|
||||
|
||||
18
SECURITY.md
@@ -1,4 +1,4 @@
|
||||
bitwarden believes that working with security researchers across the globe is crucial to keeping our
|
||||
Bitwarden believes that working with security researchers across the globe is crucial to keeping our
|
||||
users safe. If you believe you've found a security issue in our product or service, we encourage you to
|
||||
notify us. We welcome working with you to resolve the issue promptly. Thanks in advance!
|
||||
|
||||
@@ -7,7 +7,7 @@ notify us. We welcome working with you to resolve the issue promptly. Thanks in
|
||||
- Let us know as soon as possible upon discovery of a potential security issue, and we'll make every
|
||||
effort to quickly resolve the issue.
|
||||
- Provide us a reasonable amount of time to resolve the issue before any disclosure to the public or a
|
||||
third-party. We may publicly disclose the issue before resolving it, if appropriate.
|
||||
third-party. We may publicly disclose the issue before resolving it, if appropriate.
|
||||
- Make a good faith effort to avoid privacy violations, destruction of data, and interruption or
|
||||
degradation of our service. Only interact with accounts you own or with explicit permission of the
|
||||
account holder.
|
||||
@@ -16,7 +16,7 @@ notify us. We welcome working with you to resolve the issue promptly. Thanks in
|
||||
|
||||
# In-scope
|
||||
|
||||
- Security issues in any current release of bitwarden. This includes the web vault, browser extension,
|
||||
- Security issues in any current release of Bitwarden. This includes the web vault, browser extension,
|
||||
and mobile apps (iOS and Android). Product downloads are available at https://bitwarden.com. Source
|
||||
code is available at https://github.com/bitwarden.
|
||||
|
||||
@@ -24,14 +24,14 @@ notify us. We welcome working with you to resolve the issue promptly. Thanks in
|
||||
|
||||
The following bug classes are out-of scope:
|
||||
|
||||
- Bugs that are already reported on any of bitwarden's issue trackers (https://github.com/bitwarden),
|
||||
- Bugs that are already reported on any of Bitwarden's issue trackers (https://github.com/bitwarden),
|
||||
or that we already know of. Note that some of our issue tracking is private.
|
||||
- Issues in an upstream software dependency (ex: Xamarin, ASP.NET) which are already reported to the
|
||||
upstream maintainer.
|
||||
- Attacks requiring physical access to a user's device.
|
||||
- Self-XSS
|
||||
- Issues related to software or protocols not under bitwarden's control
|
||||
- Vulnerabilities in outdated versions of bitwarden
|
||||
- Issues related to software or protocols not under Bitwarden's control
|
||||
- Vulnerabilities in outdated versions of Bitwarden
|
||||
- Missing security best practices that do not directly lead to a vulnerability
|
||||
- Issues that do not have any impact on the general public
|
||||
|
||||
@@ -39,7 +39,7 @@ While researching, we'd like to ask you to refrain from:
|
||||
|
||||
- Denial of service
|
||||
- Spamming
|
||||
- Social engineering (including phishing) of bitwarden staff or contractors
|
||||
- Any physical attempts against bitwarden property or data centers
|
||||
- Social engineering (including phishing) of Bitwarden staff or contractors
|
||||
- Any physical attempts against Bitwarden property or data centers
|
||||
|
||||
Thank you for helping keep bitwarden and our users safe!
|
||||
Thank you for helping keep Bitwarden and our users safe!
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.26730.10
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Console", "src\Console\Console.csproj", "{DD4E5CD2-C9DD-4912-9A25-1600A07BF8C2}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Core", "src\Core\Core.csproj", "{AE082484-A34C-4B3A-A69F-49E5EF298B27}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Service", "src\Service\Service.csproj", "{A8FD8CED-5510-4EBD-AACE-5D3CBB7516DB}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{DD4E5CD2-C9DD-4912-9A25-1600A07BF8C2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{DD4E5CD2-C9DD-4912-9A25-1600A07BF8C2}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{DD4E5CD2-C9DD-4912-9A25-1600A07BF8C2}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{DD4E5CD2-C9DD-4912-9A25-1600A07BF8C2}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{AE082484-A34C-4B3A-A69F-49E5EF298B27}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{AE082484-A34C-4B3A-A69F-49E5EF298B27}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{AE082484-A34C-4B3A-A69F-49E5EF298B27}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{AE082484-A34C-4B3A-A69F-49E5EF298B27}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{A8FD8CED-5510-4EBD-AACE-5D3CBB7516DB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{A8FD8CED-5510-4EBD-AACE-5D3CBB7516DB}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{A8FD8CED-5510-4EBD-AACE-5D3CBB7516DB}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{A8FD8CED-5510-4EBD-AACE-5D3CBB7516DB}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {52CB25C1-56A6-4FBE-977C-E842EA0AFAD7}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@@ -1,41 +0,0 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.26730.10
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Console", "src\Console\Console.csproj", "{DD4E5CD2-C9DD-4912-9A25-1600A07BF8C2}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Core", "src\Core\Core.csproj", "{AE082484-A34C-4B3A-A69F-49E5EF298B27}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Service", "src\Service\Service.csproj", "{A8FD8CED-5510-4EBD-AACE-5D3CBB7516DB}"
|
||||
EndProject
|
||||
Project("{54435603-DBB4-11D2-8724-00A0C9A8B90C}") = "Setup", "src\Setup\Setup.vdproj", "{4D852DF8-9327-43D0-93AB-FA68D4F3414B}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{DD4E5CD2-C9DD-4912-9A25-1600A07BF8C2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{DD4E5CD2-C9DD-4912-9A25-1600A07BF8C2}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{DD4E5CD2-C9DD-4912-9A25-1600A07BF8C2}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{DD4E5CD2-C9DD-4912-9A25-1600A07BF8C2}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{AE082484-A34C-4B3A-A69F-49E5EF298B27}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{AE082484-A34C-4B3A-A69F-49E5EF298B27}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{AE082484-A34C-4B3A-A69F-49E5EF298B27}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{AE082484-A34C-4B3A-A69F-49E5EF298B27}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{A8FD8CED-5510-4EBD-AACE-5D3CBB7516DB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{A8FD8CED-5510-4EBD-AACE-5D3CBB7516DB}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{A8FD8CED-5510-4EBD-AACE-5D3CBB7516DB}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{A8FD8CED-5510-4EBD-AACE-5D3CBB7516DB}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{4D852DF8-9327-43D0-93AB-FA68D4F3414B}.Debug|Any CPU.ActiveCfg = Debug
|
||||
{4D852DF8-9327-43D0-93AB-FA68D4F3414B}.Release|Any CPU.ActiveCfg = Release
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {AB7EF6F7-C38B-4E66-BBF9-1F6915896CB0}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
1
jslib
Submodule
20619
package-lock.json
generated
Normal file
220
package.json
Normal file
@@ -0,0 +1,220 @@
|
||||
{
|
||||
"name": "@bitwarden/directory-connector",
|
||||
"description": "Sync your user directory to your Bitwarden organization.",
|
||||
"version": "0.0.0",
|
||||
"keywords": [
|
||||
"bitwarden",
|
||||
"password",
|
||||
"vault",
|
||||
"password manager"
|
||||
],
|
||||
"author": "Bitwarden Inc. <hello@bitwarden.com> (https://bitwarden.com)",
|
||||
"homepage": "https://bitwarden.com",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/bitwarden/directory-connector"
|
||||
},
|
||||
"license": "GPL-3.0",
|
||||
"scripts": {
|
||||
"sub:init": "git submodule update --init --recursive",
|
||||
"sub:update": "git submodule update --remote",
|
||||
"sub:pull": "git submodule foreach git pull origin master",
|
||||
"sub:commit": "npm run sub:pull && git commit -am \"update submodule\"",
|
||||
"preinstall": "npm run sub:init",
|
||||
"symlink:win": "rm -rf ./jslib && cmd /c mklink /J .\\jslib ..\\jslib",
|
||||
"symlink:mac": "npm run symlink:lin",
|
||||
"symlink:lin": "rm -rf ./jslib && ln -s ../jslib ./jslib",
|
||||
"rebuild": "electron-rebuild",
|
||||
"reset": "rimraf ./node_modules/keytar/* && npm install",
|
||||
"lint": "eslint . && prettier --check .",
|
||||
"lint:fix": "eslint . --fix",
|
||||
"build": "concurrently -n Main,Rend -c yellow,cyan \"npm run build:main\" \"npm run build:renderer\"",
|
||||
"build:main": "webpack --config webpack.main.js",
|
||||
"build:renderer": "webpack --config webpack.renderer.js",
|
||||
"build:renderer:watch": "webpack --config webpack.renderer.js --watch",
|
||||
"build:dist": "npm run reset && npm run rebuild && npm run build",
|
||||
"build:cli": "webpack --config webpack.cli.js",
|
||||
"build:cli:watch": "webpack --config webpack.cli.js --watch",
|
||||
"build:cli:prod": "cross-env NODE_ENV=production webpack --config webpack.cli.js",
|
||||
"build:cli:prod:watch": "cross-env NODE_ENV=production webpack --config webpack.cli.js --watch",
|
||||
"electron": "npm run build:main && concurrently -k -n Main,Rend -c yellow,cyan \"electron --inspect=5858 ./build --watch\" \"npm run build:renderer:watch\"",
|
||||
"clean:dist": "rimraf ./dist/*",
|
||||
"clean:dist:cli": "rimraf ./dist-cli/*",
|
||||
"pack:lin": "npm run clean:dist && electron-builder --linux --x64 -p never",
|
||||
"pack:mac": "npm run clean:dist && electron-builder --mac -p never",
|
||||
"pack:win": "npm run clean:dist && electron-builder --win --x64 --ia32 -p never -c.win.certificateSubjectName=\"8bit Solutions LLC\"",
|
||||
"pack:win:ci": "npm run clean:dist && electron-builder --win --x64 --ia32 -p never",
|
||||
"pack:cli": "npm run pack:cli:win | npm run pack:cli:mac | npm run pack:cli:lin",
|
||||
"pack:cli:win": "pkg ./src-cli --targets win-x64 --output ./dist-cli/windows/bwdc.exe",
|
||||
"pack:cli:mac": "pkg ./src-cli --targets macos-x64 --output ./dist-cli/macos/bwdc",
|
||||
"pack:cli:lin": "pkg ./src-cli --targets linux-x64 --output ./dist-cli/linux/bwdc",
|
||||
"dist:lin": "npm run build:dist && npm run pack:lin",
|
||||
"dist:mac": "npm run build:dist && npm run pack:mac",
|
||||
"dist:win": "npm run build:dist && npm run pack:win",
|
||||
"dist:win:ci": "npm run build && npm run pack:win:ci",
|
||||
"dist:cli": "npm run build:cli:prod && npm run clean:dist:cli && npm run pack:cli",
|
||||
"dist:cli:win": "npm run build:cli:prod && npm run clean:dist:cli && npm run pack:cli:win",
|
||||
"dist:cli:mac": "npm run build:cli:prod && npm run clean:dist:cli && npm run pack:cli:mac",
|
||||
"dist:cli:lin": "npm run build:cli:prod && npm run clean:dist:cli && npm run pack:cli:lin",
|
||||
"publish:lin": "npm run build:dist && npm run clean:dist && electron-builder --linux --x64 -p always",
|
||||
"publish:mac": "npm run build:dist && npm run clean:dist && electron-builder --mac -p always",
|
||||
"publish:win": "npm run build:dist && npm run clean:dist && electron-builder --win --x64 --ia32 -p always -c.win.certificateSubjectName=\"8bit Solutions LLC\"",
|
||||
"prettier": "prettier --write .",
|
||||
"prepare": "husky install"
|
||||
},
|
||||
"build": {
|
||||
"extraMetadata": {
|
||||
"name": "bitwarden-directory-connector"
|
||||
},
|
||||
"productName": "Bitwarden Directory Connector",
|
||||
"appId": "com.bitwarden.directory-connector",
|
||||
"copyright": "Copyright © 2015-2022 Bitwarden Inc.",
|
||||
"directories": {
|
||||
"buildResources": "resources",
|
||||
"output": "dist",
|
||||
"app": "build"
|
||||
},
|
||||
"afterSign": "scripts/notarize.js",
|
||||
"mac": {
|
||||
"category": "public.app-category.productivity",
|
||||
"gatekeeperAssess": false,
|
||||
"hardenedRuntime": true,
|
||||
"entitlements": "resources/entitlements.mac.plist",
|
||||
"entitlementsInherit": "resources/entitlements.mac.plist",
|
||||
"target": [
|
||||
"dmg",
|
||||
"zip"
|
||||
]
|
||||
},
|
||||
"win": {
|
||||
"target": [
|
||||
"portable",
|
||||
"nsis"
|
||||
],
|
||||
"sign": "scripts/sign.js"
|
||||
},
|
||||
"linux": {
|
||||
"category": "Utility",
|
||||
"synopsis": "Sync your user directory to your Bitwarden organization.",
|
||||
"target": [
|
||||
"AppImage"
|
||||
]
|
||||
},
|
||||
"dmg": {
|
||||
"artifactName": "Bitwarden-Connector-${version}.${ext}",
|
||||
"icon": "dmg.icns",
|
||||
"contents": [
|
||||
{
|
||||
"x": 150,
|
||||
"y": 185,
|
||||
"type": "file"
|
||||
},
|
||||
{
|
||||
"x": 390,
|
||||
"y": 180,
|
||||
"type": "link",
|
||||
"path": "/Applications"
|
||||
}
|
||||
],
|
||||
"window": {
|
||||
"width": 540,
|
||||
"height": 380
|
||||
}
|
||||
},
|
||||
"nsis": {
|
||||
"oneClick": false,
|
||||
"perMachine": true,
|
||||
"allowToChangeInstallationDirectory": true,
|
||||
"artifactName": "Bitwarden-Connector-Installer-${version}.${ext}",
|
||||
"uninstallDisplayName": "${productName}",
|
||||
"deleteAppDataOnUninstall": true
|
||||
},
|
||||
"portable": {
|
||||
"artifactName": "Bitwarden-Connector-Portable-${version}.${ext}"
|
||||
},
|
||||
"appImage": {
|
||||
"artifactName": "Bitwarden-Connector-${version}-${arch}.${ext}"
|
||||
}
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular/compiler-cli": "^12.2.13",
|
||||
"@microsoft/microsoft-graph-types": "^1.4.0",
|
||||
"@ngtools/webpack": "^12.2.13",
|
||||
"@types/ldapjs": "^1.0.10",
|
||||
"@types/node": "^16.11.12",
|
||||
"@types/proper-lockfile": "^4.1.1",
|
||||
"@typescript-eslint/eslint-plugin": "^5.12.1",
|
||||
"@typescript-eslint/parser": "^5.12.1",
|
||||
"clean-webpack-plugin": "^4.0.0",
|
||||
"concurrently": "^6.0.2",
|
||||
"copy-webpack-plugin": "^10.0.0",
|
||||
"cross-env": "^7.0.3",
|
||||
"css-loader": "^6.5.1",
|
||||
"electron-builder": "^22.14.5",
|
||||
"electron-notarize": "^1.1.1",
|
||||
"electron-rebuild": "^3.2.5",
|
||||
"electron-reload": "^1.5.0",
|
||||
"eslint": "^8.9.0",
|
||||
"eslint-config-prettier": "^8.4.0",
|
||||
"eslint-import-resolver-typescript": "^2.5.0",
|
||||
"eslint-plugin-import": "^2.25.4",
|
||||
"html-loader": "^3.0.1",
|
||||
"html-webpack-plugin": "^5.5.0",
|
||||
"husky": "^7.0.4",
|
||||
"lint-staged": "^12.1.3",
|
||||
"mini-css-extract-plugin": "^2.4.5",
|
||||
"node-loader": "^2.0.0",
|
||||
"pkg": "^5.5.1",
|
||||
"prebuild-install": "^5.0.0",
|
||||
"prettier": "^2.5.1",
|
||||
"rimraf": "^3.0.2",
|
||||
"sass": "^1.32.11",
|
||||
"sass-loader": "^12.4.0",
|
||||
"tapable": "^1.1.3",
|
||||
"ts-loader": "^9.2.5",
|
||||
"tsconfig-paths-webpack-plugin": "^3.5.1",
|
||||
"typescript": "4.3.5",
|
||||
"webpack": "^5.64.4",
|
||||
"webpack-cli": "^4.9.1",
|
||||
"webpack-merge": "^5.8.0",
|
||||
"webpack-node-externals": "^3.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@angular/animations": "^12.2.13",
|
||||
"@angular/cdk": "^12.2.13",
|
||||
"@angular/common": "^12.2.13",
|
||||
"@angular/compiler": "^12.2.13",
|
||||
"@angular/core": "^12.2.13",
|
||||
"@angular/forms": "^12.2.13",
|
||||
"@angular/platform-browser": "^12.2.13",
|
||||
"@angular/platform-browser-dynamic": "^12.2.13",
|
||||
"@angular/router": "^12.2.13",
|
||||
"@bitwarden/jslib-angular": "file:jslib/angular",
|
||||
"@bitwarden/jslib-common": "file:jslib/common",
|
||||
"@bitwarden/jslib-electron": "file:jslib/electron",
|
||||
"@bitwarden/jslib-node": "file:jslib/node",
|
||||
"@microsoft/microsoft-graph-client": "^2.2.1",
|
||||
"bootstrap": "^4.6.0",
|
||||
"chalk": "^4.1.1",
|
||||
"commander": "^7.2.0",
|
||||
"core-js": "^3.11.0",
|
||||
"duo_web_sdk": "git+https://github.com/duosecurity/duo_web_sdk.git",
|
||||
"form-data": "^4.0.0",
|
||||
"googleapis": "^73.0.0",
|
||||
"inquirer": "8.0.0",
|
||||
"ldapjs": "2.3.1",
|
||||
"lunr": "^2.3.9",
|
||||
"ngx-toastr": "14.1.4",
|
||||
"open": "^8.0.6",
|
||||
"proper-lockfile": "^4.1.2",
|
||||
"rxjs": "^7.4.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "~16",
|
||||
"npm": "~8"
|
||||
},
|
||||
"lint-staged": {
|
||||
"./!(jslib)**": "prettier --ignore-unknown --write",
|
||||
"*.ts": "eslint --fix"
|
||||
}
|
||||
}
|
||||
BIN
resources/background.png
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
resources/dmg.icns
Normal file
BIN
resources/dmg.iconset/icon_128x128.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
resources/dmg.iconset/icon_128x128@2x.png
Normal file
|
After Width: | Height: | Size: 40 KiB |
BIN
resources/dmg.iconset/icon_16x16.png
Normal file
|
After Width: | Height: | Size: 692 B |
BIN
resources/dmg.iconset/icon_16x16@2x.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
resources/dmg.iconset/icon_256x256.png
Normal file
|
After Width: | Height: | Size: 40 KiB |
BIN
resources/dmg.iconset/icon_256x256@2x.png
Normal file
|
After Width: | Height: | Size: 148 KiB |
BIN
resources/dmg.iconset/icon_32x32.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
resources/dmg.iconset/icon_32x32@2x.png
Normal file
|
After Width: | Height: | Size: 4.0 KiB |
BIN
resources/dmg.iconset/icon_512x512.png
Normal file
|
After Width: | Height: | Size: 148 KiB |
BIN
resources/dmg.iconset/icon_512x512@2x.png
Normal file
|
After Width: | Height: | Size: 492 KiB |
10
resources/entitlements.mac.plist
Normal file
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
|
||||
<true/>
|
||||
<key>com.apple.security.cs.disable-library-validation</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
BIN
resources/icon.icns
Normal file
BIN
resources/icon.ico
Normal file
|
After Width: | Height: | Size: 279 KiB |
BIN
resources/icon.iconset/icon_128x128.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
resources/icon.iconset/icon_128x128@2x.png
Normal file
|
After Width: | Height: | Size: 4.5 KiB |
BIN
resources/icon.iconset/icon_16x16.png
Normal file
|
After Width: | Height: | Size: 330 B |
BIN
resources/icon.iconset/icon_16x16@2x.png
Normal file
|
After Width: | Height: | Size: 507 B |
BIN
resources/icon.iconset/icon_256x256.png
Normal file
|
After Width: | Height: | Size: 4.5 KiB |
BIN
resources/icon.iconset/icon_256x256@2x.png
Normal file
|
After Width: | Height: | Size: 9.4 KiB |
BIN
resources/icon.iconset/icon_32x32.png
Normal file
|
After Width: | Height: | Size: 507 B |
BIN
resources/icon.iconset/icon_32x32@2x.png
Normal file
|
After Width: | Height: | Size: 823 B |
BIN
resources/icon.iconset/icon_512x512.png
Normal file
|
After Width: | Height: | Size: 9.4 KiB |
BIN
resources/icon.iconset/icon_512x512@2x.png
Normal file
|
After Width: | Height: | Size: 21 KiB |
BIN
resources/icon.png
Normal file
|
After Width: | Height: | Size: 21 KiB |
BIN
resources/icons/128x128.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
resources/icons/16x16.png
Normal file
|
After Width: | Height: | Size: 330 B |
BIN
resources/icons/256x256.png
Normal file
|
After Width: | Height: | Size: 4.5 KiB |
BIN
resources/icons/32x32.png
Normal file
|
After Width: | Height: | Size: 507 B |
BIN
resources/icons/48x48.png
Normal file
|
After Width: | Height: | Size: 681 B |
BIN
resources/icons/512x512.png
Normal file
|
After Width: | Height: | Size: 9.4 KiB |
BIN
resources/icons/64x64.png
Normal file
|
After Width: | Height: | Size: 961 B |
BIN
resources/installerSidebar.bmp
Normal file
|
After Width: | Height: | Size: 151 KiB |
19
scripts/notarize.js
Normal file
@@ -0,0 +1,19 @@
|
||||
/* eslint-disable @typescript-eslint/no-var-requires */
|
||||
require("dotenv").config();
|
||||
const { notarize } = require("electron-notarize");
|
||||
|
||||
exports.default = async function notarizing(context) {
|
||||
const { electronPlatformName, appOutDir } = context;
|
||||
if (electronPlatformName !== "darwin") {
|
||||
return;
|
||||
}
|
||||
const appleId = process.env.APPLE_ID_USERNAME || process.env.APPLEID;
|
||||
const appleIdPassword = process.env.APPLE_ID_PASSWORD || `@keychain:AC_PASSWORD`;
|
||||
const appName = context.packager.appInfo.productFilename;
|
||||
return await notarize({
|
||||
appBundleId: "com.bitwarden.directory-connector",
|
||||
appPath: `${appOutDir}/${appName}.app`,
|
||||
appleId: appleId,
|
||||
appleIdPassword: appleIdPassword,
|
||||
});
|
||||
};
|
||||
21
scripts/sign.js
Normal file
@@ -0,0 +1,21 @@
|
||||
/* eslint-disable @typescript-eslint/no-var-requires, no-console */
|
||||
exports.default = async function (configuration) {
|
||||
if (parseInt(process.env.ELECTRON_BUILDER_SIGN) === 1 && configuration.path.slice(-4) == ".exe") {
|
||||
console.log(`[*] Signing file: ${configuration.path}`);
|
||||
require("child_process").execSync(
|
||||
`azuresigntool sign ` +
|
||||
`-kvu ${process.env.SIGNING_VAULT_URL} ` +
|
||||
`-kvi ${process.env.SIGNING_CLIENT_ID} ` +
|
||||
`-kvt ${process.env.SIGNING_TENANT_ID} ` +
|
||||
`-kvs ${process.env.SIGNING_CLIENT_SECRET} ` +
|
||||
`-kvc ${process.env.SIGNING_CERT_NAME} ` +
|
||||
`-fd ${configuration.hash} ` +
|
||||
`-du ${configuration.site} ` +
|
||||
`-tr http://timestamp.digicert.com ` +
|
||||
`"${configuration.path}"`,
|
||||
{
|
||||
stdio: "inherit",
|
||||
}
|
||||
);
|
||||
}
|
||||
};
|
||||
1006
src-cli/package-lock.json
generated
Normal file
24
src-cli/package.json
Normal file
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"name": "@bitwarden/directory-connector",
|
||||
"productName": "Bitwarden Directory Connector",
|
||||
"description": "Sync your user directory to your Bitwarden organization.",
|
||||
"version": "2.9.5",
|
||||
"author": "Bitwarden Inc. <hello@bitwarden.com> (https://bitwarden.com)",
|
||||
"homepage": "https://bitwarden.com",
|
||||
"license": "GPL-3.0",
|
||||
"main": "main.js",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/bitwarden/directory-connector"
|
||||
},
|
||||
"bin": {
|
||||
"bwdc": "../build-cli/bwdc.js"
|
||||
},
|
||||
"pkg": {
|
||||
"assets": "../build-cli/**/*"
|
||||
},
|
||||
"dependencies": {
|
||||
"browser-hrtime": "^1.1.8",
|
||||
"keytar": "^7.7.0"
|
||||
}
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1"/>
|
||||
</startup>
|
||||
<runtime>
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral"/>
|
||||
<bindingRedirect oldVersion="0.0.0.0-10.0.0.0" newVersion="10.0.0.0"/>
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
</configuration>
|
||||
@@ -1,59 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{DD4E5CD2-C9DD-4912-9A25-1600A07BF8C2}</ProjectGuid>
|
||||
<OutputType>Exe</OutputType>
|
||||
<RootNamespace>Bit.Console</RootNamespace>
|
||||
<AssemblyName>Console</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||
<TargetFrameworkProfile />
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="App.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Core\Core.csproj">
|
||||
<Project>{ae082484-a34c-4b3a-a69f-49e5ef298b27}</Project>
|
||||
<Name>Core</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
||||
@@ -1,36 +0,0 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("Console")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("Console")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2017")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("dd4e5cd2-c9dd-4912-9a25-1600a07bf8c2")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
@@ -1,136 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{AE082484-A34C-4B3A-A69F-49E5EF298B27}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>Bit.Core</RootNamespace>
|
||||
<AssemblyName>Core</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<TargetFrameworkProfile />
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="BouncyCastle.Crypto, Version=1.8.1.0, Culture=neutral, PublicKeyToken=0e99375e54769942">
|
||||
<HintPath>..\..\packages\BouncyCastle.1.8.1\lib\BouncyCastle.Crypto.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Google.Apis, Version=1.28.0.0, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Google.Apis.1.28.0\lib\net45\Google.Apis.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Google.Apis.Admin.Directory.directory_v1, Version=1.28.0.934, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Google.Apis.Admin.Directory.directory_v1.1.28.0.934\lib\net45\Google.Apis.Admin.Directory.directory_v1.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Google.Apis.Auth, Version=1.28.0.0, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Google.Apis.Auth.1.28.0\lib\net45\Google.Apis.Auth.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Google.Apis.Auth.PlatformServices, Version=1.28.0.0, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Google.Apis.Auth.1.28.0\lib\net45\Google.Apis.Auth.PlatformServices.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Google.Apis.Core, Version=1.28.0.0, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Google.Apis.Core.1.28.0\lib\net45\Google.Apis.Core.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Google.Apis.PlatformServices, Version=1.28.0.0, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Google.Apis.1.28.0\lib\net45\Google.Apis.PlatformServices.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Graph, Version=1.5.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Microsoft.Graph.1.5.1\lib\net45\Microsoft.Graph.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Graph.Core, Version=1.6.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Microsoft.Graph.Core.1.6.1\lib\net45\Microsoft.Graph.Core.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.IdentityModel.Clients.ActiveDirectory, Version=3.16.0.14, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Microsoft.IdentityModel.Clients.ActiveDirectory.3.16.0\lib\net45\Microsoft.IdentityModel.Clients.ActiveDirectory.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.IdentityModel.Clients.ActiveDirectory.Platform, Version=3.16.0.14, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Microsoft.IdentityModel.Clients.ActiveDirectory.3.16.0\lib\net45\Microsoft.IdentityModel.Clients.ActiveDirectory.Platform.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Newtonsoft.Json, Version=10.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.DirectoryServices" />
|
||||
<Reference Include="System.DirectoryServices.Protocols" />
|
||||
<Reference Include="System.Security" />
|
||||
<Reference Include="System.ServiceProcess" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="Zlib.Portable, Version=1.11.0.0, Culture=neutral, PublicKeyToken=431cba815f6a8b5b, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Zlib.Portable.Signed.1.11.0\lib\portable-net4+sl5+wp8+win8+wpa81+MonoTouch+MonoAndroid\Zlib.Portable.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Enums\DirectoryType.cs" />
|
||||
<Compile Include="Enums\OrganizationUserType.cs" />
|
||||
<Compile Include="Enums\OrganizationUserStatusType.cs" />
|
||||
<Compile Include="Enums\TwoFactorProviderType.cs" />
|
||||
<Compile Include="Enums\UserAccountControl.cs" />
|
||||
<Compile Include="Models\ApiError.cs" />
|
||||
<Compile Include="Models\ApiResult.cs" />
|
||||
<Compile Include="Models\Entry.cs" />
|
||||
<Compile Include="Models\GSuiteConfiguration.cs" />
|
||||
<Compile Include="Models\ImportRequest.cs" />
|
||||
<Compile Include="Models\AzureConfiguration.cs" />
|
||||
<Compile Include="Models\ServerConfiguration.cs" />
|
||||
<Compile Include="Models\Organization.cs" />
|
||||
<Compile Include="Models\ProfileOrganizationResponse.cs" />
|
||||
<Compile Include="Models\SyncConfiguration.cs" />
|
||||
<Compile Include="Models\LdapConfiguration.cs" />
|
||||
<Compile Include="Models\LoginResult.cs" />
|
||||
<Compile Include="Models\ErrorResponse.cs" />
|
||||
<Compile Include="Models\EncryptedData.cs" />
|
||||
<Compile Include="Models\SyncResult.cs" />
|
||||
<Compile Include="Models\TokenRequest.cs" />
|
||||
<Compile Include="Models\ProfileResponse.cs" />
|
||||
<Compile Include="Models\TokenResponse.cs" />
|
||||
<Compile Include="Models\TwoFactorEmailRequest.cs" />
|
||||
<Compile Include="Services\ApiService.cs" />
|
||||
<Compile Include="Services\GSuiteDirectoryService.cs" />
|
||||
<Compile Include="Services\ControllerService.cs" />
|
||||
<Compile Include="Services\AzureDirectoryService.cs" />
|
||||
<Compile Include="Services\LdapDirectoryService.cs" />
|
||||
<Compile Include="Services\IDirectoryService.cs" />
|
||||
<Compile Include="Services\SettingsService.cs" />
|
||||
<Compile Include="Utilities\AzureAuthenticationProvider.cs" />
|
||||
<Compile Include="Utilities\Constants.cs" />
|
||||
<Compile Include="Utilities\Crypto.cs" />
|
||||
<Compile Include="Services\TokenService.cs" />
|
||||
<Compile Include="Services\AuthService.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Utilities\Extensions.cs" />
|
||||
<Compile Include="Utilities\Helpers.cs" />
|
||||
<Compile Include="Utilities\Sync.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="app.config" />
|
||||
<None Include="packages.config">
|
||||
<SubType>Designer</SubType>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup />
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
||||
@@ -1,16 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Bit.Core.Enums
|
||||
{
|
||||
public enum DirectoryType : byte
|
||||
{
|
||||
ActiveDirectory = 0,
|
||||
AzureActiveDirectory = 1,
|
||||
Other = 2,
|
||||
GSuite = 3
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Bit.Core.Enums
|
||||
{
|
||||
public enum OrganizationUserStatusType : byte
|
||||
{
|
||||
Invited = 0,
|
||||
Accepted = 1,
|
||||
Confirmed = 2
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Bit.Core.Enums
|
||||
{
|
||||
public enum OrganizationUserType : byte
|
||||
{
|
||||
Owner = 0,
|
||||
Admin = 1,
|
||||
User = 2
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
namespace Bit.Core.Enums
|
||||
{
|
||||
public enum TwoFactorProviderType : byte
|
||||
{
|
||||
Authenticator = 0,
|
||||
Email = 1,
|
||||
Duo = 2,
|
||||
YubiKey = 3,
|
||||
U2f = 4,
|
||||
Remember = 5
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Bit.Core.Enums
|
||||
{
|
||||
[Flags]
|
||||
public enum UserAccountControl : int
|
||||
{
|
||||
AccountDisabled = 0x00000002,
|
||||
LockOut = 0x00000010,
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Bit.Core.Models
|
||||
{
|
||||
public class ApiError
|
||||
{
|
||||
public string Message { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
|
||||
namespace Bit.Core.Models
|
||||
{
|
||||
public class ApiResult<T>
|
||||
{
|
||||
private List<ApiError> m_errors = new List<ApiError>();
|
||||
|
||||
public bool Succeeded { get; private set; }
|
||||
public T Result { get; set; }
|
||||
public IEnumerable<ApiError> Errors => m_errors;
|
||||
public HttpStatusCode StatusCode { get; private set; }
|
||||
|
||||
public static ApiResult<T> Success(T result, HttpStatusCode statusCode)
|
||||
{
|
||||
return new ApiResult<T>
|
||||
{
|
||||
Succeeded = true,
|
||||
Result = result,
|
||||
StatusCode = statusCode
|
||||
};
|
||||
}
|
||||
|
||||
public static ApiResult<T> Failed(HttpStatusCode statusCode, params ApiError[] errors)
|
||||
{
|
||||
var result = new ApiResult<T>
|
||||
{
|
||||
Succeeded = false,
|
||||
StatusCode = statusCode
|
||||
};
|
||||
|
||||
if(errors != null)
|
||||
{
|
||||
result.m_errors.AddRange(errors);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
public class ApiResult
|
||||
{
|
||||
private List<ApiError> m_errors = new List<ApiError>();
|
||||
|
||||
public bool Succeeded { get; private set; }
|
||||
public IEnumerable<ApiError> Errors => m_errors;
|
||||
public HttpStatusCode StatusCode { get; private set; }
|
||||
|
||||
public static ApiResult Success(HttpStatusCode statusCode)
|
||||
{
|
||||
return new ApiResult
|
||||
{
|
||||
Succeeded = true,
|
||||
StatusCode = statusCode
|
||||
};
|
||||
}
|
||||
|
||||
public static ApiResult Failed(HttpStatusCode statusCode, params ApiError[] errors)
|
||||
{
|
||||
var result = new ApiResult
|
||||
{
|
||||
Succeeded = false,
|
||||
StatusCode = statusCode
|
||||
};
|
||||
|
||||
if(errors != null)
|
||||
{
|
||||
result.m_errors.AddRange(errors);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.DirectoryServices;
|
||||
|
||||
namespace Bit.Core.Models
|
||||
{
|
||||
public class AzureConfiguration
|
||||
{
|
||||
public string Tenant { get; set; } = "yourcompany.onmicrosoft.com";
|
||||
public string Id { get; set; }
|
||||
public EncryptedData Secret { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Bit.Core.Models
|
||||
{
|
||||
public class EncryptedData
|
||||
{
|
||||
public EncryptedData() { }
|
||||
|
||||
public EncryptedData(byte[] plainValue)
|
||||
{
|
||||
IV = RandomBytes();
|
||||
Value = ProtectedData.Protect(plainValue, IV, DataProtectionScope.LocalMachine);
|
||||
}
|
||||
|
||||
public EncryptedData(string plainValue)
|
||||
{
|
||||
var bytes = Encoding.UTF8.GetBytes(plainValue);
|
||||
IV = RandomBytes();
|
||||
Value = ProtectedData.Protect(bytes, IV, DataProtectionScope.LocalMachine);
|
||||
}
|
||||
|
||||
public byte[] Value { get; set; }
|
||||
public byte[] IV { get; set; }
|
||||
|
||||
public byte[] Decrypt()
|
||||
{
|
||||
return ProtectedData.Unprotect(Value, IV, DataProtectionScope.LocalMachine);
|
||||
}
|
||||
|
||||
public string DecryptToString()
|
||||
{
|
||||
var bytes = ProtectedData.Unprotect(Value, IV, DataProtectionScope.LocalMachine);
|
||||
return Encoding.UTF8.GetString(bytes);
|
||||
}
|
||||
|
||||
private byte[] RandomBytes()
|
||||
{
|
||||
var entropy = new byte[16];
|
||||
new RNGCryptoServiceProvider().GetBytes(entropy);
|
||||
return entropy;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Bit.Core.Models
|
||||
{
|
||||
public abstract class Entry
|
||||
{
|
||||
public string ReferenceId { get; set; }
|
||||
public string ExternalId { get; set; }
|
||||
public DateTime? CreationDate { get; set; }
|
||||
public DateTime? RevisionDate { get; set; }
|
||||
}
|
||||
|
||||
public class GroupEntry : Entry
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public HashSet<string> UserMemberExternalIds { get; set; } = new HashSet<string>();
|
||||
public HashSet<string> GroupMemberReferenceIds { get; set; } = new HashSet<string>();
|
||||
}
|
||||
|
||||
public class UserEntry : Entry
|
||||
{
|
||||
public string Email { get; set; }
|
||||
public bool Disabled { get; set; }
|
||||
public bool Deleted { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Bit.Core.Models
|
||||
{
|
||||
public class ErrorResponse
|
||||
{
|
||||
public string Message { get; set; }
|
||||
public Dictionary<string, IEnumerable<string>> ValidationErrors { get; set; }
|
||||
// For use in development environments.
|
||||
public string ExceptionMessage { get; set; }
|
||||
public string ExceptionStackTrace { get; set; }
|
||||
public string InnerExceptionMessage { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
namespace Bit.Core.Models
|
||||
{
|
||||
public class GSuiteConfiguration
|
||||
{
|
||||
public string SecretFile { get; set; } = "client_secret.json";
|
||||
public string Customer { get; set; }
|
||||
public string Domain { get; set; } = "yourcompany.com";
|
||||
public string AdminUser { get; set; } = "adminuser@yourcompany.com";
|
||||
}
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
using Bit.Core.Services;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Bit.Core.Models
|
||||
{
|
||||
public class ImportRequest
|
||||
{
|
||||
public ImportRequest(List<GroupEntry> groups, List<UserEntry> users)
|
||||
{
|
||||
Groups = groups?.Select(g => new Group(g)).ToArray() ?? new Group[] { };
|
||||
Users = users?.Select(u => new User(u)).ToArray() ?? new User[] { };
|
||||
}
|
||||
|
||||
public Group[] Groups { get; set; }
|
||||
public User[] Users { get; set; }
|
||||
|
||||
public class Group
|
||||
{
|
||||
public Group(GroupEntry entry)
|
||||
{
|
||||
Name = entry.Name;
|
||||
ExternalId = entry.ExternalId;
|
||||
Users = entry.UserMemberExternalIds;
|
||||
}
|
||||
|
||||
public string Name { get; set; }
|
||||
public string ExternalId { get; set; }
|
||||
public IEnumerable<string> Users { get; set; }
|
||||
}
|
||||
|
||||
public class User
|
||||
{
|
||||
public User(UserEntry entry)
|
||||
{
|
||||
Email = entry.Email;
|
||||
Deleted = (SettingsService.Instance.Sync.RemoveDisabledUsers && entry.Disabled) || entry.Deleted;
|
||||
ExternalId = entry.ExternalId;
|
||||
}
|
||||
|
||||
public string ExternalId { get; set; }
|
||||
public string Email { get; set; }
|
||||
public bool Deleted { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
using Bit.Core.Services;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.DirectoryServices;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Bit.Core.Models
|
||||
{
|
||||
public class LdapConfiguration
|
||||
{
|
||||
public string Address { get; set; }
|
||||
public string Port { get; set; } = "389";
|
||||
public string Path { get; set; }
|
||||
public string Username { get; set; }
|
||||
public EncryptedData Password { get; set; }
|
||||
public Enums.DirectoryType Type { get; set; } = Enums.DirectoryType.ActiveDirectory;
|
||||
|
||||
public DirectoryEntry GetUserDirectoryEntry()
|
||||
{
|
||||
return GetPathedDirectoryEntry(SettingsService.Instance.Sync.Ldap.UserPath);
|
||||
}
|
||||
|
||||
public DirectoryEntry GetGroupDirectoryEntry()
|
||||
{
|
||||
return GetPathedDirectoryEntry(SettingsService.Instance.Sync.Ldap.GroupPath);
|
||||
}
|
||||
|
||||
public DirectoryEntry GetPathedDirectoryEntry(string pathPrefix = null)
|
||||
{
|
||||
var path = Path;
|
||||
if(!string.IsNullOrWhiteSpace(pathPrefix))
|
||||
{
|
||||
path = string.Concat(pathPrefix, ",", path);
|
||||
}
|
||||
|
||||
return GetDirectoryEntry(path);
|
||||
}
|
||||
|
||||
public DirectoryEntry GetBasePathDirectoryEntry()
|
||||
{
|
||||
var path = Path.Substring(Path.IndexOf("dc=", StringComparison.InvariantCultureIgnoreCase));
|
||||
return GetDirectoryEntry(path);
|
||||
}
|
||||
|
||||
public DirectoryEntry GetDirectoryEntry(string path = null)
|
||||
{
|
||||
if(Password == null && string.IsNullOrWhiteSpace(Username))
|
||||
{
|
||||
return new DirectoryEntry(ServerPath(path));
|
||||
}
|
||||
else
|
||||
{
|
||||
return new DirectoryEntry(ServerPath(path), Username, Password.DecryptToString(), AuthenticationTypes.None);
|
||||
}
|
||||
}
|
||||
|
||||
private string ServerPath(string path)
|
||||
{
|
||||
return $"LDAP://{Address}:{Port}/{path}";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
using Bit.Core.Enums;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Bit.Core.Models
|
||||
{
|
||||
public class LoginResult
|
||||
{
|
||||
public bool Success { get; set; }
|
||||
public string ErrorMessage { get; set; }
|
||||
public bool TwoFactorRequired => TwoFactorProviders != null && TwoFactorProviders.Count > 0;
|
||||
public Dictionary<TwoFactorProviderType, Dictionary<string, object>> TwoFactorProviders { get; set; }
|
||||
public string MasterPasswordHash { get; set; }
|
||||
public List<Organization> Organizations { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Bit.Core.Models
|
||||
{
|
||||
public class Organization
|
||||
{
|
||||
public Organization() { }
|
||||
|
||||
public Organization(ProfileOrganizationResponseModel org)
|
||||
{
|
||||
Name = org.Name;
|
||||
Id = org.Id;
|
||||
}
|
||||
|
||||
public string Name { get; set; }
|
||||
public string Id { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
using Bit.Core.Enums;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Bit.Core.Models
|
||||
{
|
||||
public class ProfileOrganizationResponseModel
|
||||
{
|
||||
public string Id { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string Key { get; set; }
|
||||
public OrganizationUserStatusType Status { get; set; }
|
||||
public OrganizationUserType Type { get; set; }
|
||||
public bool Enabled { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Bit.Core.Models
|
||||
{
|
||||
public class ProfileResponse
|
||||
{
|
||||
public string Id { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string Email { get; set; }
|
||||
public string MasterPasswordHint { get; set; }
|
||||
public string Culture { get; set; }
|
||||
public bool TwoFactorEnabled { get; set; }
|
||||
public IEnumerable<ProfileOrganizationResponseModel> Organizations { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.DirectoryServices;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Bit.Core.Models
|
||||
{
|
||||
public class ServerConfiguration
|
||||
{
|
||||
public Enums.DirectoryType Type { get; set; } = Enums.DirectoryType.ActiveDirectory;
|
||||
public LdapConfiguration Ldap { get; set; }
|
||||
public AzureConfiguration Azure { get; set; }
|
||||
public GSuiteConfiguration GSuite { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,109 +0,0 @@
|
||||
using Bit.Core.Enums;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.DirectoryServices;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Bit.Core.Models
|
||||
{
|
||||
public class SyncConfiguration
|
||||
{
|
||||
public SyncConfiguration() { }
|
||||
|
||||
public SyncConfiguration(DirectoryType type)
|
||||
{
|
||||
Ldap = new LdapSyncConfiguration(type);
|
||||
|
||||
switch(type)
|
||||
{
|
||||
case DirectoryType.ActiveDirectory:
|
||||
break;
|
||||
case DirectoryType.AzureActiveDirectory:
|
||||
break;
|
||||
case DirectoryType.Other:
|
||||
break;
|
||||
case DirectoryType.GSuite:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Depending on what server type you are using, filters are be one of the following:
|
||||
*
|
||||
* 1. ActiveDirectory or Other
|
||||
* - LDAP query/filter syntax
|
||||
* - Read more at: http://bit.ly/2qyLpzW
|
||||
* - ex. "(&(givenName=John)(|(l=Dallas)(l=Austin)))"
|
||||
*
|
||||
* 2. AzureActiveDirectory
|
||||
* - OData syntax for a Microsoft Graph query parameter '$filter'
|
||||
* - Read more at http://bit.ly/2q3FOOD
|
||||
* - ex. "startswith(displayName,'J')"
|
||||
*
|
||||
* 3. G Suite
|
||||
* - Group Filter
|
||||
* - Custom filtering syntax that allows you to exclude or include a comma separated list of group names.
|
||||
* - ex. "include:Group A,Sales People,My Other Group"
|
||||
* or "exclude:Group C,Developers,Some Other Group"
|
||||
* - User Filter
|
||||
* - Custom filtering syntax that allows you to exclude or include a comma separated list of group names.
|
||||
* - Allows you to concatenate a G Suite Admin API user search query to the end of the filter after delimiting
|
||||
* the include/exclude filter with a pipe (|).
|
||||
* - Read more at http://bit.ly/2rlTskX
|
||||
* - ex.
|
||||
* or "include:joe@company.com,bill@company.com,tom@company.com"
|
||||
* or "exclude:john@company.com,bill@company.com|orgName=Engineering orgTitle:Manager"
|
||||
* or "|orgName=Engineering orgTitle:Manager"
|
||||
*/
|
||||
|
||||
public string GroupFilter { get; set; }
|
||||
public string UserFilter { get; set; }
|
||||
|
||||
public bool SyncGroups { get; set; } = true;
|
||||
public bool SyncUsers { get; set; } = true;
|
||||
public int IntervalMinutes { get; set; } = 5;
|
||||
public bool RemoveDisabledUsers { get; set; }
|
||||
public LdapSyncConfiguration Ldap { get; set; } = new LdapSyncConfiguration();
|
||||
|
||||
public class LdapSyncConfiguration
|
||||
{
|
||||
public LdapSyncConfiguration() { }
|
||||
|
||||
public LdapSyncConfiguration(DirectoryType type)
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case DirectoryType.ActiveDirectory:
|
||||
CreationDateAttribute = "whenCreated";
|
||||
RevisionDateAttribute = "whenChanged";
|
||||
UserEmailPrefixAttribute = "sAMAccountName";
|
||||
UserPath = "CN=Users";
|
||||
GroupPath = "CN=Users";
|
||||
break;
|
||||
case DirectoryType.Other:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public string UserPath { get; set; }
|
||||
public string GroupPath { get; set; }
|
||||
public string UserObjectClass { get; set; } = "person";
|
||||
public string GroupObjectClass { get; set; } = "group";
|
||||
public string MemberAttribute { get; set; } = "member";
|
||||
public string GroupNameAttribute { get; set; } = "name";
|
||||
public string UserEmailAttribute { get; set; } = "mail";
|
||||
public bool EmailPrefixSuffix { get; set; } = false;
|
||||
public string UserEmailPrefixAttribute { get; set; } = "cn";
|
||||
public string UserEmailSuffix { get; set; } = "@companyname.com";
|
||||
public string CreationDateAttribute { get; set; }
|
||||
public string RevisionDateAttribute { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Bit.Core.Models
|
||||
{
|
||||
public class SyncResult
|
||||
{
|
||||
public bool Success { get; set; }
|
||||
public string ErrorMessage { get; set; }
|
||||
public List<GroupEntry> Groups { get; set; } = new List<GroupEntry>();
|
||||
public List<UserEntry> Users { get; set; } = new List<UserEntry>();
|
||||
}
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
using Bit.Core.Enums;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Bit.Core.Models
|
||||
{
|
||||
public class TokenRequest
|
||||
{
|
||||
public string Email { get; set; }
|
||||
public string MasterPasswordHash { get; set; }
|
||||
public string Token { get; set; }
|
||||
public TwoFactorProviderType? Provider { get; set; }
|
||||
public bool Remember { get; set; }
|
||||
|
||||
public IDictionary<string, string> ToIdentityTokenRequest()
|
||||
{
|
||||
var dict = new Dictionary<string, string>
|
||||
{
|
||||
{ "grant_type", "password" },
|
||||
{ "username", Email },
|
||||
{ "password", MasterPasswordHash },
|
||||
{ "scope", "api offline_access" },
|
||||
{ "client_id", "connector" }
|
||||
};
|
||||
|
||||
if(Token != null && Provider.HasValue)
|
||||
{
|
||||
dict.Add("TwoFactorToken", Token);
|
||||
dict.Add("TwoFactorProvider", ((byte)(Provider.Value)).ToString());
|
||||
dict.Add("TwoFactorRemember", Remember ? "1" : "0");
|
||||
}
|
||||
|
||||
return dict;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
using Bit.Core.Enums;
|
||||
using Newtonsoft.Json;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Bit.Core.Models
|
||||
{
|
||||
public class TokenResponse
|
||||
{
|
||||
[JsonProperty("access_token")]
|
||||
public string AccessToken { get; set; }
|
||||
[JsonProperty("expires_in")]
|
||||
public long ExpiresIn { get; set; }
|
||||
[JsonProperty("refresh_token")]
|
||||
public string RefreshToken { get; set; }
|
||||
[JsonProperty("token_type")]
|
||||
public string TokenType { get; set; }
|
||||
public Dictionary<TwoFactorProviderType, Dictionary<string, object>> TwoFactorProviders2 { get; set; }
|
||||
public string PrivateKey { get; set; }
|
||||
public string TwoFactorToken { get; set; }
|
||||
public string Key { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
namespace Bit.Core.Models
|
||||
{
|
||||
public class TwoFactorEmailRequest
|
||||
{
|
||||
public string Email { get; set; }
|
||||
public string MasterPasswordHash { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("Core")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("Core")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2017")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("ae082484-a34c-4b3a-a69f-49e5ef298b27")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
@@ -1,322 +0,0 @@
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Models;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Bit.Core.Services
|
||||
{
|
||||
public class ApiService
|
||||
{
|
||||
private static ApiService _instance;
|
||||
|
||||
private ApiService()
|
||||
{
|
||||
Client = new HttpClient();
|
||||
}
|
||||
|
||||
public static ApiService Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
if(_instance == null)
|
||||
{
|
||||
_instance = new ApiService();
|
||||
}
|
||||
|
||||
return _instance;
|
||||
}
|
||||
}
|
||||
|
||||
protected HttpClient Client { get; private set; }
|
||||
|
||||
public virtual async Task<ApiResult<TokenResponse>> PostTokenAsync(TokenRequest requestObj)
|
||||
{
|
||||
var requestMessage = new HttpRequestMessage
|
||||
{
|
||||
Method = HttpMethod.Post,
|
||||
RequestUri = new Uri(string.Concat(SettingsService.Instance.IdentityBaseUrl, "/connect/token")),
|
||||
Content = new FormUrlEncodedContent(requestObj.ToIdentityTokenRequest())
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
var response = await Client.SendAsync(requestMessage).ConfigureAwait(false);
|
||||
var responseContent = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
|
||||
|
||||
if(!response.IsSuccessStatusCode)
|
||||
{
|
||||
var errorResponse = JObject.Parse(responseContent);
|
||||
if(errorResponse["TwoFactorProviders2"] != null)
|
||||
{
|
||||
return ApiResult<TokenResponse>.Success(new TokenResponse
|
||||
{
|
||||
TwoFactorProviders2 = errorResponse["TwoFactorProviders2"]
|
||||
.ToObject<Dictionary<TwoFactorProviderType, Dictionary<string, object>>>()
|
||||
}, response.StatusCode);
|
||||
}
|
||||
|
||||
return await HandleErrorAsync<TokenResponse>(response).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
var responseObj = JsonConvert.DeserializeObject<TokenResponse>(responseContent);
|
||||
return ApiResult<TokenResponse>.Success(responseObj, response.StatusCode);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return HandledWebException<TokenResponse>();
|
||||
}
|
||||
}
|
||||
|
||||
public virtual async Task<ApiResult> PostImportAsync(ImportRequest requestObj)
|
||||
{
|
||||
var tokenStateResponse = await HandleTokenStateAsync();
|
||||
if(!tokenStateResponse.Succeeded)
|
||||
{
|
||||
return tokenStateResponse;
|
||||
}
|
||||
|
||||
var stringContent = JsonConvert.SerializeObject(requestObj);
|
||||
var requestMessage = new HttpRequestMessage
|
||||
{
|
||||
Method = HttpMethod.Post,
|
||||
RequestUri = new Uri(string.Concat(SettingsService.Instance.ApiBaseUrl, "/organizations/",
|
||||
SettingsService.Instance.Organization.Id, "/import")),
|
||||
Content = new StringContent(stringContent, Encoding.UTF8, "application/json"),
|
||||
};
|
||||
|
||||
requestMessage.Headers.Add("Authorization", $"Bearer3 {TokenService.Instance.AccessToken}");
|
||||
|
||||
try
|
||||
{
|
||||
var response = await Client.SendAsync(requestMessage).ConfigureAwait(false);
|
||||
if(!response.IsSuccessStatusCode)
|
||||
{
|
||||
return await HandleErrorAsync(response).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
return ApiResult.Success(response.StatusCode);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return HandledWebException();
|
||||
}
|
||||
}
|
||||
|
||||
public virtual async Task<ApiResult<ProfileResponse>> GetProfileAsync()
|
||||
{
|
||||
var tokenStateResponse = await HandleTokenStateAsync<ProfileResponse>();
|
||||
if(!tokenStateResponse.Succeeded)
|
||||
{
|
||||
return tokenStateResponse;
|
||||
}
|
||||
|
||||
var requestMessage = new HttpRequestMessage()
|
||||
{
|
||||
Method = HttpMethod.Get,
|
||||
RequestUri = new Uri(string.Concat(SettingsService.Instance.ApiBaseUrl, "/accounts/profile")),
|
||||
};
|
||||
|
||||
requestMessage.Headers.Add("Authorization", $"Bearer3 {TokenService.Instance.AccessToken}");
|
||||
|
||||
try
|
||||
{
|
||||
var response = await Client.SendAsync(requestMessage).ConfigureAwait(false);
|
||||
if(!response.IsSuccessStatusCode)
|
||||
{
|
||||
return await HandleErrorAsync<ProfileResponse>(response).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
var responseContent = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
|
||||
var responseObj = JsonConvert.DeserializeObject<ProfileResponse>(responseContent);
|
||||
return ApiResult<ProfileResponse>.Success(responseObj, response.StatusCode);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return HandledWebException<ProfileResponse>();
|
||||
}
|
||||
}
|
||||
|
||||
public virtual async Task<ApiResult> PostTwoFactorSendEmailLoginAsync(TwoFactorEmailRequest requestObj)
|
||||
{
|
||||
var stringContent = JsonConvert.SerializeObject(requestObj);
|
||||
|
||||
var requestMessage = new HttpRequestMessage()
|
||||
{
|
||||
Method = HttpMethod.Post,
|
||||
RequestUri = new Uri(string.Concat(SettingsService.Instance.ApiBaseUrl, "/two-factor/send-email-login")),
|
||||
Content = new StringContent(stringContent, Encoding.UTF8, "application/json")
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
var response = await Client.SendAsync(requestMessage).ConfigureAwait(false);
|
||||
if(!response.IsSuccessStatusCode)
|
||||
{
|
||||
return await HandleErrorAsync(response).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
return ApiResult.Success(response.StatusCode);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return HandledWebException();
|
||||
}
|
||||
}
|
||||
|
||||
protected ApiResult HandledWebException()
|
||||
{
|
||||
return ApiResult.Failed(HttpStatusCode.BadGateway,
|
||||
new ApiError { Message = "There is a problem connecting to the server." });
|
||||
}
|
||||
|
||||
protected ApiResult<T> HandledWebException<T>()
|
||||
{
|
||||
return ApiResult<T>.Failed(HttpStatusCode.BadGateway,
|
||||
new ApiError { Message = "There is a problem connecting to the server." });
|
||||
}
|
||||
|
||||
protected async Task<ApiResult> HandleTokenStateAsync()
|
||||
{
|
||||
return await HandleTokenStateAsync(
|
||||
() => ApiResult.Success(HttpStatusCode.OK),
|
||||
() => HandledWebException(),
|
||||
(r) => HandleErrorAsync(r));
|
||||
}
|
||||
|
||||
protected async Task<ApiResult<T>> HandleTokenStateAsync<T>()
|
||||
{
|
||||
return await HandleTokenStateAsync(
|
||||
() => ApiResult<T>.Success(default(T), HttpStatusCode.OK),
|
||||
() => HandledWebException<T>(),
|
||||
(r) => HandleErrorAsync<T>(r));
|
||||
}
|
||||
|
||||
private async Task<T> HandleTokenStateAsync<T>(Func<T> success, Func<T> webException,
|
||||
Func<HttpResponseMessage, Task<T>> error)
|
||||
{
|
||||
if(TokenService.Instance.AccessTokenNeedsRefresh && !string.IsNullOrWhiteSpace(TokenService.Instance.RefreshToken))
|
||||
{
|
||||
var requestMessage = new HttpRequestMessage
|
||||
{
|
||||
Method = HttpMethod.Post,
|
||||
RequestUri = new Uri(string.Concat(SettingsService.Instance.IdentityBaseUrl, "/connect/token")),
|
||||
Content = new FormUrlEncodedContent(
|
||||
new Dictionary<string, string>
|
||||
{
|
||||
{ "grant_type", "refresh_token" },
|
||||
{ "client_id", "connector" },
|
||||
{ "refresh_token", TokenService.Instance.RefreshToken }
|
||||
})
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
var response = await Client.SendAsync(requestMessage).ConfigureAwait(false);
|
||||
if(!response.IsSuccessStatusCode)
|
||||
{
|
||||
if(response.StatusCode == HttpStatusCode.BadRequest)
|
||||
{
|
||||
response.StatusCode = HttpStatusCode.Unauthorized;
|
||||
}
|
||||
|
||||
return await error.Invoke(response).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
var responseContent = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
|
||||
var tokenResponse = JsonConvert.DeserializeObject<TokenResponse>(responseContent);
|
||||
TokenService.Instance.AccessToken = tokenResponse.AccessToken;
|
||||
TokenService.Instance.RefreshToken = tokenResponse.RefreshToken;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return webException.Invoke();
|
||||
}
|
||||
}
|
||||
|
||||
return success.Invoke();
|
||||
}
|
||||
|
||||
protected async Task<ApiResult<T>> HandleErrorAsync<T>(HttpResponseMessage response)
|
||||
{
|
||||
try
|
||||
{
|
||||
var errors = await ParseErrorsAsync(response).ConfigureAwait(false);
|
||||
return ApiResult<T>.Failed(response.StatusCode, errors.ToArray());
|
||||
}
|
||||
catch
|
||||
{ }
|
||||
|
||||
return ApiResult<T>.Failed(response.StatusCode,
|
||||
new ApiError { Message = "An unknown error has occurred." });
|
||||
}
|
||||
|
||||
protected async Task<ApiResult> HandleErrorAsync(HttpResponseMessage response)
|
||||
{
|
||||
try
|
||||
{
|
||||
var errors = await ParseErrorsAsync(response).ConfigureAwait(false);
|
||||
return ApiResult.Failed(response.StatusCode, errors.ToArray());
|
||||
}
|
||||
catch
|
||||
{ }
|
||||
|
||||
return ApiResult.Failed(response.StatusCode,
|
||||
new ApiError { Message = "An unknown error has occurred." });
|
||||
}
|
||||
|
||||
private async Task<List<ApiError>> ParseErrorsAsync(HttpResponseMessage response)
|
||||
{
|
||||
var errors = new List<ApiError>();
|
||||
var statusCode = (int)response.StatusCode;
|
||||
if(statusCode >= 400 && statusCode <= 500)
|
||||
{
|
||||
ErrorResponse errorResponseModel = null;
|
||||
|
||||
var responseContent = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
|
||||
if(!string.IsNullOrWhiteSpace(responseContent))
|
||||
{
|
||||
var errorResponse = JObject.Parse(responseContent);
|
||||
if(errorResponse["ErrorModel"] != null && errorResponse["ErrorModel"]["Message"] != null)
|
||||
{
|
||||
errorResponseModel = errorResponse["ErrorModel"].ToObject<ErrorResponse>();
|
||||
}
|
||||
else if(errorResponse["Message"] != null)
|
||||
{
|
||||
errorResponseModel = errorResponse.ToObject<ErrorResponse>();
|
||||
}
|
||||
}
|
||||
|
||||
if(errorResponseModel != null)
|
||||
{
|
||||
if((errorResponseModel.ValidationErrors?.Count ?? 0) > 0)
|
||||
{
|
||||
foreach(var valError in errorResponseModel.ValidationErrors)
|
||||
{
|
||||
foreach(var errorMessage in valError.Value)
|
||||
{
|
||||
errors.Add(new ApiError { Message = errorMessage });
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
errors.Add(new ApiError { Message = errorResponseModel.Message });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(errors.Count == 0)
|
||||
{
|
||||
errors.Add(new ApiError { Message = "An unknown error has occurred." });
|
||||
}
|
||||
|
||||
return errors;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,159 +0,0 @@
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Models;
|
||||
using Bit.Core.Utilities;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Security;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Bit.Core.Services
|
||||
{
|
||||
public class AuthService
|
||||
{
|
||||
private static AuthService _instance;
|
||||
|
||||
private AuthService() { }
|
||||
|
||||
public static AuthService Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
if(_instance == null)
|
||||
{
|
||||
_instance = new AuthService();
|
||||
}
|
||||
|
||||
return _instance;
|
||||
}
|
||||
}
|
||||
|
||||
public bool Authenticated => !string.IsNullOrWhiteSpace(TokenService.Instance.AccessToken);
|
||||
public bool OrganizationSet => SettingsService.Instance.Organization != null;
|
||||
|
||||
public void LogOut()
|
||||
{
|
||||
TokenService.Instance.AccessToken = null;
|
||||
TokenService.Instance.RefreshToken = null;
|
||||
}
|
||||
|
||||
public async Task<LoginResult> LogInAsync(string email, string masterPassword)
|
||||
{
|
||||
var normalizedEmail = email.Trim().ToLower();
|
||||
var key = Crypto.MakeKeyFromPassword(masterPassword, normalizedEmail);
|
||||
|
||||
var request = new TokenRequest
|
||||
{
|
||||
Email = normalizedEmail,
|
||||
MasterPasswordHash = Crypto.HashPasswordBase64(key, masterPassword)
|
||||
};
|
||||
|
||||
var response = await ApiService.Instance.PostTokenAsync(request);
|
||||
|
||||
masterPassword = null;
|
||||
key = null;
|
||||
|
||||
var result = new LoginResult();
|
||||
if(!response.Succeeded)
|
||||
{
|
||||
result.Success = false;
|
||||
result.ErrorMessage = response.Errors.FirstOrDefault()?.Message;
|
||||
return result;
|
||||
}
|
||||
|
||||
result.Success = true;
|
||||
if(response.Result.TwoFactorProviders2 != null && response.Result.TwoFactorProviders2.Count > 0)
|
||||
{
|
||||
result.TwoFactorProviders = response.Result.TwoFactorProviders2;
|
||||
result.MasterPasswordHash = request.MasterPasswordHash;
|
||||
return result;
|
||||
}
|
||||
|
||||
return await ProcessLogInSuccessAsync(response.Result);
|
||||
}
|
||||
|
||||
public async Task<LoginResult> LogInTwoFactorAsync(TwoFactorProviderType type, string token, string email,
|
||||
string masterPassword)
|
||||
{
|
||||
var normalizedEmail = email.Trim().ToLower();
|
||||
var key = Crypto.MakeKeyFromPassword(masterPassword, normalizedEmail);
|
||||
|
||||
var result = await LogInTwoFactorWithHashAsync(type, token, email, Crypto.HashPasswordBase64(key, masterPassword));
|
||||
|
||||
key = null;
|
||||
masterPassword = null;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task<LoginResult> LogInTwoFactorWithHashAsync(TwoFactorProviderType type, string token, string email,
|
||||
string masterPasswordHash)
|
||||
{
|
||||
if(type == TwoFactorProviderType.Email || type == TwoFactorProviderType.Authenticator)
|
||||
{
|
||||
token = token.Trim().Replace(" ", "");
|
||||
}
|
||||
|
||||
var request = new TokenRequest
|
||||
{
|
||||
Email = email.Trim().ToLower(),
|
||||
MasterPasswordHash = masterPasswordHash,
|
||||
Token = token,
|
||||
Provider = type,
|
||||
Remember = false
|
||||
};
|
||||
|
||||
var response = await ApiService.Instance.PostTokenAsync(request);
|
||||
|
||||
if(!response.Succeeded)
|
||||
{
|
||||
var result = new LoginResult();
|
||||
result.Success = false;
|
||||
result.ErrorMessage = response.Errors.FirstOrDefault()?.Message;
|
||||
return result;
|
||||
}
|
||||
|
||||
return await ProcessLogInSuccessAsync(response.Result);
|
||||
}
|
||||
|
||||
private async Task<LoginResult> ProcessLogInSuccessAsync(TokenResponse response)
|
||||
{
|
||||
TokenService.Instance.AccessToken = response.AccessToken;
|
||||
TokenService.Instance.RefreshToken = response.RefreshToken;
|
||||
|
||||
var result = new LoginResult();
|
||||
|
||||
var profile = await ApiService.Instance.GetProfileAsync();
|
||||
if(profile.Succeeded)
|
||||
{
|
||||
var adminOrgs = profile.Result.Organizations.Where(o =>
|
||||
o.Status == OrganizationUserStatusType.Confirmed &&
|
||||
o.Type != OrganizationUserType.User);
|
||||
if(!adminOrgs.Any())
|
||||
{
|
||||
LogOut();
|
||||
result.Success = false;
|
||||
result.ErrorMessage = "You are not an admin of any organizations.";
|
||||
return result;
|
||||
}
|
||||
|
||||
result.Organizations = adminOrgs.Select(o => new Organization(o)).ToList();
|
||||
if(result.Organizations.Count == 1)
|
||||
{
|
||||
SettingsService.Instance.Organization = new Organization(adminOrgs.First());
|
||||
}
|
||||
|
||||
result.Success = true;
|
||||
return result;
|
||||
}
|
||||
else
|
||||
{
|
||||
LogOut();
|
||||
result.Success = false;
|
||||
result.ErrorMessage = "Could not load profile.";
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||