mirror of
https://github.com/unraid/api.git
synced 2026-01-02 06:30:02 -06:00
Compare commits
1287 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6abddd85d2 | ||
|
|
29fd61be6c | ||
|
|
92f72e33ec | ||
|
|
26639d5139 | ||
|
|
19f9261025 | ||
|
|
e7b7caae43 | ||
|
|
4f5c367fdf | ||
|
|
321703e907 | ||
|
|
a21f39d617 | ||
|
|
3c357e7e95 | ||
|
|
f22b262830 | ||
|
|
e16763b49b | ||
|
|
133c8e0d70 | ||
|
|
1392bdeecb | ||
|
|
2fce2e9a28 | ||
|
|
430656f6af | ||
|
|
d7887c2183 | ||
|
|
ebd1a391b6 | ||
|
|
1f42bbb4aa | ||
|
|
5f59d31ab3 | ||
|
|
d8478152e9 | ||
|
|
63fcde8243 | ||
|
|
2bc9af2578 | ||
|
|
5b14be6b0f | ||
|
|
9ef56d8c05 | ||
|
|
c4204d89aa | ||
|
|
048a0a88dc | ||
|
|
7b3834ca1f | ||
|
|
0e9c91af86 | ||
|
|
a6f67060b4 | ||
|
|
3c61a615f0 | ||
|
|
073a51572a | ||
|
|
c00789865c | ||
|
|
9d1442b2ee | ||
|
|
935318dda6 | ||
|
|
dfb006e696 | ||
|
|
445f3b50b1 | ||
|
|
a12181a5e0 | ||
|
|
0cb0fc9881 | ||
|
|
42610d290d | ||
|
|
9e12407565 | ||
|
|
bb92c3f9f8 | ||
|
|
5b0971ea8d | ||
|
|
7f997663f9 | ||
|
|
8b75d6cc99 | ||
|
|
b1a993a8e9 | ||
|
|
b1a1779a8b | ||
|
|
36d8399045 | ||
|
|
6beafbe8ed | ||
|
|
a502134c0a | ||
|
|
fa16dcd801 | ||
|
|
d38f3ef49b | ||
|
|
ce92cb06b7 | ||
|
|
1d5c2c8338 | ||
|
|
0163acb7f3 | ||
|
|
5347d54b11 | ||
|
|
547ae180dd | ||
|
|
05f661e0e5 | ||
|
|
5d909a856b | ||
|
|
4d45caf258 | ||
|
|
805bc5bfc0 | ||
|
|
81d33f6b3a | ||
|
|
2a82ea4765 | ||
|
|
6bb3d55e3c | ||
|
|
8251c6f2d3 | ||
|
|
ad32cffd75 | ||
|
|
2b213619db | ||
|
|
61ee689658 | ||
|
|
904cd466db | ||
|
|
6cb28d5f8f | ||
|
|
c180728696 | ||
|
|
84752043e5 | ||
|
|
c112f19c95 | ||
|
|
9acb2926da | ||
|
|
29d216ece7 | ||
|
|
5f597f9d4c | ||
|
|
d26ddef33e | ||
|
|
21208bfcf6 | ||
|
|
6c46f9413f | ||
|
|
b56b2157fa | ||
|
|
2108ed0ecd | ||
|
|
9c5e418872 | ||
|
|
c4d731401c | ||
|
|
7e5dd07d4a | ||
|
|
62824ba76f | ||
|
|
e58410bd57 | ||
|
|
e88593620b | ||
|
|
8026ef53e8 | ||
|
|
1ecac5ee4e | ||
|
|
e7d15ee5ec | ||
|
|
c3f4cf53c1 | ||
|
|
d8a5b1711a | ||
|
|
8481c9a9fb | ||
|
|
ddfc36fd73 | ||
|
|
3cc3f27dae | ||
|
|
097415f6b8 | ||
|
|
b1d9ad7ef1 | ||
|
|
c7d4e39287 | ||
|
|
0c6f44da35 | ||
|
|
4655d72fbb | ||
|
|
4b3d6a7ba3 | ||
|
|
ed18945088 | ||
|
|
69cd92f974 | ||
|
|
74b9fd0159 | ||
|
|
ff63535b00 | ||
|
|
76711be3e8 | ||
|
|
961bcc5db6 | ||
|
|
0cfdd5a61b | ||
|
|
8d905974be | ||
|
|
132840b0ef | ||
|
|
e4ebfc8a13 | ||
|
|
8483143a40 | ||
|
|
d6fa35cdee | ||
|
|
8a374b5b27 | ||
|
|
b73623e72a | ||
|
|
bddda823e1 | ||
|
|
bb37140d40 | ||
|
|
4d8f2ddac6 | ||
|
|
5afa76043f | ||
|
|
14fe30e925 | ||
|
|
eb1c62d3d9 | ||
|
|
f62f0d3a0f | ||
|
|
e7b689c546 | ||
|
|
b9249544fc | ||
|
|
cdfb3c772b | ||
|
|
f1e53831c8 | ||
|
|
32f9c50227 | ||
|
|
a8211cef7d | ||
|
|
e338eb9788 | ||
|
|
dae57389c6 | ||
|
|
44d3d939a7 | ||
|
|
6bfd8a2687 | ||
|
|
923e929878 | ||
|
|
2ad612cef8 | ||
|
|
1756cc5b4b | ||
|
|
3a8c9b13ee | ||
|
|
daf904bc1b | ||
|
|
632775e435 | ||
|
|
e33c7583f7 | ||
|
|
55100daed4 | ||
|
|
b9d9105e3e | ||
|
|
3734730bf7 | ||
|
|
c1fe95fcb6 | ||
|
|
a1351b0469 | ||
|
|
f0395bdf47 | ||
|
|
76cf6f35dc | ||
|
|
ca94cc8602 | ||
|
|
f560df0270 | ||
|
|
bb95795a31 | ||
|
|
cbb42dc85e | ||
|
|
060a1992c4 | ||
|
|
a1cf44162a | ||
|
|
1e6fb7e3e3 | ||
|
|
336478c2e0 | ||
|
|
895d5857f9 | ||
|
|
5ca225fe7a | ||
|
|
6faef27d7c | ||
|
|
bc04129342 | ||
|
|
b63720a6f2 | ||
|
|
29a8689ad8 | ||
|
|
3042ffa37e | ||
|
|
942b143fba | ||
|
|
75d7e08824 | ||
|
|
f30292484d | ||
|
|
3867dfacb2 | ||
|
|
0da77d7119 | ||
|
|
09f741557b | ||
|
|
ae753d6bea | ||
|
|
56cfa84794 | ||
|
|
065211413d | ||
|
|
1854aa9f28 | ||
|
|
cb59090698 | ||
|
|
81f051e02c | ||
|
|
11ff890bcc | ||
|
|
3abf20b347 | ||
|
|
6f5edb2406 | ||
|
|
428ad15ec7 | ||
|
|
bd584902e0 | ||
|
|
aae38e3404 | ||
|
|
e5d1146613 | ||
|
|
b3551a1b69 | ||
|
|
76a9ae9386 | ||
|
|
92799312c9 | ||
|
|
b969f3a9ab | ||
|
|
3419837eb5 | ||
|
|
2b25537e26 | ||
|
|
2d3892deb8 | ||
|
|
0ab40fefda | ||
|
|
58f65eabba | ||
|
|
89d756ef4e | ||
|
|
a1a046f900 | ||
|
|
d844903d78 | ||
|
|
29ca5829ff | ||
|
|
27049d9d91 | ||
|
|
03e336b72f | ||
|
|
c2e29dfb5f | ||
|
|
e9bd18a409 | ||
|
|
02c197f244 | ||
|
|
6f9977eea0 | ||
|
|
05e77a4bc6 | ||
|
|
a892a3ce35 | ||
|
|
33dd90af04 | ||
|
|
7fa849d2a0 | ||
|
|
7ceac1b184 | ||
|
|
3348a47470 | ||
|
|
85cdb8f525 | ||
|
|
796cb09c61 | ||
|
|
a554bde5c2 | ||
|
|
3acc0dc9c0 | ||
|
|
c163998175 | ||
|
|
4fbbbd7f6a | ||
|
|
203c2b88ac | ||
|
|
746d1a8aaa | ||
|
|
c0d3cf5782 | ||
|
|
64d3765a9a | ||
|
|
5dd36d1836 | ||
|
|
4264557789 | ||
|
|
344b023503 | ||
|
|
0331e24a74 | ||
|
|
2b597f9f02 | ||
|
|
bd31e09bcf | ||
|
|
6c73cbf4ad | ||
|
|
4b4aadb5f1 | ||
|
|
5ddecce21c | ||
|
|
6669a963af | ||
|
|
8d386043ae | ||
|
|
16f00a0d8c | ||
|
|
a4e2a77410 | ||
|
|
91a9949a5c | ||
|
|
235746c0ba | ||
|
|
e366cad0a4 | ||
|
|
83344e05c1 | ||
|
|
61ec04cb87 | ||
|
|
a947ff14fa | ||
|
|
5dfd6d5ded | ||
|
|
71e2b70678 | ||
|
|
4daa54cfb5 | ||
|
|
7ef3729769 | ||
|
|
46a368e1b5 | ||
|
|
b53bb3f197 | ||
|
|
1935ba1a7f | ||
|
|
14abc13cc8 | ||
|
|
c3548d5122 | ||
|
|
6c54fa14b1 | ||
|
|
8b93bcea08 | ||
|
|
a6cd74dc5c | ||
|
|
aa1ef1bd4c | ||
|
|
2cdc02f64a | ||
|
|
d0819b8d02 | ||
|
|
74b3e29c74 | ||
|
|
b32f84b105 | ||
|
|
806bd633ac | ||
|
|
e5e1c43bb3 | ||
|
|
3b2d61efc2 | ||
|
|
fe98295496 | ||
|
|
b9947108a4 | ||
|
|
3c27b51ab8 | ||
|
|
2327b00d30 | ||
|
|
bf3b00fbaf | ||
|
|
4f04f93033 | ||
|
|
5dc13755df | ||
|
|
69a34aca14 | ||
|
|
bbc1e02782 | ||
|
|
e77db18870 | ||
|
|
b6805d439e | ||
|
|
f37dda16c2 | ||
|
|
88be62317f | ||
|
|
6b5e012950 | ||
|
|
e05a05926d | ||
|
|
c817cc4b7e | ||
|
|
491b5fe8bc | ||
|
|
8675653e4e | ||
|
|
1f9e282880 | ||
|
|
90cf2c8a16 | ||
|
|
729ed42329 | ||
|
|
309d221542 | ||
|
|
859440386e | ||
|
|
ceac6269b3 | ||
|
|
286ffc54e5 | ||
|
|
84f4f67ce1 | ||
|
|
8827483699 | ||
|
|
f8393eeebe | ||
|
|
5d72b5a970 | ||
|
|
1f5c6424c7 | ||
|
|
39612cd978 | ||
|
|
b1b93e2783 | ||
|
|
eff6c32ccd | ||
|
|
b1ac0f9c83 | ||
|
|
d88b1e9660 | ||
|
|
124fb610b1 | ||
|
|
143515560c | ||
|
|
f0f5a3057a | ||
|
|
4404208deb | ||
|
|
f45719fa6b | ||
|
|
acba0b0365 | ||
|
|
8760a66907 | ||
|
|
5f81c4bd27 | ||
|
|
2310d53684 | ||
|
|
5b3ec8304c | ||
|
|
7a009b6be7 | ||
|
|
be7135efdd | ||
|
|
939383e4ef | ||
|
|
0042f14ab3 | ||
|
|
3e8c101edd | ||
|
|
477c113ce1 | ||
|
|
caf797cf4a | ||
|
|
73a12496d5 | ||
|
|
cea11daf15 | ||
|
|
bb6baf9bf4 | ||
|
|
5f1a61d4aa | ||
|
|
bbf28075c6 | ||
|
|
7dcf947527 | ||
|
|
4ee42a6cf6 | ||
|
|
91de6e6c1e | ||
|
|
e2a1f27b22 | ||
|
|
4e9ab645e6 | ||
|
|
7828ef2648 | ||
|
|
dfa27e2c0d | ||
|
|
9d2405bd21 | ||
|
|
e1515a118a | ||
|
|
961c343f5d | ||
|
|
6cbb9c07e4 | ||
|
|
833a99fe18 | ||
|
|
943c907d03 | ||
|
|
d28fb24d68 | ||
|
|
0c1b89ff41 | ||
|
|
cead97560c | ||
|
|
5f0446fa79 | ||
|
|
000692ca50 | ||
|
|
d8f9f03146 | ||
|
|
29035429bd | ||
|
|
5f8602b864 | ||
|
|
77558a5cd9 | ||
|
|
116efe6f72 | ||
|
|
8e0962adba | ||
|
|
d23a38960b | ||
|
|
d5f5921534 | ||
|
|
a52cc7861c | ||
|
|
0d6a0035aa | ||
|
|
0fa41f5690 | ||
|
|
45327ce01d | ||
|
|
11ce9e2644 | ||
|
|
00b8ffe87d | ||
|
|
4eda0991d6 | ||
|
|
9a869a49e3 | ||
|
|
7ef3286191 | ||
|
|
cb91fbb054 | ||
|
|
c6547a51fc | ||
|
|
24435613f8 | ||
|
|
4a29fc9dda | ||
|
|
2ef9fbb20e | ||
|
|
a09f7c935d | ||
|
|
29d9371cc3 | ||
|
|
ef82ec5af5 | ||
|
|
cf72c8b359 | ||
|
|
0705764385 | ||
|
|
ea6ae83919 | ||
|
|
478254e134 | ||
|
|
8f5814589e | ||
|
|
dab6985297 | ||
|
|
e40a9ebecd | ||
|
|
bc4708f405 | ||
|
|
99704a9dbb | ||
|
|
23b1f1ac73 | ||
|
|
a5cf63fe28 | ||
|
|
78ec4663cc | ||
|
|
a3b171f58d | ||
|
|
060fb91546 | ||
|
|
af1994cb62 | ||
|
|
bad7f71fea | ||
|
|
a355a64136 | ||
|
|
cf08627725 | ||
|
|
6962cdd214 | ||
|
|
a39da15be4 | ||
|
|
bb555f8296 | ||
|
|
9a0d63d4ee | ||
|
|
9bbab0f86c | ||
|
|
349145ba53 | ||
|
|
c12d8dae4e | ||
|
|
b1a2ba78cc | ||
|
|
2409ef2dd6 | ||
|
|
0055637602 | ||
|
|
547b75a55e | ||
|
|
c36082e82b | ||
|
|
0f3bebf859 | ||
|
|
96f3902b57 | ||
|
|
b9cd8c426d | ||
|
|
7c8e8a0e53 | ||
|
|
801abac06b | ||
|
|
3fe13d5235 | ||
|
|
eeb3289ae8 | ||
|
|
939d7a304d | ||
|
|
acccb3694c | ||
|
|
2724485989 | ||
|
|
2f4ff21986 | ||
|
|
83e00c640a | ||
|
|
abcaa5aedb | ||
|
|
4c663dc69c | ||
|
|
89eb841b20 | ||
|
|
7296195495 | ||
|
|
696b55de6c | ||
|
|
aa5fad39f3 | ||
|
|
9c38fa6a9c | ||
|
|
da5d1132d1 | ||
|
|
001be86181 | ||
|
|
ecfc797e7d | ||
|
|
dffbfc2dab | ||
|
|
e5f029830b | ||
|
|
1a33e6343a | ||
|
|
69441d890e | ||
|
|
46c82ecae3 | ||
|
|
0b469f5b3f | ||
|
|
3fc41480a2 | ||
|
|
e27776df3d | ||
|
|
abd8e09908 | ||
|
|
504283f227 | ||
|
|
ff7e09e15c | ||
|
|
deb42f6a81 | ||
|
|
95d018ea05 | ||
|
|
106b2e42c0 | ||
|
|
1c5ff58d2d | ||
|
|
d7bab9f443 | ||
|
|
902c76c759 | ||
|
|
5e50f24d70 | ||
|
|
4f0210d16a | ||
|
|
ddb8772692 | ||
|
|
787f8b9bf5 | ||
|
|
61ba324ca0 | ||
|
|
a230a33df5 | ||
|
|
84b234c9cf | ||
|
|
9bfc04c2a5 | ||
|
|
e84430471d | ||
|
|
2d60045784 | ||
|
|
e9137f2553 | ||
|
|
dbe0dd5dfb | ||
|
|
9d2796f2c9 | ||
|
|
972a19be04 | ||
|
|
c8da8fe314 | ||
|
|
353132b67a | ||
|
|
88b7cbfe95 | ||
|
|
3ed1d10c98 | ||
|
|
62693cfcc0 | ||
|
|
810708f775 | ||
|
|
08f6d6df65 | ||
|
|
da673c3f2b | ||
|
|
cb463bfdd0 | ||
|
|
7177171b75 | ||
|
|
9f0ab7fa38 | ||
|
|
a32374a3ac | ||
|
|
cb6534d9d9 | ||
|
|
2eaf175515 | ||
|
|
50376a0d66 | ||
|
|
4b2007b689 | ||
|
|
72fcaca4f3 | ||
|
|
2f48ddf942 | ||
|
|
62dfa6c83a | ||
|
|
27bb375460 | ||
|
|
cc4d5bdefb | ||
|
|
f55302c130 | ||
|
|
b8dbe3f9d9 | ||
|
|
20771f61a8 | ||
|
|
b9b8bbe871 | ||
|
|
b8e61007e3 | ||
|
|
49536032df | ||
|
|
9229cf3df6 | ||
|
|
58665a4e98 | ||
|
|
885d1537b6 | ||
|
|
198cfe5015 | ||
|
|
42189dd451 | ||
|
|
6122b3c001 | ||
|
|
cda7368d3d | ||
|
|
447cecd19d | ||
|
|
7321bd0088 | ||
|
|
67e898efe1 | ||
|
|
41e5de83a2 | ||
|
|
5c020a62d6 | ||
|
|
1393e967fa | ||
|
|
f07c14354f | ||
|
|
d42a426244 | ||
|
|
125bc29166 | ||
|
|
a6333bf5a2 | ||
|
|
e8e985ad6a | ||
|
|
1a598885cc | ||
|
|
d73f267245 | ||
|
|
7c1873249e | ||
|
|
09f33a0127 | ||
|
|
db00d7442d | ||
|
|
724159314c | ||
|
|
180f115b71 | ||
|
|
eb38eb219e | ||
|
|
3da701a53b | ||
|
|
6e5b2f1f67 | ||
|
|
812053d7a4 | ||
|
|
a929c7e3b3 | ||
|
|
c0179c8351 | ||
|
|
d5c7be54b0 | ||
|
|
32478f34c2 | ||
|
|
4daa09b340 | ||
|
|
346ce91f73 | ||
|
|
cee3a6d0ef | ||
|
|
e90f606f43 | ||
|
|
05fa344454 | ||
|
|
406c400bd2 | ||
|
|
1ae466899e | ||
|
|
5178e131ce | ||
|
|
0bd11bce5a | ||
|
|
fddde33977 | ||
|
|
1f5df845eb | ||
|
|
ef54af655e | ||
|
|
bb44862b7b | ||
|
|
9709dc82ea | ||
|
|
38f0699e19 | ||
|
|
6ca9f421eb | ||
|
|
935825571b | ||
|
|
9beaa78820 | ||
|
|
420c2c1afd | ||
|
|
7c0cb07b83 | ||
|
|
c6a7137f19 | ||
|
|
44f9ba0e7f | ||
|
|
1c61e64169 | ||
|
|
cf0eeebd31 | ||
|
|
f118597e47 | ||
|
|
6f2fcffd3e | ||
|
|
8f7748404c | ||
|
|
88c2605d4f | ||
|
|
c2d645612a | ||
|
|
b20f69c208 | ||
|
|
b9cedb70ff | ||
|
|
a11978aa33 | ||
|
|
b0efcc0d51 | ||
|
|
92b5f2226e | ||
|
|
98f2603525 | ||
|
|
cfb1d50c8e | ||
|
|
545ccf1938 | ||
|
|
0c79995107 | ||
|
|
9d3397a687 | ||
|
|
11c160835a | ||
|
|
e388b37aa6 | ||
|
|
1da882b807 | ||
|
|
d9d5a24b70 | ||
|
|
24e3cad882 | ||
|
|
323a4a17cf | ||
|
|
9968e0f7df | ||
|
|
2ccc53630b | ||
|
|
d7bb3defc3 | ||
|
|
ddb8bf8a5c | ||
|
|
6234d61ae5 | ||
|
|
a665ee3ec6 | ||
|
|
7ca3efe8b8 | ||
|
|
28f4952599 | ||
|
|
7e4022518d | ||
|
|
4d1656eaa8 | ||
|
|
5b2421cb0c | ||
|
|
0578b066f1 | ||
|
|
57fdcf3e60 | ||
|
|
eb7bdb6a85 | ||
|
|
ebd671e7b6 | ||
|
|
15a1a3ac15 | ||
|
|
9a0c7fe9c8 | ||
|
|
91bcbc3d6f | ||
|
|
b3d046f4ea | ||
|
|
0f13e34562 | ||
|
|
e18cd87180 | ||
|
|
421949a9f8 | ||
|
|
8c7c580f3f | ||
|
|
c616641044 | ||
|
|
fd16243287 | ||
|
|
7352bbe77a | ||
|
|
4d33908e01 | ||
|
|
adabe92f72 | ||
|
|
958f9e57e1 | ||
|
|
ac5032df83 | ||
|
|
5f4cc07473 | ||
|
|
38524bce88 | ||
|
|
64db2f19a7 | ||
|
|
8fe1e80bbd | ||
|
|
1c4506cf50 | ||
|
|
84fe7f6df6 | ||
|
|
5c7e650b3b | ||
|
|
6cac078e15 | ||
|
|
4e555021a7 | ||
|
|
b1e2f043b1 | ||
|
|
bc69852333 | ||
|
|
2c79ccc883 | ||
|
|
c240fab58a | ||
|
|
3c50022ac3 | ||
|
|
9201136cb1 | ||
|
|
ff52f75abf | ||
|
|
eed40f7875 | ||
|
|
754d4560ea | ||
|
|
f6d09f4ba2 | ||
|
|
a1f0dac42d | ||
|
|
fff935cf02 | ||
|
|
0849468fc2 | ||
|
|
6a57924fbf | ||
|
|
57802c2ea0 | ||
|
|
924df0dc9e | ||
|
|
d04001e052 | ||
|
|
92ec931aff | ||
|
|
30f92374d0 | ||
|
|
6bfd221cd1 | ||
|
|
ceb537ae91 | ||
|
|
81b197a9aa | ||
|
|
54b4ad0df8 | ||
|
|
e84c3ebe14 | ||
|
|
81acf1d947 | ||
|
|
80bfc231e0 | ||
|
|
b1409684db | ||
|
|
14d9448e4c | ||
|
|
924fa699eb | ||
|
|
999a8e39eb | ||
|
|
5a1c85d739 | ||
|
|
ba77ff4a4c | ||
|
|
05765495c4 | ||
|
|
f7cccc8c37 | ||
|
|
85e0f7993e | ||
|
|
d5a424ebe1 | ||
|
|
01441961c3 | ||
|
|
836f64d28f | ||
|
|
79bb4e585b | ||
|
|
409e88b727 | ||
|
|
5034a8981a | ||
|
|
e61d9f195d | ||
|
|
b3e213ba04 | ||
|
|
a7ea678683 | ||
|
|
791e16ce52 | ||
|
|
173da0e65b | ||
|
|
287aabfda7 | ||
|
|
d8656cc6b3 | ||
|
|
a3500c9bc9 | ||
|
|
b513cbe614 | ||
|
|
b5c525a9c2 | ||
|
|
648b560148 | ||
|
|
6eb34c3501 | ||
|
|
21544bd2dc | ||
|
|
3e115f84d7 | ||
|
|
ba586fc438 | ||
|
|
e6cbed14a9 | ||
|
|
f531e68b87 | ||
|
|
53f718e240 | ||
|
|
de36bfab99 | ||
|
|
1e2f57a4cd | ||
|
|
46aa3a3e24 | ||
|
|
0c627d1ade | ||
|
|
f20349fb2a | ||
|
|
dc72d63481 | ||
|
|
e9efed8067 | ||
|
|
71ce064008 | ||
|
|
b67b0ea633 | ||
|
|
bf3d46d190 | ||
|
|
a1fa3462eb | ||
|
|
c84175e763 | ||
|
|
0f9fe18379 | ||
|
|
76c0d35783 | ||
|
|
3ece0d1acc | ||
|
|
0473c9b676 | ||
|
|
1956227f63 | ||
|
|
c515d08d5c | ||
|
|
0bd9820c00 | ||
|
|
0c2299cfcd | ||
|
|
12fdfac467 | ||
|
|
3fc20ec593 | ||
|
|
69a6163e29 | ||
|
|
00294699f0 | ||
|
|
90ff980a00 | ||
|
|
17e7d2a2de | ||
|
|
d2a88df5bf | ||
|
|
9471f5c918 | ||
|
|
492d45f363 | ||
|
|
2951d68f9d | ||
|
|
4857bc0478 | ||
|
|
c794a1d1a1 | ||
|
|
d2a34acfb9 | ||
|
|
3dc60b6106 | ||
|
|
57587b9175 | ||
|
|
5ee7cb2647 | ||
|
|
911a3f8f1a | ||
|
|
d426001372 | ||
|
|
2d0c65aaf4 | ||
|
|
fd4605b956 | ||
|
|
3f84b6bbfd | ||
|
|
5ad10af303 | ||
|
|
9aa11faaaa | ||
|
|
bfa98574f1 | ||
|
|
dd2dc40ff1 | ||
|
|
8a3265d7b1 | ||
|
|
a240a031a8 | ||
|
|
979e41fe41 | ||
|
|
03dc404aa7 | ||
|
|
364320ffc9 | ||
|
|
2492f4cec9 | ||
|
|
1a643b3eef | ||
|
|
58ee3b958b | ||
|
|
2928cf5821 | ||
|
|
b21b276151 | ||
|
|
d80f25dc96 | ||
|
|
f5f5a081e6 | ||
|
|
f60474b4d7 | ||
|
|
364373df0c | ||
|
|
bb38533bb2 | ||
|
|
836801c524 | ||
|
|
b54cf5ede9 | ||
|
|
1a20c66c02 | ||
|
|
587bbb3b4d | ||
|
|
e95f7a1a03 | ||
|
|
9c75f6e2ca | ||
|
|
822042ab9c | ||
|
|
3a843b6e16 | ||
|
|
6072387c37 | ||
|
|
313162dbf2 | ||
|
|
495515abac | ||
|
|
09087040e9 | ||
|
|
4423829911 | ||
|
|
c8f469c4fb | ||
|
|
bc61b45f9f | ||
|
|
f530d9ea82 | ||
|
|
2046fa5310 | ||
|
|
9ea2327fa0 | ||
|
|
ff67b54a1b | ||
|
|
e6bd7a54be | ||
|
|
5827b5ffa3 | ||
|
|
572a1310e0 | ||
|
|
c1403d3826 | ||
|
|
29afe9b9e8 | ||
|
|
e9ff33d263 | ||
|
|
a62f60a436 | ||
|
|
838964c6ef | ||
|
|
800fc12c15 | ||
|
|
80175241e3 | ||
|
|
5d801f22f5 | ||
|
|
ba772add54 | ||
|
|
ff24f12cae | ||
|
|
487f5c1865 | ||
|
|
e0c90037fb | ||
|
|
aa5f603cba | ||
|
|
409db43973 | ||
|
|
cef1b29355 | ||
|
|
045750c87e | ||
|
|
85802e7af7 | ||
|
|
4bfdb66d46 | ||
|
|
81a6a52d9f | ||
|
|
7759fe1dc3 | ||
|
|
3b2acb29b5 | ||
|
|
5f2b949ecf | ||
|
|
1b956d563e | ||
|
|
c6a97f5082 | ||
|
|
7f512e47e9 | ||
|
|
5d725b0e76 | ||
|
|
fe63607260 | ||
|
|
0a1d4daf6e | ||
|
|
9e9e385bef | ||
|
|
6fed39e05b | ||
|
|
3dec53d13d | ||
|
|
f0ded9f5be | ||
|
|
7d55a1c2cd | ||
|
|
f3dc9663b8 | ||
|
|
05c7c481a9 | ||
|
|
adcc1543f0 | ||
|
|
95f873c752 | ||
|
|
ec90f8b295 | ||
|
|
f84195a98d | ||
|
|
5e98a68e2e | ||
|
|
b91dbca144 | ||
|
|
79a01da18d | ||
|
|
14951d3004 | ||
|
|
64c2061bea | ||
|
|
e3adc9a29a | ||
|
|
6b689ffcce | ||
|
|
c995a4c5c8 | ||
|
|
8d1e0f67d1 | ||
|
|
7877a5dca2 | ||
|
|
16db278ffd | ||
|
|
521b4381f2 | ||
|
|
9ae9d40f94 | ||
|
|
1d562d404c | ||
|
|
7ac1b268d9 | ||
|
|
4833e9dccf | ||
|
|
f28b7510fa | ||
|
|
37b717b142 | ||
|
|
fd8b40d9aa | ||
|
|
1d944781cf | ||
|
|
1f4c64d022 | ||
|
|
f69b5130a3 | ||
|
|
f8b143904b | ||
|
|
31a5413643 | ||
|
|
a95fc5ed07 | ||
|
|
fcd7bb790e | ||
|
|
008e10948e | ||
|
|
c97a4f1268 | ||
|
|
3eba95b8cc | ||
|
|
2bf8f0b937 | ||
|
|
9ae45d1258 | ||
|
|
1835a4cf3f | ||
|
|
2ab44b894d | ||
|
|
1108f49b07 | ||
|
|
cc69213beb | ||
|
|
460e557dd8 | ||
|
|
05e29468d2 | ||
|
|
4d3a311fb4 | ||
|
|
bc62d210ec | ||
|
|
43d3ea6553 | ||
|
|
882e3e1ef4 | ||
|
|
b33c86c99c | ||
|
|
cd0248e4c9 | ||
|
|
ecb3ed5003 | ||
|
|
0569339a41 | ||
|
|
3e9faead43 | ||
|
|
6e700b2385 | ||
|
|
464fc4993c | ||
|
|
4316c72809 | ||
|
|
ce0cebe09c | ||
|
|
23b90a0d56 | ||
|
|
3f8b3536b5 | ||
|
|
0dcf785b45 | ||
|
|
8cf4aff622 | ||
|
|
cefda7c42b | ||
|
|
0393b2382c | ||
|
|
23e900f7fd | ||
|
|
2d6aafc257 | ||
|
|
b191efece1 | ||
|
|
2a7f0043f5 | ||
|
|
607c7e3704 | ||
|
|
c246a443c5 | ||
|
|
fd495e1f5c | ||
|
|
621a06cafa | ||
|
|
f890b05151 | ||
|
|
567d8fdd6d | ||
|
|
7d996906ad | ||
|
|
b5ec076279 | ||
|
|
de8dfe3dba | ||
|
|
7249956d40 | ||
|
|
e6eb56466e | ||
|
|
8954700bcb | ||
|
|
eb595cea9e | ||
|
|
9a1a0a54e6 | ||
|
|
134396b602 | ||
|
|
2aa65fdb68 | ||
|
|
a9c4d7d5dd | ||
|
|
2cbbd5ee40 | ||
|
|
c84c55761c | ||
|
|
77eed36990 | ||
|
|
5c2d84d8b4 | ||
|
|
9883f0f82f | ||
|
|
e62b05b6f6 | ||
|
|
8e6ee8b770 | ||
|
|
666b51a28a | ||
|
|
1962097a66 | ||
|
|
7f010854b5 | ||
|
|
17288a4c02 | ||
|
|
ea48def9fc | ||
|
|
a1d5c29ffb | ||
|
|
bf99eb25c8 | ||
|
|
b35a440792 | ||
|
|
58f9eec8b1 | ||
|
|
26841aa10d | ||
|
|
e18a8d670e | ||
|
|
49d077db97 | ||
|
|
9dafe165b0 | ||
|
|
cce1953cb8 | ||
|
|
7e33b25593 | ||
|
|
78fb49a6fc | ||
|
|
f1e0d93bc5 | ||
|
|
195a178d15 | ||
|
|
b9257fce28 | ||
|
|
41eaf4ef1b | ||
|
|
93d0c08955 | ||
|
|
c5bc3454ff | ||
|
|
c33b4ef709 | ||
|
|
ce3ba7d070 | ||
|
|
639eb08291 | ||
|
|
6d109b4c4c | ||
|
|
6f3971dc47 | ||
|
|
2ccb503dc8 | ||
|
|
3cb9fdf102 | ||
|
|
40d81a4081 | ||
|
|
5a85f55be8 | ||
|
|
5455e211bc | ||
|
|
cb4cc989c7 | ||
|
|
037aa479bf | ||
|
|
08567f287a | ||
|
|
a57f1d890d | ||
|
|
3ab406e012 | ||
|
|
f36f4702a2 | ||
|
|
62697f7972 | ||
|
|
ec8d2bc0e8 | ||
|
|
d83664b6a3 | ||
|
|
6910a020d2 | ||
|
|
60e5c6e3e8 | ||
|
|
90b1432875 | ||
|
|
f1059aa381 | ||
|
|
01b4937f35 | ||
|
|
3e051815c5 | ||
|
|
e976daf8b0 | ||
|
|
422046dc03 | ||
|
|
9a270971d1 | ||
|
|
0742382ae1 | ||
|
|
763c38430e | ||
|
|
4d926bba8e | ||
|
|
4acc4ea9a9 | ||
|
|
565bf47818 | ||
|
|
176a0f30be | ||
|
|
6f4d983d89 | ||
|
|
6a0e258cf2 | ||
|
|
8d82064888 | ||
|
|
4300179b67 | ||
|
|
7e31ae2ebf | ||
|
|
7a27560b0d | ||
|
|
93655fef62 | ||
|
|
a581a95cb4 | ||
|
|
261fdda47c | ||
|
|
7a2a243a21 | ||
|
|
bead4256af | ||
|
|
e8dfd7e3b3 | ||
|
|
e456b7fcac | ||
|
|
fbe5e417ef | ||
|
|
5f80053a33 | ||
|
|
fa520a2d3e | ||
|
|
cf54f01945 | ||
|
|
44d2d58f12 | ||
|
|
daba2a352f | ||
|
|
d1ff2b1fad | ||
|
|
b1bd71f2e2 | ||
|
|
7f49816275 | ||
|
|
d73d460e88 | ||
|
|
ab1e852b6c | ||
|
|
117b7430db | ||
|
|
2e73f9e37a | ||
|
|
d3158983b4 | ||
|
|
dae7baa6ad | ||
|
|
e29f5e1adf | ||
|
|
e8d15c7dbb | ||
|
|
58be009da4 | ||
|
|
d4eb0ce3f2 | ||
|
|
d73324a141 | ||
|
|
7061be60f4 | ||
|
|
2a65f64ac1 | ||
|
|
120ba3e447 | ||
|
|
a527c7183a | ||
|
|
a0dfbb4e15 | ||
|
|
764f65ff61 | ||
|
|
1615e8623c | ||
|
|
d7bb9ff073 | ||
|
|
d896581e12 | ||
|
|
f833fa1fab | ||
|
|
2823517b26 | ||
|
|
3e0a8d0070 | ||
|
|
b3768d65aa | ||
|
|
d2e17c0051 | ||
|
|
d0354c2ef2 | ||
|
|
17fc1181c2 | ||
|
|
dbe7c5fb93 | ||
|
|
54b421d01f | ||
|
|
0e9611f802 | ||
|
|
4743a2439d | ||
|
|
242c167f82 | ||
|
|
e071b994cf | ||
|
|
60bb8aa0fa | ||
|
|
9f56f34ea4 | ||
|
|
d66b33e600 | ||
|
|
63b7c0361e | ||
|
|
dea66ff49d | ||
|
|
c29621741e | ||
|
|
6d7d013f7a | ||
|
|
ed8e2420a5 | ||
|
|
92ad66dd59 | ||
|
|
5699e34ae9 | ||
|
|
5f9dc26173 | ||
|
|
6d29ec2b90 | ||
|
|
f91ae5c7a0 | ||
|
|
33c69bf76f | ||
|
|
3e95bb259f | ||
|
|
64b6bee559 | ||
|
|
61cb029780 | ||
|
|
c02d823618 | ||
|
|
fec36919c2 | ||
|
|
072242704d | ||
|
|
9199ffdeee | ||
|
|
b92307eef5 | ||
|
|
6445d1647a | ||
|
|
3046fb9eed | ||
|
|
ad2c8b451a | ||
|
|
b39c5203fd | ||
|
|
6e11ca209b | ||
|
|
eeb3598255 | ||
|
|
c2063c28af | ||
|
|
23b63de91f | ||
|
|
05a9340fc3 | ||
|
|
16f0ac5771 | ||
|
|
ebebf76933 | ||
|
|
8c956d45c7 | ||
|
|
4040933fad | ||
|
|
63899f94fc | ||
|
|
7630ae87d4 | ||
|
|
127e2c3be6 | ||
|
|
2aacbc1f1a | ||
|
|
6f0673f428 | ||
|
|
1315dc6099 | ||
|
|
48bc19543e | ||
|
|
08f7f95ea0 | ||
|
|
6b72f188ef | ||
|
|
79ff9bedb9 | ||
|
|
d1c0f46325 | ||
|
|
909c2c6798 | ||
|
|
56dcd85aa1 | ||
|
|
7918f5754f | ||
|
|
519c24983a | ||
|
|
735db3d5f5 | ||
|
|
53627f20c7 | ||
|
|
181026567e | ||
|
|
db6ca23533 | ||
|
|
e0560afb6d | ||
|
|
7e081e6661 | ||
|
|
213caea5b6 | ||
|
|
abd439f131 | ||
|
|
c681848d60 | ||
|
|
46a0567881 | ||
|
|
0c80ef88b5 | ||
|
|
71252ddbea | ||
|
|
1ef2522089 | ||
|
|
f9652d7c06 | ||
|
|
1de59150bc | ||
|
|
2dd8cbb779 | ||
|
|
f2b9cb0478 | ||
|
|
e79ac7122a | ||
|
|
c1c4baf476 | ||
|
|
e023ba6a19 | ||
|
|
2ffeabe2a6 | ||
|
|
36c5bbc3fd | ||
|
|
da1ee3d631 | ||
|
|
86b54dbe9a | ||
|
|
296906758d | ||
|
|
cc2ea1244d | ||
|
|
4aaf223007 | ||
|
|
d283f1f321 | ||
|
|
f1731d732b | ||
|
|
33e4ba261c | ||
|
|
00f73bd3b8 | ||
|
|
5ebce0ebfc | ||
|
|
81f7f41b3b | ||
|
|
00182ebb3c | ||
|
|
58b2b2f130 | ||
|
|
d132ad481b | ||
|
|
dd1ec82a52 | ||
|
|
2edc062569 | ||
|
|
a9c4e69e01 | ||
|
|
5f987458ef | ||
|
|
376a19bac6 | ||
|
|
a1c07370ca | ||
|
|
1efd6b7e18 | ||
|
|
1a31b2c929 | ||
|
|
9623f238b3 | ||
|
|
fa5658fd81 | ||
|
|
0fa76f5d09 | ||
|
|
b4f0a084f1 | ||
|
|
7d49bb2f10 | ||
|
|
8dd99b7f32 | ||
|
|
eaddb696d4 | ||
|
|
898c4e5656 | ||
|
|
62900565fb | ||
|
|
e409ab805d | ||
|
|
463ff4a38a | ||
|
|
205552eda5 | ||
|
|
ca3ffdc603 | ||
|
|
be9e1e34f4 | ||
|
|
00f1c63c46 | ||
|
|
1c8437733c | ||
|
|
a658206cd4 | ||
|
|
95554e9832 | ||
|
|
fb31fb584b | ||
|
|
051faa06ac | ||
|
|
0e0a652dff | ||
|
|
1403a76b80 | ||
|
|
c4c51e83c2 | ||
|
|
c91fef9c5f | ||
|
|
9c33ef8248 | ||
|
|
05ce165b83 | ||
|
|
485fc2a3b6 | ||
|
|
f45f5f7a9a | ||
|
|
9b9a6998b7 | ||
|
|
82d9dc644b | ||
|
|
81678d4de5 | ||
|
|
032fd9853e | ||
|
|
bf60f1e5ac | ||
|
|
bda8f4e1b3 | ||
|
|
8c7160de2e | ||
|
|
2bd460effb | ||
|
|
fdadfe699c | ||
|
|
84c96371f5 | ||
|
|
799b77f09b | ||
|
|
1d67fa4c56 | ||
|
|
8534fec4b2 | ||
|
|
5483861055 | ||
|
|
bb60cbbc18 | ||
|
|
fe906c025e | ||
|
|
79e2e89a80 | ||
|
|
c30b926134 | ||
|
|
a87d83de04 | ||
|
|
7b3bd08c15 | ||
|
|
00375a4590 | ||
|
|
6619138b54 | ||
|
|
e9a7fcf95b | ||
|
|
be1f419d92 | ||
|
|
3a6b511de3 | ||
|
|
82f15afbd2 | ||
|
|
524867b4e2 | ||
|
|
d289e06c0b | ||
|
|
13f366472b | ||
|
|
830718cd2c | ||
|
|
8fffc7725c | ||
|
|
6fa6beb270 | ||
|
|
36846d2377 | ||
|
|
ef962f5f5d | ||
|
|
5cbccb06ad | ||
|
|
220a64ebdc | ||
|
|
3145e30cf1 | ||
|
|
ef198494b0 | ||
|
|
9f1e3c5fda | ||
|
|
ddf8dc7ebf | ||
|
|
8bdffdc7b0 | ||
|
|
915cdc3e06 | ||
|
|
4601388f3f | ||
|
|
66913bd221 | ||
|
|
f554c3d3e2 | ||
|
|
2104eebe02 | ||
|
|
caab570be6 | ||
|
|
ca93ac7143 | ||
|
|
9e895aed58 | ||
|
|
af4f53ed04 | ||
|
|
e021c48daa | ||
|
|
ed4aa3d62c | ||
|
|
2aa491e6f2 | ||
|
|
1098e0f0e9 | ||
|
|
8903371409 | ||
|
|
749eab85bd | ||
|
|
86d4defa3e | ||
|
|
41fd15e7e3 | ||
|
|
c1cff9e95f | ||
|
|
30a0e7d082 | ||
|
|
c387a28dbd | ||
|
|
207ae12522 | ||
|
|
22ebb06980 | ||
|
|
c0319d56b0 | ||
|
|
3aaac2c244 | ||
|
|
d8a66e7b22 | ||
|
|
00838e5cb8 | ||
|
|
6deaf9c342 | ||
|
|
5d6d91cfbd | ||
|
|
f35e0ab627 | ||
|
|
c5da9ea002 | ||
|
|
9334322f11 | ||
|
|
57a039b7d8 | ||
|
|
2621137e31 | ||
|
|
7276e9ddc9 | ||
|
|
4e60c0ac1e | ||
|
|
13df4923a1 | ||
|
|
0eb0bdc918 | ||
|
|
aaaa93f79e | ||
|
|
280dbfa53a | ||
|
|
3a5f976ff6 | ||
|
|
ea417435ac | ||
|
|
ecb69ba059 | ||
|
|
35f6a6cd3c | ||
|
|
64dc4c922d | ||
|
|
33a1e20338 | ||
|
|
9e1320b272 | ||
|
|
93649d0557 | ||
|
|
46181dfa08 | ||
|
|
44066b292e | ||
|
|
2f84fae344 | ||
|
|
d75548e219 | ||
|
|
ad416413fe | ||
|
|
f99ea0bf16 | ||
|
|
d97be1e7aa | ||
|
|
01019ad546 | ||
|
|
3d99061a07 | ||
|
|
4c6ed1b530 | ||
|
|
50f0d03735 | ||
|
|
9461a3e889 | ||
|
|
65a69b2009 | ||
|
|
c07e4f45fb | ||
|
|
2fc8169d00 | ||
|
|
a152943047 | ||
|
|
4444af6938 | ||
|
|
ed0b41a425 | ||
|
|
41879fa27c | ||
|
|
110108daf6 | ||
|
|
27deaf91cc | ||
|
|
37d548db8c | ||
|
|
67c2e1f3cf | ||
|
|
efc55e77ef | ||
|
|
a1a10777a5 | ||
|
|
7282bde765 | ||
|
|
1a384e53ec | ||
|
|
00c07290ad | ||
|
|
817f92d398 | ||
|
|
d943b67270 | ||
|
|
c171524dc6 | ||
|
|
0dcff37419 | ||
|
|
65ebfc95d0 | ||
|
|
e8609526b0 | ||
|
|
4bc0015b48 | ||
|
|
bfa667c1ab | ||
|
|
cadbd65cf6 | ||
|
|
eae6d75bca | ||
|
|
f4ab363901 | ||
|
|
7c806fee8a | ||
|
|
9f3fab6de4 | ||
|
|
2c3c9c441e | ||
|
|
a7644ee487 | ||
|
|
396b98da01 | ||
|
|
d0da1f4e39 | ||
|
|
a24e73da7e | ||
|
|
3aa082fec1 | ||
|
|
70fd31afb6 | ||
|
|
c299a794b2 | ||
|
|
d3429f31a6 | ||
|
|
7b951f3e3b | ||
|
|
b0bd1b9635 | ||
|
|
10ab864a43 | ||
|
|
6a6f0e9c53 | ||
|
|
8cd19bbc26 | ||
|
|
7404c4ce6b | ||
|
|
6d336fda23 | ||
|
|
b9c45d96c1 | ||
|
|
b0e1d5dafb | ||
|
|
05369a49a4 | ||
|
|
04916756c6 | ||
|
|
2581254a02 | ||
|
|
c1b509220e | ||
|
|
676ea0629b | ||
|
|
41d6ebe536 | ||
|
|
422b93495a | ||
|
|
7246ee34bd | ||
|
|
4d3e8bee84 | ||
|
|
7dffa1a701 | ||
|
|
ba16411bf1 | ||
|
|
de1da57286 | ||
|
|
6687a1eba0 | ||
|
|
f0998271ba | ||
|
|
a84b972121 | ||
|
|
e5b51564fd | ||
|
|
6ddcdf2812 | ||
|
|
bc177ad740 | ||
|
|
7b471588ab | ||
|
|
d7a4e4fde6 | ||
|
|
4986b69c62 | ||
|
|
7a22f4ac88 | ||
|
|
f059b6fd0d | ||
|
|
65fb41c562 | ||
|
|
c3d8002a76 | ||
|
|
6c98369719 | ||
|
|
f5b0ca63e8 | ||
|
|
90303689db | ||
|
|
17a5767108 | ||
|
|
e04b619071 | ||
|
|
858a93ccd2 | ||
|
|
e22d1f0a6c | ||
|
|
9994dd49f7 | ||
|
|
5cf1740977 | ||
|
|
297bce3a89 | ||
|
|
d8faef0146 | ||
|
|
57efcef072 | ||
|
|
5c58a86d86 | ||
|
|
ab06ed75c3 | ||
|
|
6f812dad90 | ||
|
|
aa50d88575 | ||
|
|
971e879744 | ||
|
|
dc2191f228 | ||
|
|
a270b926b3 | ||
|
|
051bcf1dc2 | ||
|
|
578e5ea6b7 | ||
|
|
56525f8008 | ||
|
|
32559bab5d | ||
|
|
cb1f3411ce | ||
|
|
6fb916eccd | ||
|
|
313736e3c6 | ||
|
|
f8eccde99b | ||
|
|
c5cc372d7f | ||
|
|
8b5ba1aa97 | ||
|
|
f4d6755f20 | ||
|
|
ed8d69b27f | ||
|
|
ac216678c0 | ||
|
|
004ca2437f | ||
|
|
d96ea5a21a | ||
|
|
c96190447e | ||
|
|
7194a44822 | ||
|
|
cceb33d791 |
1
.github/CODEOWNERS
vendored
Normal file
1
.github/CODEOWNERS
vendored
Normal file
@@ -0,0 +1 @@
|
||||
@elibosley @pujitm @mdatelle @zackspear
|
||||
1
.github/unraid.svg
vendored
Normal file
1
.github/unraid.svg
vendored
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" version="1.2" viewBox="0 0 1000 1000"><defs><linearGradient id="a" x1="-900" x2="-100" y1="-100" y2="-900" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#e32929"/><stop offset="1" stop-color="#ff8d30"/></linearGradient></defs><path fill="url(#a)" d="M1000 500.1v376.4c0 57.5-43.4 110.1-100 120.9-8.4 1.6-17.1 2.5-25.6 2.5-250.1.1-500.2.1-750.3.1-61.3 0-114.8-47-122.8-108q-.3-2.1-.6-4.1-.2-2-.3-4.1-.2-2-.3-4v-4.1C0 624.9 0 374.2 0 123.5 0 66 43.4 13.3 100 2.6 108.4 1 117.1.1 125.6.1 375.9 0 626.2 0 876.5 0 934 0 986.7 43.4 997.4 100c1.5 8.4 2.5 17.1 2.5 25.6.1 124.8.1 249.7.1 374.5z"/><path fill="#fff" d="M481.6 392.1h36.5v216.2h-36.5zm-356 0h36.5v216.2h-36.5zm178 242h36.5v82.5h-36.5zm-89.3-92.7h36.5v133.7h-36.5zm178 0h36.5V675h-36.5zm445.8-149.3h36.5v216.1h-36.5zm-178-107.8h36.5v82.6h-36.5zm89.3 41.5h36.5v133.1h-36.5zm-178.6 0h36.5v133h-36.5z"/></svg>
|
||||
|
After Width: | Height: | Size: 915 B |
74
.github/workflows/lint-test-build-web.yml
vendored
74
.github/workflows/lint-test-build-web.yml
vendored
@@ -1,74 +0,0 @@
|
||||
name: Lint, Test, and Build Web Components
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
lint-web:
|
||||
defaults:
|
||||
run:
|
||||
working-directory: web
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Create env file
|
||||
run: |
|
||||
touch .env
|
||||
echo VITE_ACCOUNT=${{ vars.VITE_ACCOUNT }} >> .env
|
||||
echo VITE_CONNECT=${{ vars.VITE_CONNECT }} >> .env
|
||||
echo VITE_UNRAID_NET=${{ vars.VITE_UNRAID_NET }} >> .env
|
||||
echo VITE_CALLBACK_KEY=${{ vars.VITE_CALLBACK_KEY }} >> .env
|
||||
cat .env
|
||||
|
||||
- name: Install node
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
cache: "npm"
|
||||
cache-dependency-path: "web/package-lock.json"
|
||||
node-version-file: "web/.nvmrc"
|
||||
|
||||
- name: Installing node deps
|
||||
run: npm install
|
||||
|
||||
- name: Lint files
|
||||
run: npm run lint
|
||||
|
||||
build-web:
|
||||
defaults:
|
||||
run:
|
||||
working-directory: web
|
||||
runs-on: ubuntu-latest
|
||||
needs: [lint-web]
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Create env file
|
||||
run: |
|
||||
touch .env
|
||||
echo VITE_ACCOUNT=${{ vars.VITE_ACCOUNT }} >> .env
|
||||
echo VITE_CONNECT=${{ vars.VITE_CONNECT }} >> .env
|
||||
echo VITE_UNRAID_NET=${{ vars.VITE_UNRAID_NET }} >> .env
|
||||
echo VITE_CALLBACK_KEY=${{ vars.VITE_CALLBACK_KEY }} >> .env
|
||||
cat .env
|
||||
|
||||
- name: Install node
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
cache: "npm"
|
||||
cache-dependency-path: "web/package-lock.json"
|
||||
node-version-file: "web/.nvmrc"
|
||||
|
||||
- name: Installing node deps
|
||||
run: npm install
|
||||
|
||||
- name: Build
|
||||
run: npm run build
|
||||
|
||||
- name: Upload build to Github artifacts
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: unraid-web
|
||||
path: web/.nuxt/nuxt-custom-elements/dist/unraid-components
|
||||
401
.github/workflows/main.yml
vendored
401
.github/workflows/main.yml
vendored
@@ -1,6 +1,7 @@
|
||||
name: CI - Main (API)
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
@@ -12,6 +13,18 @@ concurrency:
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
release-please:
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
steps:
|
||||
- id: release
|
||||
uses: googleapis/release-please-action@v4
|
||||
outputs:
|
||||
releases_created: ${{ steps.release.outputs.releases_created }}
|
||||
tag_name: ${{ steps.release.outputs.tag_name }}
|
||||
start:
|
||||
# This prevents a tag running twice as it'll have a "tag" and a "commit" event
|
||||
# We only want the tag to run the action as it'll be able to create the release notes
|
||||
@@ -21,171 +34,115 @@ jobs:
|
||||
- name: Validate branch and tag
|
||||
run: exit 0
|
||||
|
||||
lint-api:
|
||||
continue-on-error: true
|
||||
build-test-api:
|
||||
name: Build and Test API
|
||||
runs-on: ubuntu-latest
|
||||
defaults:
|
||||
run:
|
||||
working-directory: api
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Reconfigure git to use HTTP authenti:cation
|
||||
run: >
|
||||
git config --global url."https://github.com/".insteadOf
|
||||
ssh://git@github.com/
|
||||
|
||||
- name: Install node
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version-file: "api/.nvmrc"
|
||||
|
||||
# - name: Get npm cache directory
|
||||
# id: npm-cache
|
||||
# run: echo "::set-output name=dir::$(npm config get cache)"
|
||||
|
||||
# - name: Load npm cache
|
||||
# uses: actions/cache@v3
|
||||
# with:
|
||||
# path: ${{ steps.npm-cache.outputs.dir }}
|
||||
# key: ${{ runner.os }}-npm-cache-${{ hashFiles('**/package-lock.json') }}
|
||||
|
||||
- name: Install libvirt-dev
|
||||
run: sudo apt-get update && sudo apt-get install libvirt-dev
|
||||
|
||||
- name: Installing node deps
|
||||
run: npm install
|
||||
|
||||
- name: Lint files
|
||||
run: npm run lint
|
||||
|
||||
test-api:
|
||||
defaults:
|
||||
run:
|
||||
working-directory: api
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Reconfigure git to use HTTP authentication
|
||||
run: >
|
||||
git config --global url."https://github.com/".insteadOf
|
||||
ssh://git@github.com/
|
||||
|
||||
- name: Build Docker Compose
|
||||
run: |
|
||||
docker network create mothership_default
|
||||
docker-compose build builder
|
||||
|
||||
- name: Run Docker Compose
|
||||
run: docker-compose run builder npm run coverage
|
||||
|
||||
lint-web:
|
||||
defaults:
|
||||
run:
|
||||
working-directory: web
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Create env file
|
||||
run: |
|
||||
touch .env
|
||||
echo VITE_ACCOUNT=${{ vars.VITE_ACCOUNT }} >> .env
|
||||
echo VITE_CONNECT=${{ vars.VITE_CONNECT }} >> .env
|
||||
echo VITE_UNRAID_NET=${{ vars.VITE_UNRAID_NET }} >> .env
|
||||
echo VITE_CALLBACK_KEY=${{ vars.VITE_CALLBACK_KEY }} >> .env
|
||||
cat .env
|
||||
|
||||
- name: Install node
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
cache: "npm"
|
||||
cache-dependency-path: "web/package-lock.json"
|
||||
node-version-file: "web/.nvmrc"
|
||||
|
||||
- name: Installing node deps
|
||||
run: npm install
|
||||
|
||||
- name: Lint files
|
||||
run: npm run lint
|
||||
|
||||
build-api:
|
||||
defaults:
|
||||
run:
|
||||
working-directory: api
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
outputs:
|
||||
API_VERSION: ${{ steps.build-pack-binary.outputs.API_VERSION }}
|
||||
API_VERSION: ${{ steps.vars.outputs.API_VERSION }}
|
||||
API_MD5: ${{ steps.set-hashes.outputs.API_MD5 }}
|
||||
API_SHA256: ${{ steps.set-hashes.outputs.API_SHA256 }}
|
||||
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Add SSH deploy key
|
||||
uses: shimataro/ssh-key-action@v2
|
||||
uses: actions/checkout@v4
|
||||
- name: Build with Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
with:
|
||||
key: ${{ secrets.UNRAID_BOT_SSH_KEY }}
|
||||
known_hosts: ${{ secrets.KNOWN_HOSTS }}
|
||||
|
||||
- name: Install node
|
||||
uses: actions/setup-node@v3
|
||||
install: true
|
||||
platforms: linux/amd64
|
||||
- name: Build Builder
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
node-version-file: "api/.nvmrc"
|
||||
context: ./api
|
||||
push: false
|
||||
tags: builder:latest
|
||||
cache-from: type=gha,ref=builder:latest
|
||||
cache-to: type=gha,mode=max,ref=builder:latest
|
||||
load: true
|
||||
- name: Lint inside of the docker container
|
||||
continue-on-error: false
|
||||
run: |
|
||||
docker run --rm builder npm run lint
|
||||
|
||||
- name: Install libvirt-dev
|
||||
run: sudo apt-get update && sudo apt-get install libvirt-dev
|
||||
|
||||
- name: Installing node deps
|
||||
run: npm install
|
||||
|
||||
- name: Install pkg and node-prune
|
||||
run: npm i -g pkg && curl -sf https://gobinaries.com/tj/node-prune | sh
|
||||
|
||||
# See https://github.com/apollographql/subscriptions-transport-ws/issues/433
|
||||
- name: Patch subscriptions-transport-ws
|
||||
run: npm run patch:subscriptions-transport-ws
|
||||
|
||||
|
||||
- name: Build and Pack
|
||||
- name: Test inside of the docker container
|
||||
run: |
|
||||
git fetch --depth=2 origin main
|
||||
if git diff --name-only --relative=api origin/main HEAD | grep -q '.'; then
|
||||
docker run --rm builder npm run coverage
|
||||
else
|
||||
echo "No changes in /api folder, skipping coverage."
|
||||
fi
|
||||
- name: Get Git Short Sha and API version
|
||||
id: vars
|
||||
run: |
|
||||
GIT_SHA=$(git rev-parse --short HEAD)
|
||||
IS_TAGGED=$(git describe --tags --abbrev=0 --exact-match || echo '')
|
||||
PACKAGE_LOCK_VERSION=$(jq -r '.version' package-lock.json)
|
||||
echo "GIT_SHA=$GIT_SHA" >> $GITHUB_OUTPUT
|
||||
echo "IS_TAGGED=$IS_TAGGED" >> $GITHUB_OUTPUT
|
||||
echo "PACKAGE_LOCK_VERSION=$PACKAGE_LOCK_VERSION" >> $GITHUB_OUTPUT
|
||||
echo "API_VERSION=$([[ -n "$IS_TAGGED" ]] && echo "$PACKAGE_LOCK_VERSION" || echo "${PACKAGE_LOCK_VERSION}+${GIT_SHA}")" >> $GITHUB_OUTPUT
|
||||
- name: Build inside of the docker container
|
||||
id: build-pack-binary
|
||||
run: WORKDIR=${{ github.workspace }} && npm run build-pkg
|
||||
run: |
|
||||
docker run --rm -v ${{ github.workspace }}/api/deploy/release:/app/deploy/release -e API_VERSION=${{ steps.vars.outputs.API_VERSION }} builder npm run build-and-pack
|
||||
|
||||
- name: Set Hashes
|
||||
id: set-hashes
|
||||
run: |
|
||||
API_MD5=$(md5sum ${{ github.workspace }}/api/deploy/release/*.tgz | awk '{ print $1 }')
|
||||
API_SHA256=$(sha256sum ${{ github.workspace }}/api/deploy/release/*.tgz | awk '{ print $1 }')
|
||||
echo "::set-output name=API_MD5::${API_MD5}"
|
||||
echo "::set-output name=API_SHA256::${API_SHA256}"
|
||||
echo "API_MD5=$(md5sum ${{ github.workspace }}/api/deploy/release/*.tgz | awk '{ print $1 }')" >> $GITHUB_OUTPUT
|
||||
echo "API_SHA256=$(sha256sum ${{ github.workspace }}/api/deploy/release/*.tgz | awk '{ print $1 }')" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Upload tgz to Github artifacts
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: unraid-api
|
||||
path: ${{ github.workspace }}/api/deploy/release/*.tgz
|
||||
|
||||
build-unraid-ui-webcomponents:
|
||||
name: Build Unraid UI Library (Webcomponent Version)
|
||||
defaults:
|
||||
run:
|
||||
working-directory: unraid-ui
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install node
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
cache: "npm"
|
||||
cache-dependency-path: |
|
||||
unraid-ui/package-lock.json
|
||||
node-version-file: ".nvmrc"
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm install
|
||||
|
||||
- name: Build
|
||||
run: npm run build:wc
|
||||
|
||||
- name: Upload Artifact to Github
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: unraid-wc-ui
|
||||
path: unraid-ui/dist/
|
||||
|
||||
build-web:
|
||||
# needs: [build-unraid-ui]
|
||||
name: Build Web App
|
||||
environment:
|
||||
name: production
|
||||
defaults:
|
||||
run:
|
||||
working-directory: web
|
||||
runs-on: ubuntu-latest
|
||||
environment:
|
||||
name: production
|
||||
needs: [lint-web]
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Create env file
|
||||
run: |
|
||||
@@ -197,26 +154,40 @@ jobs:
|
||||
cat .env
|
||||
|
||||
- name: Install node
|
||||
uses: actions/setup-node@v3
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
cache: "npm"
|
||||
cache-dependency-path: "web/package-lock.json"
|
||||
cache-dependency-path: |
|
||||
web/package-lock.json
|
||||
node-version-file: "web/.nvmrc"
|
||||
|
||||
- name: Setup Just
|
||||
uses: extractions/setup-just@v2
|
||||
|
||||
- name: Build Unraid UI
|
||||
run: just ../unraid-ui/setup
|
||||
|
||||
- name: Installing node deps
|
||||
run: npm install
|
||||
|
||||
- name: Lint files
|
||||
continue-on-error: true
|
||||
run: npm run lint
|
||||
|
||||
- name: Test
|
||||
run: npm run test:ci
|
||||
|
||||
- name: Build
|
||||
run: npm run build
|
||||
|
||||
- name: Upload build to Github artifacts
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: unraid-web
|
||||
name: unraid-wc-rich
|
||||
path: web/.nuxt/nuxt-custom-elements/dist/unraid-components
|
||||
|
||||
build-plugin:
|
||||
needs: [lint-api, lint-web, test-api, build-api, build-web]
|
||||
needs: [build-test-api, build-web, build-unraid-ui-webcomponents]
|
||||
defaults:
|
||||
run:
|
||||
working-directory: plugin
|
||||
@@ -227,31 +198,98 @@ jobs:
|
||||
with:
|
||||
timezoneLinux: "America/Los_Angeles"
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@v3
|
||||
- name: Download unraid web components
|
||||
uses: actions/download-artifact@v3
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
name: unraid-web
|
||||
fetch-depth: 0
|
||||
- name: Build with Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
with:
|
||||
install: true
|
||||
platforms: linux/amd64
|
||||
- name: Build Builder
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: ./plugin
|
||||
push: false
|
||||
tags: plugin-builder:latest
|
||||
cache-from: type=gha,ref=plugin-builder:latest
|
||||
cache-to: type=gha,mode=max,ref=plugin-builder:latest
|
||||
load: true
|
||||
- name: Download Unraid Web Components
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
pattern: unraid-wc-*
|
||||
path: ./plugin/source/dynamix.unraid.net/usr/local/emhttp/plugins/dynamix.my.servers/unraid-components
|
||||
merge-multiple: true
|
||||
- name: Build Plugin
|
||||
run: |
|
||||
cd source/dynamix.unraid.net
|
||||
export API_VERSION=${{needs.build-api.outputs.API_VERSION}}
|
||||
export API_MD5=${{needs.build-api.outputs.API_MD5}}
|
||||
export API_SHA256=${{needs.build-api.outputs.API_SHA256}}
|
||||
bash ./pkg_build.sh s
|
||||
bash ./pkg_build.sh p
|
||||
echo "API_VERSION=${{needs.build-test-api.outputs.API_VERSION}}" > .env
|
||||
echo "API_SHA256=${{needs.build-test-api.outputs.API_SHA256}}" >> .env
|
||||
echo "PR=${{ github.event.pull_request.number }}" >> .env
|
||||
npm run start
|
||||
- name: Upload binary txz and plg to Github artifacts
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: connect-files
|
||||
path: |
|
||||
${{ github.workspace }}/plugin/archive/*.txz
|
||||
${{ github.workspace }}/plugin/plugins/*.plg
|
||||
plugin/deploy/release/plugins/*.plg
|
||||
plugin/deploy/release/archive/*.txz
|
||||
retention-days: 5
|
||||
if-no-files-found: error
|
||||
|
||||
release-pull-request:
|
||||
if: |
|
||||
github.event_name == 'pull_request'
|
||||
runs-on: ubuntu-latest
|
||||
needs: [build-plugin]
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Make PR Release Folder
|
||||
run: mkdir pr-release/
|
||||
|
||||
- name: Download unraid-api binary tgz
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: unraid-api
|
||||
path: pr-release
|
||||
|
||||
- name: Download plugin binary tgz
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: connect-files
|
||||
|
||||
- name: Copy other release files to pr-release
|
||||
run: |
|
||||
cp archive/*.txz pr-release/
|
||||
cp plugins/dynamix.unraid.net.pr.plg pr-release/dynamix.unraid.net.plg
|
||||
|
||||
- name: Upload to Cloudflare
|
||||
uses: jakejarvis/s3-sync-action@v0.5.1
|
||||
env:
|
||||
AWS_S3_ENDPOINT: ${{ secrets.CF_ENDPOINT }}
|
||||
AWS_S3_BUCKET: ${{ secrets.CF_BUCKET_PREVIEW }}
|
||||
AWS_ACCESS_KEY_ID: ${{ secrets.CF_ACCESS_KEY_ID }}
|
||||
AWS_SECRET_ACCESS_KEY: ${{ secrets.CF_SECRET_ACCESS_KEY }}
|
||||
AWS_REGION: "auto"
|
||||
SOURCE_DIR: pr-release
|
||||
DEST_DIR: unraid-api/pr/${{ github.event.pull_request.number }}
|
||||
- name: Comment URL
|
||||
uses: thollander/actions-comment-pull-request@v3
|
||||
with:
|
||||
comment-tag: prlink
|
||||
mode: recreate
|
||||
message: |
|
||||
This plugin has been deployed to Cloudflare R2 and is available for testing.
|
||||
Download it at this URL:
|
||||
```
|
||||
https://preview.dl.unraid.net/unraid-api/pr/${{ github.event.pull_request.number }}/dynamix.unraid.net.plg
|
||||
```
|
||||
|
||||
release-staging:
|
||||
environment:
|
||||
name: staging
|
||||
# Only release if this is a push to the main branch
|
||||
if: startsWith(github.ref, 'refs/heads/main')
|
||||
runs-on: ubuntu-latest
|
||||
@@ -259,44 +297,38 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Make Staging Release Folder
|
||||
run: mkdir staging-release/
|
||||
|
||||
- name: Download unraid-api binary tgz
|
||||
uses: actions/download-artifact@v3
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: unraid-api
|
||||
path: staging-release
|
||||
|
||||
- name: Download plugin binary tgz
|
||||
uses: actions/download-artifact@v3
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: connect-files
|
||||
|
||||
- name: Parse Changelog
|
||||
id: changelog
|
||||
uses: ocavue/changelog-parser-action@v1
|
||||
with:
|
||||
removeMarkdown: false
|
||||
filePath: "./api/CHANGELOG.md"
|
||||
|
||||
- name: Run LS in unraid-api folder
|
||||
- name: Copy Files for Staging Release
|
||||
run: |
|
||||
cp archive/dynamix.unraid.net.staging-*.txz staging-release/
|
||||
cp plugins/dynamix.unraid.net.staging.plg staging-release/
|
||||
cp archive/*.txz staging-release/
|
||||
cp plugins/dynamix.unraid.net.staging.plg staging-release/dynamix.unraid.net.plg
|
||||
ls -al staging-release
|
||||
|
||||
- name: Upload Staging Plugin to DO Spaces
|
||||
uses: BetaHuhn/do-spaces-action@v2
|
||||
with:
|
||||
access_key: ${{ secrets.DO_ACCESS_KEY }}
|
||||
secret_key: ${{ secrets.DO_SECRET_KEY }}
|
||||
space_name: ${{ secrets.DO_SPACE_NAME }}
|
||||
space_region: ${{ secrets.DO_SPACE_REGION }}
|
||||
source: staging-release
|
||||
out_dir: unraid-api
|
||||
- name: Upload Staging Plugin to Cloudflare Bucket
|
||||
uses: jakejarvis/s3-sync-action@v0.5.1
|
||||
env:
|
||||
AWS_S3_ENDPOINT: ${{ secrets.CF_ENDPOINT }}
|
||||
AWS_S3_BUCKET: ${{ secrets.CF_BUCKET_PREVIEW }}
|
||||
AWS_ACCESS_KEY_ID: ${{ secrets.CF_ACCESS_KEY_ID }}
|
||||
AWS_SECRET_ACCESS_KEY: ${{ secrets.CF_SECRET_ACCESS_KEY }}
|
||||
AWS_REGION: "auto"
|
||||
SOURCE_DIR: staging-release
|
||||
DEST_DIR: unraid-api
|
||||
|
||||
create-draft-release:
|
||||
# Only create new draft if this is a version tag
|
||||
@@ -307,26 +339,31 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Download unraid-api binary tgz
|
||||
uses: actions/download-artifact@v3
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: unraid-api
|
||||
|
||||
- name: Download plugin binary tgz
|
||||
uses: actions/download-artifact@v3
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: connect-files
|
||||
|
||||
- name: Move Files to Release Folder
|
||||
run: |
|
||||
mkdir -p release/
|
||||
mv unraid-api-*.tgz release/
|
||||
mv plugins/dynamix.unraid.net.plg release/
|
||||
mv archive/* release/
|
||||
|
||||
- name: Create Github release
|
||||
uses: softprops/action-gh-release@v1
|
||||
with:
|
||||
draft: true
|
||||
prerelease: false
|
||||
files: |
|
||||
unraid-api-*.tgz
|
||||
plugins/dynamix.unraid.net*
|
||||
archive/dynamix.unraid.net*
|
||||
release/*
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
82
.github/workflows/pull-request-web.yml
vendored
82
.github/workflows/pull-request-web.yml
vendored
@@ -1,82 +0,0 @@
|
||||
name: Pull Request Web
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- 'web/**'
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}-web
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
lint-web:
|
||||
defaults:
|
||||
run:
|
||||
working-directory: web
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Create env file
|
||||
run: |
|
||||
touch .env
|
||||
echo VITE_ACCOUNT=${{ vars.VITE_ACCOUNT }} >> .env
|
||||
echo VITE_CONNECT=${{ vars.VITE_CONNECT }} >> .env
|
||||
echo VITE_UNRAID_NET=${{ vars.VITE_UNRAID_NET }} >> .env
|
||||
echo VITE_CALLBACK_KEY=${{ vars.VITE_CALLBACK_KEY }} >> .env
|
||||
cat .env
|
||||
|
||||
- name: Install node
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
cache: "npm"
|
||||
cache-dependency-path: "web/package-lock.json"
|
||||
node-version-file: "web/.nvmrc"
|
||||
|
||||
- name: Installing node deps
|
||||
run: npm install
|
||||
|
||||
- name: Lint files
|
||||
run: npm run lint
|
||||
|
||||
build-web:
|
||||
defaults:
|
||||
run:
|
||||
working-directory: web
|
||||
runs-on: ubuntu-latest
|
||||
environment:
|
||||
name: production
|
||||
needs: [lint-web]
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Create env file
|
||||
run: |
|
||||
touch .env
|
||||
echo VITE_ACCOUNT=${{ vars.VITE_ACCOUNT }} >> .env
|
||||
echo VITE_CONNECT=${{ vars.VITE_CONNECT }} >> .env
|
||||
echo VITE_UNRAID_NET=${{ vars.VITE_UNRAID_NET }} >> .env
|
||||
echo VITE_CALLBACK_KEY=${{ vars.VITE_CALLBACK_KEY }} >> .env
|
||||
cat .env
|
||||
|
||||
- name: Install node
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
cache: "npm"
|
||||
cache-dependency-path: "web/package-lock.json"
|
||||
node-version-file: "web/.nvmrc"
|
||||
|
||||
- name: Installing node deps
|
||||
run: npm install
|
||||
|
||||
- name: Build
|
||||
run: npm run build
|
||||
|
||||
- name: Upload build to Github artifacts
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: unraid-web
|
||||
path: web/.nuxt/nuxt-custom-elements/dist/unraid-components
|
||||
183
.github/workflows/pull-request.yml
vendored
183
.github/workflows/pull-request.yml
vendored
@@ -1,183 +0,0 @@
|
||||
name: Pull Request
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- api/**
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
lint-api:
|
||||
services:
|
||||
registry: # Using a local registry is ~3x faster than exporting the image to docker agent
|
||||
image: registry:2
|
||||
ports:
|
||||
- 5000:5000
|
||||
|
||||
continue-on-error: true
|
||||
defaults:
|
||||
run:
|
||||
working-directory: api
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
persist-credentials: true
|
||||
- uses: docker/setup-buildx-action@v2
|
||||
with:
|
||||
# network=host driver-opt needed to push to local registry
|
||||
driver-opts: network=host
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v4
|
||||
with:
|
||||
context: api
|
||||
target: builder
|
||||
push: true
|
||||
tags: localhost:5000/unraid-api:builder
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
- name: Lint
|
||||
run: |
|
||||
docker run localhost:5000/unraid-api:builder npm run lint
|
||||
|
||||
test-api:
|
||||
services:
|
||||
registry: # Using a local registry is ~3x faster than exporting the image to docker agent
|
||||
image: registry:2
|
||||
ports:
|
||||
- 5000:5000
|
||||
|
||||
defaults:
|
||||
run:
|
||||
working-directory: api
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
persist-credentials: true
|
||||
- uses: docker/setup-buildx-action@v2
|
||||
with:
|
||||
# network=host driver-opt needed to push to local registry
|
||||
driver-opts: network=host
|
||||
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v4
|
||||
with:
|
||||
context: api
|
||||
target: builder
|
||||
push: true
|
||||
tags: localhost:5000/unraid-api:builder
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
- name: Test
|
||||
run: |
|
||||
docker run localhost:5000/unraid-api:builder npm run coverage
|
||||
|
||||
build-api:
|
||||
services:
|
||||
registry: # Using a local registry is ~3x faster than exporting the image to docker agent
|
||||
image: registry:2
|
||||
ports:
|
||||
- 5000:5000
|
||||
|
||||
defaults:
|
||||
run:
|
||||
working-directory: api
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
outputs:
|
||||
API_VERSION: ${{ steps.build-pack-binary.outputs.API_VERSION }}
|
||||
API_MD5: ${{ steps.set-hashes.outputs.API_MD5 }}
|
||||
API_SHA256: ${{ steps.set-hashes.outputs.API_SHA256 }}
|
||||
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
persist-credentials: true
|
||||
- uses: docker/setup-buildx-action@v2
|
||||
with:
|
||||
# network=host driver-opt needed to push to local registry
|
||||
driver-opts: network=host
|
||||
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v4
|
||||
with:
|
||||
context: api
|
||||
target: builder
|
||||
push: true
|
||||
tags: localhost:5000/unraid-api:builder
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
|
||||
- name: Run Build
|
||||
run: docker run -e GIT_SHA=$(git rev-parse --short HEAD) -e IS_TAGGED=$(git describe --tags --abbrev=0 --exact-match) -v $(pwd)/deploy:/app/deploy/ localhost:5000/unraid-api:builder npm run build-pkg
|
||||
|
||||
- name: Set Hashes
|
||||
id: set-hashes
|
||||
run: |
|
||||
API_MD5=$(md5sum ${{ github.workspace }}/api/deploy/release/*.tgz | awk '{ print $1 }')
|
||||
API_SHA256=$(sha256sum ${{ github.workspace }}/api/deploy/release/*.tgz | awk '{ print $1 }')
|
||||
echo "::set-output name=API_MD5::${API_MD5}"
|
||||
echo "::set-output name=API_SHA256::${API_SHA256}"
|
||||
|
||||
- name: Upload tgz to Github artifacts
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: unraid-api
|
||||
path: ${{ github.workspace }}/api/deploy/release/*.tgz
|
||||
|
||||
- name: Parse Changelog
|
||||
id: changelog
|
||||
uses: ocavue/changelog-parser-action@v1
|
||||
with:
|
||||
removeMarkdown: false
|
||||
filePath: "./api/CHANGELOG.md"
|
||||
|
||||
- name: View release notes
|
||||
run: |
|
||||
escapedNotes=$(sed -e 's/[&\\/]/\\&/g; s/$/\\/' -e '$s/\\$//' <<<"${{steps.changelog.outputs.latestBody}}")
|
||||
echo "${escapedNotes}"
|
||||
build-plugin:
|
||||
defaults:
|
||||
run:
|
||||
working-directory: plugin
|
||||
runs-on: ubuntu-latest
|
||||
needs: [lint-api, test-api, build-api]
|
||||
steps:
|
||||
- name: Set Timezone
|
||||
uses: szenius/set-timezone@v1.2
|
||||
with:
|
||||
timezoneLinux: "America/Los_Angeles"
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@v3
|
||||
- name: Build Plugin
|
||||
run: |
|
||||
cd source/dynamix.unraid.net
|
||||
export API_VERSION=${{needs.build-api.outputs.API_VERSION}}
|
||||
export API_MD5=${{needs.build-api.outputs.API_MD5}}
|
||||
export API_SHA256=${{needs.build-api.outputs.API_SHA256}}
|
||||
bash ./pkg_build.sh s
|
||||
bash ./pkg_build.sh p
|
||||
- name: Create release notes
|
||||
run: |
|
||||
LAST_RELEASE=$(git tag --list --sort=v:refname | tail -1)
|
||||
echo ${LAST_RELEASE}
|
||||
RELEASE_NOTES=$(git log "$LAST_RELEASE...HEAD" --pretty=format:"- %s [\`%h\`](http://github.com/$GITHUB_REPOSITORY/commit/%H)" --reverse)
|
||||
echo "${RELEASE_NOTES}"
|
||||
# escapedNotes=$(sed -e 's/[&\\/]/\\&/g; s/$/\\/' -e '$s/\\$//' <<<"${RELEASE_NOTES}")
|
||||
# sed -i -z -E "s/<CHANGES>(.*)<\/CHANGES>/<CHANGES>\n${escapedNotes}\n<\/CHANGES>/g" "plugins/dynamix.unraid.net.staging.plg"
|
||||
- name: Upload binary txz and plg to Github artifacts
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: connect-files
|
||||
path: |
|
||||
${{ github.workspace }}/plugin/archive/*.txz
|
||||
${{ github.workspace }}/plugin/plugins/*.plg
|
||||
retention-days: 5
|
||||
if-no-files-found: error
|
||||
57
.github/workflows/push-staging-pr-on-close.yml
vendored
Normal file
57
.github/workflows/push-staging-pr-on-close.yml
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
name: Push Staging Plugin on PR Close
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types:
|
||||
- closed
|
||||
|
||||
jobs:
|
||||
push-staging:
|
||||
if: github.event.pull_request.merged == true
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
- name: Set Timezone
|
||||
uses: szenius/set-timezone@v1.2
|
||||
with:
|
||||
timezoneLinux: "America/Los_Angeles"
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: refs/pull/${{ github.event.pull_request.number }}/merge
|
||||
|
||||
- name: Download artifact
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: connect-files
|
||||
path: connect-files
|
||||
|
||||
- name: Update Downloaded Staging Plugin to New Date
|
||||
run: |
|
||||
if [ ! -f "connect-files/plugins/dynamix.unraid.net.pr.plg" ]; then
|
||||
echo "ERROR: dynamix.unraid.net.pr.plg not found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
plgfile="connect-files/plugins/dynamix.unraid.net.pr.plg"
|
||||
version=$(date +"%Y.%m.%d.%H%M")
|
||||
sed -i -E "s#(<!ENTITY version \").*(\">)#\1${version}\2#g" "${plgfile}" || exit 1
|
||||
|
||||
# Change the plugin url to point to staging
|
||||
url="https://preview.dl.unraid.net/unraid-api/dynamix.unraid.net.plg"
|
||||
sed -i -E "s#(<!ENTITY pluginURL \").*(\">)#\1${url}\2#g" "${plgfile}" || exit 1
|
||||
cat "${plgfile}"
|
||||
mkdir -p pr-release
|
||||
mv "${plgfile}" pr-release/dynamix.unraid.net.plg
|
||||
|
||||
- name: Upload to Cloudflare
|
||||
uses: jakejarvis/s3-sync-action@v0.5.1
|
||||
env:
|
||||
AWS_S3_ENDPOINT: ${{ secrets.CF_ENDPOINT }}
|
||||
AWS_S3_BUCKET: ${{ secrets.CF_BUCKET_PREVIEW }}
|
||||
AWS_ACCESS_KEY_ID: ${{ secrets.CF_ACCESS_KEY_ID }}
|
||||
AWS_SECRET_ACCESS_KEY: ${{ secrets.CF_SECRET_ACCESS_KEY }}
|
||||
AWS_REGION: "auto"
|
||||
SOURCE_DIR: pr-release
|
||||
DEST_DIR: unraid-api/pr/${{ github.event.pull_request.number }}
|
||||
56
.github/workflows/release-production.yml
vendored
Normal file
56
.github/workflows/release-production.yml
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
name: Publish Release to Digital Ocean
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
|
||||
jobs:
|
||||
publish-to-digital-ocean:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Download Release Artifacts (Plugins)
|
||||
uses: dsaltares/fetch-gh-release-asset@master
|
||||
with:
|
||||
file: ".*"
|
||||
regex: true
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
target: "./"
|
||||
version: "latest"
|
||||
|
||||
- uses: cardinalby/git-get-release-action@v1
|
||||
id: release-info
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
latest: true
|
||||
prerelease: false
|
||||
- name: Get Release Changelog
|
||||
run: |
|
||||
notes=$(cat << EOF
|
||||
${{ steps.release-info.outputs.body }}
|
||||
EOF
|
||||
)
|
||||
escapedNotes=$(sed -e 's/[&\\/]/\\&/g; s/$/\\/' -e '$s/\\$//' <<<"$notes")
|
||||
sed -i -z -E "s/<CHANGES>(.*)<\/CHANGES>/<CHANGES>\n${escapedNotes}\n<\/CHANGES>/g" "dynamix.unraid.net.plg"
|
||||
|
||||
- name: Upload All Release Files to DO Spaces
|
||||
uses: BetaHuhn/do-spaces-action@v2
|
||||
with:
|
||||
access_key: ${{ secrets.DO_ACCESS_KEY }}
|
||||
secret_key: ${{ secrets.DO_SECRET_KEY }}
|
||||
space_name: ${{ secrets.DO_SPACE_NAME }}
|
||||
space_region: ${{ secrets.DO_SPACE_REGION }}
|
||||
source: "."
|
||||
out_dir: unraid-api
|
||||
|
||||
- name: Upload Staging Plugin to Cloudflare Bucket
|
||||
uses: jakejarvis/s3-sync-action@v0.5.1
|
||||
env:
|
||||
AWS_S3_ENDPOINT: ${{ secrets.CF_ENDPOINT }}
|
||||
AWS_S3_BUCKET: ${{ secrets.CF_BUCKET }}
|
||||
AWS_ACCESS_KEY_ID: ${{ secrets.CF_ACCESS_KEY_ID }}
|
||||
AWS_SECRET_ACCESS_KEY: ${{ secrets.CF_SECRET_ACCESS_KEY }}
|
||||
AWS_REGION: 'auto'
|
||||
SOURCE_DIR: "."
|
||||
DEST_DIR: unraid-api
|
||||
15
.gitignore
vendored
15
.gitignore
vendored
@@ -24,6 +24,7 @@ build/Release
|
||||
# Dependency directories
|
||||
node_modules/
|
||||
jspm_packages/
|
||||
unraid-ui/node_modules/
|
||||
|
||||
# TypeScript v1 declaration files
|
||||
typings/
|
||||
@@ -50,17 +51,21 @@ typings/
|
||||
.next
|
||||
|
||||
# Visual Studio Code workspace
|
||||
.vscode/*
|
||||
!.vscode/extensions.json
|
||||
.vscode/sftp.json
|
||||
.history/
|
||||
|
||||
# OSX
|
||||
.DS_Store
|
||||
|
||||
# Jetbrains Settings Files
|
||||
.idea
|
||||
|
||||
# Temp dir for tests
|
||||
test/__temp__/*
|
||||
|
||||
# Built files
|
||||
dist
|
||||
unraid-ui/storybook-static
|
||||
|
||||
# Typescript
|
||||
typescript
|
||||
@@ -71,7 +76,7 @@ typescript
|
||||
# Github actions
|
||||
RELEASE_NOTES.md
|
||||
|
||||
# Docker Deploy Folder
|
||||
# Docker Deploy Folder
|
||||
deploy/*
|
||||
!deploy/.gitkeep
|
||||
|
||||
@@ -84,4 +89,6 @@ deploy/*
|
||||
.cache
|
||||
.output
|
||||
.env*
|
||||
!.env.example
|
||||
!.env.example
|
||||
|
||||
fb_keepalive
|
||||
|
||||
1
.release-please-manifest.json
Normal file
1
.release-please-manifest.json
Normal file
@@ -0,0 +1 @@
|
||||
{"api":"3.10.0","web":"3.10.0"}
|
||||
10
.vscode/extensions.json
vendored
Normal file
10
.vscode/extensions.json
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"recommendations": [
|
||||
"natizyskunk.sftp",
|
||||
"davidanson.vscode-markdownlint",
|
||||
"bmewburn.vscode-intelephense-client",
|
||||
"foxundermoon.shell-format",
|
||||
"timonwong.shellcheck",
|
||||
"esbenp.prettier-vscode"
|
||||
]
|
||||
}
|
||||
43
.vscode/settings.json
vendored
43
.vscode/settings.json
vendored
@@ -1,30 +1,15 @@
|
||||
{
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll": false,
|
||||
"source.fixAll.eslint": true
|
||||
},
|
||||
"workbench.colorCustomizations": {
|
||||
"activityBar.activeBackground": "#78797d",
|
||||
"activityBar.background": "#78797d",
|
||||
"activityBar.foreground": "#e7e7e7",
|
||||
"activityBar.inactiveForeground": "#e7e7e799",
|
||||
"activityBarBadge.background": "#df9fac",
|
||||
"activityBarBadge.foreground": "#15202b",
|
||||
"commandCenter.border": "#e7e7e799",
|
||||
"sash.hoverBorder": "#78797d",
|
||||
"statusBar.background": "#5f6063",
|
||||
"statusBar.foreground": "#e7e7e7",
|
||||
"statusBarItem.hoverBackground": "#78797d",
|
||||
"statusBarItem.remoteBackground": "#5f6063",
|
||||
"statusBarItem.remoteForeground": "#e7e7e7",
|
||||
"titleBar.activeBackground": "#5f6063",
|
||||
"titleBar.activeForeground": "#e7e7e7",
|
||||
"titleBar.inactiveBackground": "#5f606399",
|
||||
"titleBar.inactiveForeground": "#e7e7e799"
|
||||
},
|
||||
"peacock.color": "#5f6063",
|
||||
"i18n-ally.localesPaths": [
|
||||
"locales"
|
||||
],
|
||||
"i18n-ally.keystyle": "flat"
|
||||
}
|
||||
"files.associations": {
|
||||
"*.page": "php"
|
||||
},
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll": "never",
|
||||
"source.fixAll.eslint": "explicit"
|
||||
},
|
||||
"i18n-ally.localesPaths": [
|
||||
"locales"
|
||||
],
|
||||
"i18n-ally.keystyle": "flat",
|
||||
"eslint.experimental.useFlatConfig": true
|
||||
}
|
||||
|
||||
22
.vscode/sftp-template.json
vendored
Normal file
22
.vscode/sftp-template.json
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"_comment": "rename this file to .vscode/sftp.json and replace name/host/privateKeyPath for your system",
|
||||
"name": "Tower",
|
||||
"host": "Tower.local",
|
||||
"protocol": "sftp",
|
||||
"port": 22,
|
||||
"username": "root",
|
||||
"privateKeyPath": "C:/Users/username/.ssh/tower",
|
||||
"remotePath": "/",
|
||||
"context": "plugin/source/dynamix.unraid.net/",
|
||||
"uploadOnSave": true,
|
||||
"useTempFile": false,
|
||||
"openSsh": false,
|
||||
"ignore": [
|
||||
"// comment: ignore dot files/dirs in root of repo",
|
||||
".github",
|
||||
".vscode",
|
||||
".git",
|
||||
".DS_Store"
|
||||
]
|
||||
}
|
||||
|
||||
1
api/.dockerignore
Normal file
1
api/.dockerignore
Normal file
@@ -0,0 +1 @@
|
||||
node_modules/
|
||||
@@ -1,11 +1,14 @@
|
||||
PATHS_UNRAID_DATA=./dev/data # Where we store plugin data (e.g. permissions.json)
|
||||
PATHS_STATES=./dev/states # Where .ini files live (e.g. vars.ini)
|
||||
PATHS_AUTH_SESSIONS=./dev/sessions # Where user sessions live
|
||||
PATHS_AUTH_KEY=./dev/keys # Auth key directory
|
||||
PATHS_DYNAMIX_BASE=./dev/dynamix # Dynamix's data directory
|
||||
PATHS_DYNAMIX_CONFIG_DEFAULT=./dev/dynamix/default.cfg # Dynamix's default config file, which ships with unraid
|
||||
PATHS_DYNAMIX_CONFIG=./dev/dynamix/dynamix.cfg # Dynamix's config file
|
||||
PATHS_MY_SERVERS_CONFIG=./dev/Unraid.net/myservers.cfg # My servers config file
|
||||
PATHS_MY_SERVERS_FB=./dev/Unraid.net/fb_keepalive # My servers flashbackup timekeeper file
|
||||
PATHS_KEYFILE_BASE=./dev/Unraid.net # Keyfile location
|
||||
PATHS_MACHINE_ID=./dev/data/machine-id
|
||||
|
||||
ENVIRONMENT="development"
|
||||
NODE_ENV="development"
|
||||
PORT="3001"
|
||||
@@ -13,6 +16,8 @@ PLAYGROUND=true
|
||||
INTROSPECTION=true
|
||||
MOTHERSHIP_GRAPHQL_LINK="http://authenticator:3000/graphql"
|
||||
NODE_TLS_REJECT_UNAUTHORIZED=0
|
||||
BYPASS_PERMISSION_CHECKS=true
|
||||
BYPASS_CORS_CHECKS=false
|
||||
BYPASS_PERMISSION_CHECKS=false
|
||||
BYPASS_CORS_CHECKS=true
|
||||
CHOKIDAR_USEPOLLING=true
|
||||
LOG_TRANSPORT=console
|
||||
LOG_LEVEL=trace
|
||||
11
api/.env.test
Normal file
11
api/.env.test
Normal file
@@ -0,0 +1,11 @@
|
||||
VERSION="THIS_WILL_BE_REPLACED_WHEN_BUILT"
|
||||
|
||||
PATHS_UNRAID_DATA=./dev/data # Where we store plugin data (e.g. permissions.json)
|
||||
PATHS_STATES=./dev/states # Where .ini files live (e.g. vars.ini)
|
||||
PATHS_DYNAMIX_BASE=./dev/dynamix # Dynamix's data directory
|
||||
PATHS_DYNAMIX_CONFIG=./dev/dynamix/dynamix.cfg # Dynamix's config file
|
||||
PATHS_MY_SERVERS_CONFIG=./dev/Unraid.net/myservers.cfg # My servers config file
|
||||
PATHS_MY_SERVERS_FB=./dev/Unraid.net/fb_keepalive # My servers flashbackup timekeeper file
|
||||
PATHS_KEYFILE_BASE=./dev/Unraid.net # Keyfile location
|
||||
PORT=5000
|
||||
NODE_ENV=test
|
||||
@@ -1,47 +0,0 @@
|
||||
/** @type {import('eslint').Linter.Config} */
|
||||
module.exports = {
|
||||
root: true,
|
||||
plugins: [
|
||||
'@typescript-eslint/eslint-plugin',
|
||||
'unused-imports',
|
||||
'eslint-plugin-unicorn',
|
||||
],
|
||||
ignorePatterns: ['src/graphql/generated/**/*.ts', '*.test.ts', 'tsup.config.ts', 'vite.config.ts'],
|
||||
parser: '@typescript-eslint/parser',
|
||||
rules: {
|
||||
'@typescript-eslint/no-redundant-type-constituents': 'off',
|
||||
'@typescript-eslint/no-unsafe-call': 'off',
|
||||
'@typescript-eslint/naming-convention': 'off',
|
||||
'@typescript-eslint/no-unsafe-assignment': 'off',
|
||||
'@typescript-eslint/no-unsafe-return': 'off',
|
||||
'@typescript-eslint/ban-types': 'off',
|
||||
'@typescript-eslint/no-explicit-any': 'off',
|
||||
'@typescript-eslint/consistent-type-imports': [
|
||||
'warn',
|
||||
{ fixStyle: 'inline-type-imports' },
|
||||
],
|
||||
'unicorn/numeric-separators-style': [
|
||||
'error',
|
||||
{ number: { minimumDigits: 0, groupLength: 3 } },
|
||||
],
|
||||
'import/no-cycle': 'off', // Change this to "error" to find circular imports
|
||||
'@typescript-eslint/no-use-before-define': ['error'],
|
||||
'no-multiple-empty-lines': ['error', { max: 1, maxBOF: 0, maxEOF: 1 }],
|
||||
},
|
||||
overrides: [
|
||||
{
|
||||
files: ['*.ts'],
|
||||
extends: [
|
||||
'eslint:recommended',
|
||||
'plugin:@typescript-eslint/recommended',
|
||||
],
|
||||
parserOptions: {
|
||||
project: true,
|
||||
tsconfigRootDir: __dirname,
|
||||
},
|
||||
rules: {
|
||||
'@typescript-eslint/no-explicit-any': 'off',
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
35
api/.eslintrc.ts
Normal file
35
api/.eslintrc.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
import eslint from '@eslint/js';
|
||||
import noRelativeImportPaths from 'eslint-plugin-no-relative-import-paths';
|
||||
import prettier from 'eslint-plugin-prettier';
|
||||
import tseslint from 'typescript-eslint';
|
||||
|
||||
export default tseslint.config(eslint.configs.recommended, ...tseslint.configs.recommended, {
|
||||
plugins: {
|
||||
'no-relative-import-paths': noRelativeImportPaths,
|
||||
prettier: prettier,
|
||||
},
|
||||
rules: {
|
||||
'@typescript-eslint/no-redundant-type-constituents': 'off',
|
||||
'@typescript-eslint/no-unsafe-call': 'off',
|
||||
'@typescript-eslint/naming-convention': 'off',
|
||||
'@typescript-eslint/no-unsafe-assignment': 'off',
|
||||
'@typescript-eslint/no-unsafe-return': 'off',
|
||||
'@typescript-eslint/ban-types': 'off',
|
||||
'@typescript-eslint/no-explicit-any': 'off',
|
||||
'@typescript-eslint/no-empty-object-type': 'off',
|
||||
'no-use-before-define': ['off'],
|
||||
'no-multiple-empty-lines': ['error', { max: 1, maxBOF: 0, maxEOF: 1 }],
|
||||
'@typescript-eslint/no-unused-vars': 'off',
|
||||
'@typescript-eslint/no-unused-expressions': 'off',
|
||||
'import/no-unresolved': 'off',
|
||||
'import/extensions': 'off',
|
||||
'import/no-absolute-path': 'off',
|
||||
'import/prefer-default-export': 'off',
|
||||
'no-relative-import-paths/no-relative-import-paths': [
|
||||
'error',
|
||||
{ allowSameFolder: false, rootDir: 'src', prefix: '@app' },
|
||||
],
|
||||
'prettier/prettier': 'error',
|
||||
},
|
||||
ignores: ['src/graphql/generated/client/**/*'],
|
||||
});
|
||||
82
api/.gitignore
vendored
Normal file
82
api/.gitignore
vendored
Normal file
@@ -0,0 +1,82 @@
|
||||
# Logs
|
||||
./logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||
lib-cov
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
coverage
|
||||
coverage-ts
|
||||
|
||||
# nyc test coverage
|
||||
.nyc_output
|
||||
|
||||
# node-waf configuration
|
||||
.lock-wscript
|
||||
|
||||
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||
build/Release
|
||||
|
||||
# Dependency directories
|
||||
node_modules/
|
||||
jspm_packages/
|
||||
|
||||
# TypeScript v1 declaration files
|
||||
typings/
|
||||
|
||||
# Optional npm cache directory
|
||||
.npm
|
||||
|
||||
# Optional eslint cache
|
||||
.eslintcache
|
||||
|
||||
# Optional REPL history
|
||||
.node_repl_history
|
||||
|
||||
# Output of 'npm pack'
|
||||
*.tgz
|
||||
|
||||
# Yarn Integrity file
|
||||
.yarn-integrity
|
||||
|
||||
# dotenv environment variables file
|
||||
.env
|
||||
|
||||
# next.js build output
|
||||
.next
|
||||
|
||||
# Visual Studio Code workspace
|
||||
.vscode/*
|
||||
!.vscode/extensions.json
|
||||
|
||||
# OSX
|
||||
.DS_Store
|
||||
|
||||
# Temp dir for tests
|
||||
test/__temp__/*
|
||||
|
||||
# Built files
|
||||
dist
|
||||
|
||||
# Typescript
|
||||
typescript
|
||||
|
||||
# Ultra runner
|
||||
.ultra.cache.json
|
||||
|
||||
# Github actions
|
||||
RELEASE_NOTES.md
|
||||
|
||||
# Docker Deploy Folder
|
||||
deploy/*
|
||||
!deploy/.gitkeep
|
||||
|
||||
# pkg cache
|
||||
.pkg-cache
|
||||
|
||||
# IDE Settings Files
|
||||
.idea
|
||||
@@ -1 +1 @@
|
||||
18.17.1
|
||||
v20
|
||||
7
api/.prettierignore
Normal file
7
api/.prettierignore
Normal file
@@ -0,0 +1,7 @@
|
||||
!src/*
|
||||
|
||||
# Downloaded Fixtures (For File Modifications)
|
||||
src/unraid-api/unraid-file-modifier/modifications/__fixtures__/downloaded/*
|
||||
|
||||
# Generated Types
|
||||
src/graphql/generated/client/*.ts
|
||||
38
api/.prettierrc.cjs
Normal file
38
api/.prettierrc.cjs
Normal file
@@ -0,0 +1,38 @@
|
||||
/**
|
||||
* @see https://prettier.io/docs/en/configuration.html
|
||||
* @type {import("prettier").Config}
|
||||
*/
|
||||
module.exports = {
|
||||
trailingComma: 'es5',
|
||||
tabWidth: 4,
|
||||
semi: true,
|
||||
singleQuote: true,
|
||||
printWidth: 105,
|
||||
plugins: ['@ianvs/prettier-plugin-sort-imports'],
|
||||
// decorators-legacy lets the import sorter transform files with decorators
|
||||
importOrderParserPlugins: ['typescript', 'decorators-legacy'],
|
||||
importOrder: [
|
||||
/**----------------------
|
||||
* Nest.js & node.js imports
|
||||
*------------------------**/
|
||||
'<TYPES>^@nestjs(/.*)?$',
|
||||
'^@nestjs(/.*)?$', // matches imports starting with @nestjs
|
||||
'<TYPES>^(node:)',
|
||||
'<BUILTIN_MODULES>', // Node.js built-in modules
|
||||
'',
|
||||
/**----------------------
|
||||
* Third party packages
|
||||
*------------------------**/
|
||||
'<TYPES>',
|
||||
'<THIRD_PARTY_MODULES>', // Imports not matched by other special words or groups.
|
||||
'',
|
||||
/**----------------------
|
||||
* Application Code
|
||||
*------------------------**/
|
||||
'<TYPES>^@app(/.*)?$', // matches type imports starting with @app
|
||||
'^@app(/.*)?$',
|
||||
'',
|
||||
'<TYPES>^[.]',
|
||||
'^[.]', // relative imports
|
||||
],
|
||||
};
|
||||
7
api/.vscode/settings.json
vendored
Normal file
7
api/.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"eslint.lintTask.options": "--flag unstable_ts_config",
|
||||
"eslint.options": {
|
||||
"flags": ["unstable_ts_config"],
|
||||
"overrideConfigFile": ".eslintrc.ts"
|
||||
}
|
||||
}
|
||||
987
api/CHANGELOG.md
987
api/CHANGELOG.md
@@ -2,6 +2,991 @@
|
||||
|
||||
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
||||
|
||||
### [4.0.1](https://github.com/unraid/api/compare/v4.0.0...v4.0.1) (2025-02-06)
|
||||
|
||||
## [4.0.0](https://github.com/unraid/api/compare/v3.11.0...v4.0.0) (2025-02-06)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* actual install url ([89d667e](https://github.com/unraid/api/commit/89d667e33bffb17df43c768f12c21302571270ff))
|
||||
* actually exit on stop and start ([bce5fde](https://github.com/unraid/api/commit/bce5fde64278dd853e71c022c03b9f6888dccfcf))
|
||||
* add api key creation logic ([81382bc](https://github.com/unraid/api/commit/81382bcf1d26364ad9c5445530f648209101cf91))
|
||||
* add command to package.json scripts ([0dfb07f](https://github.com/unraid/api/commit/0dfb07f9eb519e60441f4123423f65acfdffca3b))
|
||||
* add csrf support to api & web components ([#999](https://github.com/unraid/api/issues/999)) ([19241ed](https://github.com/unraid/api/commit/19241ed55f5112f878b9890d8695badf7eb1c3eb))
|
||||
* add date formatting helper ([#938](https://github.com/unraid/api/issues/938)) ([b8c8b00](https://github.com/unraid/api/commit/b8c8b005410bbb612014f34ada51ca23cae67a30))
|
||||
* add deletion & update methods to NotificationService ([ac82b08](https://github.com/unraid/api/commit/ac82b08a9e865cd095cfb5c484404f9e7383391e))
|
||||
* add description flag, remove console log, and update readme ([c416c30](https://github.com/unraid/api/commit/c416c30951de4ed6b8d7a8c014403772db1c2015))
|
||||
* add deviceCount to serverAccountPayload for callbacks ([0fb8b87](https://github.com/unraid/api/commit/0fb8b87ff2645ec642d2f038e5f941a880274817))
|
||||
* add ecosystem.config.json to files ([913febc](https://github.com/unraid/api/commit/913febc0e461bfe052fe116e76d9871e54584aa2))
|
||||
* add exclude to vite.config ([e64dde7](https://github.com/unraid/api/commit/e64dde7a23414a2e649bef999de8e2164c7b507f))
|
||||
* add ID prefix plugin to prefix IDs with server identifier ([066e93a](https://github.com/unraid/api/commit/066e93a52afa17f53df2f238065d853ce2945a1e))
|
||||
* add line about recommendation for sso command ([44727a8](https://github.com/unraid/api/commit/44727a8d1a7c16c566678da43119b17a6303e375))
|
||||
* add log rotation ([f5c7ad9](https://github.com/unraid/api/commit/f5c7ad9221f80e4630e69f78d57f08f4c7252719))
|
||||
* add logging around fixture downloads ([a1ce27b](https://github.com/unraid/api/commit/a1ce27b17c970657f52635600f0d13116523f928))
|
||||
* add logrotate cron again ([4f85f66](https://github.com/unraid/api/commit/4f85f6687f920dae50277e726e2db2c3d946e867))
|
||||
* add patch for auth-request.php ([ec6ec56](https://github.com/unraid/api/commit/ec6ec562f43aac9947de2e9c269181303f42b2db))
|
||||
* add user with cli ([37458cd](https://github.com/unraid/api/commit/37458cd7408a1ad8aedca66a55ff13ac19ee30db))
|
||||
* add validation step to ensure that variables are set ([e3e9b2b](https://github.com/unraid/api/commit/e3e9b2bf404cb6f3bcae83db0395be272e4b79e3))
|
||||
* add web gitignore ([8b49190](https://github.com/unraid/api/commit/8b491900947c9a7a63b7ad61e7d355ff2fd1f801))
|
||||
* address log level feedback ([49774aa](https://github.com/unraid/api/commit/49774aae459797f04ef2866ca064050aa476ae91))
|
||||
* allow csrf passing through querystring ([dba38c0](https://github.com/unraid/api/commit/dba38c0d149a77e4104c718c53d426330a17f2fa))
|
||||
* allow deletion and creation of files with patches ([32c9524](https://github.com/unraid/api/commit/32c952402c25e8340b1c628b4d0fdc4816b28ade))
|
||||
* almost working ([df1fc6d](https://github.com/unraid/api/commit/df1fc6dffaa242d85d8ab79f2bfe9e9b1de4b261))
|
||||
* also copy in other files ([599b365](https://github.com/unraid/api/commit/599b365e8b668d9fba9d88f3d0d03fb7f63244cb))
|
||||
* always ensureDirectory for keys exists ([c6e9f80](https://github.com/unraid/api/commit/c6e9f804c58e44b46bce9f0da2260888544354cd))
|
||||
* always start the API and run npm link from script path ([30133ac](https://github.com/unraid/api/commit/30133acb0514a480177f563d4aee364a8a3fab1b))
|
||||
* **api:** add default dynamix config to dev docker container ([0aeea34](https://github.com/unraid/api/commit/0aeea34427805a9b61a762efbd01c938016be28c))
|
||||
* **api:** graphql sandbox on unraid servers ([#1047](https://github.com/unraid/api/issues/1047)) ([ec504f3](https://github.com/unraid/api/commit/ec504f39297c92b64d9d3cc2f8f482cc1f3a2e44))
|
||||
* **api:** omit tz from sys time date format by default ([b2acde3](https://github.com/unraid/api/commit/b2acde3351d7afe18a2902e90b672537aadabffd))
|
||||
* **api:** rm 2fa & t2fa from myservers config type ([#996](https://github.com/unraid/api/issues/996)) ([89e791a](https://github.com/unraid/api/commit/89e791ad2e6f0395bee05e3f8bdcb2c8d72305dd))
|
||||
* **api:** sort notifications file listing by date (latest first) ([cae8d0b](https://github.com/unraid/api/commit/cae8d0bc07a465d73f0242a8d68816fd0a6042c7))
|
||||
* array iteration for restoring files ([036e97b](https://github.com/unraid/api/commit/036e97bb02e463872b3c2f4b5f1aa3b4bf525d1e))
|
||||
* async disk mapping ([bbb27e6](https://github.com/unraid/api/commit/bbb27e686897e4f9a0c926553d75aa046d7a8323))
|
||||
* async hypervisor and FIXED vm listing ([e79f4dd](https://github.com/unraid/api/commit/e79f4ddbc7061c249efb8214a311bb629628f669))
|
||||
* attempt to fix pm2 ([ab67717](https://github.com/unraid/api/commit/ab67717d5954ae3965c1e4082605af5e42f73ca2))
|
||||
* attempt to start unraid-api with background task ([2a102fc](https://github.com/unraid/api/commit/2a102fc9944f3080af66a8ebadee35059bce2009))
|
||||
* **Auth:** add cookie guard to check for valid sessions ([3dffc0c](https://github.com/unraid/api/commit/3dffc0c663cfbe8c4368ab98c834baf611a8910a))
|
||||
* **auth:** make cors aware of authenticated sessions ([f9c23aa](https://github.com/unraid/api/commit/f9c23aa8852a8335640bbd16caa783e9a38b449c))
|
||||
* automatic session setup for dev ([36d630e](https://github.com/unraid/api/commit/36d630e89bbf9bc7e3ae64bdf5cf73a8536d44ab))
|
||||
* back to callbackUrl ([e39b120](https://github.com/unraid/api/commit/e39b1203a315889c5b5232ecfd32c7377ae04800))
|
||||
* begin building plugin with node instead of bash ([#1120](https://github.com/unraid/api/issues/1120)) ([253b65a](https://github.com/unraid/api/commit/253b65a85ab9c5f53d53ef265b41aa132678f278))
|
||||
* begin fixing dark mode in the webcomponents ([5f7dcdb](https://github.com/unraid/api/commit/5f7dcdb1a7e7bce87b29add7849c94a0353c2c96))
|
||||
* begin nuking alpha beta gamma ([25acd4b](https://github.com/unraid/api/commit/25acd4b39fff9a0cb573f9e90c52830fef41d737))
|
||||
* better patch application ([a3e7daa](https://github.com/unraid/api/commit/a3e7daa6a6565ac81004ffd13da35d8b95b429cf))
|
||||
* better pm2 calls, log lines ([338ce30](https://github.com/unraid/api/commit/338ce3061310dfc42ad5f65edacbe5272de4afc7))
|
||||
* build and pack in docker ([2a322d1](https://github.com/unraid/api/commit/2a322d12570ba3e797fb84289a42b010f3f88467))
|
||||
* buildx build caching ([b38be3c](https://github.com/unraid/api/commit/b38be3ceb7c7299fe30c90ed5a75e131af3b33da))
|
||||
* checkout correct branch on close ([#1123](https://github.com/unraid/api/issues/1123)) ([a20b812](https://github.com/unraid/api/commit/a20b812b020adfade129ebd9fb0e6536004f8bee))
|
||||
* cleanup config entries ([943e73f](https://github.com/unraid/api/commit/943e73fa696b6ecec3227be914ab4962c4fee79d))
|
||||
* cleanup disclaimer and command to add users ([6be3af8](https://github.com/unraid/api/commit/6be3af8d7569d9c413dd9349df52e3fa4cb4f631))
|
||||
* cleanup unused variables ([b50e289](https://github.com/unraid/api/commit/b50e2896f765cecfe631aa839186a6124beb41a3))
|
||||
* cli Commands ([f8e5367](https://github.com/unraid/api/commit/f8e5367f3eb47daa5bcbd7711ae5835369502a1d))
|
||||
* CLI options for adding and deleting users ([16bf6d4](https://github.com/unraid/api/commit/16bf6d4c27ae8fa8d6d05ec4b28ce49a12673278))
|
||||
* code review changes ([fe38acc](https://github.com/unraid/api/commit/fe38acc92e4b1891b0b61fdb4947ec91070cb535))
|
||||
* codeowners ([ab090b4](https://github.com/unraid/api/commit/ab090b48ec7291597a135a72b8e55c2d1bb389f3))
|
||||
* coderabbit suggestion ([11ac36c](https://github.com/unraid/api/commit/11ac36c3616a90853d91467526fd39ecba17db88))
|
||||
* comment URL for plugin on PR ([9840b33](https://github.com/unraid/api/commit/9840b334b4466a4f72e3e57055338a3d5557553d))
|
||||
* configure PM2 on startup ([2b908f1](https://github.com/unraid/api/commit/2b908f100b9eefaccf2264d5ff9945667568acf0))
|
||||
* copy ([7e33e5c](https://github.com/unraid/api/commit/7e33e5ca32e95168bb82f090c1acaee43bce1f25))
|
||||
* copy node modules ([bb0436c](https://github.com/unraid/api/commit/bb0436c7fec54be9ea63681104e720bb5b499f58))
|
||||
* copy only needed files for nodejs ([acf587a](https://github.com/unraid/api/commit/acf587aa53ca25a3beae86afc608fc9ed68919ef))
|
||||
* create key cli command logic and add to index command list ([9b2a62d](https://github.com/unraid/api/commit/9b2a62d642b0942e3787e4ddd582a66e40321ab2))
|
||||
* csv validation ([84aae15](https://github.com/unraid/api/commit/84aae15a73014592c226fa3701e34e57c7b60b46))
|
||||
* default value for option ([6513fc4](https://github.com/unraid/api/commit/6513fc49de61c836e1aabf32a874d7da7da18adb))
|
||||
* delete unused imports ([97a3772](https://github.com/unraid/api/commit/97a3772d95aff534d85c410e58391d30494d9237))
|
||||
* diff ([02c0c5f](https://github.com/unraid/api/commit/02c0c5f8e09476ddcd207c49e1c7d6c764c40d69))
|
||||
* disable button on submit ([2ceb5da](https://github.com/unraid/api/commit/2ceb5da3c70826cc50df476decb6b117025f46c0))
|
||||
* disable casbin logging ([2518e7c](https://github.com/unraid/api/commit/2518e7c506f0d3aa9f44031d61dce95d9db0a4cf))
|
||||
* do not move upgradepkg ([ea16419](https://github.com/unraid/api/commit/ea16419929e0233e2c1ce37e2f4b79e3e64ce619))
|
||||
* docstrings ([b836ba7](https://github.com/unraid/api/commit/b836ba72516c554ee8973d69aaaa4ed35b465fa7))
|
||||
* don't remove directory, only files ([c2227cb](https://github.com/unraid/api/commit/c2227cbaadbbfe3dda6a89690a396db5bd6db444))
|
||||
* dont pass entire server state for privacy ([54e3f17](https://github.com/unraid/api/commit/54e3f17bd9e541f50970c696bbe8b602ec38a748))
|
||||
* download fixtures from the web ([1258c2b](https://github.com/unraid/api/commit/1258c2bc1813f0fa3cd52b4932302ad12b4edd01))
|
||||
* download nodejs and install on legacy OS versions ([2a95e4b](https://github.com/unraid/api/commit/2a95e4beb2364510003f187459e28bb610583c41))
|
||||
* eliminate all alpha beta gamma variable usage ([fbdbce9](https://github.com/unraid/api/commit/fbdbce97ec2171ec7057f0f159e73032e984705a))
|
||||
* enable PR releases on non-mainline merges ([7ae8d03](https://github.com/unraid/api/commit/7ae8d03166952a602f0b7ebaf1cc65a9a8d27e7b))
|
||||
* enable sandbox in dev mode ([4536d70](https://github.com/unraid/api/commit/4536d7092d77c68f5a996fd63bf74ce6e64f5efe))
|
||||
* enable sandbox with developer command ([c354d48](https://github.com/unraid/api/commit/c354d482283295547afeb99c5e110b0181197c44))
|
||||
* enable token sign in with comma separated subs in myservers.config ([ebed5bd](https://github.com/unraid/api/commit/ebed5bddea1445d9aaaee60d54758dc74b77271e))
|
||||
* error state outside of button ([18c63e0](https://github.com/unraid/api/commit/18c63e0b0c7451c99eacabb504e18f8070ff7dc2))
|
||||
* error when nodejs download fails ([6a9b14c](https://github.com/unraid/api/commit/6a9b14c68170d6430328cbb793d750f3177bdb32))
|
||||
* exit after running status ([12f551c](https://github.com/unraid/api/commit/12f551c9d91692b40b73d96133d45c04f795548e))
|
||||
* exit cli after running command ([04bf528](https://github.com/unraid/api/commit/04bf528616fcbdf916916734a12d5fd32db9a06d))
|
||||
* expose mutations for notifications over graphql ([59dc330](https://github.com/unraid/api/commit/59dc33029d03c3d3cda5b4c2a60772e2b7d01811))
|
||||
* extensive file checking ([ab881c8](https://github.com/unraid/api/commit/ab881c8aed8dd4aa9fd71c32b50d3514d1496fa5))
|
||||
* extract node to usr/local/ ([4c0b55b](https://github.com/unraid/api/commit/4c0b55b269f47a9d8f746344ae701e353d80509a))
|
||||
* fallback to local ([a2579c2](https://github.com/unraid/api/commit/a2579c2a7f80f54b4cc61533aec9ecc41a7e7f54))
|
||||
* faster failure logic ([b439434](https://github.com/unraid/api/commit/b439434f1574e174fcf23f3a5f5b8df8e092eb1e))
|
||||
* fix header strategy ([4187b77](https://github.com/unraid/api/commit/4187b77a107c0f37e47a1e272c5acb9b798ad3be))
|
||||
* fix issues with permissions and invalid modules ([e0cfb40](https://github.com/unraid/api/commit/e0cfb40c847a53def1057ae00c97f9306713c3d1))
|
||||
* fix missing flash line ([6897aad](https://github.com/unraid/api/commit/6897aad67f5c8b38450aa81e612b8aa98a9328c7))
|
||||
* fix missing import in ESM ([8e99bdd](https://github.com/unraid/api/commit/8e99bdd8f97e772b07374d833debff4eadbf6501))
|
||||
* fix more imports ([028df06](https://github.com/unraid/api/commit/028df06cd2279d219bd0b3039ad8680de6138b83))
|
||||
* fix pm2 setup and add link command ([de9500f](https://github.com/unraid/api/commit/de9500ffa6f3aa1842152e0ab26f54c8c5c6e5cb))
|
||||
* force linting on build ([43e6639](https://github.com/unraid/api/commit/43e663998a55e83c142067cb64ae7a331395fe68))
|
||||
* generate key one time ([afe53c3](https://github.com/unraid/api/commit/afe53c30ea9987e6d8728faa2cb7291f8a126ecb))
|
||||
* glob for files ([3fe281f](https://github.com/unraid/api/commit/3fe281f1ae28e3cbc089b5244a6ae2863b20adcb))
|
||||
* hide sign in from the dropdown text ([3e68aaf](https://github.com/unraid/api/commit/3e68aaf8cdc0fb20c6e1b819a8571f419d94a811))
|
||||
* hypervisor async imports ([32686ca](https://github.com/unraid/api/commit/32686ca4f0c25c43c6a9f7162bb8179b39e58f7e))
|
||||
* ID prefixer improvement ([ed55b32](https://github.com/unraid/api/commit/ed55b32645d7414657c7775d5a786fa2653294d5))
|
||||
* ignore generated code ([68265a2](https://github.com/unraid/api/commit/68265a26efa588b60001310b9a11b398f04ae88f))
|
||||
* implement mutations for updating many notifications at once ([6c90508](https://github.com/unraid/api/commit/6c90508c64e453849d06818cca2a3f6f7dfbf172))
|
||||
* improve packing ([9ef02d5](https://github.com/unraid/api/commit/9ef02d53666b70d41fdd186364808deac715e1ff))
|
||||
* initial patcher implementation using the diff tool ([c87acbb](https://github.com/unraid/api/commit/c87acbb146c2e4e30997c964cd8be325dee68cea))
|
||||
* initial setup of permissions on keys ([#1068](https://github.com/unraid/api/issues/1068)) ([cf0fa85](https://github.com/unraid/api/commit/cf0fa850954ea2f018e338a132149f872b966df4))
|
||||
* initial version of modification service ([b80469d](https://github.com/unraid/api/commit/b80469d38e519a7ba0e6eae636cda2a821e2d465))
|
||||
* inject after form ([a4b276f](https://github.com/unraid/api/commit/a4b276f7874580bbf9827025730777715c9983da))
|
||||
* install nghttp3 ([7e6cf85](https://github.com/unraid/api/commit/7e6cf858b270e615ec3eeddd394d0c2e6d810e21))
|
||||
* install node ([4b85338](https://github.com/unraid/api/commit/4b853389d4ee7d0fb8e539d948dac21e748f642a))
|
||||
* integrate cross-domain authentication to api ([7749783](https://github.com/unraid/api/commit/77497830c13d8e3ce1c348a8c79d8835ad5e3eb2))
|
||||
* kill timeout extended ([22d4026](https://github.com/unraid/api/commit/22d40264a02672a818053b5280d63a03ff7336b9))
|
||||
* linting continues on error ([a3499d6](https://github.com/unraid/api/commit/a3499d6feee56319657c37bb77277d5c637ee0b5))
|
||||
* log size and only tar files ([731f2f8](https://github.com/unraid/api/commit/731f2f8e77a77b544a7f526c78aabfacca71eee4))
|
||||
* logrotate test ([4504c39](https://github.com/unraid/api/commit/4504c39a2bbcf51385578b69a9fdc7b81a950e98))
|
||||
* lots of progress on colors ([dc8b2ee](https://github.com/unraid/api/commit/dc8b2ee01b454d307e779d495dbcf11227760480))
|
||||
* make notification id logic ([d5e0b3a](https://github.com/unraid/api/commit/d5e0b3a81ef3406b40e3376b5bca2fd101aa9c11))
|
||||
* manually install libvirt in build process to ensure it is included in the final build ([e695481](https://github.com/unraid/api/commit/e695481363f0d5d7add9d0e0d50d1e113b3024f6))
|
||||
* massive rc.unraid-api updates to facilitate installing and linking ([ded03d8](https://github.com/unraid/api/commit/ded03d86b25b51af98de2b7e7397a641dd0c082a))
|
||||
* more cleanup ([9f6aeec](https://github.com/unraid/api/commit/9f6aeecfd90d069a0b2a642f99ef9622f4e0526d))
|
||||
* more pm2 fixes ([8257bdf](https://github.com/unraid/api/commit/8257bdff3624211ee645349abdec303bf271538e))
|
||||
* more process improvements ([9491be1](https://github.com/unraid/api/commit/9491be1038ee2e0e24be111bd8e8c78ec2890124))
|
||||
* mount git folder to builder ([91350ea](https://github.com/unraid/api/commit/91350ea8535511c964d5869bd74a37830fc1bc40))
|
||||
* move fixtures into __test__ folder ([22a901d](https://github.com/unraid/api/commit/22a901de9b0c274d3f75ed4b4618cd6cd90324ba))
|
||||
* move ssoenabled to a boolean flag rather than ids ([404a02b](https://github.com/unraid/api/commit/404a02b26bae6554d15e317f613ebc727c8f702f))
|
||||
* move to singular build and test step ([c9c8e86](https://github.com/unraid/api/commit/c9c8e8653321eaa0292a16e970d6dd4e79a3928f))
|
||||
* move variable declarations to theme.ts ([3c82ee1](https://github.com/unraid/api/commit/3c82ee1e9acc197c9768a624cdef8c2e23c56d00))
|
||||
* myservers_fb keepalive location ([e07e7f3](https://github.com/unraid/api/commit/e07e7f335c8ea4a73966ada90c26b7c82dbb025e))
|
||||
* name package with PR number ([a642bf1](https://github.com/unraid/api/commit/a642bf15fd813dca522808765994414e4ed5a56c))
|
||||
* nghttp3 sha256 missing ([589cc9b](https://github.com/unraid/api/commit/589cc9b4624d9d0e00ec3b86873d8ecb6a861427))
|
||||
* nodejs issues with version 2 ([9c6e52c](https://github.com/unraid/api/commit/9c6e52c2fa46e7504bc3fa500770373d8c1d1690))
|
||||
* **NotificationService:** endpoint to manually recalculate notification overview ([18e150f](https://github.com/unraid/api/commit/18e150f908b937cccd13171830fc418c3600cdbe))
|
||||
* **NotificationsService:** use existing notifier script to create notifications when possible ([2f1711f](https://github.com/unraid/api/commit/2f1711f06a2fa0a679aeae12176cb2dd763494a4))
|
||||
* nuxt config simplification and formatting ([02ffde2](https://github.com/unraid/api/commit/02ffde24d19594949faa97f9d070383b498fdcbe))
|
||||
* only run mainline build ([b6ee6f9](https://github.com/unraid/api/commit/b6ee6f9c9f7740e91856754caecb6630bc62f37b))
|
||||
* only write config when a specific config update action occurs ([ec29778](https://github.com/unraid/api/commit/ec29778e37a50f43eb164991bcf2a6ff9c266033))
|
||||
* or button on sign in page ([1433e93](https://github.com/unraid/api/commit/1433e938d7ac01af326e2875c582a6aa6d622615))
|
||||
* pack everything in API ([178a6f6](https://github.com/unraid/api/commit/178a6f6b0d7cf2fc4b2ad4cfbd9a928f880c222c))
|
||||
* package scripts ([123aa77](https://github.com/unraid/api/commit/123aa77fe6f21e64809083d8b872ef2152be1ad1))
|
||||
* pass env into builder ([e75ac99](https://github.com/unraid/api/commit/e75ac99d8e19e7ea66671c211bd4cf85ec3b81b0))
|
||||
* plg builder improvements to be more explicit ([78c2f03](https://github.com/unraid/api/commit/78c2f035da0f0c6aaaedbee11c8c4f2a8cd42d0f))
|
||||
* **plugin:** rm Date & Time format settings from Notification Settings ([e2148f3](https://github.com/unraid/api/commit/e2148f3c2eaf77ad707eddb7989cc20ec8df70ab))
|
||||
* pm2 fixes ([5b322b4](https://github.com/unraid/api/commit/5b322b4faed6e8f0bb0742832cb94c8027d0e12b))
|
||||
* pm2 fully working ([ecb642b](https://github.com/unraid/api/commit/ecb642b6a88bd66c3ccd1f4e1dcd2c92d7ff4b35))
|
||||
* pm2 initial setup ([3cee381](https://github.com/unraid/api/commit/3cee381c442032d24c9c33dfa6d8a43581061fca))
|
||||
* PR builds ([0025852](https://github.com/unraid/api/commit/00258524fa3f7ed745abfe471dfdb780b6d2b365))
|
||||
* process env fixed and copy gql files ([8b90620](https://github.com/unraid/api/commit/8b90620d28378caabc7bbc1745ca43a1ddf8bd87))
|
||||
* properly read log level from environment ([b5151e9](https://github.com/unraid/api/commit/b5151e9ba76a6814e24e8da34e8a3c1bf1cc2144))
|
||||
* properly set outputs ([aa6904e](https://github.com/unraid/api/commit/aa6904e0a455a75a8187259d491b04366ad50fb0))
|
||||
* rem converter ([d2489df](https://github.com/unraid/api/commit/d2489df6eaaa267a2f51b896c6c14ac9c5b00f85))
|
||||
* remove apiKey from server ([b110a11](https://github.com/unraid/api/commit/b110a118fb153c0af09a74755deb468b3760ba27))
|
||||
* remove console log disabler ([0cf24d2](https://github.com/unraid/api/commit/0cf24d2a212e1f44e0b379221c93aa436c3b7179))
|
||||
* remove many unneded simple libraries ([483e6dc](https://github.com/unraid/api/commit/483e6dc28d70b933dc956b4ffd6da4ade8ab7eb9))
|
||||
* remove more unused calls ([5d2923f](https://github.com/unraid/api/commit/5d2923f8ee5bfd574420fca85e2c4aefbe7b33d6))
|
||||
* remove nghttp3 and only bundle nodejs ([8d8df15](https://github.com/unraid/api/commit/8d8df1592e5af127a992d5634ee9d344055cdf2c))
|
||||
* remove sso if disabled on Unraid-API start ([3bc407c](https://github.com/unraid/api/commit/3bc407c54e8e7aeadebd9ac223d71f21ef97fca1))
|
||||
* remove sso user command ([bbd809b](https://github.com/unraid/api/commit/bbd809b83826e81eef38a06e66f3393e4f83e81e))
|
||||
* remove sso user options ([e34041f](https://github.com/unraid/api/commit/e34041f86ef7ab6cf5e2fdf7efb86458d190edc1))
|
||||
* remove unused config sections ([f0b9c4f](https://github.com/unraid/api/commit/f0b9c4f44ab0ee8f75bf96fde2413988ef4f6a8c))
|
||||
* remove unused fields ([d2d0f7c](https://github.com/unraid/api/commit/d2d0f7cd9acb53ea2372245d7ef669c7ca24ee8a))
|
||||
* remove unused vars ([0507713](https://github.com/unraid/api/commit/0507713972e344ad47bd077554d5888269669e9c))
|
||||
* remove wtfnode ([cbdcc47](https://github.com/unraid/api/commit/cbdcc476b617539611478cf6f29bbb57d0be83b3))
|
||||
* rename api key resource back to api_key ([ee9666b](https://github.com/unraid/api/commit/ee9666b317d7feb5c15d53e2a6b902c7771c8c7a))
|
||||
* rename modification file ([70a93f2](https://github.com/unraid/api/commit/70a93f2cc63e0e62242be6fe1a717515a6fbec85))
|
||||
* responsive notifications ([d427054](https://github.com/unraid/api/commit/d427054443176563faa3e44249219c1d938e4b07))
|
||||
* restart the API when an SSO user is added ([a6b0c90](https://github.com/unraid/api/commit/a6b0c906a423df048401750943f02dfdc9bc2619))
|
||||
* restoring sso error ([234bf7d](https://github.com/unraid/api/commit/234bf7dfa4b0be88b6cc13996d8f29ec819da26e))
|
||||
* revert local api key value ([ff40e7a](https://github.com/unraid/api/commit/ff40e7ae392052d3d9e1b084c5f4851e8ebd529e))
|
||||
* right workin directory ([0d99ab0](https://github.com/unraid/api/commit/0d99ab0d74356e4ea309cb86dfc710ed93ab70e7))
|
||||
* rollback if patch exists before applying ([c2f4e8d](https://github.com/unraid/api/commit/c2f4e8d4e5c758601bd20ba491fd077b434ba45e))
|
||||
* secondary changes ([d75331a](https://github.com/unraid/api/commit/d75331a67e3566875ce8642fce80195e79932a4c))
|
||||
* separate install process ([b90a516](https://github.com/unraid/api/commit/b90a51600c3f70615b117f157d41585e55ef49de))
|
||||
* server identifier changes ([b9686e9](https://github.com/unraid/api/commit/b9686e9c67f2a48df419848e18c5451123813185))
|
||||
* service tests for modifier service ([08c1502](https://github.com/unraid/api/commit/08c150259f2b4630d973803f4edff69c8bf0ec3a))
|
||||
* session issues ([5981693](https://github.com/unraid/api/commit/5981693abd605337f9174ba4c85fd1bfc243edeb))
|
||||
* set background color on webcomponents ([b66e684](https://github.com/unraid/api/commit/b66e6847c895f216a5dec42410186b81a31af1a9))
|
||||
* shared call to createPatch ([eb3e263](https://github.com/unraid/api/commit/eb3e263fb32a748bfa06ec6d119ee51d242707cf))
|
||||
* sidebar notification count ([694f01b](https://github.com/unraid/api/commit/694f01b6c4ab83c4131ae42bc11002d0300497c5))
|
||||
* simplify getting version ([8fb8cb3](https://github.com/unraid/api/commit/8fb8cb304ee1b0f007b81a679dc3eadf098f6b4b))
|
||||
* sso button token exchange ([f6f2390](https://github.com/unraid/api/commit/f6f2390b0169ceaf90ab88edfab3f2809bfe86b5))
|
||||
* sso testing page and form disable on submit ([ffc6d8a](https://github.com/unraid/api/commit/ffc6d8a286d7c6ba751894464000f9870784507c))
|
||||
* start command path ([a7aece5](https://github.com/unraid/api/commit/a7aece5570d3fdb073bda1dc7a89b7ea6e7eedf6))
|
||||
* state using crypto ([afce130](https://github.com/unraid/api/commit/afce13099f5018d0c39765bfdd181adc8383a105))
|
||||
* style improvements ([b0f395e](https://github.com/unraid/api/commit/b0f395ef76f11047eaa13091df277df0459e9d8f))
|
||||
* substantial docs updates ([928bd03](https://github.com/unraid/api/commit/928bd03a4853a28a6b563ed82f95681a7f712b3a))
|
||||
* swap to action ([ef7281b](https://github.com/unraid/api/commit/ef7281b2a863422593de5e948fcfad1a6df489f2))
|
||||
* swap to async exit hook ([4302f31](https://github.com/unraid/api/commit/4302f316820a109c76408092994727b2dc030a15))
|
||||
* switch to nest-commander ([1ab2ab5](https://github.com/unraid/api/commit/1ab2ab5b58a1f49cd6b05aaa84bfeced49d68e8e))
|
||||
* track node version in slackware ([42b010e](https://github.com/unraid/api/commit/42b010e4a141f2a338d65f4f727bf1d15521a5c6))
|
||||
* try catch restart ([89abee6](https://github.com/unraid/api/commit/89abee680bdbdaa9946ddb991f0e6b5ada9ccdf7))
|
||||
* **ui:** webgui-compatible web component library ([#1075](https://github.com/unraid/api/issues/1075)) ([1c7b2e0](https://github.com/unraid/api/commit/1c7b2e091b0975438860a8e1fc3db5fd8d3fcf93))
|
||||
* unnecessary comment ([0c52256](https://github.com/unraid/api/commit/0c5225612875b96319b28ef447db69ecab15cfda))
|
||||
* unraid single sign on with account app ([5183104](https://github.com/unraid/api/commit/5183104b322a328eea3e4b2f6d86fd9d4b1c76e3))
|
||||
* unraid ui component library ([#976](https://github.com/unraid/api/issues/976)) ([03e2fee](https://github.com/unraid/api/commit/03e2feebc73d620b21e54912e0bbddc1826880e1))
|
||||
* update based on review feedback ([4383971](https://github.com/unraid/api/commit/43839711e3365e31120e156abac3746c55e8e694))
|
||||
* Update plugin/source/dynamix.unraid.net/usr/local/emhttp/plugins/dynamix.my.servers/include/state.php ([42c0d58](https://github.com/unraid/api/commit/42c0d58da4d0570b7d865a8774964c18120ed585))
|
||||
* upgrade dependencies ([0a0cac3](https://github.com/unraid/api/commit/0a0cac3da74c2fe20f7100a9ad5d1caafa74b157))
|
||||
* upload files directly to cloudflare ([1982fc2](https://github.com/unraid/api/commit/1982fc238fefa1c67323bdc11ec1fb9c9f43c387))
|
||||
* use execa for start and stop ([46ab014](https://github.com/unraid/api/commit/46ab0144d41b425015487c251c1884744223ba29))
|
||||
* use plugin file for install and uninstall ([c9ac3a5](https://github.com/unraid/api/commit/c9ac3a5a0a3103fbd9c33a5d909fa475614a704a))
|
||||
* use state passing to validate requests ([4480c14](https://github.com/unraid/api/commit/4480c14c932fd8b42ba44989abdbecb49252e6f3))
|
||||
* use text-secondary-foreground instead of gray ([463a1f7](https://github.com/unraid/api/commit/463a1f7b611599a19a23d3c75156c0a16da83312))
|
||||
* use zod to parse config ([19cf1be](https://github.com/unraid/api/commit/19cf1be079f2ccb9e0cfa10f2fb97a18f15c5729))
|
||||
* validate entries correctly ([b101a69](https://github.com/unraid/api/commit/b101a695e18d71ddd170462b3d49289352166489))
|
||||
* validate token format in both PHP and CLI ([6ef05a3](https://github.com/unraid/api/commit/6ef05a3d7770f799e7d587c2cef8d29f6058bee1))
|
||||
* viewport watch refactor ([9aefa38](https://github.com/unraid/api/commit/9aefa382ec64f08b1da8a3748ce16f637d562c8c))
|
||||
* vite ([c78ba4a](https://github.com/unraid/api/commit/c78ba4a774d053d4a9dca938020e4393c5a1fc75))
|
||||
* vite dev mode ([7646c6b](https://github.com/unraid/api/commit/7646c6b6c437a2b523245a29d829ead44fb57d28))
|
||||
* warning on missing fields ([0ef9aec](https://github.com/unraid/api/commit/0ef9aecccdde879e3be44d0b2a0fa4d8befc53b5))
|
||||
* **web:** activation modal steps, updated copy ([#1079](https://github.com/unraid/api/issues/1079)) ([8af9d8c](https://github.com/unraid/api/commit/8af9d8c58895010e3ddc03cc5fa075ac1e264f50))
|
||||
* **web:** add an 'all' option to notification filter ([7c2a72e](https://github.com/unraid/api/commit/7c2a72e0c9537827c3c96df7b6378c03e2cc2852))
|
||||
* **web:** add confirmation before archiving or deleting all notifications ([d16f08c](https://github.com/unraid/api/commit/d16f08c266953ddb84223f90f1275d19c9d3c380))
|
||||
* **web:** add count labels to notification tabs ([4caea3d](https://github.com/unraid/api/commit/4caea3dfc2c7067062f3ce8d863f9385ad030dbd))
|
||||
* **web:** add delete all notifications button to archive view in notifications sidebar ([3bda9d6](https://github.com/unraid/api/commit/3bda9d6a4ca01cc5580012b0133e72929d6dab40))
|
||||
* **web:** add empty state to notifications list ([5675fe1](https://github.com/unraid/api/commit/5675fe14d9d36ab638cb5e1b907f24bcf71cb7f1))
|
||||
* **web:** add gql archival mutations to notifications sidebar & item ([5f93be9](https://github.com/unraid/api/commit/5f93be9f55f3262502951a726f8fc015d73abc92))
|
||||
* **web:** add link to settings in notification sidebar ([f1a4d87](https://github.com/unraid/api/commit/f1a4d873481c212ffde1af7e38327a53a7e41d43))
|
||||
* **web:** add loading and error states to notification sidebar ([2e9183a](https://github.com/unraid/api/commit/2e9183a479e0ec5f7cfc34bb81ccfd05e4bd2b29))
|
||||
* **web:** clear notifications indicator after opening sidebar ([68958d1](https://github.com/unraid/api/commit/68958d17b78220c77c3cda4f0f4068b3ce623688))
|
||||
* **web:** delete notifications from archive view ([c8fc15d](https://github.com/unraid/api/commit/c8fc15d20bae527193ed289aef622a953a0d00bc))
|
||||
* **web:** display error when a notification mutation fails ([838ed86](https://github.com/unraid/api/commit/838ed86ffa47207ca2282a9ddabe245da713ba23))
|
||||
* **web:** enhance notifications indicator in UPC ([#950](https://github.com/unraid/api/issues/950)) ([6376848](https://github.com/unraid/api/commit/63768486e4ec64ab32666a26adf96f4db4a53e81))
|
||||
* **web:** implement notification filtering ([fa5156b](https://github.com/unraid/api/commit/fa5156bbc1f6bcc6c2e71b64b1e063120a868410))
|
||||
* **web:** make empty notification message clearer ([abab00d](https://github.com/unraid/api/commit/abab00ddccb7e485f2603b554704f531be79dd45))
|
||||
* **web:** make notifications list scrollable inside the sheet & tabs ([4c5d97b](https://github.com/unraid/api/commit/4c5d97b380de5574226e653c372c45ce61ea3ebb))
|
||||
* **web:** move notification indicator icons to top-right of bell icon ([2fe4303](https://github.com/unraid/api/commit/2fe4303387023d303d7e50fc4d9a41f1eafdcc45))
|
||||
* **web:** open official release notes via header os version ([54a893f](https://github.com/unraid/api/commit/54a893f396b29251b982ff1f26d376d24b962b93))
|
||||
* **web:** pull date format from display/date and time settings ([b058067](https://github.com/unraid/api/commit/b058067b628ca7866a9ba0a6c4c5e4d5505d98cb))
|
||||
* **web:** reconcile pagination with notifications apollo cache ([e38bc2c](https://github.com/unraid/api/commit/e38bc2c1218019cd1632123709620808c7543d11))
|
||||
* **web:** remove notification indicator pulse ([f320a77](https://github.com/unraid/api/commit/f320a77330c8cc7b92e170b0099d6c7f93b11c0e))
|
||||
* **web:** rm api-key validation from connect sign in ([#986](https://github.com/unraid/api/issues/986)) ([7b105d1](https://github.com/unraid/api/commit/7b105d18678e88a064f0643d6e857704789e0ee8))
|
||||
* **web:** rm old notification bell upon plugin installation ([#979](https://github.com/unraid/api/issues/979)) ([e09c07c](https://github.com/unraid/api/commit/e09c07c5070d59ac032baeff1ed253b5c00f4163))
|
||||
* **web:** support markdown in notification messages ([90cbef7](https://github.com/unraid/api/commit/90cbef774962e9d8ede47df7a4c1ca06f2a6651b))
|
||||
* **web:** update cache & view when archiving notifications ([08ab4d1](https://github.com/unraid/api/commit/08ab4d1a96c729c47feb868c10f398cad6dee5ba))
|
||||
* **web:** use Markdown helper class to interact with markdown ([f9c2d35](https://github.com/unraid/api/commit/f9c2d353133b01e74fe1bfbc420df3980d944012))
|
||||
* **web:** wip query api for notifications ([dec48b2](https://github.com/unraid/api/commit/dec48b2b0081362c5d0435eaabff1fb657d5f431))
|
||||
* WIP create teleport composable ([20e795e](https://github.com/unraid/api/commit/20e795ed6921337ae7875b483f2ab94860b74797))
|
||||
* wip Notification UI starter ([2f9e2ee](https://github.com/unraid/api/commit/2f9e2eef2db61221be66683caa4e75368aa475e0))
|
||||
* WIP notifications w/ shadcn ([5a90b32](https://github.com/unraid/api/commit/5a90b3285ad8524cea58cbaca8293675b3dc257b))
|
||||
* WIP sidebar filter select ([0c214fa](https://github.com/unraid/api/commit/0c214faaf69a69fc4da10a4a71b9c7cf7bd128c2))
|
||||
* workflow changes ([c97bfb8](https://github.com/unraid/api/commit/c97bfb8794d779ef253236fbdb7bb9909f4dfbca))
|
||||
* working ([29d7bd7](https://github.com/unraid/api/commit/29d7bd729bdfed79a3ce9c50014b3f1f32f9ac4e))
|
||||
* wrap Notifications in a GraphQL Node & implement notification overviews ([bf89178](https://github.com/unraid/api/commit/bf89178cb7e359e73da8c8f27253734be982dcc8))
|
||||
* zod config no longer any ([c32c5f5](https://github.com/unraid/api/commit/c32c5f57127b9469bde8806d78dc364562e73d9f))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 12 hour timestamp logic corrected ([03be43b](https://github.com/unraid/api/commit/03be43b4579f1dcf6a666a144f75b3063576748a))
|
||||
* actually install dependencies ([0895420](https://github.com/unraid/api/commit/089542061294e354b0e63a9f41001b77c0d62fed))
|
||||
* add another missing symlink ([4e7f3ff](https://github.com/unraid/api/commit/4e7f3ff4d9aa0e4af417a50e2b30537dda3c759c))
|
||||
* add ecosystem config ([7dd5531](https://github.com/unraid/api/commit/7dd553174e1c3aaaf71380abfe57348f30815bde))
|
||||
* add error check to nodejs ([c8e0fe8](https://github.com/unraid/api/commit/c8e0fe87a34d7f066b7d0900dda205a40616bfb6))
|
||||
* add max var ([ed681e1](https://github.com/unraid/api/commit/ed681e1d27fb7fa13bc8cbb5238da06e453a7c3b))
|
||||
* add return to resolver and update jsdoc for getNotifications ([a5e7d29](https://github.com/unraid/api/commit/a5e7d2956074376ef8e708b2bb7416cd2af3fe12))
|
||||
* allow concurrent testing with a shared patcher instance ([623846e](https://github.com/unraid/api/commit/623846ef46eb24a32c62516de58e8bc5d0219833))
|
||||
* always mangle ([e3a1eec](https://github.com/unraid/api/commit/e3a1eec5b62d010d05bb0908ba15fd8cb4f9d717))
|
||||
* **api:** append time to formatted date when a custom date format is selected ([0ac8ed9](https://github.com/unraid/api/commit/0ac8ed9d9e7e239e471eedf466832aed0270d123))
|
||||
* **api:** delay pm2 start until server has booted ([bd3188e](https://github.com/unraid/api/commit/bd3188efea4d3656994ffae32bd53f821c96358d))
|
||||
* **api:** exclude duplicates from legacy script in archive retrieval ([8644e13](https://github.com/unraid/api/commit/8644e130979ed8740c5a8da0b3984266e2b3684c))
|
||||
* **api:** improve defaults in PM2 service ([#1116](https://github.com/unraid/api/issues/1116)) ([57526de](https://github.com/unraid/api/commit/57526dede69e3a6547d05183e43c5b36dd1cae89))
|
||||
* **api:** load dynamix config in the same way as the webgui ([2c4fd24](https://github.com/unraid/api/commit/2c4fd2419ce05a10c8543a7f679852b54df3d10f)), closes [/github.com/unraid/webgui/blob/95c6913c62e64314b985e08222feb3543113b2ec/emhttp/plugins/dynamix/include/Wrappers.php#L42](https://github.com/unraid//github.com/unraid/webgui/blob/95c6913c62e64314b985e08222feb3543113b2ec/emhttp/plugins/dynamix/include/Wrappers.php/issues/L42)
|
||||
* **api:** make cookie recognition during websocket connection more ([353e012](https://github.com/unraid/api/commit/353e012db8ab5280863f32392c520b4a330c13cc))
|
||||
* **api:** pm2 start script & limit auto restarts ([#1040](https://github.com/unraid/api/issues/1040)) ([ebcd347](https://github.com/unraid/api/commit/ebcd3479e735724626ffc6907c338d5080898bee))
|
||||
* **api:** retry mothership connection up to 3x before logout ([#1069](https://github.com/unraid/api/issues/1069)) ([c27bb1b](https://github.com/unraid/api/commit/c27bb1be4c7a9ab201585586f3bc5e4afa1c7791))
|
||||
* **api:** sanitize incoming user session id's ([f5e3424](https://github.com/unraid/api/commit/f5e3424b79702e8f959b5519e83370a9e1d2033b))
|
||||
* **api:** slow init of unraid-api cli ([#1022](https://github.com/unraid/api/issues/1022)) ([5dbbae7](https://github.com/unraid/api/commit/5dbbae796792a62234497d056eac019aa084b21c))
|
||||
* **api:** strip server id prefixes from graphql request variables ([326d054](https://github.com/unraid/api/commit/326d0540f0865735f220e0fc7c5822913a7865ea))
|
||||
* **api:** update deploy-dev script to dist instead of src ([55cce09](https://github.com/unraid/api/commit/55cce09e65521762a6fe388d5b9b88ace1337c26))
|
||||
* **api:** validate cookie session data ([491f680](https://github.com/unraid/api/commit/491f680607ce7244d9e47a457e44cde711fbe00c))
|
||||
* apollo client lint issues ([a6d6dcc](https://github.com/unraid/api/commit/a6d6dcc2acc2b529c6f6821ce57865e521b84075))
|
||||
* app running ([5f71670](https://github.com/unraid/api/commit/5f716701715595f93fd0bc63b92ecf02335daa41))
|
||||
* apply and rollback error handling ([e22191b](https://github.com/unraid/api/commit/e22191bc77bc09f5c6c4ad57e5073829cf966ba4))
|
||||
* attempt to restore upgradepkg if install failed ([19c2a79](https://github.com/unraid/api/commit/19c2a79ce6c31c989f3d7f70cf7d8e2c219517b2))
|
||||
* authorization type error ([#987](https://github.com/unraid/api/issues/987)) ([7a4799e](https://github.com/unraid/api/commit/7a4799e9cd4caef6acfc3661d205a377fcf499ab))
|
||||
* back to default configs ([b5711c9](https://github.com/unraid/api/commit/b5711c91284072991bcf409ac6126cd4b46afc7c))
|
||||
* backup restore formatting ([15210f6](https://github.com/unraid/api/commit/15210f64b0938ec884a3ef4379d245c661eab9a3))
|
||||
* basic test fixed ([2f38035](https://github.com/unraid/api/commit/2f38035520ca0fe796c981d08b9136d89ffc5888))
|
||||
* better js file handling ([ddf160e](https://github.com/unraid/api/commit/ddf160e878a352842e813154b607945ccc7b4081))
|
||||
* better loader functionality and error handling ([8a57d2d](https://github.com/unraid/api/commit/8a57d2dccbcb9c2effc5df5d8c69ad02713de24a))
|
||||
* better logging when error ([6e4e3f8](https://github.com/unraid/api/commit/6e4e3f85abf64f8d799e33c33823810e71ef13e2))
|
||||
* build issues based on removed code ([59c1d5a](https://github.com/unraid/api/commit/59c1d5a3f991c4e3625a8853ade17d2ca8936474))
|
||||
* builder cache ([56771f6](https://github.com/unraid/api/commit/56771f6ee210297406d6bddff04de816ba0bb2d5))
|
||||
* capitalize name ([31166b3](https://github.com/unraid/api/commit/31166b3483dc01847ad555618c43f8248411bdfa))
|
||||
* changelog parser ([6fecec8](https://github.com/unraid/api/commit/6fecec8d4af3a4fccf2886791188711e1d2db77b))
|
||||
* check width before changing viewport ([f07381b](https://github.com/unraid/api/commit/f07381b243501ecc6d54063881faad77a99a7655))
|
||||
* cleaner logs for starting API ([79f26ef](https://github.com/unraid/api/commit/79f26ef251cb42e7f2106d00c6c05e2bf17b8227))
|
||||
* cleanup commands ([052aea0](https://github.com/unraid/api/commit/052aea06a0d30963532f29f9961fce0ffc7fa3e8))
|
||||
* clearer error messaging ([e373849](https://github.com/unraid/api/commit/e37384966c5b9079bb507052dcaba56232c1c42a))
|
||||
* code review feedback ([c66079e](https://github.com/unraid/api/commit/c66079e9a8e0ef47e5054118d0581bec708ac604))
|
||||
* completion script registration ([05c8c9b](https://github.com/unraid/api/commit/05c8c9bf078ece2061ad8ae32497f52b8c9b94dc))
|
||||
* connect key role ([2dcfc1c](https://github.com/unraid/api/commit/2dcfc1c19a1d085df84f0b1b50c096e3220205dd))
|
||||
* connect plugin location ([7867a93](https://github.com/unraid/api/commit/7867a932eb0bda43d3fb3613bdba227717510e4a))
|
||||
* convert updateId function to iterative instead of recursive ([65c20d2](https://github.com/unraid/api/commit/65c20d210987bc4dbb19f3e200fffa655b5fe2f4))
|
||||
* **CookieService:** potential race condition in unit tests ([1f2a380](https://github.com/unraid/api/commit/1f2a380b775adf44fdb3c85278fe0151584284f1))
|
||||
* **cors:** excessive instantiation of CookieService to improve memory overhead ([28c553d](https://github.com/unraid/api/commit/28c553d4c8d7c744e2b5554b1254cdd2bfda5ff5))
|
||||
* create api key for connect on startup ([58329bc](https://github.com/unraid/api/commit/58329bc29521ebc26b27ee20013ac3926c5088c2))
|
||||
* create api key permissions ([cefb644](https://github.com/unraid/api/commit/cefb644bd7fa513f553ca0ca4c49f0fb42a74112))
|
||||
* create connect key ([6b1ab7b](https://github.com/unraid/api/commit/6b1ab7b74ae1d2938fa9105180a5f66e9604fd41))
|
||||
* cwd on ecosystem.config.json ([dfd0da4](https://github.com/unraid/api/commit/dfd0da4ca23078f6de2e54d5e5bd6cba06334abc))
|
||||
* dark theme as array ([1021d0d](https://github.com/unraid/api/commit/1021d0da0d7a919dedec70656bb52775575aa9e7))
|
||||
* default overwrite false test ([cf59107](https://github.com/unraid/api/commit/cf59107e568d91be684176335db5300bee9be865))
|
||||
* delete .original files ([a9eb21a](https://github.com/unraid/api/commit/a9eb21aac0f373990aaa3f7a99731612540533cf))
|
||||
* delete boot script and update nvmrc ([ecd6b44](https://github.com/unraid/api/commit/ecd6b443c7dee8c5c5dee959f9ff3ace192204c7))
|
||||
* delete unused line ([de4882e](https://github.com/unraid/api/commit/de4882ea17f54e788049cc5bb96b99b16822b6b4))
|
||||
* delete upgradepkg ([74f0177](https://github.com/unraid/api/commit/74f0177ba0fd57722caa3ec14318d35167d3c6f7))
|
||||
* deprecated version warning ([89d0bd2](https://github.com/unraid/api/commit/89d0bd2e6da35fb1e8d95627d38edb54f82e0c6b))
|
||||
* **deps:** update apollo graphql packages ([7b1ee99](https://github.com/unraid/api/commit/7b1ee9940cca46e563bb79c7056996315f9decc5))
|
||||
* **deps:** update dependency @apollo/client to v3.12.6 ([22ce615](https://github.com/unraid/api/commit/22ce61574f862eac4cdf8c00141bfbf1ac948055))
|
||||
* **deps:** update dependency @apollo/client to v3.12.6 ([bb7800a](https://github.com/unraid/api/commit/bb7800a8c088705fd8310671a9896cbe9b0184e5))
|
||||
* **deps:** update dependency @apollo/client to v3.12.9 ([6607cf2](https://github.com/unraid/api/commit/6607cf20c10a091d466c6a8031eebc17feb3e3fc))
|
||||
* **deps:** update dependency @floating-ui/dom to v1.6.13 ([08798d2](https://github.com/unraid/api/commit/08798d2f77683412807d684d7a8e63f1aadb0c34))
|
||||
* **deps:** update dependency @floating-ui/dom to v1.6.13 ([4d4c218](https://github.com/unraid/api/commit/4d4c218ac78e82a18679ec7b4939523db032b99b))
|
||||
* **deps:** update dependency @floating-ui/vue to v1.1.6 ([b4b7d89](https://github.com/unraid/api/commit/b4b7d898b62f746180b7f5730b5d9b5033dcecc2))
|
||||
* **deps:** update dependency @floating-ui/vue to v1.1.6 ([4c07d38](https://github.com/unraid/api/commit/4c07d389523f277950b8d2d359102f889587e5ce))
|
||||
* **deps:** update dependency @graphql-tools/load-files to v7.0.1 ([4e5c724](https://github.com/unraid/api/commit/4e5c7242e43cc356f1c69adcfcd25b57896af476))
|
||||
* **deps:** update dependency @nestjs/schedule to v4.1.2 ([faf0de5](https://github.com/unraid/api/commit/faf0de5a19256efb83dc45a484e3cba65596ccd7))
|
||||
* **deps:** update dependency chokidar to v4.0.3 ([d63a93c](https://github.com/unraid/api/commit/d63a93c55004d17b6d17634c55ffbc5670ebbec7))
|
||||
* **deps:** update dependency dotenv to v16.4.7 ([c66a650](https://github.com/unraid/api/commit/c66a6502b027853046d126a14ddee870ffabd10c))
|
||||
* **deps:** update dependency execa to v9.5.2 ([d487c90](https://github.com/unraid/api/commit/d487c90ccc20162c76f0cdf49a736c1fee4271bd))
|
||||
* **deps:** update dependency express to v4.21.2 ([a070306](https://github.com/unraid/api/commit/a07030684c8777e47eb4a51be0ea680b7f217e74))
|
||||
* **deps:** update dependency focus-trap to v7.6.4 ([41ff232](https://github.com/unraid/api/commit/41ff232a3232dda66e5cdc2d4808a820a90a5d34))
|
||||
* **deps:** update dependency focus-trap to v7.6.4 ([f0e3038](https://github.com/unraid/api/commit/f0e3038ee7426aafb6cef01b85b47893c2238302))
|
||||
* **deps:** update dependency got to v14.4.5 ([975a47c](https://github.com/unraid/api/commit/975a47c7d47841c49443f46264feb54abf53698c))
|
||||
* **deps:** update dependency graphql-ws to v5.16.2 ([a189a03](https://github.com/unraid/api/commit/a189a0308a734e66750fe5059f7c59d8c9532bd8))
|
||||
* **deps:** update dependency graphql-ws to v5.16.2 ([25d8f08](https://github.com/unraid/api/commit/25d8f085b67c2e53876d837c739214dc874116b8))
|
||||
* **deps:** update dependency ini to v4.1.3 ([4c88cbe](https://github.com/unraid/api/commit/4c88cbee4b2d5f6717241dadac23bfe90ce15193))
|
||||
* **deps:** update dependency node-window-polyfill to v1.0.4 ([8bfa88f](https://github.com/unraid/api/commit/8bfa88f4bc932eb82dd9b33a494811ea15764758))
|
||||
* **deps:** update dependency openid-client to v6.1.7 ([0f50517](https://github.com/unraid/api/commit/0f50517a8544e1eb9b08ad1b3f05f798491b7f23))
|
||||
* **deps:** update dependency p-retry to v6.2.1 ([c6f3241](https://github.com/unraid/api/commit/c6f324155019e066701723a57b642c6e3ba8332d))
|
||||
* **deps:** update dependency pm2 to v5.4.3 ([a754090](https://github.com/unraid/api/commit/a75409026dd4e3d9ed120802012b67b179327448))
|
||||
* **deps:** update dependency radix-vue to v1.9.12 ([0fd433f](https://github.com/unraid/api/commit/0fd433fe2a6b3f787624cb5a98efeae0f6c31cfd))
|
||||
* **deps:** update dependency radix-vue to v1.9.13 ([249feff](https://github.com/unraid/api/commit/249feff5cfe0bbb60bfa8f943b76b9c16c6c161b))
|
||||
* **deps:** update dependency uuid to v11.0.5 ([7e3398b](https://github.com/unraid/api/commit/7e3398b2efabf1a5407d6e20c165eb4923b3bab2))
|
||||
* **deps:** update graphql-tools monorepo ([cd7e2fe](https://github.com/unraid/api/commit/cd7e2feea199276a1d431cf355e54e12e5960d9a))
|
||||
* **deps:** update graphqlcodegenerator monorepo ([0446c59](https://github.com/unraid/api/commit/0446c5924a6a9dd15b875628ca0f1197cfe521c4))
|
||||
* **deps:** update graphqlcodegenerator monorepo ([15c789d](https://github.com/unraid/api/commit/15c789dbb34b85bed55c2731fb8ae8260f5f311f))
|
||||
* **deps:** update nest monorepo to v10.4.15 ([07b1ea9](https://github.com/unraid/api/commit/07b1ea9a10634a597909ae1d237cc3b1e7f959b7))
|
||||
* **deps:** update nest-graphql monorepo to v12.2.2 ([91aabd9](https://github.com/unraid/api/commit/91aabd9ffbfb8c2ceb4110217dfc05de8859077d))
|
||||
* detection script path bin instead of sbin ([7138fd2](https://github.com/unraid/api/commit/7138fd297abc1435f61e7e4c8f4a5a91662c64f0))
|
||||
* dev mode ([fd64e01](https://github.com/unraid/api/commit/fd64e01e0c87db03fc2d4d0f32a0e8205fbe8b84))
|
||||
* disable permissions bypass to avoid incorrect role assignment to api keys ([343489e](https://github.com/unraid/api/commit/343489e52c526757c1449a6f5074def50e73a380))
|
||||
* dnserr on new line ([a3398a2](https://github.com/unraid/api/commit/a3398a29e15269be006e887fba6366c81b1d00f5))
|
||||
* do not process.exit on restart or stop command ([933575f](https://github.com/unraid/api/commit/933575fc2badbb09b3a9d3c66724e37a9ee246f2))
|
||||
* docker formatting and build mkdir issues ([f447739](https://github.com/unraid/api/commit/f447739585e8ed8449653802c1f0d4d11d6c65de))
|
||||
* don't check code for execa ([508a5eb](https://github.com/unraid/api/commit/508a5eb49d9514dca9953317d9fa93314fe63e4c))
|
||||
* don't LS in the release folder ([ab9d969](https://github.com/unraid/api/commit/ab9d9695394a300d6b0799e9b644dd5d0f969d72))
|
||||
* dont remove login file without a backup presetn ([0370e4f](https://github.com/unraid/api/commit/0370e4f7ea3e3df0d2264264324d8e53ffc0c086))
|
||||
* downgrade marked to fix changelog preview issue ([cfb3a45](https://github.com/unraid/api/commit/cfb3a45533d3c1bd31c44094f7ae2912e77a673e))
|
||||
* edit settings padding issue ([adf349b](https://github.com/unraid/api/commit/adf349b76560b5f1fd4c320da35b3c6f660895fb))
|
||||
* ensure directory exists before making connect key ([9e27ec9](https://github.com/unraid/api/commit/9e27ec98b68a49bdd6dc4b03de8c0cc3a1470a5e))
|
||||
* env correct ([9929856](https://github.com/unraid/api/commit/99298566382313f1da9c374dbec3652c1b2812d3))
|
||||
* env input ([c182c06](https://github.com/unraid/api/commit/c182c06d9443597521eaacd2052d905e0138cac4))
|
||||
* EOF ([25ac1b5](https://github.com/unraid/api/commit/25ac1b5f0772d3ce63d47eb8a1dc640be125b68b))
|
||||
* eslint config ([b28a605](https://github.com/unraid/api/commit/b28a605300cee1e9ce1f5db3a165b4d0d2080316))
|
||||
* excess spacing in api-key.service ([1deb002](https://github.com/unraid/api/commit/1deb0023287a39d40e52e89c515a28e62352f62c))
|
||||
* execa upgrade snapshots fixed ([d8244f7](https://github.com/unraid/api/commit/d8244f7aac02dd97c756a9784391cd661f3536ba))
|
||||
* extra log line ([1183063](https://github.com/unraid/api/commit/1183063aa7063afd8222def18f5e1fd6077e8c88))
|
||||
* extra spacing in config.ts ([f3ee7be](https://github.com/unraid/api/commit/f3ee7be80f2c60266fbb13597a70f0a389fb577f))
|
||||
* file modification service fixes ([aa5b3f4](https://github.com/unraid/api/commit/aa5b3f4e47ed88df23af00dfcccb7b64786b6231))
|
||||
* find by key, not ID ([3c3fa1e](https://github.com/unraid/api/commit/3c3fa1e27cfabbe6926c3da8870751397eed1def))
|
||||
* floating-ui fixes ([1c3b43b](https://github.com/unraid/api/commit/1c3b43b4464662e1a1b21695e601cd7f7e4fd734))
|
||||
* forced restarting on commands ([925866d](https://github.com/unraid/api/commit/925866d389e337fcb8c249ead929e1f65854465b))
|
||||
* format authrequest mod as other files ([180a81d](https://github.com/unraid/api/commit/180a81dbae8e749eae237fc8cee2950c790eedf0))
|
||||
* formatting issue ([42ca969](https://github.com/unraid/api/commit/42ca9691f7547a4340501863c1882efc0aee4c60))
|
||||
* further resolve sso sub ids issues ([ef3d0ea](https://github.com/unraid/api/commit/ef3d0ead687d4a6071da290c0df29c12163303e1))
|
||||
* handle special chars better ([d364bb1](https://github.com/unraid/api/commit/d364bb1fc4c042469ce4b0ca6001a807d0b002da))
|
||||
* improve typing and format lookup ([c6097f8](https://github.com/unraid/api/commit/c6097f86e42fcc57209c1344029abe854198edca))
|
||||
* initial feedback about report addressed ([5dee09c](https://github.com/unraid/api/commit/5dee09c77ad375de2eca59f650e5fea2070087b5))
|
||||
* install as-integrations/fastify ([ff4546d](https://github.com/unraid/api/commit/ff4546d6692d2a4799f2dbeef0d5e5c6bac62561))
|
||||
* install syntax error ([ec83480](https://github.com/unraid/api/commit/ec83480eb6aea09b98b9135516dc1fc8cdd6c692))
|
||||
* integration of `unraid-ui` tailwind config in `web` ([#1074](https://github.com/unraid/api/issues/1074)) ([f3cd85b](https://github.com/unraid/api/commit/f3cd85bd3f02bdbe4c44136189d1c61935015844))
|
||||
* invalid type ([e13794f](https://github.com/unraid/api/commit/e13794f8e56081335ebc16b00a2f8631f9639909))
|
||||
* length ([83579f1](https://github.com/unraid/api/commit/83579f1fbd03ffe929d009c20d214b4de62835c6))
|
||||
* lint ([0f218b8](https://github.com/unraid/api/commit/0f218b8b72e397734823efab8f2141973a3a80ce))
|
||||
* lint ([82bca54](https://github.com/unraid/api/commit/82bca54c594265ddf23a298691bd7ef6d4b47f32))
|
||||
* lint ([ceb443d](https://github.com/unraid/api/commit/ceb443da15d177a950c36af61b93a7126cf4ca85))
|
||||
* lint ([da04e7c](https://github.com/unraid/api/commit/da04e7ce0873d7802a936952d91e9867f0868a6e))
|
||||
* lint ([7d87f0e](https://github.com/unraid/api/commit/7d87f0eee23dfa0f391fd342d38ed9084f18d8d4))
|
||||
* lint issues ([48e482b](https://github.com/unraid/api/commit/48e482b913d4f27f49ae669c7c19dc0714d3c0c7))
|
||||
* linter error ([6dba28d](https://github.com/unraid/api/commit/6dba28dd1bbe0125f842271eeae9daf54826b063))
|
||||
* load builder image to cache ([5497bc3](https://github.com/unraid/api/commit/5497bc3235bd3c8b427b3418a7be2e3ece4c4abc))
|
||||
* load notifications from file system instead of redux state ([53a37cd](https://github.com/unraid/api/commit/53a37cd1d20bb2b738bdeda832a42196d662b8a4))
|
||||
* load PM2 from node_modules ([5a07e8c](https://github.com/unraid/api/commit/5a07e8cae5ce9ced9980a9df950d053196edf65b))
|
||||
* local variable assignment ([f7d9ccc](https://github.com/unraid/api/commit/f7d9ccc0820f0fe8efa55b1c2d75f79819c764c4))
|
||||
* logging location ([572b922](https://github.com/unraid/api/commit/572b922f4d72759a5ed7d06ddfa4af3bfb655c6b))
|
||||
* logrotate error ([8c64dd2](https://github.com/unraid/api/commit/8c64dd2f2c65aa83ce0e2d501357ee595c976e56))
|
||||
* lowercase or ([386cbde](https://github.com/unraid/api/commit/386cbdef5c9158290e03c670efb992cf11d5af1b))
|
||||
* make cli.js executable ([644db0e](https://github.com/unraid/api/commit/644db0ef3315b00361524ea0fe440083f35088a0))
|
||||
* marked single input ([ceacbbe](https://github.com/unraid/api/commit/ceacbbe5d46466627df0fccc5ca8e7c56fa36a37))
|
||||
* missing ip-regex module ([fde7202](https://github.com/unraid/api/commit/fde720264bf395c0047356c3084878c8878aadfa))
|
||||
* missing server type ([f1b721b](https://github.com/unraid/api/commit/f1b721bd72b875d9ff8c0bca2cc1eee506ba7697))
|
||||
* mock ensureDirSync ([7e012e6](https://github.com/unraid/api/commit/7e012e6a2eb96ccddf5a1f69d7580b4bdfe7a0a9))
|
||||
* more color work ([c48f826](https://github.com/unraid/api/commit/c48f8268def64ef8828dea556360b375b8cb32c7))
|
||||
* more filename fixes and PR var passing ([088dbed](https://github.com/unraid/api/commit/088dbed9b2fabfaf55b003fb1fa9c10c558f21d5))
|
||||
* more generic test ([0f651db](https://github.com/unraid/api/commit/0f651dbf61a1822b492aa80030f0bc231bc6f606))
|
||||
* more verbose logging for node install to find issues ([445af0c](https://github.com/unraid/api/commit/445af0c147ef641dac05ebeb2d44e63e8a4df799))
|
||||
* mv paths() to top of NotificationsService to make it more intuitive ([7138568](https://github.com/unraid/api/commit/713856818dfaf7d7f5807eacc3b7d61561888082))
|
||||
* no more node_dl_server ([77779a6](https://github.com/unraid/api/commit/77779a655f18e9d474ad8a7e61c8ef51090a49d8))
|
||||
* no nodehost ([6787ec7](https://github.com/unraid/api/commit/6787ec7d65ecef27652ca48193fe64f2ea82ca4e))
|
||||
* no vite-node in non-dev mode ([023f73f](https://github.com/unraid/api/commit/023f73f3992b42f60aa56d8dd51a5e698c140306))
|
||||
* node install process improvements ([b8540dd](https://github.com/unraid/api/commit/b8540ddeb888678edd24db31a6747583761d5aa9))
|
||||
* node_txz naming ([b7c24ca](https://github.com/unraid/api/commit/b7c24ca861e92bf01118a17bc7e2322063e6a800))
|
||||
* **NotificationItem:** icon & text alignment in header ([98716f7](https://github.com/unraid/api/commit/98716f70a6a2c29610e1ed7cda1aedad5065134d))
|
||||
* **NotificationService:** file watcher initialization ([b7e3f8e](https://github.com/unraid/api/commit/b7e3f8e42ae4bf488228503b4e5234b1e7a38180))
|
||||
* **NotificationsService:** edge-case in deleteAllNotifications by adding fs-extra package ([fef763a](https://github.com/unraid/api/commit/fef763a3298b9bf4aae2e18db4722637ce9bd7e4))
|
||||
* **NotificationsSidebar:** occupy full viewport on small screens ([1f81fb8](https://github.com/unraid/api/commit/1f81fb8b92bef102b0b7d2daf562c9b4e296473e))
|
||||
* oauth2 api prefix ([ec00add](https://github.com/unraid/api/commit/ec00adde20d4d9eca28f6b18615073305f491a73))
|
||||
* only instantiate service one time ([933dc81](https://github.com/unraid/api/commit/933dc81b6c50db5a33f586f7094e1ea524b9a9fa))
|
||||
* only test if API was changed ([5871143](https://github.com/unraid/api/commit/5871143b809d6a6784e949e20212599a54afc71f))
|
||||
* only test when API is changed ([ddea0e8](https://github.com/unraid/api/commit/ddea0e8e11816c58e5b50cb611e5796fbca3fecf))
|
||||
* only toast unread notifications, not archived ones ([cc59be6](https://github.com/unraid/api/commit/cc59be6cb3efc71226ee50f9f04e37a2e4b50de6))
|
||||
* padding and glob function issues ([1d3f2eb](https://github.com/unraid/api/commit/1d3f2eb8213115c3385ac2d29ee8f53560347ba8))
|
||||
* pass env through to docker ([200be38](https://github.com/unraid/api/commit/200be384f9dec86a1e77f46a0e6a336e86ba7563))
|
||||
* pass ssoSubIds only ([5adf13e](https://github.com/unraid/api/commit/5adf13ee070bdcd849339460b9888e51d224e765))
|
||||
* pass token to password field ([499b023](https://github.com/unraid/api/commit/499b023d359ed5181450ee9e04cbbf4531a4a680))
|
||||
* patch-utils unused ([047808d](https://github.com/unraid/api/commit/047808dce0cd9e9b4b273a9124dbd45ca9446208))
|
||||
* paths now correct, better download logic ([16db2d9](https://github.com/unraid/api/commit/16db2d908dcb2c65508b367712c51bf9872a95e5))
|
||||
* pkg_build ([d4bff0e](https://github.com/unraid/api/commit/d4bff0ee96e6e0974978465573e72e68d09fd829))
|
||||
* plugin download route and add env node to cli script ([78bd982](https://github.com/unraid/api/commit/78bd9820200a0996d9b8c5f718a97c20ed4feab4))
|
||||
* PR build missing files ([57f9b95](https://github.com/unraid/api/commit/57f9b95134be5c3dd8053f57f82e91a0e0622d3e))
|
||||
* production env for web build ([b4107f6](https://github.com/unraid/api/commit/b4107f6c4d4db47d7331f4b3d30a4ace724a8f0e))
|
||||
* proper directory in rc.unraid-api ([a3add5a](https://github.com/unraid/api/commit/a3add5ae165b09dd695a2ddabf6131ac8700825f))
|
||||
* proper file replacements ([e0042f3](https://github.com/unraid/api/commit/e0042f353b47cfa72a485d6a58ad0b956ea6dbc2))
|
||||
* properly log error with template string ([3781f1f](https://github.com/unraid/api/commit/3781f1f41c7f0eef604daee0402ed9a2bb27cd46))
|
||||
* properly restart the API when installed ([765593a](https://github.com/unraid/api/commit/765593a3da1e3b8bee1ae6c8aa1d9d0f2498d41c))
|
||||
* pull node version directly from nvmrc ([b2e6948](https://github.com/unraid/api/commit/b2e694881218c08765b26ada08ed6ab325177b1e))
|
||||
* pull token from query not params ([2e827e7](https://github.com/unraid/api/commit/2e827e7cabe4a6a069d4e8779015e5896d8a1d1d))
|
||||
* race condition when updating notification types ([f048f56](https://github.com/unraid/api/commit/f048f566627e91947cc98550412ca68d728c52c7))
|
||||
* re-add type-check ([60e9d1d](https://github.com/unraid/api/commit/60e9d1d912c983cf04e3e6cf15e221c39938612a))
|
||||
* recreate package-lock to fix issues ([ad5a537](https://github.com/unraid/api/commit/ad5a53793d25ac9f63bae6df6c2a30d8d2780c67))
|
||||
* remove console log ([8e75b82](https://github.com/unraid/api/commit/8e75b8254bbda93ded786750226090b769bed5c4))
|
||||
* remove console logs with vue plugin ([2b2e923](https://github.com/unraid/api/commit/2b2e9236ce55cfc3ca10f708ed08e09dcfd402d1))
|
||||
* remove devDependencies from output package json ([294869b](https://github.com/unraid/api/commit/294869bbea7f8a1863f8aafae6b074330e057679))
|
||||
* remove extra space ([a99ee03](https://github.com/unraid/api/commit/a99ee03fc37059b3a018db289c43fc419a634524))
|
||||
* remove isNaN in favor of number.isNaN ([03e3a46](https://github.com/unraid/api/commit/03e3a46092db613281176b88cae284f6448027c6))
|
||||
* remove line from or in button ([1a1bce7](https://github.com/unraid/api/commit/1a1bce7b64b1cf90505f811e11b585ff87476f72))
|
||||
* remove memory key generation ([b84db13](https://github.com/unraid/api/commit/b84db1322104c7f26f7b6378f25a2757b3010c6d))
|
||||
* remove uneeded env variable ([f688a35](https://github.com/unraid/api/commit/f688a350d3d0a1c47be5896e6fbf92eeb8433967))
|
||||
* remove unused constructor ([e0e2a7b](https://github.com/unraid/api/commit/e0e2a7b41c5e599ed4cf3bf49c7faea3b71f0b70))
|
||||
* remove unused date-fns ([fe94ef5](https://github.com/unraid/api/commit/fe94ef5ba88df56aad87089081dd5fe4518fa414))
|
||||
* remove unused disableProductionConsoleLogs call ([691661b](https://github.com/unraid/api/commit/691661b952394e61a1b79c41419745fbf6caba20))
|
||||
* remove unused imports ([65c1891](https://github.com/unraid/api/commit/65c18917563745cab9711e9900086e90ab44e284))
|
||||
* remove unused job dependency ([84533d8](https://github.com/unraid/api/commit/84533d8fa56dc19635ea33d79bd8e644e539edd2))
|
||||
* remove unused login entries ([7833b5d](https://github.com/unraid/api/commit/7833b5db386f724318857fc31d825fb3534c84b9))
|
||||
* remove usage of Role.UPC ([d1e2f6e](https://github.com/unraid/api/commit/d1e2f6e0b391cb4eca75a0997b41cb99a9953d42))
|
||||
* render function fixed ([8008ab4](https://github.com/unraid/api/commit/8008ab46fb2f231b68201758a258fd43e2e1672e))
|
||||
* replace express cookie parser with fastify's ([0acebb0](https://github.com/unraid/api/commit/0acebb0dd25e919f3cc132eb7f96927992fc4151))
|
||||
* report issues + pm2 issues ([28c383e](https://github.com/unraid/api/commit/28c383e1d111d4ac4226d7d966533ba80ca5d9a1))
|
||||
* reset config to be closer to default ([b7fbb0b](https://github.com/unraid/api/commit/b7fbb0b6af0453f5f6a17087bb7e68c393b9fe3f))
|
||||
* resource busy when removing all subdirectories ([29936c9](https://github.com/unraid/api/commit/29936c90938fb83bc2f154315ca63a9d7cc98552))
|
||||
* restart command elegant ([296117b](https://github.com/unraid/api/commit/296117b51aac8a4c15366f2271af858868b6e071))
|
||||
* restore upgradepkg before install ([fddca27](https://github.com/unraid/api/commit/fddca2738c0ec016e744169d88b35a55dea092fa))
|
||||
* revert changes to indicator.vue ([84d2a83](https://github.com/unraid/api/commit/84d2a832c0f64e52be05670eb438b21bff2e5163))
|
||||
* revert myservers.cfg ([d0896f3](https://github.com/unraid/api/commit/d0896f3ef8aebdd9c76d805ed6a35b4a5d5a1b08))
|
||||
* rm getServerIdentifier wrapping Notifications id ([eaea306](https://github.com/unraid/api/commit/eaea306d54f633f563c7340f8a992e03b631f903))
|
||||
* rm rf to fix build issues ([a27cbe0](https://github.com/unraid/api/commit/a27cbe00d813ede6f31d4824fd63ff29a1ef6972))
|
||||
* sandbox defaults in dev mode wrong ([2a24919](https://github.com/unraid/api/commit/2a2491936cf85013be836450ab7ed0cc11207e11))
|
||||
* sequential test execution for generic-modification ([79ee1f7](https://github.com/unraid/api/commit/79ee1f7552cee47c6f5a8eb5942468292212e2f2))
|
||||
* shell path to unraid-api ([15d11e4](https://github.com/unraid/api/commit/15d11e477bb2a08d785a7b22bd51900279a55508))
|
||||
* staging build issues ([e6bcb8d](https://github.com/unraid/api/commit/e6bcb8de7daee463f7ac0dbf977e085e108302ba))
|
||||
* start command simplification ([e1faf3a](https://github.com/unraid/api/commit/e1faf3aa8db5973eb1bb0ea7a4844f820504618d))
|
||||
* stop command exits ([2dbfdb6](https://github.com/unraid/api/commit/2dbfdb670a773114c0fdc68c7cf9d29fa4e28a9b))
|
||||
* strip components from tar line ([911cd5b](https://github.com/unraid/api/commit/911cd5bc0b0983df4ca8c9057bea5166f7d1c7f1))
|
||||
* subdependenies ([f1ad3b0](https://github.com/unraid/api/commit/f1ad3b0af13345189e10973b422f4e5c6b5d7839))
|
||||
* swap to flexible IDs in tests ([b95559d](https://github.com/unraid/api/commit/b95559d9a1e743f92bc3b776892286e8d7abfc1e))
|
||||
* swap to placeholder key ([d1864d0](https://github.com/unraid/api/commit/d1864d0020ed56ab2368d23b48604b55cff21ae4))
|
||||
* switch to useToggle ([848233f](https://github.com/unraid/api/commit/848233f05465053876ac6f9f6ac4bfad2a48abff))
|
||||
* test issues ([e4b55b1](https://github.com/unraid/api/commit/e4b55b133bb2dc4bf2ccfd6fd2fc244daadbea53))
|
||||
* test simplification to ensure no redownloads ([e07dad3](https://github.com/unraid/api/commit/e07dad3a6947aa186c4ac03032b5b3813cd046b6))
|
||||
* tests ([25c1c1a](https://github.com/unraid/api/commit/25c1c1a55a3fb32b76bf5cb7257a4ba44f717a89))
|
||||
* tests and validate token clears screen ([7f48ddd](https://github.com/unraid/api/commit/7f48dddcd2e2ea1ae3a55ecc54d5ac274535b714))
|
||||
* text classes ([1e17cfc](https://github.com/unraid/api/commit/1e17cfc2bca5e8431188804b28f4645eb42cdc9f))
|
||||
* theme store now uses singular variables object ([5ca6e40](https://github.com/unraid/api/commit/5ca6e40b2d4942385b12a4325d6b8a551cb3f44b))
|
||||
* thorw on invalid token body ([f1af763](https://github.com/unraid/api/commit/f1af763eaf0dd8215eed470293d3a7f98784f38a))
|
||||
* trigger loading correctly ([e18f3d3](https://github.com/unraid/api/commit/e18f3d3e566011054163ec7827494fa047b26ec9))
|
||||
* type & build errors ([800969a](https://github.com/unraid/api/commit/800969a87a45d1d3ca9eca65657fddeccba66f28))
|
||||
* type error on element render ([a2563eb](https://github.com/unraid/api/commit/a2563eb8e710a9ac7259c4260cad9a3454565dae))
|
||||
* type for generic test ([e856535](https://github.com/unraid/api/commit/e85653592a9d6eadcd0be89bf90a96c5d313fda3))
|
||||
* unit test failure ([fed165e](https://github.com/unraid/api/commit/fed165eab0358fe032a99e5afbdb19813b00b741))
|
||||
* unit test issues ([c58f7a7](https://github.com/unraid/api/commit/c58f7a7f246902c7d354eb51d1c87c8ea3b636a3))
|
||||
* unit tests updated ([9548505](https://github.com/unraid/api/commit/954850535bec6b09aaf66b01d3ee749c8a22de5d))
|
||||
* unneeded await on api-key service ([0325be7](https://github.com/unraid/api/commit/0325be757ee4c04b5c23365ff592f521a492595b))
|
||||
* unraid-api in usr/bin ([580babd](https://github.com/unraid/api/commit/580babdafddd89ee2fb0b07aa7f5dff865be37d2))
|
||||
* unused import ([83fbea5](https://github.com/unraid/api/commit/83fbea5632b1de71afa4d0ca3224a946bf76fd23))
|
||||
* unused imports ([a5447aa](https://github.com/unraid/api/commit/a5447aa2f4c99968651fa3750d6bf0e8d68678de))
|
||||
* unused node dl line ([7ea1c3a](https://github.com/unraid/api/commit/7ea1c3a8f24e47f2e10994ffe629135dc4614159))
|
||||
* upc header text color ([f989026](https://github.com/unraid/api/commit/f9890260d1c4abe69dac3ac4c05ebab17aab5161))
|
||||
* update tests ([d0696a9](https://github.com/unraid/api/commit/d0696a93810893ccd6c676df1c639ca279992428))
|
||||
* upgradepkg ([90cf1a8](https://github.com/unraid/api/commit/90cf1a8eea67d3dbc736ecdfba47e0025b1dc31c))
|
||||
* use an enum and defaults for sandbox value ([eb56483](https://github.com/unraid/api/commit/eb56483ba2693944d39f4409c91b75ee82a7d30b))
|
||||
* use batchProcess ([ffbb9d7](https://github.com/unraid/api/commit/ffbb9d7750568bfa849d21e051503d1fcca5355f))
|
||||
* use correct ini encoder in notification service ([d1f8c61](https://github.com/unraid/api/commit/d1f8c61f1b9ea5745acdfd2d60de4725b4dffe05))
|
||||
* use cwd when running application ([e016652](https://github.com/unraid/api/commit/e01665264b6f45366cdacf60c0f3553adfbd85d3))
|
||||
* use foreground text color for UPC ([87b8165](https://github.com/unraid/api/commit/87b816550d413dc9023c5057efe18b9cb26761e7))
|
||||
* use placeholder in test API key ([c6b7755](https://github.com/unraid/api/commit/c6b7755214de8bedd5c0f2735473c2a559b1e26f))
|
||||
* use unraid binary path to call unraid commands ([555087d](https://github.com/unraid/api/commit/555087dcdd2bc9e5a6f2ccbdaff30a1bc89ad712))
|
||||
* used TGZ instead of TXZ for nghttp3 ([09ad394](https://github.com/unraid/api/commit/09ad39483fed7a8155176b6568114b4e6679d587))
|
||||
* variable naming ([dbffc0d](https://github.com/unraid/api/commit/dbffc0d293cefcb8d923cbcb17ad1f1a1d5e302d))
|
||||
* variables passed properly ([e0875e7](https://github.com/unraid/api/commit/e0875e7a1b273969939d6902a55f4a9772640078))
|
||||
* version and EOF key ([cafa47d](https://github.com/unraid/api/commit/cafa47d283d9b637c1e8dfbd7407186e58233358))
|
||||
* watch all events to load keys ([59ca177](https://github.com/unraid/api/commit/59ca17787e4d36113b0a8c5ef2117acfc491c49c))
|
||||
* **web:** add default values to optional vue component props ([d3092e4](https://github.com/unraid/api/commit/d3092e487ead2ca4647928008ee54f3cd6b333c2))
|
||||
* **web:** dedupe incoming notifications during cache merge ([4a40729](https://github.com/unraid/api/commit/4a40729e3721d01ac45614f4b7d1c48aec483cbc))
|
||||
* **web:** display error message in sidebar when api is offline ([#984](https://github.com/unraid/api/issues/984)) ([125c0a1](https://github.com/unraid/api/commit/125c0a140b4e9b5401bacf1addab1820c412917e))
|
||||
* **web:** edge case where archived notifications don't appear ([0a8c574](https://github.com/unraid/api/commit/0a8c5746fc2b8f8639643f013c1f19f0d7236d41))
|
||||
* **web:** env var typo ([22cf90b](https://github.com/unraid/api/commit/22cf90b27fadec3024d9d038c53683e8f8a723bc))
|
||||
* **web:** escaping html-encoded symbols like apostrophes in translations ([#1002](https://github.com/unraid/api/issues/1002)) ([04a3362](https://github.com/unraid/api/commit/04a33621e1d406d75ed0ff9af9f1f945813a1e8d))
|
||||
* **web:** flash of disconnected api state on page load ([a8c02f4](https://github.com/unraid/api/commit/a8c02f4c49433b440a6f9c70f269bf69076655dc))
|
||||
* **web:** infinite scroll loop when there's only 1 page of notifications ([e9f2fc4](https://github.com/unraid/api/commit/e9f2fc424c350d07c756ae7573e90f615bcae25b))
|
||||
* **web:** infinite trigger at bottom of infinite scroll ([eb691d3](https://github.com/unraid/api/commit/eb691d3514d8dc079987bfa566de4aa86094ef67))
|
||||
* **web:** inline shadcn variables into tailwind config to simplify build ([07fd7fe](https://github.com/unraid/api/commit/07fd7fe120f42ddf15c19f2a7df135fb9741187b))
|
||||
* **web:** notification styles & alignment ([#968](https://github.com/unraid/api/issues/968)) ([0d65e12](https://github.com/unraid/api/commit/0d65e12cede3324261fd3b219745b1e7793a33de))
|
||||
* **web:** refetch notifications for sidebar when new notifications arrive ([591bf4a](https://github.com/unraid/api/commit/591bf4a643ccc13c151c0a8cafad833d3137043e))
|
||||
* **web:** remove unused infinite-scroll emit from SheetContent ([95db23f](https://github.com/unraid/api/commit/95db23f8e13574a50e0ba3860bbfd54fd663c20e))
|
||||
* **web:** remove warn and error console log removal ([#1086](https://github.com/unraid/api/issues/1086)) ([9375639](https://github.com/unraid/api/commit/9375639e4a71ecfe8d4b877301c1f9bb22800a72))
|
||||
* **web:** replace incorrect custom types with codegen from gql & update values to match expected shapes ([fc93ef8](https://github.com/unraid/api/commit/fc93ef8e32607c807f9bd8529088a69937bdaefc))
|
||||
* **web:** replace manual height hack in notifications infinite scroll ([de1e272](https://github.com/unraid/api/commit/de1e272357264afc0f7f5fdd653c6a865105d710))
|
||||
* **web:** reset infinite scroll when notification filters change ([da6de2c](https://github.com/unraid/api/commit/da6de2ccdb710772a199c8cba8952adc247412db))
|
||||
* **web:** sanitize changelog markup after parsing ([c960292](https://github.com/unraid/api/commit/c96029273283f5970a5029eea1d7f451bbd0071b))
|
||||
* **web:** stop opening notification sidebar to archive tab ([325e75f](https://github.com/unraid/api/commit/325e75f5d444908a2227fbe2e94be9ab5196ad8e))
|
||||
* **web:** theme header differences ([#1085](https://github.com/unraid/api/issues/1085)) ([1ccdd8d](https://github.com/unraid/api/commit/1ccdd8dc71ee5e1e3aacabd113d1cf213ca7c7ae))
|
||||
* **web:** track 'notification seen' state across tabs & page loads ([#1121](https://github.com/unraid/api/issues/1121)) ([64cf6ec](https://github.com/unraid/api/commit/64cf6ecc6aec25cd8edee5659efb09f288bb9908))
|
||||
* **web:** update unread total immediately upon archiving ([#982](https://github.com/unraid/api/issues/982)) ([ff5fd8e](https://github.com/unraid/api/commit/ff5fd8e5eb8eb4803db1265e31b0c1352af20251))
|
||||
|
||||
## [3.11.0](https://github.com/unraid/api/compare/v3.10.1...v3.11.0) (2024-09-11)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* reduce how often rc.flashbackup checks for changes ([793d368](https://github.com/unraid/api/commit/793d3681404018e0ae933df0ad111809220ad138))
|
||||
* send api_version to flash/activate endpoint ([d8ec20e](https://github.com/unraid/api/commit/d8ec20ea6aa35aa241abd8424c4d884bcbb8f590))
|
||||
* update ProvisionCert.php to clean hosts file when it runs ([fbe20c9](https://github.com/unraid/api/commit/fbe20c97b327849c15a4b34f5f53476edaefbeb6))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* remove local flash backup ratelimit file on uninstall/update ([abf207b](https://github.com/unraid/api/commit/abf207b077861798c53739b1965207f87d5633b3))
|
||||
|
||||
### [3.10.1](https://github.com/unraid/api/compare/v3.10.0...v3.10.1) (2024-09-03)
|
||||
|
||||
## [3.10.0](https://github.com/unraid/api/compare/v3.9.0...v3.10.0) (2024-09-03)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* add a timestamp to flash backup ([#877](https://github.com/unraid/api/issues/877)) ([b868fd4](https://github.com/unraid/api/commit/b868fd46c3886b2182245a61f20be6df65e46abe))
|
||||
* add environment to docker-compose ([2ee4683](https://github.com/unraid/api/commit/2ee46839095e3b8ee287cfe10f29ae9a39dcff68))
|
||||
* add global agent ([#897](https://github.com/unraid/api/issues/897)) ([8b0dc69](https://github.com/unraid/api/commit/8b0dc69f65bd3e280a21c50aab221334f7341b1c))
|
||||
* add logrotate to cron in nestjs ([#839](https://github.com/unraid/api/issues/839)) ([5c91524](https://github.com/unraid/api/commit/5c91524d849147c0ac7925f3a2f1cce67ffe75de))
|
||||
* add new staging url for connect website ([#841](https://github.com/unraid/api/issues/841)) ([4cfc07b](https://github.com/unraid/api/commit/4cfc07b6763dbb79b68cf01f7eaf7cf33370d4db))
|
||||
* add support for expiration in var.ini ([#833](https://github.com/unraid/api/issues/833)) ([0474c2e](https://github.com/unraid/api/commit/0474c2e14fa462d2e1ec6d9a7f974660385d073e))
|
||||
* always show DRA even if disabled ([ab708c0](https://github.com/unraid/api/commit/ab708c0df634e21bf81595412d7de0be3ff7c392))
|
||||
* close log on exit ([d6ede86](https://github.com/unraid/api/commit/d6ede86eca6301342cdf35bf1f9365896b5e5009))
|
||||
* create stable hash based on apikey rather than hostname ([ecf5554](https://github.com/unraid/api/commit/ecf5554e304cc7dee78cb1f206ef4e80222c3e64))
|
||||
* disable all legacy dashboard and network logic ([6784f4b](https://github.com/unraid/api/commit/6784f4b6e1a12b2f30bfa9ab4fe6310994bd18ae))
|
||||
* dynamic remote access using remote queries ([f7fc0c4](https://github.com/unraid/api/commit/f7fc0c431561978054d2ff37d1aa644865e846ec))
|
||||
* extraOrigins public, remove origin listener ([91f96ba](https://github.com/unraid/api/commit/91f96ba818773d6e71dde1ff52a4c8ec21ba6b5d))
|
||||
* fix codegen ([d0bf5bb](https://github.com/unraid/api/commit/d0bf5bb8197b11f7a250ca5392890184a1dbeff7))
|
||||
* fix exit hook and cleanup docker scripts ([#758](https://github.com/unraid/api/issues/758)) ([a9ff73e](https://github.com/unraid/api/commit/a9ff73e0a04c67e9ec9d5551cf0b1f124be6f381))
|
||||
* fix logging format on start and stop ([c6720c3](https://github.com/unraid/api/commit/c6720c331df055480d2d65b37290f4978fe429da))
|
||||
* local start command ([99b6007](https://github.com/unraid/api/commit/99b6007ba30353084a8bea54cc0e782fcc1bfea4))
|
||||
* log config recreation reason ([f36c72f](https://github.com/unraid/api/commit/f36c72f5ad44b7e41d1726fa181dc2b9f594c72c))
|
||||
* move dynamic remote access to be fully api controlled ([206eb6b](https://github.com/unraid/api/commit/206eb6b74aa83047237e5f6c94c46b08c6507168))
|
||||
* move FQDN urls to a generic parser ([#899](https://github.com/unraid/api/issues/899)) ([246595e](https://github.com/unraid/api/commit/246595ee7acd8370906a759cbe618def4f52c173))
|
||||
* nestjs initial query implementation ([#748](https://github.com/unraid/api/issues/748)) ([075d7f2](https://github.com/unraid/api/commit/075d7f25785bf686779b7fee1d5ea39f09ff3ea8))
|
||||
* new key types in API ([e42f9dc](https://github.com/unraid/api/commit/e42f9dc95be03e8389aac443f2147c07a316d48d))
|
||||
* regTy swapped ([564b25c](https://github.com/unraid/api/commit/564b25cf5ce0a62d40f8d63d44c81e9c8560e0be))
|
||||
* remove dashboard resolver completely in favor of direct field resolvers ([1cd1ee5](https://github.com/unraid/api/commit/1cd1ee534825ccf775208c438ae0bd777bbe4d39))
|
||||
* remove dashboard types ([2f0167d](https://github.com/unraid/api/commit/2f0167dc89835bcf8aa946425c5c6683221fd763))
|
||||
* run codegen and update build script ([07512ad](https://github.com/unraid/api/commit/07512adc13ee0d819db45ff6c5c5f58a0ba31141))
|
||||
* settings through the API ([#867](https://github.com/unraid/api/issues/867)) ([e73624b](https://github.com/unraid/api/commit/e73624be6be8bc2c70d898b8601a88cc8d20a3e4))
|
||||
* swap to docker compose from docker-compose ([ec16a6a](https://github.com/unraid/api/commit/ec16a6aab1a2d5c836387da438fbeade07d23425))
|
||||
* swap to fragement usage on webcomponent ([42733ab](https://github.com/unraid/api/commit/42733abf6e443516ff715569333422ce80d3b1d2))
|
||||
* update tests and snapshots ([c39aa17](https://github.com/unraid/api/commit/c39aa17e4302ed56b3097ab3244d840f11eb686b))
|
||||
* upgrade a ton of dependencies ([#842](https://github.com/unraid/api/issues/842)) ([94c1746](https://github.com/unraid/api/commit/94c174620c2347a3cf3d100404635f99a5b47287))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* add serverName / description to dashboard payload ([9677aff](https://github.com/unraid/api/commit/9677aff1cd0942f36a2845f3f105601c494efd9e))
|
||||
* allow failure for log deletion ([eff3142](https://github.com/unraid/api/commit/eff31423927644be436a831126678719c2eb0621))
|
||||
* allowed origins check not working without spaces ([#838](https://github.com/unraid/api/issues/838)) ([b998b38](https://github.com/unraid/api/commit/b998b38355fab77ecc2f62bc64896766218db3d4))
|
||||
* **api:** readme discord url ([ffd5c6a](https://github.com/unraid/api/commit/ffd5c6afb64956e76df22c77104a21bc22798008))
|
||||
* build docker command updated to use dc.sh script ([0b40886](https://github.com/unraid/api/commit/0b40886e84f27a94dbf67ef4ca0cd8539ef3913e))
|
||||
* codegen on web run ([e2e67c2](https://github.com/unraid/api/commit/e2e67c21067a138d963f5f10760b84cf6a533542))
|
||||
* **deps:** update dependency @apollo/client to v3.9.5 ([#785](https://github.com/unraid/api/issues/785)) ([75b98bc](https://github.com/unraid/api/commit/75b98bc1cbca5b66ae72f52a0b6f5f58230a2473))
|
||||
* **deps:** update dependency graphql to v16.8.1 ([bff1b19](https://github.com/unraid/api/commit/bff1b19706bee1e3103e3a0a1d2fceb3154f9bba))
|
||||
* **deps:** update dependency graphql-ws to v5.15.0 ([#790](https://github.com/unraid/api/issues/790)) ([4773b13](https://github.com/unraid/api/commit/4773b132167d740d4c996efe22e0f1b99576fb9b))
|
||||
* **deps:** update dependency ws to v8.16.0 ([#815](https://github.com/unraid/api/issues/815)) ([212020e](https://github.com/unraid/api/commit/212020e78d4de0576137058a3374837b4a43e02d))
|
||||
* **deps:** update dependency wtfnode to v0.9.3 ([#901](https://github.com/unraid/api/issues/901)) ([a88482b](https://github.com/unraid/api/commit/a88482bfcbf134f55330f8728bc5c7f67c521773))
|
||||
* **deps:** update graphql-tools monorepo ([3447eb0](https://github.com/unraid/api/commit/3447eb047a1dcd575b88a96bbcef9946aca366a1))
|
||||
* **deps:** update graphql-tools monorepo (major) ([#693](https://github.com/unraid/api/issues/693)) ([3447eb0](https://github.com/unraid/api/commit/3447eb047a1dcd575b88a96bbcef9946aca366a1))
|
||||
* **deps:** update nest monorepo ([#816](https://github.com/unraid/api/issues/816)) ([4af3699](https://github.com/unraid/api/commit/4af36991b8b376f816ed51fd503a66e99675a3e7))
|
||||
* excessive logging ([89cb254](https://github.com/unraid/api/commit/89cb2544ed0e0edd33b59f15d487487e22c0ae32))
|
||||
* exit with process.exit not process.exitcode ([dcb6def](https://github.com/unraid/api/commit/dcb6def1cf3365dca819feed101160c8ad0125dc))
|
||||
* lint ([919873d](https://github.com/unraid/api/commit/919873d9edee304d99036a4a810db3789c734fbf))
|
||||
* local container startup commands cleaned up ([6c0ccb2](https://github.com/unraid/api/commit/6c0ccb2b24f98282be4db2e0b2e6362f4a187def))
|
||||
* logrotate not working due to invalid ownership of unraid-api folder ([ec0581a](https://github.com/unraid/api/commit/ec0581abf58a217f698d52d5337f2b312e5a645b))
|
||||
* optional check on api.version to allow fallback to save value ([0ac4455](https://github.com/unraid/api/commit/0ac4455f78407eca7aa1d6ee360830067a1c5c3e))
|
||||
* permission for dashboard payload ([704a530](https://github.com/unraid/api/commit/704a530653dac415766bded5e96f6060f931e591))
|
||||
* rearrange exit hook to try to fix closing ([843d3f4](https://github.com/unraid/api/commit/843d3f41162c5dbcfd7803912b1879d7a182231a))
|
||||
* revert myservers.cfg to fix test ([a7705be](https://github.com/unraid/api/commit/a7705beb0a5b32660367ad8de9b46b06f7a3bec7))
|
||||
* run hourly ([0425794](https://github.com/unraid/api/commit/0425794356a01262222e7dff2645d3629e00d0f6))
|
||||
* unused import ([065fe57](https://github.com/unraid/api/commit/065fe575f578a74d593805c3121dd7fbdfc3e5ae))
|
||||
* update snapshots ([c8a0a8e](https://github.com/unraid/api/commit/c8a0a8ec007abc0372464c7e2b44bd47b6babd94))
|
||||
|
||||
## [3.9.0](https://github.com/unraid/api/compare/api-v3.8.1...api-v3.9.0) (2024-09-03)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* add a timestamp to flash backup ([#877](https://github.com/unraid/api/issues/877)) ([b868fd4](https://github.com/unraid/api/commit/b868fd46c3886b2182245a61f20be6df65e46abe))
|
||||
* add environment to docker-compose ([2ee4683](https://github.com/unraid/api/commit/2ee46839095e3b8ee287cfe10f29ae9a39dcff68))
|
||||
* add global agent ([#897](https://github.com/unraid/api/issues/897)) ([8b0dc69](https://github.com/unraid/api/commit/8b0dc69f65bd3e280a21c50aab221334f7341b1c))
|
||||
* add logrotate to cron in nestjs ([#839](https://github.com/unraid/api/issues/839)) ([5c91524](https://github.com/unraid/api/commit/5c91524d849147c0ac7925f3a2f1cce67ffe75de))
|
||||
* add new staging url for connect website ([#841](https://github.com/unraid/api/issues/841)) ([4cfc07b](https://github.com/unraid/api/commit/4cfc07b6763dbb79b68cf01f7eaf7cf33370d4db))
|
||||
* add support for expiration in var.ini ([#833](https://github.com/unraid/api/issues/833)) ([0474c2e](https://github.com/unraid/api/commit/0474c2e14fa462d2e1ec6d9a7f974660385d073e))
|
||||
* always show DRA even if disabled ([ab708c0](https://github.com/unraid/api/commit/ab708c0df634e21bf81595412d7de0be3ff7c392))
|
||||
* close log on exit ([d6ede86](https://github.com/unraid/api/commit/d6ede86eca6301342cdf35bf1f9365896b5e5009))
|
||||
* create stable hash based on apikey rather than hostname ([ecf5554](https://github.com/unraid/api/commit/ecf5554e304cc7dee78cb1f206ef4e80222c3e64))
|
||||
* disable all legacy dashboard and network logic ([6784f4b](https://github.com/unraid/api/commit/6784f4b6e1a12b2f30bfa9ab4fe6310994bd18ae))
|
||||
* dynamic remote access using remote queries ([f7fc0c4](https://github.com/unraid/api/commit/f7fc0c431561978054d2ff37d1aa644865e846ec))
|
||||
* extraOrigins public, remove origin listener ([91f96ba](https://github.com/unraid/api/commit/91f96ba818773d6e71dde1ff52a4c8ec21ba6b5d))
|
||||
* fix codegen ([d0bf5bb](https://github.com/unraid/api/commit/d0bf5bb8197b11f7a250ca5392890184a1dbeff7))
|
||||
* fix exit hook and cleanup docker scripts ([#758](https://github.com/unraid/api/issues/758)) ([a9ff73e](https://github.com/unraid/api/commit/a9ff73e0a04c67e9ec9d5551cf0b1f124be6f381))
|
||||
* fix logging format on start and stop ([c6720c3](https://github.com/unraid/api/commit/c6720c331df055480d2d65b37290f4978fe429da))
|
||||
* local start command ([99b6007](https://github.com/unraid/api/commit/99b6007ba30353084a8bea54cc0e782fcc1bfea4))
|
||||
* log config recreation reason ([f36c72f](https://github.com/unraid/api/commit/f36c72f5ad44b7e41d1726fa181dc2b9f594c72c))
|
||||
* move dynamic remote access to be fully api controlled ([206eb6b](https://github.com/unraid/api/commit/206eb6b74aa83047237e5f6c94c46b08c6507168))
|
||||
* move FQDN urls to a generic parser ([#899](https://github.com/unraid/api/issues/899)) ([246595e](https://github.com/unraid/api/commit/246595ee7acd8370906a759cbe618def4f52c173))
|
||||
* nestjs initial query implementation ([#748](https://github.com/unraid/api/issues/748)) ([075d7f2](https://github.com/unraid/api/commit/075d7f25785bf686779b7fee1d5ea39f09ff3ea8))
|
||||
* new key types in API ([e42f9dc](https://github.com/unraid/api/commit/e42f9dc95be03e8389aac443f2147c07a316d48d))
|
||||
* regTy swapped ([564b25c](https://github.com/unraid/api/commit/564b25cf5ce0a62d40f8d63d44c81e9c8560e0be))
|
||||
* remove dashboard resolver completely in favor of direct field resolvers ([1cd1ee5](https://github.com/unraid/api/commit/1cd1ee534825ccf775208c438ae0bd777bbe4d39))
|
||||
* remove dashboard types ([2f0167d](https://github.com/unraid/api/commit/2f0167dc89835bcf8aa946425c5c6683221fd763))
|
||||
* run codegen and update build script ([07512ad](https://github.com/unraid/api/commit/07512adc13ee0d819db45ff6c5c5f58a0ba31141))
|
||||
* settings through the API ([#867](https://github.com/unraid/api/issues/867)) ([e73624b](https://github.com/unraid/api/commit/e73624be6be8bc2c70d898b8601a88cc8d20a3e4))
|
||||
* swap to docker compose from docker-compose ([ec16a6a](https://github.com/unraid/api/commit/ec16a6aab1a2d5c836387da438fbeade07d23425))
|
||||
* swap to fragement usage on webcomponent ([42733ab](https://github.com/unraid/api/commit/42733abf6e443516ff715569333422ce80d3b1d2))
|
||||
* update tests and snapshots ([c39aa17](https://github.com/unraid/api/commit/c39aa17e4302ed56b3097ab3244d840f11eb686b))
|
||||
* upgrade a ton of dependencies ([#842](https://github.com/unraid/api/issues/842)) ([94c1746](https://github.com/unraid/api/commit/94c174620c2347a3cf3d100404635f99a5b47287))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* add serverName / description to dashboard payload ([9677aff](https://github.com/unraid/api/commit/9677aff1cd0942f36a2845f3f105601c494efd9e))
|
||||
* allow failure for log deletion ([eff3142](https://github.com/unraid/api/commit/eff31423927644be436a831126678719c2eb0621))
|
||||
* allowed origins check not working without spaces ([#838](https://github.com/unraid/api/issues/838)) ([b998b38](https://github.com/unraid/api/commit/b998b38355fab77ecc2f62bc64896766218db3d4))
|
||||
* **api:** readme discord url ([ffd5c6a](https://github.com/unraid/api/commit/ffd5c6afb64956e76df22c77104a21bc22798008))
|
||||
* build docker command updated to use dc.sh script ([0b40886](https://github.com/unraid/api/commit/0b40886e84f27a94dbf67ef4ca0cd8539ef3913e))
|
||||
* codegen on web run ([e2e67c2](https://github.com/unraid/api/commit/e2e67c21067a138d963f5f10760b84cf6a533542))
|
||||
* **deps:** update dependency @apollo/client to v3.9.5 ([#785](https://github.com/unraid/api/issues/785)) ([75b98bc](https://github.com/unraid/api/commit/75b98bc1cbca5b66ae72f52a0b6f5f58230a2473))
|
||||
* **deps:** update dependency graphql to v16.8.1 ([bff1b19](https://github.com/unraid/api/commit/bff1b19706bee1e3103e3a0a1d2fceb3154f9bba))
|
||||
* **deps:** update dependency graphql-ws to v5.15.0 ([#790](https://github.com/unraid/api/issues/790)) ([4773b13](https://github.com/unraid/api/commit/4773b132167d740d4c996efe22e0f1b99576fb9b))
|
||||
* **deps:** update dependency ws to v8.16.0 ([#815](https://github.com/unraid/api/issues/815)) ([212020e](https://github.com/unraid/api/commit/212020e78d4de0576137058a3374837b4a43e02d))
|
||||
* **deps:** update dependency wtfnode to v0.9.3 ([#901](https://github.com/unraid/api/issues/901)) ([a88482b](https://github.com/unraid/api/commit/a88482bfcbf134f55330f8728bc5c7f67c521773))
|
||||
* **deps:** update graphql-tools monorepo ([3447eb0](https://github.com/unraid/api/commit/3447eb047a1dcd575b88a96bbcef9946aca366a1))
|
||||
* **deps:** update graphql-tools monorepo (major) ([#693](https://github.com/unraid/api/issues/693)) ([3447eb0](https://github.com/unraid/api/commit/3447eb047a1dcd575b88a96bbcef9946aca366a1))
|
||||
* **deps:** update nest monorepo ([#816](https://github.com/unraid/api/issues/816)) ([4af3699](https://github.com/unraid/api/commit/4af36991b8b376f816ed51fd503a66e99675a3e7))
|
||||
* excessive logging ([89cb254](https://github.com/unraid/api/commit/89cb2544ed0e0edd33b59f15d487487e22c0ae32))
|
||||
* exit with process.exit not process.exitcode ([dcb6def](https://github.com/unraid/api/commit/dcb6def1cf3365dca819feed101160c8ad0125dc))
|
||||
* lint ([919873d](https://github.com/unraid/api/commit/919873d9edee304d99036a4a810db3789c734fbf))
|
||||
* local container startup commands cleaned up ([6c0ccb2](https://github.com/unraid/api/commit/6c0ccb2b24f98282be4db2e0b2e6362f4a187def))
|
||||
* logrotate not working due to invalid ownership of unraid-api folder ([ec0581a](https://github.com/unraid/api/commit/ec0581abf58a217f698d52d5337f2b312e5a645b))
|
||||
* optional check on api.version to allow fallback to save value ([0ac4455](https://github.com/unraid/api/commit/0ac4455f78407eca7aa1d6ee360830067a1c5c3e))
|
||||
* permission for dashboard payload ([704a530](https://github.com/unraid/api/commit/704a530653dac415766bded5e96f6060f931e591))
|
||||
* rearrange exit hook to try to fix closing ([843d3f4](https://github.com/unraid/api/commit/843d3f41162c5dbcfd7803912b1879d7a182231a))
|
||||
* revert myservers.cfg to fix test ([a7705be](https://github.com/unraid/api/commit/a7705beb0a5b32660367ad8de9b46b06f7a3bec7))
|
||||
* run hourly ([0425794](https://github.com/unraid/api/commit/0425794356a01262222e7dff2645d3629e00d0f6))
|
||||
* unused import ([065fe57](https://github.com/unraid/api/commit/065fe575f578a74d593805c3121dd7fbdfc3e5ae))
|
||||
* update snapshots ([c8a0a8e](https://github.com/unraid/api/commit/c8a0a8ec007abc0372464c7e2b44bd47b6babd94))
|
||||
|
||||
### [3.8.1](https://github.com/unraid/api/compare/v3.8.0...v3.8.1) (2024-08-13)
|
||||
|
||||
## [3.8.0](https://github.com/unraid/api/compare/v3.7.1...v3.8.0) (2024-08-13)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* always force push ([662f3ce](https://github.com/unraid/api/commit/662f3ce440593e609c64364726f7da16dda0972b))
|
||||
* don't allow flash backup repos larger than 500MB ([#890](https://github.com/unraid/api/issues/890)) ([30a32f5](https://github.com/unraid/api/commit/30a32f5fe684bb32c084c4125aade5e63ffd788b))
|
||||
* downgradeOs callback for non stable osCurrentBranch ([17c4489](https://github.com/unraid/api/commit/17c4489e97bda504ca45e360591655ded166c355))
|
||||
* settings through the API ([#867](https://github.com/unraid/api/issues/867)) ([e73624b](https://github.com/unraid/api/commit/e73624be6be8bc2c70d898b8601a88cc8d20a3e4))
|
||||
* swap to docker compose from docker-compose ([ec16a6a](https://github.com/unraid/api/commit/ec16a6aab1a2d5c836387da438fbeade07d23425))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* apolloClient types ([f14c767](https://github.com/unraid/api/commit/f14c7673735b92aa167e9e8dcb14a045bcfea994))
|
||||
* **deps:** update dependency @vue/apollo-composable to v4.0.2 ([#787](https://github.com/unraid/api/issues/787)) ([edfc846](https://github.com/unraid/api/commit/edfc8464b0e0c2f38003ae8420e81532fd18351f))
|
||||
* formattedRegTm type ([748906e](https://github.com/unraid/api/commit/748906e15d30c6162e2f08f28724c9104c81d123))
|
||||
* i18n t prop type ([96d519f](https://github.com/unraid/api/commit/96d519f3e6b96ea7c4dc60616522216de20ee140))
|
||||
* lint error for web components ([bc27b20](https://github.com/unraid/api/commit/bc27b20524934cf896efb84a131cd270431c508c))
|
||||
* lint issues ([853dc19](https://github.com/unraid/api/commit/853dc195b13fff29160afb44f9ff11d4dd6a3232))
|
||||
* swap undefined to null ([ebba976](https://github.com/unraid/api/commit/ebba9769873a6536e3fce65978e6475d93280560))
|
||||
* tailwind config types ([0f77e55](https://github.com/unraid/api/commit/0f77e5596db3356b5dc05129b3ce215a8809e1dc))
|
||||
* ts-expect-error unneeded ([ee4d4e9](https://github.com/unraid/api/commit/ee4d4e9f12b4488ff39445bc72c1b83a9d93e993))
|
||||
* type check ([606aad7](https://github.com/unraid/api/commit/606aad703d91b72a14e15da3100dfa355052ed58))
|
||||
* type errors round 1 ([977d5da](https://github.com/unraid/api/commit/977d5daf04012f16e7b6602167338f0bc363735a))
|
||||
* update status button alignment ([4f2deaf](https://github.com/unraid/api/commit/4f2deaf70e5caa9f29fc5b2974b278f80b7b3a8a))
|
||||
|
||||
### [3.7.1](https://github.com/unraid/api/compare/v3.7.0...v3.7.1) (2024-05-15)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* reboot required and available edge case ([#885](https://github.com/unraid/api/issues/885)) ([76e9cdf](https://github.com/unraid/api/commit/76e9cdf81f06a19c2e4c9a40a4d8e062bad2a607))
|
||||
|
||||
## [3.7.0](https://github.com/unraid/api/compare/v3.6.0...v3.7.0) (2024-05-14)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* add a timestamp to flash backup ([#877](https://github.com/unraid/api/issues/877)) ([b868fd4](https://github.com/unraid/api/commit/b868fd46c3886b2182245a61f20be6df65e46abe))
|
||||
* add support for outgoing proxies ([#863](https://github.com/unraid/api/issues/863)) ([223693e](https://github.com/unraid/api/commit/223693e0981d5f2884a1f8b8baf03d4dc58e8cb2))
|
||||
* array state on registration page ([d36fef0](https://github.com/unraid/api/commit/d36fef0545ddb820e67e8bc6cb42ea3644021d66))
|
||||
* downgradeOs callback ([154a976](https://github.com/unraid/api/commit/154a976109f0a32653a2851988420707631327ca))
|
||||
* Flash Backup requires connection to mothership ([#868](https://github.com/unraid/api/issues/868)) ([d127208](https://github.com/unraid/api/commit/d127208b5e0f7f9991f515f95b0e266d38cf3287))
|
||||
* **plg:** install prevent downgrade of shared page & php files ([#873](https://github.com/unraid/api/issues/873)) ([4ac72b1](https://github.com/unraid/api/commit/4ac72b16692c4246c9d2c0b53b23d8b2d95f5de6))
|
||||
* **plg:** plg install prevent web component downgrade ([8703bd4](https://github.com/unraid/api/commit/8703bd498108f5c05562584a708bd2306e53f7a6))
|
||||
* postbuild script to add timestamp to web component manifest ([47f08ea](https://github.com/unraid/api/commit/47f08ea3594a91098f67718c0123110c7b5f86f7))
|
||||
* registration page server error heading + subheading ([6038ebd](https://github.com/unraid/api/commit/6038ebdf39bf47f2cb5c0b1de84764795374f018))
|
||||
* remove cron to download JS daily ([#864](https://github.com/unraid/api/issues/864)) ([33f6d6b](https://github.com/unraid/api/commit/33f6d6b343de07dbe70de863926906736d42f371)), closes [#529](https://github.com/unraid/api/issues/529)
|
||||
* ui to allow second update without reboot ([b0f2d10](https://github.com/unraid/api/commit/b0f2d102917f54ab33f0ad10863522b8ff8e3ce5))
|
||||
* UI Update OS Cancel ([7c02308](https://github.com/unraid/api/commit/7c02308964d5e21990427a2c626c9db2d9e1fed0))
|
||||
* UnraidUpdateCancel script ([b73bdc0](https://github.com/unraid/api/commit/b73bdc021764762ed12dca494e1345412a45c677))
|
||||
* **web:** callback types myKeys & linkKey ([c88ee01](https://github.com/unraid/api/commit/c88ee01827396c3fa8a30bb88c4be712c80b1f4f))
|
||||
* **web:** Registration key linked to account status ([8f6182d](https://github.com/unraid/api/commit/8f6182d426453b73aa19c5f0f59469fa07571694))
|
||||
* **web:** registration page array status messaging ([23ef5a9](https://github.com/unraid/api/commit/23ef5a975e0d5ff0c246c2df5e6c2cb38979d12a))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **api:** readme discord url ([ffd5c6a](https://github.com/unraid/api/commit/ffd5c6afb64956e76df22c77104a21bc22798008))
|
||||
* keep minor enhancements from [#872](https://github.com/unraid/api/issues/872) ([#878](https://github.com/unraid/api/issues/878)) ([94a5aa8](https://github.com/unraid/api/commit/94a5aa87b9979fe0f02f884ac61298473bb3271a))
|
||||
* plugin file deployment script ([780d87d](https://github.com/unraid/api/commit/780d87d6589a5469f47ac3fdfd50610ecfc394c8))
|
||||
* prevent corrupt case model in state.php ([#874](https://github.com/unraid/api/issues/874)) ([4ad31df](https://github.com/unraid/api/commit/4ad31dfea9192146dbd2c90bc64a913c696ab0b7))
|
||||
* prevent local dev from throwing ssl error ([051f647](https://github.com/unraid/api/commit/051f6474becf3b25b242cdc6ceee67247b79f8ba))
|
||||
* rc.flashbackup needs to check both signed in and connected ([#882](https://github.com/unraid/api/issues/882)) ([ac8068c](https://github.com/unraid/api/commit/ac8068c9b084622d46fe2c9cb320b793c9ea8c52))
|
||||
* update os cancel refresh on update page ([213c16b](https://github.com/unraid/api/commit/213c16ba3d5a84ebf4965f9d2f4024c66605a613))
|
||||
* **web:** discord url ([1a6f4c6](https://github.com/unraid/api/commit/1a6f4c6db4ef0e5eefac467ec6583b14cb3546c4))
|
||||
* **web:** lint unused rebootVersion ([e198ec9](https://github.com/unraid/api/commit/e198ec9d458e262c412c2dcb5a9d279238de1730))
|
||||
* **web:** registration component remove unused ref ([76f556b](https://github.com/unraid/api/commit/76f556bd64b95ba96af795c9edfa045ebdff4444))
|
||||
|
||||
## [3.6.0](https://github.com/unraid/api/compare/v3.5.3...v3.6.0) (2024-03-26)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* server config enum message w/ ineligible support ([#861](https://github.com/unraid/api/issues/861)) ([4d3a351](https://github.com/unraid/api/commit/4d3a3510777090788573f4cee83694a0dc6f8df5))
|
||||
|
||||
### [3.5.3](https://github.com/unraid/api/compare/v3.5.2...v3.5.3) (2024-03-25)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* regDevs usage to allow more flexibility for STARTER ([#860](https://github.com/unraid/api/issues/860)) ([92a9600](https://github.com/unraid/api/commit/92a9600f3a242c5f263f1672eab81054b9cf4fae))
|
||||
|
||||
### [3.5.2](https://github.com/unraid/api/compare/v3.5.1...v3.5.2) (2024-03-06)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **deps:** update dependency vue-i18n to v9.10.1 ([#813](https://github.com/unraid/api/issues/813)) ([69b599c](https://github.com/unraid/api/commit/69b599c5ed8d44864201a32b4d952427d454dc74))
|
||||
* **deps:** update dependency wretch to v2.8.0 ([#814](https://github.com/unraid/api/issues/814)) ([66900b4](https://github.com/unraid/api/commit/66900b495b82b923264897d38b1529a22b10aa1c))
|
||||
* update os check modal button conditionals ([282a836](https://github.com/unraid/api/commit/282a83625f417ccefe090b65cc6b73a084727a87))
|
||||
* update os check modal ineligible date format ([83083de](https://github.com/unraid/api/commit/83083de1e698f73a35635ae6047dcf49fd4b8114))
|
||||
|
||||
### [3.5.1](https://github.com/unraid/api/compare/v3.5.0...v3.5.1) (2024-02-29)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* build docker command updated to use dc.sh script ([0b40886](https://github.com/unraid/api/commit/0b40886e84f27a94dbf67ef4ca0cd8539ef3913e))
|
||||
* date format in UnraidCheck.php ([#852](https://github.com/unraid/api/issues/852)) ([6465f2d](https://github.com/unraid/api/commit/6465f2d7b2394090f35e29cdd680d98ce37f3728))
|
||||
* **deps:** update dependency @apollo/client to v3.9.5 ([#785](https://github.com/unraid/api/issues/785)) ([75b98bc](https://github.com/unraid/api/commit/75b98bc1cbca5b66ae72f52a0b6f5f58230a2473))
|
||||
* **deps:** update dependency @heroicons/vue to v2.1.1 ([#804](https://github.com/unraid/api/issues/804)) ([a0eb7ee](https://github.com/unraid/api/commit/a0eb7ee3ec459dbe1992a7f85bf194da30395a74))
|
||||
* **deps:** update dependency focus-trap to v7.5.4 ([#788](https://github.com/unraid/api/issues/788)) ([fe000e8](https://github.com/unraid/api/commit/fe000e83825e82cac558d3277664a440e59c0e4a))
|
||||
* **deps:** update dependency graphql-ws to v5.15.0 ([#790](https://github.com/unraid/api/issues/790)) ([4773b13](https://github.com/unraid/api/commit/4773b132167d740d4c996efe22e0f1b99576fb9b))
|
||||
* display dropdown for pro key no connect installed ([#848](https://github.com/unraid/api/issues/848)) ([b559604](https://github.com/unraid/api/commit/b55960429895b46627f1cd3ed1683ee527e62944))
|
||||
* dropdown reboot link text ([#849](https://github.com/unraid/api/issues/849)) ([a8ed5e5](https://github.com/unraid/api/commit/a8ed5e5628bc71fb783a03c3db92d21805243738))
|
||||
* os updates rc to stable ([bf1bd88](https://github.com/unraid/api/commit/bf1bd887d60ac085bf4aeae90f11be3b45ee1182))
|
||||
* state connect values without connect installed ([e47de6c](https://github.com/unraid/api/commit/e47de6c2c5db7a2a1a9b24099feb02023b3a7bbf))
|
||||
* state php breaking with double quotes in server description ([c6e92aa](https://github.com/unraid/api/commit/c6e92aa3157c9fe9e7b83580881ebcc1cbd03658))
|
||||
* state php special chars for html attributes ([#853](https://github.com/unraid/api/issues/853)) ([dd4139c](https://github.com/unraid/api/commit/dd4139cf1a7ae5c6f9b00111c33ae124bb17e630))
|
||||
* unraid-api missing start command + var defaults ([ceb4c58](https://github.com/unraid/api/commit/ceb4c587d20c7527f2b36a3278c310b0e657bfba))
|
||||
* unraid-api.php $param1 fallback ([909c79c](https://github.com/unraid/api/commit/909c79c8c82500aea1a0d4d00766f788103c5fe3))
|
||||
|
||||
## [3.5.0](https://github.com/unraid/api/compare/v3.4.0...v3.5.0) (2024-02-07)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* add manage account link to all versions of upc dropdown ([678e620](https://github.com/unraid/api/commit/678e620c1902a376b1866265711d5722b4119d8e))
|
||||
* add new staging url for connect website ([#841](https://github.com/unraid/api/issues/841)) ([4cfc07b](https://github.com/unraid/api/commit/4cfc07b6763dbb79b68cf01f7eaf7cf33370d4db))
|
||||
* also ship to cloudflare ([#844](https://github.com/unraid/api/issues/844)) ([41c4210](https://github.com/unraid/api/commit/41c42103685209592b272f81a877702da04d0915))
|
||||
* button add underline-hover-red style option ([f2fa5fa](https://github.com/unraid/api/commit/f2fa5fa49675ef461330be7b7eb3e3e4106983b0))
|
||||
* changelog modal ([2ddbacd](https://github.com/unraid/api/commit/2ddbacd137cc5748244c3d25ac91f82e64d77f99))
|
||||
* check update response modal ([39678f0](https://github.com/unraid/api/commit/39678f0bb0ddc5f87ea7f5ed80a0472100ea8b5d))
|
||||
* create WebguiCheckForUpdate endpoint ([41d546e](https://github.com/unraid/api/commit/41d546eea5fcf6593d7b5047274c074bb89c1802))
|
||||
* getOsReleaseBySha256 cached endpoint with keyfile header ([cd2413a](https://github.com/unraid/api/commit/cd2413abe8c5baab40e4e5974e08a5d18dce8e0d))
|
||||
* new check update buttons in dropdown ([ef5fcb9](https://github.com/unraid/api/commit/ef5fcb96a324143da864df803acaa0da1cd00eb7))
|
||||
* ship preview to different bucket ([#845](https://github.com/unraid/api/issues/845)) ([8e5d247](https://github.com/unraid/api/commit/8e5d247bca83d9e50977c9b16b212841ac9f70ad))
|
||||
* ship production to different bucket ([#846](https://github.com/unraid/api/issues/846)) ([63c0875](https://github.com/unraid/api/commit/63c08758c76425e007b1779bb2f77b75bc45896e))
|
||||
* unraidcheck callable from webgui with altUrl & json output ([ba8a67e](https://github.com/unraid/api/commit/ba8a67edfa043f442b11724227129f8d3f6cae0a))
|
||||
* update modals ([8ad7d8b](https://github.com/unraid/api/commit/8ad7d8be9437e0caa0409da8f7322050919fbbaa))
|
||||
* update os ignore release ([1955eb2](https://github.com/unraid/api/commit/1955eb23a3cdc30f0a67bc5950a047f83a860d99))
|
||||
* update os notifications enabled usage + link to enable & more options to account app ([5c82aff](https://github.com/unraid/api/commit/5c82aff80dc7e6d8f4b23e52af29abc2b8576424))
|
||||
* updateOs check response determines if update auth is required ([a9816d9](https://github.com/unraid/api/commit/a9816d9ad48ff80d87b5aeb236ff60c4979ad298))
|
||||
* updateOs store call local server-side endpoint & add modal support ([be48447](https://github.com/unraid/api/commit/be48447f943828af281095c5a092ac686e729030))
|
||||
* upgrade a ton of dependencies ([#842](https://github.com/unraid/api/issues/842)) ([94c1746](https://github.com/unraid/api/commit/94c174620c2347a3cf3d100404635f99a5b47287))
|
||||
* WebguiCheckForUpdate using server-side check ([590deb1](https://github.com/unraid/api/commit/590deb130c301d4004fecdc211270583806b5593))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* backport _var() PHP function to older versions of Unraid ([f53150e](https://github.com/unraid/api/commit/f53150e1fa33b3f45b66ad0dc5eaabc470564d45))
|
||||
* changlog relative links and external links ([a789e20](https://github.com/unraid/api/commit/a789e204ce7b966e6c935923626538ac344aeefe))
|
||||
* check update response modal expired key button styles ([92993e3](https://github.com/unraid/api/commit/92993e3e0b6240c83a6a64efedd8ddb3be3f9ef7))
|
||||
* **deps:** update dependency ws to v8.16.0 ([#815](https://github.com/unraid/api/issues/815)) ([212020e](https://github.com/unraid/api/commit/212020e78d4de0576137058a3374837b4a43e02d))
|
||||
* extraLinks when no updates available ([853a991](https://github.com/unraid/api/commit/853a9911e3fd7eec9bbc88468de78f87b448d477))
|
||||
* ignore release localStorage ([62c45ec](https://github.com/unraid/api/commit/62c45ec9d7c68498bbcfe933a5b63e4759c7129c))
|
||||
* lint ([83235f9](https://github.com/unraid/api/commit/83235f9db726f4582b9d353a66f2f5e8925b8e34))
|
||||
* lint unused value ([2c7e53b](https://github.com/unraid/api/commit/2c7e53bf67d1f214201624b39786bfb7de6aa520))
|
||||
* marked-base-url install ([416ba71](https://github.com/unraid/api/commit/416ba716aa750a094e8cd521a79f6deebcd37864))
|
||||
* missing translations ([faf17e4](https://github.com/unraid/api/commit/faf17e41e81c11443bc062d8ce35a33d9ae9ebbc))
|
||||
* regTm format after key install without page refresh ([f3ddb31](https://github.com/unraid/api/commit/f3ddb31f994de9192f7203698ecc5d7de673c6a3))
|
||||
* regTm format when already set ([5ad911f](https://github.com/unraid/api/commit/5ad911f8133daa60de53da738d41c6a59e2f02cc))
|
||||
* ServerUpdateOsResponse type ([78bdae8](https://github.com/unraid/api/commit/78bdae86c907142d3ee32d6715eaa8f5a974a1ed))
|
||||
* State Class usage in other files ([4ad7f53](https://github.com/unraid/api/commit/4ad7f53ec145b2e6d2895619523e90c1daa3f68f))
|
||||
* state data humanReadable switch fallthrus ([9144e39](https://github.com/unraid/api/commit/9144e39d39aa56af0ad897735d1a3545330920d0))
|
||||
* state php usage from cli ([46fd321](https://github.com/unraid/api/commit/46fd321707c14cd1f265ee806f673500d87132dd))
|
||||
* translations ([3fabd57](https://github.com/unraid/api/commit/3fabd5756674c06fa803729cf13d19c592d8d46a))
|
||||
* type issue with changlelog modal visibility ([e3c3f6b](https://github.com/unraid/api/commit/e3c3f6bf0f1882788291db17bd74865fefc3abf6))
|
||||
|
||||
## [3.4.0](https://github.com/unraid/api/compare/v3.3.0...v3.4.0) (2024-01-11)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* add logrotate to cron in nestjs ([#839](https://github.com/unraid/api/issues/839)) ([5c91524](https://github.com/unraid/api/commit/5c91524d849147c0ac7925f3a2f1cce67ffe75de))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* allow failure for log deletion ([eff3142](https://github.com/unraid/api/commit/eff31423927644be436a831126678719c2eb0621))
|
||||
* allowed origins check not working without spaces ([#838](https://github.com/unraid/api/issues/838)) ([b998b38](https://github.com/unraid/api/commit/b998b38355fab77ecc2f62bc64896766218db3d4))
|
||||
* excessive logging ([89cb254](https://github.com/unraid/api/commit/89cb2544ed0e0edd33b59f15d487487e22c0ae32))
|
||||
* run hourly ([0425794](https://github.com/unraid/api/commit/0425794356a01262222e7dff2645d3629e00d0f6))
|
||||
|
||||
## [3.3.0](https://github.com/unraid/api/compare/v3.2.3...v3.3.0) (2024-01-09)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* add button to add current origin to extra origins setting ([8c15163](https://github.com/unraid/api/commit/8c15163b3b072122bff1f8f25de62594b1e67992))
|
||||
* add environment to docker-compose ([2ee4683](https://github.com/unraid/api/commit/2ee46839095e3b8ee287cfe10f29ae9a39dcff68))
|
||||
* add support for expiration in var.ini ([#833](https://github.com/unraid/api/issues/833)) ([0474c2e](https://github.com/unraid/api/commit/0474c2e14fa462d2e1ec6d9a7f974660385d073e))
|
||||
* always show DRA even if disabled ([ab708c0](https://github.com/unraid/api/commit/ab708c0df634e21bf81595412d7de0be3ff7c392))
|
||||
* change sort order of Update/Downgrade ([#754](https://github.com/unraid/api/issues/754)) ([be96b3a](https://github.com/unraid/api/commit/be96b3aac709682a6517fa6e84beb586b9d8bf5c))
|
||||
* check for OS updates via PHP ([#752](https://github.com/unraid/api/issues/752)) ([4496615](https://github.com/unraid/api/commit/44966157b80a51dfe01d927c2af2d010c04becc5))
|
||||
* close log on exit ([d6ede86](https://github.com/unraid/api/commit/d6ede86eca6301342cdf35bf1f9365896b5e5009))
|
||||
* disable account & key actions when unraid-api CORS error ([1d15406](https://github.com/unraid/api/commit/1d1540646a264038ae96f4063c31a40cd048d2f9))
|
||||
* extraOrigins public, remove origin listener ([91f96ba](https://github.com/unraid/api/commit/91f96ba818773d6e71dde1ff52a4c8ec21ba6b5d))
|
||||
* fix codegen ([d0bf5bb](https://github.com/unraid/api/commit/d0bf5bb8197b11f7a250ca5392890184a1dbeff7))
|
||||
* fix exit hook and cleanup docker scripts ([#758](https://github.com/unraid/api/issues/758)) ([a9ff73e](https://github.com/unraid/api/commit/a9ff73e0a04c67e9ec9d5551cf0b1f124be6f381))
|
||||
* fix logging format on start and stop ([c6720c3](https://github.com/unraid/api/commit/c6720c331df055480d2d65b37290f4978fe429da))
|
||||
* improve check for OS updates via PHP ([cde12b2](https://github.com/unraid/api/commit/cde12b247f9bba97644750cd95a2b0db320ca1d9))
|
||||
* local start command ([99b6007](https://github.com/unraid/api/commit/99b6007ba30353084a8bea54cc0e782fcc1bfea4))
|
||||
* log config recreation reason ([f36c72f](https://github.com/unraid/api/commit/f36c72f5ad44b7e41d1726fa181dc2b9f594c72c))
|
||||
* nestjs initial query implementation ([#748](https://github.com/unraid/api/issues/748)) ([075d7f2](https://github.com/unraid/api/commit/075d7f25785bf686779b7fee1d5ea39f09ff3ea8))
|
||||
* new key types in API ([e42f9dc](https://github.com/unraid/api/commit/e42f9dc95be03e8389aac443f2147c07a316d48d))
|
||||
* npm scripts to prevent webgui builds with wrong urls ([279966a](https://github.com/unraid/api/commit/279966afa3c218fbe85bafe91ee40fff2eb59ef2))
|
||||
* patch DefaultPageLayout for web component ([629fec6](https://github.com/unraid/api/commit/629fec64f911131e4ab3810c99028b484ce18b83))
|
||||
* **plg:** WIP extra origins support ([85acaae](https://github.com/unraid/api/commit/85acaaee02dad98eeef8a8c4a09b463e84d593b4))
|
||||
* regTy swapped ([564b25c](https://github.com/unraid/api/commit/564b25cf5ce0a62d40f8d63d44c81e9c8560e0be))
|
||||
* run codegen and update build script ([07512ad](https://github.com/unraid/api/commit/07512adc13ee0d819db45ff6c5c5f58a0ba31141))
|
||||
* server store isOsVersionStable ([b5ee4d4](https://github.com/unraid/api/commit/b5ee4d4ee632a7528e6f5df079cab0cb5ea656eb))
|
||||
* stretch downgrade component buttons ([fa4f63e](https://github.com/unraid/api/commit/fa4f63e8bfca525ccfedb16f19d395bf11a68561))
|
||||
* swap to fragement usage on webcomponent ([42733ab](https://github.com/unraid/api/commit/42733abf6e443516ff715569333422ce80d3b1d2))
|
||||
* **web:** caseModel ([4174d0b](https://github.com/unraid/api/commit/4174d0bf2cac99af5db48e5642e0037d7425c952))
|
||||
* **web:** create script to move build to webgui repo ([92df453](https://github.com/unraid/api/commit/92df453255fed45210d9a192c68bb27d3b0ee981))
|
||||
* **web:** downgrade os web component ([45496ab](https://github.com/unraid/api/commit/45496ab7685d4bbfe591be46489260bac9b03474))
|
||||
* **web:** finalize api cors error & settings field ([e1d9e16](https://github.com/unraid/api/commit/e1d9e16b8e80e0940a0078131ea629559e3238ec))
|
||||
* **web:** guidValidation if new keyfile auto install ([0abb196](https://github.com/unraid/api/commit/0abb196d2c57ead4dca2adb2981ab79cdd1647c4))
|
||||
* **web:** localStorage craftUrl for dev ([e646187](https://github.com/unraid/api/commit/e646187b04548c010cf26c7ae38a82ced6270394))
|
||||
* **web:** refactor generic updateOS with date comparison ([91a753c](https://github.com/unraid/api/commit/91a753cd7018b89d53e9cd2d7c429ce53e291336))
|
||||
* **web:** registration component ui / ux ([717d873](https://github.com/unraid/api/commit/717d8733bd4b8c87b6ae6f1cd66717056c5df876))
|
||||
* **web:** registration replace eligibility docs btn ([b69285f](https://github.com/unraid/api/commit/b69285ff8ca5b896082b5f0e1aeba70f9a2c5129))
|
||||
* **web:** registration too many devices messaging ([1c0b5a3](https://github.com/unraid/api/commit/1c0b5a317aadf6173405770878e6038d4d8b448f))
|
||||
* **web:** start prep for new key type support ([5c5035a](https://github.com/unraid/api/commit/5c5035a5446516999729ddc56d1077ee512f14d3))
|
||||
* **web:** update os create flash backup button ([50ba61c](https://github.com/unraid/api/commit/50ba61cf80b7df2d121962cf4ec4b10952e8eecb))
|
||||
* **web:** WIP key expiration ([24618fe](https://github.com/unraid/api/commit/24618fe09db2109c2eb57ab1655ab0fb7d79fc90))
|
||||
* **web:** WIP registration page UI UX ([559e5b8](https://github.com/unraid/api/commit/559e5b8698d5df80ca57f530a2bf2cb6f01e30c7))
|
||||
* **web:** WIP registration page web component ([bd772a9](https://github.com/unraid/api/commit/bd772a9c97d49b57a0b5a0e6a367c9a4e3732086))
|
||||
* **web:** WIP updateOs callback ([2ad55ed](https://github.com/unraid/api/commit/2ad55ed019155e46d8627ea5c1b82cd5e4351127))
|
||||
* WIP first pass at UpdateOs page replacement component ([3a5d871](https://github.com/unraid/api/commit/3a5d871f1fd054720c3693705484072ff567ff28))
|
||||
* WIP UpdateOs page component ([8e4c36d](https://github.com/unraid/api/commit/8e4c36d38ce4e70307f5d14c953d5103c8b7e8e4))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 6.10 view release notes js ([254d894](https://github.com/unraid/api/commit/254d894f39e512d1b4a0472180cb27090de256a0))
|
||||
* add missing translation keys ([03b506c](https://github.com/unraid/api/commit/03b506cd4e68f23a85bbfd54205322a6a4f93e5b))
|
||||
* add serverName / description to dashboard payload ([9677aff](https://github.com/unraid/api/commit/9677aff1cd0942f36a2845f3f105601c494efd9e))
|
||||
* allow null for the local entry in the myservers cfg ([01157c8](https://github.com/unraid/api/commit/01157c86ea3838ca675d65528a882cf25d0019a6))
|
||||
* azure and gray theme custom colors ([92e552c](https://github.com/unraid/api/commit/92e552c9c7f7804902f18eb2d71f8483671fe048))
|
||||
* codegen on web run ([e2e67c2](https://github.com/unraid/api/commit/e2e67c21067a138d963f5f10760b84cf6a533542))
|
||||
* combinedKnownOrigins in state.php for UPC ([b550eea](https://github.com/unraid/api/commit/b550eeae7077cbdbd6d004506bdc96d04c04bc4c))
|
||||
* Connect settings myservers config parse ([1c1483a](https://github.com/unraid/api/commit/1c1483a5cc506deab9d858dabbb8388c8b1d1ec1))
|
||||
* dateTime system settings ([56ccbff](https://github.com/unraid/api/commit/56ccbff61fb61ab67277100c525b80adf95e9b72))
|
||||
* **deps:** update dependency graphql to v16.8.1 ([bff1b19](https://github.com/unraid/api/commit/bff1b19706bee1e3103e3a0a1d2fceb3154f9bba))
|
||||
* **deps:** update graphql-tools monorepo (major) ([#693](https://github.com/unraid/api/issues/693)) ([3447eb0](https://github.com/unraid/api/commit/3447eb047a1dcd575b88a96bbcef9946aca366a1))
|
||||
* **deps:** update nest monorepo ([#816](https://github.com/unraid/api/issues/816)) ([4af3699](https://github.com/unraid/api/commit/4af36991b8b376f816ed51fd503a66e99675a3e7))
|
||||
* downgrade remove erroneous file_get_contents ([df9c918](https://github.com/unraid/api/commit/df9c91867cf3f7cf6b424a386d7e68bd510ec20f))
|
||||
* exit with process.exit not process.exitcode ([dcb6def](https://github.com/unraid/api/commit/dcb6def1cf3365dca819feed101160c8ad0125dc))
|
||||
* graphQL CORS error detection ([e5ea67f](https://github.com/unraid/api/commit/e5ea67fe5224fd5aaf06e1e63e7efc01974a10ac))
|
||||
* header version thirdPartyDriversDownloading pill ([c2ff31c](https://github.com/unraid/api/commit/c2ff31c672bc30683062c6cefbd5e744a7a2a676))
|
||||
* lint unused param var prefixed ([8d103a9](https://github.com/unraid/api/commit/8d103a9ca89139d7b4f513318a67bcc64c0daa0c))
|
||||
* local container startup commands cleaned up ([6c0ccb2](https://github.com/unraid/api/commit/6c0ccb2b24f98282be4db2e0b2e6362f4a187def))
|
||||
* logrotate not working due to invalid ownership of unraid-api folder ([ec0581a](https://github.com/unraid/api/commit/ec0581abf58a217f698d52d5337f2b312e5a645b))
|
||||
* missing translation ([81a9380](https://github.com/unraid/api/commit/81a93802993e7d95fb587cbfe3b598136a89348b))
|
||||
* optional check on api.version to allow fallback to save value ([0ac4455](https://github.com/unraid/api/commit/0ac4455f78407eca7aa1d6ee360830067a1c5c3e))
|
||||
* patch ShowChanges.php in 6.10 ([92d09c2](https://github.com/unraid/api/commit/92d09c2846c1bf64276e140c4cf4635e8bbfa94b))
|
||||
* plg installer header version replacement ([7d0de2c](https://github.com/unraid/api/commit/7d0de2c8b3dc3c2d3c204e7846cf65d6df07545f))
|
||||
* plg remove reboot-details path ([d54d90e](https://github.com/unraid/api/commit/d54d90ec04c67ee532cbcb77c4c5890545899e5a))
|
||||
* **plg:** Downgrade & Update page file locations ([3fbb6b7](https://github.com/unraid/api/commit/3fbb6b70c1152d0691f3d74298908338e19cda53))
|
||||
* **plg:** third party reboot detection ([f0ee640](https://github.com/unraid/api/commit/f0ee640767e446a829fd2e60033560786e5f63b0))
|
||||
* plugin install should suppress output from `unraid-api stop` ([#757](https://github.com/unraid/api/issues/757)) ([3da5d95](https://github.com/unraid/api/commit/3da5d9573b499c84c25e33b26a2014e79bef40f7))
|
||||
* rearrange exit hook to try to fix closing ([843d3f4](https://github.com/unraid/api/commit/843d3f41162c5dbcfd7803912b1879d7a182231a))
|
||||
* refreshServerState check regExp ([7fca971](https://github.com/unraid/api/commit/7fca971cab40b6e5493e7e21baf85e3d6ba66b90))
|
||||
* remove var_dump Connect settings ([9425f8b](https://github.com/unraid/api/commit/9425f8b133d44ac759d09158eadd13c81e7796fb))
|
||||
* renew callback messaging in modal ([e98d065](https://github.com/unraid/api/commit/e98d0654237b111cf912eb5014dbcc5da0e92ca3))
|
||||
* replaceRenew response cache use & purge ([ca85199](https://github.com/unraid/api/commit/ca851991ecb09720d70135d302aa93ad10a96d3a))
|
||||
* set sha in test step as well. ([8af3367](https://github.com/unraid/api/commit/8af3367226f9a3bc51db65ffe5dd53d6c5aa0017))
|
||||
* state php version checking ([494f5e9](https://github.com/unraid/api/commit/494f5e9935bc207b81098e84a0fe3e259939cf39))
|
||||
* stop using username to determine reg status ([c5a6cd7](https://github.com/unraid/api/commit/c5a6cd7bf930d8bc94ccae45f5363c12fd1fccfc))
|
||||
* ThirdPartyDriver messaging on Update page ([f23ad76](https://github.com/unraid/api/commit/f23ad762c04c3da918429a376146fe096a5030d5))
|
||||
* try to set environment in docker build ([caece63](https://github.com/unraid/api/commit/caece63e7f180f94a7ee6b962c905296c6b987bb))
|
||||
* uninstall reboot-details include ([3849462](https://github.com/unraid/api/commit/3849462f572659a43157a49511075f2d8cd5dd4c))
|
||||
* unraid-api server state refresh after key extension use regExp ([490595f](https://github.com/unraid/api/commit/490595f9b420054e6c2fe40d868b902b262718af))
|
||||
* updateOs auth group usage ([52b1ad9](https://github.com/unraid/api/commit/52b1ad9a7d3c9cdc989dd729d7828b0678349c27))
|
||||
* updateOs type check ([ba230e2](https://github.com/unraid/api/commit/ba230e2643399fbfa1612059f235ccdf61f7f486))
|
||||
* web component translations class ([6c81f6f](https://github.com/unraid/api/commit/6c81f6f70dcbe4f055a0041863fe275d6e01d6b9))
|
||||
* **web:** azure & gray theme header font colors ([8a5c7c9](https://github.com/unraid/api/commit/8a5c7c9304a063b26d7ff2df5c174aa9f1c0f53c))
|
||||
* **web:** card wrapper error border styles ([c71f420](https://github.com/unraid/api/commit/c71f420a4c9f7325127e3f38157dbc6255b3e139))
|
||||
* **web:** connect graph error handling ([c239937](https://github.com/unraid/api/commit/c239937c407cfea0defde1994809a5c0a196cca2))
|
||||
* **web:** default time format include am/pm ([31694cd](https://github.com/unraid/api/commit/31694cd7141e2ec0b0c3b4e4480d34d19c80adae))
|
||||
* **web:** downgrade status pill for no downgrade available ([9d9ebb1](https://github.com/unraid/api/commit/9d9ebb1c6efd486a90dcd78ba63766e24be26d55))
|
||||
* **web:** downgrade-not-available when downgrade initiated ([d060359](https://github.com/unraid/api/commit/d0603592596a3173889e9d06d57cfaa602eb80bb))
|
||||
* **web:** installPlugin composable for os updates ([9fb024a](https://github.com/unraid/api/commit/9fb024a68d65905e5351cfa71ca64cdffa0fa74c))
|
||||
* **web:** lint fixes ([224d637](https://github.com/unraid/api/commit/224d63773d505b8d65c9455fb94260ae617d9fe5))
|
||||
* **web:** localStorage craftUrl for dev ([2e108da](https://github.com/unraid/api/commit/2e108da0db7de01d03ee3b0657a614355a61b208))
|
||||
* **web:** missing translation ([74a8f27](https://github.com/unraid/api/commit/74a8f27643d7ba9c9d5dcd6a43b189a936dae648))
|
||||
* **web:** missing translation for update ([cb46a94](https://github.com/unraid/api/commit/cb46a94c7238bf381fbfc48109b1dd648d2e4949))
|
||||
* **web:** missing translations ([8ea733b](https://github.com/unraid/api/commit/8ea733b295a5f3bd922e867f544e5538873a5088))
|
||||
* **web:** missing translations ([d2eed92](https://github.com/unraid/api/commit/d2eed9291de9297aa0d556f06b9b8f5f09734250))
|
||||
* **web:** no plugin, don't show restart api button ([e628a8b](https://github.com/unraid/api/commit/e628a8b64fab4d1a5ce84af62abde3cd4c53ba96))
|
||||
* **web:** preview and test releases usage ([4b8cfb4](https://github.com/unraid/api/commit/4b8cfb464e8296ce20d6ff3870949d739a86ca1b))
|
||||
* **web:** reboot required disable update check link ([f029652](https://github.com/unraid/api/commit/f0296528bae52227ecbe281786ddf4d3a0cc940f))
|
||||
* **web:** reg component conditional keyActions ([730dff2](https://github.com/unraid/api/commit/730dff2e6344f7ee076e1c67d82ef0783a5931b2))
|
||||
* **web:** Registration key actions ([f7b1016](https://github.com/unraid/api/commit/f7b1016980c3f576b007a1d01184bf35f0eef311))
|
||||
* **web:** regTy on account payload ([64b0b5e](https://github.com/unraid/api/commit/64b0b5eb5767d41012f6bcb9536030ec39e45af9))
|
||||
* **web:** regUpdatesExpired use .isAfter ([5d67adf](https://github.com/unraid/api/commit/5d67adf4625a108e3374eb72714cdc1747b2a9c5))
|
||||
* **web:** replace check request error handling ([c1491fe](https://github.com/unraid/api/commit/c1491fecdc327d78f8de7c0f04fda481fb47cb56))
|
||||
* **web:** replaceCheck type ([1bd9729](https://github.com/unraid/api/commit/1bd9729b0197b49ca460912bbc56cd3b206d00dc))
|
||||
* **web:** replaceCheck type ([8cc6020](https://github.com/unraid/api/commit/8cc602019a2c8a718b59590d166644a1cb4d16cc))
|
||||
* **web:** state $_SESSION usage ([412392d](https://github.com/unraid/api/commit/412392dc1c5e612199e76ee7e1cae03705957e3d))
|
||||
* **web:** state php warnings ([1460cab](https://github.com/unraid/api/commit/1460cabe6b041f9f9fb89ca474a7d7e872d31c39))
|
||||
* **web:** translation ([cc85a49](https://github.com/unraid/api/commit/cc85a4903178999dbb80da50aa3b02ff38012172))
|
||||
* **web:** type errors ([e6c57eb](https://github.com/unraid/api/commit/e6c57eb910a1c1f948a3104c4e7fc04ac8b2d327))
|
||||
* **web:** upc dropdown updates external icon ([13936bb](https://github.com/unraid/api/commit/13936bb157f9097a19c7498fce252f3f86526ccb))
|
||||
* **web:** update CallbackButton import ([eabfeca](https://github.com/unraid/api/commit/eabfeca618d3bf682a331c6d9e1f17b5facdcdca))
|
||||
* **web:** Update OS auto redirect loop with account ([9b56fc3](https://github.com/unraid/api/commit/9b56fc3883f51942de9b1c8d1d1f30595fee7fa5))
|
||||
* **web:** updateOs lint ([bd9e9d5](https://github.com/unraid/api/commit/bd9e9d55cc7bba432f65d78feee83526dbfff059))
|
||||
* **web:** use dateTime format from server ([7090f38](https://github.com/unraid/api/commit/7090f38a9ab8b2d1dfce4095f4e2669d4d78a3e1))
|
||||
|
||||
### [3.2.3](https://github.com/unraid/api/compare/v3.2.2...v3.2.3) (2023-09-08)
|
||||
|
||||
|
||||
@@ -3168,4 +4153,4 @@ All notable changes to this project will be documented in this file. See [standa
|
||||
|
||||
# Changelog
|
||||
|
||||
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
||||
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
||||
|
||||
@@ -1,39 +1,31 @@
|
||||
###########################################################
|
||||
# Development/Build Image
|
||||
###########################################################
|
||||
FROM node:18.17.1-alpine As development
|
||||
FROM node:20-bookworm-slim AS development
|
||||
|
||||
# Install build tools and dependencies
|
||||
RUN apk add --no-cache \
|
||||
RUN apt-get update -y && apt-get install -y \
|
||||
bash \
|
||||
# Real PS Command (needed for some dependencies)
|
||||
procps \
|
||||
alpine-sdk \
|
||||
python3 \
|
||||
libvirt-dev \
|
||||
jq \
|
||||
zstd
|
||||
|
||||
RUN mkdir /var/log/unraid-api/
|
||||
zstd \
|
||||
git \
|
||||
build-essential
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Set app env
|
||||
ENV NODE_ENV=development
|
||||
|
||||
# Setup cache for pkg
|
||||
ENV PKG_CACHE_PATH /app/.pkg-cache
|
||||
RUN mkdir -p ${PKG_CACHE_PATH}
|
||||
|
||||
COPY tsconfig.json tsup.config.ts .eslintrc.cjs .npmrc .env.production .env.staging ./
|
||||
COPY tsconfig.json .eslintrc.ts .prettierrc.cjs .npmrc .env.production .env.staging ./
|
||||
|
||||
COPY package.json package-lock.json ./
|
||||
|
||||
# Install pkg
|
||||
RUN npm i -g pkg zx
|
||||
|
||||
# Install deps
|
||||
RUN npm ci
|
||||
RUN npm i
|
||||
|
||||
EXPOSE 4000
|
||||
|
||||
@@ -43,6 +35,8 @@ EXPOSE 4000
|
||||
|
||||
FROM development AS builder
|
||||
|
||||
ENV NODE_ENV=production
|
||||
|
||||
COPY . .
|
||||
|
||||
CMD ["npm", "run", "build-pkg"]
|
||||
CMD ["npm", "run", "build-and-pack"]
|
||||
76
api/README.md
Normal file
76
api/README.md
Normal file
@@ -0,0 +1,76 @@
|
||||
# @unraid/api
|
||||
|
||||
## Installation
|
||||
|
||||
Install the production plugin via the apps tab (search for "Unraid Connect")
|
||||
|
||||
Manual install can be done with the following routes:
|
||||
[production](https://stable.dl.unraid.net/unraid-api/dynamix.unraid.net.plg)
|
||||
[staging](https://preview.dl.unraid.net/unraid-api/dynamix.unraid.net.staging.plg)
|
||||
|
||||
## CLI
|
||||
|
||||
If you're on a unraid v6.9.2 or later machine this should be available by running `unraid-api` in any directory.
|
||||
|
||||
```bash
|
||||
root@Devon:~# unraid-api
|
||||
|
||||
Unraid API
|
||||
|
||||
Thanks for using the official Unraid API
|
||||
|
||||
Usage:
|
||||
|
||||
$ unraid-api command <options>
|
||||
|
||||
Commands:
|
||||
|
||||
start/stop/restart/version/status/report/switch-env
|
||||
|
||||
Options:
|
||||
|
||||
-h, --help Prints this usage guide.
|
||||
-d, --debug Enabled debug mode.
|
||||
-p, --port string Set the graphql port.
|
||||
--environment production/staging/development Set the working environment.
|
||||
--log-level ALL/TRACE/DEBUG/INFO/WARN/ERROR/FATAL/MARK/OFF Set the log level.
|
||||
|
||||
Copyright © 2024 Lime Technology, Inc.
|
||||
|
||||
```
|
||||
|
||||
## Key
|
||||
|
||||
To create and work with Unraid API keys, used for the local API, run the following command to view all available options. These options may change over time.
|
||||
|
||||
```sh
|
||||
unraid-api key --help
|
||||
```
|
||||
|
||||
## Report
|
||||
|
||||
To view the current status of the unraid-api and its connection to mothership, run:
|
||||
|
||||
```sh
|
||||
unraid-api report
|
||||
```
|
||||
|
||||
To view verbose data (anonymized), run:
|
||||
|
||||
```sh
|
||||
unraid-api report -v
|
||||
```
|
||||
|
||||
To view non-anonymized verbose data, run:
|
||||
|
||||
```sh
|
||||
unraid-api report -vv
|
||||
```
|
||||
|
||||
## Secrets
|
||||
|
||||
If you found this file you're likely a developer. If you'd like to know more about the API and when it's available please join [our discord](https://discord.unraid.net/).
|
||||
|
||||
## License
|
||||
|
||||
Copyright Lime Technology Inc. All rights reserved.
|
||||
105
api/codegen.ts
Normal file
105
api/codegen.ts
Normal file
@@ -0,0 +1,105 @@
|
||||
import type { CodegenConfig } from '@graphql-codegen/cli';
|
||||
|
||||
const config: CodegenConfig = {
|
||||
overwrite: true,
|
||||
emitLegacyCommonJSImports: false,
|
||||
verbose: true,
|
||||
config: {
|
||||
namingConvention: {
|
||||
typeNames: './fix-array-type.cjs',
|
||||
enumValues: 'change-case#upperCase',
|
||||
useTypeImports: true,
|
||||
},
|
||||
scalars: {
|
||||
DateTime: 'string',
|
||||
Long: 'number',
|
||||
JSON: '{ [key: string]: any }',
|
||||
URL: 'URL',
|
||||
Port: 'number',
|
||||
UUID: 'string',
|
||||
},
|
||||
},
|
||||
generates: {
|
||||
'src/graphql/generated/client/': {
|
||||
documents: './src/graphql/mothership/*.ts',
|
||||
schema: {
|
||||
[process.env.MOTHERSHIP_GRAPHQL_LINK as string]: {
|
||||
headers: {
|
||||
origin: 'https://forums.unraid.net',
|
||||
},
|
||||
},
|
||||
},
|
||||
preset: 'client',
|
||||
presetConfig: {
|
||||
gqlTagName: 'graphql',
|
||||
},
|
||||
config: {
|
||||
useTypeImports: true,
|
||||
withObjectType: true,
|
||||
},
|
||||
plugins: [
|
||||
{ add: { content: '/* eslint-disable */' } },
|
||||
],
|
||||
},
|
||||
// Generate Types for the API Server
|
||||
'src/graphql/generated/api/types.ts': {
|
||||
schema: [
|
||||
'./src/graphql/types.ts',
|
||||
'./src/graphql/schema/types/**/*.graphql',
|
||||
],
|
||||
plugins: [
|
||||
'typescript',
|
||||
'typescript-resolvers',
|
||||
{ add: { content: '/* eslint-disable */' } },
|
||||
],
|
||||
config: {
|
||||
contextType: '@app/graphql/schema/utils#Context',
|
||||
useIndexSignature: true,
|
||||
},
|
||||
},
|
||||
// Generate Operations for any built-in API Server Operations (e.g., report.ts)
|
||||
'src/graphql/generated/api/operations.ts': {
|
||||
documents: './src/graphql/client/api/*.ts',
|
||||
schema: [
|
||||
'./src/graphql/types.ts',
|
||||
'./src/graphql/schema/types/**/*.graphql',
|
||||
],
|
||||
preset: 'import-types',
|
||||
presetConfig: {
|
||||
typesPath: '@app/graphql/generated/api/types',
|
||||
},
|
||||
plugins: [
|
||||
'typescript-validation-schema',
|
||||
'typescript-operations',
|
||||
'typed-document-node',
|
||||
{ add: { content: '/* eslint-disable */' } },
|
||||
],
|
||||
config: {
|
||||
importFrom: '@app/graphql/generated/api/types',
|
||||
strictScalars: false,
|
||||
schema: 'zod',
|
||||
withObjectType: true,
|
||||
},
|
||||
},
|
||||
'src/graphql/generated/client/validators.ts': {
|
||||
schema: {
|
||||
[process.env.MOTHERSHIP_GRAPHQL_LINK as string]: {
|
||||
headers: {
|
||||
origin: 'https://forums.unraid.net',
|
||||
},
|
||||
},
|
||||
},
|
||||
plugins: [
|
||||
'typescript-validation-schema',
|
||||
{ add: { content: '/* eslint-disable */' } },
|
||||
],
|
||||
config: {
|
||||
importFrom: '@app/graphql/generated/client/graphql',
|
||||
strictScalars: false,
|
||||
schema: 'zod',
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default config;
|
||||
@@ -1,77 +0,0 @@
|
||||
overwrite: true
|
||||
emitLegacyCommonJSImports: false
|
||||
verbose: true
|
||||
require:
|
||||
- ts-node/register
|
||||
config:
|
||||
namingConvention:
|
||||
typeNames: './fix-array-type.cjs'
|
||||
enumValues: 'change-case#upperCase'
|
||||
useTypeImports: true
|
||||
scalars:
|
||||
DateTime: string
|
||||
Long: number
|
||||
JSON: "{ [key: string]: any }"
|
||||
URL: URL
|
||||
Port: number
|
||||
UUID: string
|
||||
|
||||
generates:
|
||||
src/graphql/generated/client/:
|
||||
documents: './src/graphql/mothership/*.ts'
|
||||
schema:
|
||||
'${MOTHERSHIP_GRAPHQL_LINK}':
|
||||
headers:
|
||||
origin: 'https://forums.unraid.net'
|
||||
preset: client
|
||||
presetConfig:
|
||||
gqlTagName: graphql
|
||||
config:
|
||||
useTypeImports: true
|
||||
withObjectType: true
|
||||
plugins:
|
||||
- add: { content: '/* eslint-disable */' }
|
||||
|
||||
# Generate Types for the API Server
|
||||
src/graphql/generated/api/types.ts:
|
||||
schema:
|
||||
- './src/graphql/types.ts'
|
||||
- './src/graphql/schema/types/**/*.graphql'
|
||||
plugins:
|
||||
- typescript
|
||||
- typescript-resolvers
|
||||
- add: { content: '/* eslint-disable */' }
|
||||
config:
|
||||
contextType: '@app/graphql/schema/utils#Context'
|
||||
useIndexSignature: true
|
||||
# Generate Operations for any built in API Server Operations (ie report.ts)
|
||||
src/graphql/generated/api/operations.ts:
|
||||
documents: './src/graphql/client/api/*.ts'
|
||||
schema:
|
||||
- './src/graphql/types.ts'
|
||||
- './src/graphql/schema/types/**/*.graphql'
|
||||
preset: import-types
|
||||
presetConfig:
|
||||
typesPath: '@app/graphql/generated/api/types'
|
||||
plugins:
|
||||
- typescript-validation-schema
|
||||
- typescript-operations
|
||||
- typed-document-node
|
||||
- add: { content: '/* eslint-disable */' }
|
||||
config:
|
||||
importFrom: '@app/graphql/generated/api/types'
|
||||
strictScalars: false
|
||||
schema: 'zod'
|
||||
withObjectType: true
|
||||
src/graphql/generated/client/validators.ts:
|
||||
schema:
|
||||
'${MOTHERSHIP_GRAPHQL_LINK}':
|
||||
headers:
|
||||
origin: 'https://forums.unraid.net'
|
||||
plugins:
|
||||
- typescript-validation-schema
|
||||
- add: { content: '/* eslint-disable */'}
|
||||
config:
|
||||
importFrom: '@app/graphql/generated/client/graphql'
|
||||
strictScalars: false
|
||||
schema: 'zod'
|
||||
@@ -1,19 +1,20 @@
|
||||
[api]
|
||||
version="3.1.1+8efc0992"
|
||||
version="3.11.0"
|
||||
extraOrigins="https://google.com,https://test.com"
|
||||
[local]
|
||||
[notifier]
|
||||
apikey="unnotify_30994bfaccf839c65bae75f7fa12dd5ee16e69389f754c3b98ed7d5"
|
||||
sandbox="yes"
|
||||
[remote]
|
||||
wanaccess="yes"
|
||||
wanport="8443"
|
||||
upnpEnabled="no"
|
||||
apikey="_______________________BIG_API_KEY_HERE_________________________"
|
||||
localApiKey="_______________________LOCAL_API_KEY_HERE_________________________"
|
||||
email="test@example.com"
|
||||
username="zspearmint"
|
||||
avatar="https://via.placeholder.com/200"
|
||||
regWizTime="1611175408732_0951-1653-3509-FBA155FA23C0"
|
||||
idtoken=""
|
||||
accesstoken=""
|
||||
idtoken=""
|
||||
refreshtoken=""
|
||||
[upc]
|
||||
apikey="unupc_fab6ff6ffe51040595c6d9ffb63a353ba16cc2ad7d93f813a2e80a5810"
|
||||
dynamicRemoteAccessType="DISABLED"
|
||||
ssoSubIds=""
|
||||
|
||||
@@ -1,191 +0,0 @@
|
||||
{
|
||||
"admin": {
|
||||
"extends": "user",
|
||||
"permissions": [
|
||||
{
|
||||
"resource": "apikey",
|
||||
"action": "read:any",
|
||||
"attributes": "*"
|
||||
},
|
||||
{
|
||||
"resource": "array",
|
||||
"action": "read:any",
|
||||
"attributes": "*"
|
||||
},
|
||||
{
|
||||
"resource": "cpu",
|
||||
"action": "read:any",
|
||||
"attributes": "*"
|
||||
},
|
||||
{
|
||||
"resource": "device",
|
||||
"action": "read:any",
|
||||
"attributes": "*"
|
||||
},
|
||||
{
|
||||
"resource": "device/unassigned",
|
||||
"action": "read:any",
|
||||
"attributes": "*"
|
||||
},
|
||||
{
|
||||
"resource": "disk",
|
||||
"action": "read:any",
|
||||
"attributes": "*"
|
||||
},
|
||||
{
|
||||
"resource": "disk/settings",
|
||||
"action": "read:any",
|
||||
"attributes": "*"
|
||||
},
|
||||
{
|
||||
"resource": "display",
|
||||
"action": "read:any",
|
||||
"attributes": "*"
|
||||
},
|
||||
{
|
||||
"resource": "docker/container",
|
||||
"action": "read:any",
|
||||
"attributes": "*"
|
||||
},
|
||||
{
|
||||
"resource": "docker/network",
|
||||
"action": "read:any",
|
||||
"attributes": "*"
|
||||
},
|
||||
{
|
||||
"resource": "info",
|
||||
"action": "read:any",
|
||||
"attributes": "*"
|
||||
},
|
||||
{
|
||||
"resource": "license-key",
|
||||
"action": "read:any",
|
||||
"attributes": "*"
|
||||
},
|
||||
{
|
||||
"resource": "machine-id",
|
||||
"action": "read:any",
|
||||
"attributes": "*"
|
||||
},
|
||||
{
|
||||
"resource": "memory",
|
||||
"action": "read:any",
|
||||
"attributes": "*"
|
||||
},
|
||||
{
|
||||
"resource": "notifications",
|
||||
"action": "read:any",
|
||||
"attributes": "*"
|
||||
},
|
||||
{
|
||||
"resource": "online",
|
||||
"action": "read:any",
|
||||
"attributes": "*"
|
||||
},
|
||||
{
|
||||
"resource": "os",
|
||||
"action": "read:any",
|
||||
"attributes": "*"
|
||||
},
|
||||
{
|
||||
"resource": "parity-history",
|
||||
"action": "read:any",
|
||||
"attributes": "*"
|
||||
},
|
||||
{
|
||||
"resource": "permission",
|
||||
"action": "read:any",
|
||||
"attributes": "*"
|
||||
},
|
||||
{
|
||||
"resource": "servers",
|
||||
"action": "read:any",
|
||||
"attributes": "*"
|
||||
},
|
||||
{
|
||||
"resource": "service",
|
||||
"action": "read:any",
|
||||
"attributes": "*"
|
||||
},
|
||||
{
|
||||
"resource": "service/emhttpd",
|
||||
"action": "read:any",
|
||||
"attributes": "*"
|
||||
},
|
||||
{
|
||||
"resource": "service/unraid-api",
|
||||
"action": "read:any",
|
||||
"attributes": "*"
|
||||
},
|
||||
{
|
||||
"resource": "services",
|
||||
"action": "read:any",
|
||||
"attributes": "*"
|
||||
},
|
||||
{
|
||||
"resource": "share",
|
||||
"action": "read:any",
|
||||
"attributes": "*"
|
||||
},
|
||||
{
|
||||
"resource": "software-versions",
|
||||
"action": "read:any",
|
||||
"attributes": "*"
|
||||
},
|
||||
{
|
||||
"resource": "unraid-version",
|
||||
"action": "read:any",
|
||||
"attributes": "*"
|
||||
},
|
||||
{
|
||||
"resource": "user",
|
||||
"action": "read:any",
|
||||
"attributes": "*"
|
||||
},
|
||||
{
|
||||
"resource": "var",
|
||||
"action": "read:any",
|
||||
"attributes": "*"
|
||||
},
|
||||
{
|
||||
"resource": "vars",
|
||||
"action": "read:any",
|
||||
"attributes": "*"
|
||||
},
|
||||
{
|
||||
"resource": "vm/domain",
|
||||
"action": "read:any",
|
||||
"attributes": "*"
|
||||
},
|
||||
{
|
||||
"resource": "vm/network",
|
||||
"action": "read:any",
|
||||
"attributes": "*"
|
||||
}
|
||||
]
|
||||
},
|
||||
"user": {
|
||||
"extends": "guest",
|
||||
"permissions": [
|
||||
{
|
||||
"resource": "apikey",
|
||||
"action": "read:own",
|
||||
"attributes": "*"
|
||||
},
|
||||
{
|
||||
"resource": "permission",
|
||||
"action": "read:any",
|
||||
"attributes": "*"
|
||||
}
|
||||
]
|
||||
},
|
||||
"guest": {
|
||||
"permissions": [
|
||||
{
|
||||
"resource": "welcome",
|
||||
"action": "read:any",
|
||||
"attributes": "*"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
80
api/dev/dynamix/default.cfg
Normal file
80
api/dev/dynamix/default.cfg
Normal file
@@ -0,0 +1,80 @@
|
||||
[confirm]
|
||||
down="1"
|
||||
stop="1"
|
||||
[display]
|
||||
width=""
|
||||
font=""
|
||||
tty="15"
|
||||
date="%c"
|
||||
time="%R"
|
||||
number=".,"
|
||||
unit="C"
|
||||
scale="-1"
|
||||
resize="0"
|
||||
wwn="0"
|
||||
total="1"
|
||||
banner=""
|
||||
header=""
|
||||
background=""
|
||||
tabs="1"
|
||||
users="Tasks:3"
|
||||
usage="0"
|
||||
text="1"
|
||||
warning="70"
|
||||
critical="90"
|
||||
hot="45"
|
||||
max="55"
|
||||
hotssd="60"
|
||||
maxssd="70"
|
||||
power=""
|
||||
theme="white"
|
||||
locale=""
|
||||
raw=""
|
||||
rtl=""
|
||||
headermetacolor=""
|
||||
headerdescription="yes"
|
||||
showBannerGradient="yes"
|
||||
[parity]
|
||||
mode="0"
|
||||
hour="0 0"
|
||||
dotm="1"
|
||||
month="1"
|
||||
day="0"
|
||||
cron=""
|
||||
write="NOCORRECT"
|
||||
[notify]
|
||||
display="0"
|
||||
life="5"
|
||||
date="d-m-Y"
|
||||
time="H:i"
|
||||
position="top-right"
|
||||
path="/tmp/notifications"
|
||||
system="*/1 * * * *"
|
||||
entity="1"
|
||||
normal="1"
|
||||
warning="1"
|
||||
alert="1"
|
||||
unraid="1"
|
||||
plugin="1"
|
||||
docker_notify="1"
|
||||
language_notify="1"
|
||||
report="1"
|
||||
unraidos=""
|
||||
version=""
|
||||
docker_update=""
|
||||
language_update=""
|
||||
status=""
|
||||
[ssmtp]
|
||||
root=""
|
||||
RcptTo=""
|
||||
SetEmailPriority="True"
|
||||
Subject="Unraid Status: "
|
||||
server="smtp.gmail.com"
|
||||
port="465"
|
||||
UseTLS="YES"
|
||||
UseSTARTTLS="NO"
|
||||
UseTLSCert="NO"
|
||||
TLSCert=""
|
||||
AuthMethod="login"
|
||||
AuthUser=""
|
||||
AuthPass=""
|
||||
@@ -1,5 +1,6 @@
|
||||
[display]
|
||||
date="%c"
|
||||
time="%I:%M %p"
|
||||
number=".,"
|
||||
scale="-1"
|
||||
tabs="1"
|
||||
|
||||
11
api/dev/keys/b5b4aa3d-8e40-4c92-bc40-d50182071886.json
Normal file
11
api/dev/keys/b5b4aa3d-8e40-4c92-bc40-d50182071886.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"createdAt": "2025-01-27T16:22:56.501Z",
|
||||
"description": "API key for Connect user",
|
||||
"id": "b5b4aa3d-8e40-4c92-bc40-d50182071886",
|
||||
"key": "_______________________LOCAL_API_KEY_HERE_________________________",
|
||||
"name": "Connect",
|
||||
"permissions": [],
|
||||
"roles": [
|
||||
"connect"
|
||||
]
|
||||
}
|
||||
@@ -3,3 +3,4 @@ event=Unraid Parity check
|
||||
subject=Notice [UNRAID] - Parity check finished (0 errors)
|
||||
description=Canceled
|
||||
importance=warning
|
||||
link=/
|
||||
|
||||
1
api/dev/sessions/sess_mockusersession
Normal file
1
api/dev/sessions/sess_mockusersession
Normal file
@@ -0,0 +1 @@
|
||||
unraid_login|i:1736523078;unraid_user|s:4:"root";locale|s:0:"";buildDate|s:8:"20241202";
|
||||
@@ -1,22 +1,24 @@
|
||||
[api]
|
||||
version="3.1.1+8efc0992"
|
||||
version="3.11.0"
|
||||
extraOrigins="https://google.com,https://test.com"
|
||||
[local]
|
||||
[notifier]
|
||||
apikey="unnotify_30994bfaccf839c65bae75f7fa12dd5ee16e69389f754c3b98ed7d5"
|
||||
sandbox="yes"
|
||||
[remote]
|
||||
wanaccess="yes"
|
||||
wanport="8443"
|
||||
upnpEnabled="no"
|
||||
apikey="_______________________BIG_API_KEY_HERE_________________________"
|
||||
localApiKey="_______________________LOCAL_API_KEY_HERE_________________________"
|
||||
email="test@example.com"
|
||||
username="zspearmint"
|
||||
avatar="https://via.placeholder.com/200"
|
||||
regWizTime="1611175408732_0951-1653-3509-FBA155FA23C0"
|
||||
idtoken=""
|
||||
accesstoken=""
|
||||
idtoken=""
|
||||
refreshtoken=""
|
||||
allowedOrigins="/var/run/unraid-notifications.sock, /var/run/unraid-php.sock, /var/run/unraid-cli.sock, http://localhost:8080, https://localhost:4443, https://tower.local:4443, https://192.168.1.150:4443, https://tower:4443, https://192-168-1-150.thisisfourtyrandomcharacters012345678900.myunraid.net:4443, https://85-121-123-122.thisisfourtyrandomcharacters012345678900.myunraid.net:8443, https://10-252-0-1.hash.myunraid.net:4443, https://10-252-1-1.hash.myunraid.net:4443, https://10-253-3-1.hash.myunraid.net:4443, https://10-253-4-1.hash.myunraid.net:4443, https://10-253-5-1.hash.myunraid.net:4443, https://connect.myunraid.net, https://staging.connect.myunraid.net, https://dev-my.myunraid.net:4000, https://studio.apollographql.com"
|
||||
[upc]
|
||||
apikey="unupc_fab6ff6ffe51040595c6d9ffb63a353ba16cc2ad7d93f813a2e80a5810"
|
||||
dynamicRemoteAccessType="DISABLED"
|
||||
ssoSubIds=""
|
||||
allowedOrigins="/var/run/unraid-notifications.sock, /var/run/unraid-php.sock, /var/run/unraid-cli.sock, http://localhost:8080, https://localhost:4443, https://tower.local:4443, https://192.168.1.150:4443, https://tower:4443, https://192-168-1-150.thisisfourtyrandomcharacters012345678900.myunraid.net:4443, https://85-121-123-122.thisisfourtyrandomcharacters012345678900.myunraid.net:8443, https://10-252-0-1.hash.myunraid.net:4443, https://10-252-1-1.hash.myunraid.net:4443, https://10-253-3-1.hash.myunraid.net:4443, https://10-253-4-1.hash.myunraid.net:4443, https://10-253-5-1.hash.myunraid.net:4443, https://10-100-0-1.hash.myunraid.net:4443, https://10-100-0-2.hash.myunraid.net:4443, https://10-123-1-2.hash.myunraid.net:4443, https://221-123-121-112.hash.myunraid.net:4443, https://google.com, https://test.com, https://connect.myunraid.net, https://connect-staging.myunraid.net, https://dev-my.myunraid.net:4000, https://studio.apollographql.com"
|
||||
[connectionStatus]
|
||||
minigraph="PRE_INIT"
|
||||
upnpStatus=""
|
||||
|
||||
26
api/dev/states/nginx.ini
Normal file
26
api/dev/states/nginx.ini
Normal file
@@ -0,0 +1,26 @@
|
||||
NGINX_LANIP="192.168.1.150"
|
||||
NGINX_LANIP6=""
|
||||
NGINX_LANNAME="Tower"
|
||||
NGINX_LANMDNS="Tower.local"
|
||||
NGINX_CERTPATH="/boot/config/ssl/certs/certificate_bundle.pem"
|
||||
NGINX_USESSL="yes"
|
||||
NGINX_PORT="8080"
|
||||
NGINX_PORTSSL="4443"
|
||||
NGINX_DEFAULTURL="https://Tower.local:4443"
|
||||
NGINX_CERTNAME="*.thisisfourtyrandomcharacters012345678900.myunraid.net"
|
||||
NGINX_LANFQDN="192-168-1-150.thisisfourtyrandomcharacters012345678900.myunraid.net"
|
||||
NGINX_LANFQDN6=""
|
||||
NGINX_WANACCESS=""
|
||||
NGINX_WANIP=""
|
||||
NGINX_WANIP6=""
|
||||
NGINX_WANFQDN="85-121-123-122.thisisfourtyrandomcharacters012345678900.myunraid.net"
|
||||
NGINX_WANFQDN6=""
|
||||
NGINX_WG0FQDN="10-252-0-1.hash.myunraid.net"
|
||||
NGINX_WG1FQDN="10-252-1-1.hash.myunraid.net"
|
||||
NGINX_WG3FQDN="10-253-3-1.hash.myunraid.net"
|
||||
NGINX_WG4FQDN="10-253-4-1.hash.myunraid.net"
|
||||
NGINX_WG55FQDN="10-253-5-1.hash.myunraid.net"
|
||||
NGINX_TAILSCALEFQDN="10-100-0-1.hash.myunraid.net"
|
||||
NGINX_TAILSCALE0FQDN="10-100-0-2.hash.myunraid.net"
|
||||
NGINX_CUSTOMFQDN="10-123-1-2.hash.myunraid.net"
|
||||
NGINX_CUSTOMFQDN6="221-123-121-112.hash.myunraid.net"
|
||||
143
api/dev/states/var.ini
Normal file
143
api/dev/states/var.ini
Normal file
@@ -0,0 +1,143 @@
|
||||
version="6.11.2"
|
||||
MAX_ARRAYSZ="30"
|
||||
MAX_CACHESZ="30"
|
||||
NAME="Tower"
|
||||
timeZone="Australia/Adelaide"
|
||||
COMMENT="Dev Server"
|
||||
SECURITY="user"
|
||||
WORKGROUP="WORKGROUP"
|
||||
DOMAIN=""
|
||||
DOMAIN_SHORT=""
|
||||
hideDotFiles="no"
|
||||
localMaster="yes"
|
||||
enableFruit="no"
|
||||
USE_NETBIOS="yes"
|
||||
USE_WSD="no"
|
||||
WSD_OPT=""
|
||||
USE_NTP="yes"
|
||||
NTP_SERVER1="time1.google.com"
|
||||
NTP_SERVER2="time2.google.com"
|
||||
NTP_SERVER3="time3.google.com"
|
||||
NTP_SERVER4="time4.google.com"
|
||||
DOMAIN_LOGIN="Administrator"
|
||||
SYS_MODEL="Dell R710"
|
||||
SYS_ARRAY_SLOTS="24"
|
||||
SYS_FLASH_SLOTS="1"
|
||||
USE_SSL="auto"
|
||||
PORT="80"
|
||||
PORTSSL="443"
|
||||
LOCAL_TLD="local"
|
||||
BIND_MGT="no"
|
||||
USE_TELNET="yes"
|
||||
PORTTELNET="23"
|
||||
USE_SSH="yes"
|
||||
PORTSSH="22"
|
||||
USE_UPNP="yes"
|
||||
START_PAGE="Main"
|
||||
startArray="no"
|
||||
spindownDelay="0"
|
||||
spinupGroups="no"
|
||||
defaultFsType="xfs"
|
||||
shutdownTimeout="90"
|
||||
luksKeyfile="/tmp/unraid/keyfile"
|
||||
poll_attributes="1800"
|
||||
poll_attributes_default="1800"
|
||||
poll_attributes_status="default"
|
||||
queueDepth="auto"
|
||||
nr_requests="Auto"
|
||||
nr_requests_default="Auto"
|
||||
nr_requests_status="default"
|
||||
md_scheduler="auto"
|
||||
md_scheduler_default="auto"
|
||||
md_scheduler_status="default"
|
||||
md_num_stripes="1280"
|
||||
md_num_stripes_default="1280"
|
||||
md_num_stripes_status="default"
|
||||
md_queue_limit="80"
|
||||
md_queue_limit_default="80"
|
||||
md_queue_limit_status="default"
|
||||
md_sync_limit="5"
|
||||
md_sync_limit_default="5"
|
||||
md_sync_limit_status="default"
|
||||
md_write_method="auto"
|
||||
md_write_method_default="auto"
|
||||
md_write_method_status="default"
|
||||
shareDisk="yes"
|
||||
shareUser="e"
|
||||
shareUserInclude=""
|
||||
shareUserExclude=""
|
||||
shareSMBEnabled="yes"
|
||||
shareNFSEnabled="no"
|
||||
shareInitialOwner="Administrator"
|
||||
shareInitialGroup="Domain Users"
|
||||
shareCacheEnabled="yes"
|
||||
shareCacheFloor="2000000"
|
||||
shareMoverSchedule="40 3 * * *"
|
||||
shareMoverLogging="no"
|
||||
fuse_remember="330"
|
||||
fuse_remember_default="330"
|
||||
fuse_remember_status="default"
|
||||
fuse_directio="auto"
|
||||
fuse_directio_default="auto"
|
||||
fuse_directio_status="default"
|
||||
fuse_useino="yes"
|
||||
shareAvahiEnabled="yes"
|
||||
shareAvahiSMBName="%h"
|
||||
shareAvahiSMBModel="Xserve"
|
||||
shfs_logging="1"
|
||||
safeMode="no"
|
||||
startMode="Normal"
|
||||
configValid="yes"
|
||||
joinStatus="Not joined"
|
||||
deviceCount="4"
|
||||
flashGUID="0000-0000-0000-000000000000"
|
||||
flashProduct="DataTraveler_3.0"
|
||||
flashVendor="KINGSTON"
|
||||
regCheck=""
|
||||
regFILE="/app/dev/Unraid.net/Pro.key"
|
||||
regGUID="13FE-4200-C300-58C372A52B19"
|
||||
regTy="Pro"
|
||||
regTo="Eli Bosley"
|
||||
regTm="1833409182"
|
||||
regTm2="0"
|
||||
regExp=""
|
||||
regGen="0"
|
||||
sbName="/boot/config/super.dat"
|
||||
sbVersion="2.9.13"
|
||||
sbUpdated="1596079143"
|
||||
sbEvents="173"
|
||||
sbState="1"
|
||||
sbClean="yes"
|
||||
sbSynced="1586819259"
|
||||
sbSyncErrs="0"
|
||||
sbSynced2="1586822456"
|
||||
sbSyncExit="0"
|
||||
sbNumDisks="5"
|
||||
mdColor="green-blink"
|
||||
mdNumDisks="4"
|
||||
mdNumDisabled="1"
|
||||
mdNumInvalid="1"
|
||||
mdNumMissing="0"
|
||||
mdNumNew="0"
|
||||
mdNumErased="0"
|
||||
mdResync="0"
|
||||
mdResyncCorr="0"
|
||||
mdResyncPos="0"
|
||||
mdResyncDb="0"
|
||||
mdResyncDt="0"
|
||||
mdResyncAction="check P"
|
||||
mdResyncSize="438960096"
|
||||
mdState="STOPPED"
|
||||
mdVersion="2.9.14"
|
||||
fsState="Stopped"
|
||||
fsProgress="Autostart disabled"
|
||||
fsCopyPrcnt="0"
|
||||
fsNumMounted="0"
|
||||
fsNumUnmountable="0"
|
||||
fsUnmountableMask=""
|
||||
shareCount="0"
|
||||
shareSMBCount="1"
|
||||
shareNFSCount="0"
|
||||
shareMoverActive="no"
|
||||
reservedNames="parity,parity2,parity3,diskP,diskQ,diskR,disk,disks,flash,boot,user,user0,disk0,disk1,disk2,disk3,disk4,disk5,disk6,disk7,disk8,disk9,disk10,disk11,disk12,disk13,disk14,disk15,disk16,disk17,disk18,disk19,disk20,disk21,disk22,disk23,disk24,disk25,disk26,disk27,disk28,disk29,disk30,disk31"
|
||||
csrf_token="0000000000000000"
|
||||
@@ -1,14 +1,10 @@
|
||||
version: '3.8'
|
||||
|
||||
x-volumes: &volumes
|
||||
volumes:
|
||||
- ./dev:/app/dev
|
||||
- ./src:/app/src
|
||||
- ./patches:/app/patches
|
||||
- ./package.json:/app/package.json
|
||||
- ./package-lock.json:/app/package-lock.json
|
||||
- ./tsconfig.json:/app/tsconfig.json
|
||||
- ./tsup.config.ts:/app/tsup.config.ts
|
||||
- ./vite.config.ts:/app/vite.config.ts
|
||||
- ./dist/:/app/dist/
|
||||
- ./deploy/:/app/deploy/
|
||||
@@ -19,19 +15,15 @@ x-volumes: &volumes
|
||||
- ./.env.staging:/app/.env.staging
|
||||
- ./.env.test:/app/.env.test
|
||||
- ./.env.development:/app/.env.development
|
||||
- ./.pkg-cache:/app/.pkg-cache
|
||||
- ./codegen.yml:/app/codegen.yml
|
||||
- ./codegen.ts:/app/codegen.ts
|
||||
- ./fix-array-type.cjs:/app/fix-array-type.cjs
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
- ./unraid-api.js:/app/unraid-api.js
|
||||
- ./ecosystem.config.json:/app/ecosystem.config.json
|
||||
|
||||
|
||||
networks:
|
||||
mothership_default:
|
||||
services:
|
||||
|
||||
dev:
|
||||
networks:
|
||||
- mothership_default
|
||||
image: unraid-api:development
|
||||
ports:
|
||||
- "3001:3001"
|
||||
@@ -45,12 +37,33 @@ services:
|
||||
entrypoint: /bin/bash
|
||||
environment:
|
||||
- IS_DOCKER=true
|
||||
- GIT_SHA=${GIT_SHA:?err}
|
||||
- IS_TAGGED=${IS_TAGGED}
|
||||
profiles:
|
||||
- builder
|
||||
|
||||
local:
|
||||
image: unraid-api:development
|
||||
ports:
|
||||
- "3001:3001"
|
||||
build:
|
||||
context: .
|
||||
target: development
|
||||
dockerfile: Dockerfile
|
||||
<<: *volumes
|
||||
command: npm run start:dev
|
||||
environment:
|
||||
- IS_DOCKER=true
|
||||
- GIT_SHA=${GIT_SHA:?err}
|
||||
- IS_TAGGED=${IS_TAGGED}
|
||||
profiles:
|
||||
- builder
|
||||
|
||||
builder:
|
||||
image: unraid-api:builder
|
||||
environment:
|
||||
- GIT_SHA=${GIT_SHA:?err}
|
||||
- IS_TAGGED=${IS_TAGGED}
|
||||
build:
|
||||
context: .
|
||||
target: builder
|
||||
|
||||
116
api/docs/development.md
Normal file
116
api/docs/development.md
Normal file
@@ -0,0 +1,116 @@
|
||||
# Development
|
||||
|
||||
## Installation
|
||||
|
||||
Manual install can be done with the following routes:
|
||||
[production](https://stable.dl.unraid.net/unraid-api/dynamix.unraid.net.plg)
|
||||
[staging](https://preview.dl.unraid.net/unraid-api/dynamix.unraid.net.staging.plg)
|
||||
|
||||
## Connecting to the API
|
||||
|
||||
### HTTP
|
||||
|
||||
This can be accessed by default via `http://tower.local/graphql`.
|
||||
|
||||
See <https://graphql.org/learn/serving-over-http/#http-methods-headers-and-body>
|
||||
|
||||
## Building in Docker
|
||||
|
||||
To get a development environment for testing start by running this docker command:
|
||||
|
||||
`npm run build:docker`
|
||||
`npm run start:ddev`
|
||||
|
||||
which will give you an interactive shell inside of the newly build linux container.
|
||||
|
||||
To automatically build the plugin run the command below:
|
||||
|
||||
`npm run build:docker`
|
||||
|
||||
The builder command will build the plugin into deploy/release, and the interactive plugin lets you build the plugin or install node modules how you like.
|
||||
|
||||
## Logs
|
||||
|
||||
Logging can be configured via environment variables.
|
||||
|
||||
Log levels can be set when the api starts via `LOG_LEVEL=all/trace/debug/info/warn/error/fatal/mark/off`.
|
||||
|
||||
Additional detail for the log entry can be added with `LOG_CONTEXT=true` (warning, generates a lot of data).
|
||||
|
||||
By default, logs will be sent to syslog. Or you can set `LOG_TRANSPORT=file` to have logs saved in `/var/log/unraid-api/stdout.log`. Or enable debug mode to view logs inline.
|
||||
|
||||
Examples:
|
||||
|
||||
- `unraid-api start`
|
||||
- `LOG_LEVEL=debug unraid-api start --debug`
|
||||
- `LOG_LEVEL=trace LOG_CONTEXT=true LOG_TRANSPORT=file unraid-api start`
|
||||
|
||||
## Viewing data sent to mothership
|
||||
|
||||
If the environment variable `LOG_MOTHERSHIP_MESSAGES=true` exists, any data the unraid-api sends to mothership will be saved in clear text here: `/var/log/unraid-api/relay-messages.log`
|
||||
|
||||
Examples:
|
||||
|
||||
- `LOG_MOTHERSHIP_MESSAGES=true unraid-api start`
|
||||
- `LOG_MOTHERSHIP_MESSAGES=true LOG_LEVEL=debug unraid-api start --debug`
|
||||
|
||||
## Debug Logging
|
||||
|
||||
To view debug logs, change the log level when starting the API. Then type unraid-api logs to trail the logs.
|
||||
Examples:
|
||||
|
||||
- `LOG_LEVEL=debug unraid-api start`
|
||||
- `unraid-api logs`
|
||||
|
||||
## Switching between staging and production environments
|
||||
|
||||
1. Stop the api: `unraid-api stop`
|
||||
2. Switch environments: `unraid-api switch-env`
|
||||
3. Start the api: `unraid-api start`
|
||||
4. Confirm the environment: `unraid-api report`
|
||||
|
||||
## Playground
|
||||
|
||||
The playground can be access via `http://tower.local/graphql` while in debug mode.
|
||||
To get your API key open a terminal on your server and run `cat /boot/config/plugins/dynamix.my.servers/myservers.cfg | grep apikey=\"unraid | cut -d '"' -f2`. Add that API key in the "HTTP headers" panel of the playground.
|
||||
|
||||
```json
|
||||
{
|
||||
"x-api-key": "__REPLACE_ME_WITH_API_KEY__"
|
||||
}
|
||||
```
|
||||
|
||||
Next add the query you want to run and hit the play icon.
|
||||
|
||||
```gql
|
||||
query welcome {
|
||||
welcome {
|
||||
message
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
You should get something like this back.
|
||||
|
||||
```json
|
||||
{
|
||||
"data": {
|
||||
"welcome": {
|
||||
"message": "Welcome root to this Unraid 6.10.0 server"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Click the "Schema" and "Docs" button on the right side of the playground to learn more.
|
||||
|
||||
## Create a new release
|
||||
|
||||
To create a new version run `npm run release` and then run **ONLY** the `git push` section of the commands it returns.
|
||||
To create a new prerelease run `npm run release -- --prerelease alpha`.
|
||||
|
||||
Pushing to this repo will cause an automatic "rolling" release to be built which can be accessed via the page for the associated Github action run.
|
||||
|
||||
## Using a custom version (e.g. testing a new release)
|
||||
|
||||
Find the Pull Request you'd like to install, and a link will be present as a comment to install a PR-specific version.
|
||||
25
api/ecosystem.config.json
Normal file
25
api/ecosystem.config.json
Normal file
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/pm2-ecosystem",
|
||||
"apps": [
|
||||
{
|
||||
"name": "unraid-api",
|
||||
"script": "./dist/main.js",
|
||||
"cwd": "/usr/local/unraid-api",
|
||||
"exec_mode": "fork",
|
||||
"wait_ready": true,
|
||||
"listen_timeout": 15000,
|
||||
"max_restarts": 10,
|
||||
"min_uptime": 10000,
|
||||
"watch": false,
|
||||
"ignore_watch": [
|
||||
"node_modules",
|
||||
"src",
|
||||
".env.*",
|
||||
"myservers.cfg"
|
||||
],
|
||||
"out_file": "/var/log/unraid-api/unraid-api.log",
|
||||
"error_file": "/var/log/unraid-api/unraid-api.error.log",
|
||||
"kill_timeout": 10000
|
||||
}
|
||||
]
|
||||
}
|
||||
21
api/justfile
Normal file
21
api/justfile
Normal file
@@ -0,0 +1,21 @@
|
||||
set fallback
|
||||
|
||||
default:
|
||||
@just --list --justfile {{justfile()}} --list-heading $'\nAPI project recipes:\n'
|
||||
@just list-commands
|
||||
|
||||
setup:
|
||||
npm install
|
||||
npm run container:build
|
||||
|
||||
# builds js files that can run on an unraid server
|
||||
@build:
|
||||
npm run build
|
||||
|
||||
# deploys to an unraid server
|
||||
@deploy:
|
||||
./scripts/deploy-dev.sh
|
||||
|
||||
# build & deploy
|
||||
bd: build deploy
|
||||
|
||||
43956
api/package-lock.json
generated
43956
api/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
384
api/package.json
384
api/package.json
@@ -1,202 +1,190 @@
|
||||
{
|
||||
"name": "@unraid/api",
|
||||
"version": "3.2.3",
|
||||
"main": "dist/index.js",
|
||||
"bin": "dist/unraid-api.cjs",
|
||||
"type": "module",
|
||||
"repository": "git@github.com:unraid/api.git",
|
||||
"author": "Alexis Tyler <xo@wvvw.me> (https://wvvw.me/)",
|
||||
"license": "UNLICENSED",
|
||||
"engines": {
|
||||
"node": ">=16.5.0"
|
||||
},
|
||||
"pkg": {
|
||||
"assets": [
|
||||
"dist/index.cjs",
|
||||
"node_modules/@vmngr/libvirt/build/Release",
|
||||
"node_modules/ts-invariant/",
|
||||
"src/**/*.graphql"
|
||||
"name": "@unraid/api",
|
||||
"version": "4.0.1",
|
||||
"main": "src/cli/index.ts",
|
||||
"type": "module",
|
||||
"repository": "git@github.com:unraid/api.git",
|
||||
"author": "Lime Technology, Inc. <unraid.net>",
|
||||
"license": "UNLICENSED",
|
||||
"scripts": {
|
||||
"start": "node dist/main.js",
|
||||
"build:docker": "./scripts/dc.sh run --rm builder",
|
||||
"build": "vite build --mode=production",
|
||||
"postbuild": "chmod +x dist/main.js && chmod +x dist/cli.js",
|
||||
"build-and-pack": "./scripts/build.mjs",
|
||||
"codegen": "MOTHERSHIP_GRAPHQL_LINK='https://staging.mothership.unraid.net/ws' graphql-codegen --config codegen.ts -r dotenv/config './.env.staging'",
|
||||
"codegen:watch": "DOTENV_CONFIG_PATH='./.env.staging' graphql-codegen --config codegen.ts --watch -r dotenv/config",
|
||||
"codegen:local": "NODE_TLS_REJECT_UNAUTHORIZED=0 MOTHERSHIP_GRAPHQL_LINK='https://mothership.localhost/ws' graphql-codegen --config codegen.ts --watch",
|
||||
"tsc": "tsc --noEmit",
|
||||
"lint": "eslint --config .eslintrc.ts src/",
|
||||
"lint:fix": "eslint --fix --config .eslintrc.ts src/",
|
||||
"test:watch": "vitest --pool=forks",
|
||||
"test": "vitest run --pool=forks",
|
||||
"coverage": "vitest run --pool=forks --coverage",
|
||||
"release": "standard-version",
|
||||
"dev": "vite",
|
||||
"command": "npm run build && clear && ./dist/cli.js",
|
||||
"container:build": "./scripts/dc.sh build dev",
|
||||
"container:start": "./scripts/dc.sh run --rm --service-ports dev",
|
||||
"container:stop": "./scripts/dc.sh stop dev",
|
||||
"container:test": "./scripts/dc.sh run --rm builder npm run test",
|
||||
"container:enter": "./scripts/dc.sh exec dev /bin/bash"
|
||||
},
|
||||
"files": [
|
||||
".env.staging",
|
||||
".env.production",
|
||||
"ecosystem.config.json",
|
||||
"README.md",
|
||||
"src",
|
||||
"node_modules/"
|
||||
],
|
||||
"targets": [
|
||||
"node18-linux-x64"
|
||||
],
|
||||
"outputPath": "dist"
|
||||
},
|
||||
"scripts": {
|
||||
"compile": "tsup --config ./tsup.config.ts",
|
||||
"bundle": "pkg . --public",
|
||||
"build": "npm run compile && npm run bundle",
|
||||
"build:docker": "docker-compose run --rm builder",
|
||||
"build-pkg": "./scripts/build.mjs",
|
||||
"codegen": "MOTHERSHIP_GRAPHQL_LINK='https://staging.mothership.unraid.net/ws' graphql-codegen --config codegen.yml -r dotenv/config './.env.staging'",
|
||||
"codegen:watch": "DOTENV_CONFIG_PATH='./.env.staging' graphql-codegen-esm --config codegen.yml --watch -r dotenv/config",
|
||||
"codegen:local": "MOTHERSHIP_GRAPHQL_LINK='http://localhost:3000/graphql' graphql-codegen-esm --config codegen.yml --watch",
|
||||
"tsc": "tsc --noEmit",
|
||||
"lint": "DEBUG=eslint:cli-engine eslint . --config .eslintrc.cjs",
|
||||
"lint:fix": "DEBUG=eslint:cli-engine eslint . --fix --config .eslintrc.cjs",
|
||||
"test:watch": "vitest --segfault-retry=3 --no-threads",
|
||||
"test": "vitest run --segfault-retry=3 --no-threads",
|
||||
"coverage": "vitest run --segfault-retry=3 --coverage",
|
||||
"patch:subscriptions-transport-ws": "node ./.scripts/patches/subscriptions-transport-ws.cjs",
|
||||
"release": "standard-version",
|
||||
"typesync": "typesync",
|
||||
"install:unraid": "./scripts/install-in-unraid.sh",
|
||||
"start:plugin": "LOG_MOTHERSHIP_MESSAGES=true LOG_TYPE=pretty LOG_LEVEL=trace unraid-api start --debug",
|
||||
"start:plugin-verbose": "LOG_CONTEXT=true LOG_MOTHERSHIP_MESSAGES=true LOG_TYPE=pretty LOG_LEVEL=trace unraid-api start --debug",
|
||||
"start:dev": "LOG_MOTHERSHIP_MESSAGES=true LOG_TYPE=pretty NODE_ENV=development LOG_LEVEL=trace NODE_ENV=development tsup --config ./tsup.config.ts --watch --onSuccess 'DOTENV_CONFIG_PATH=./.env.development node -r dotenv/config dist/unraid-api.cjs start --debug'",
|
||||
"stop:dev": "LOG_MOTHERSHIP_MESSAGES=true LOG_TYPE=pretty NODE_ENV=development LOG_LEVEL=trace NODE_ENV=development tsup --config ./tsup.config.ts --watch --onSuccess 'DOTENV_CONFIG_PATH=./.env.development node -r dotenv/config dist/unraid-api.cjs stop --debug'",
|
||||
"start:report": "LOG_MOTHERSHIP_MESSAGES=true LOG_TYPE=pretty NODE_ENV=development LOG_LEVEL=trace NODE_ENV=development LOG_CONTEXT=true tsup --config ./tsup.config.ts --watch --onSuccess 'DOTENV_CONFIG_PATH=./.env.development node -r dotenv/config dist/unraid-api.cjs report --debug'",
|
||||
"start:docker": "docker compose run --rm builder-interactive",
|
||||
"docker:dev": "docker-compose run --rm --service-ports dev",
|
||||
"docker:test": "docker-compose run --rm builder npm run test"
|
||||
},
|
||||
"files": [
|
||||
".env.staging",
|
||||
".env.production",
|
||||
"dist",
|
||||
"unraid-api"
|
||||
],
|
||||
"dependencies": {
|
||||
"@apollo/client": "^3.7.12",
|
||||
"@apollo/server": "^4.6.0",
|
||||
"@graphql-codegen/client-preset": "^3.0.0",
|
||||
"@graphql-tools/load-files": "^6.6.1",
|
||||
"@graphql-tools/merge": "^8.4.0",
|
||||
"@graphql-tools/schema": "^9.0.17",
|
||||
"@graphql-tools/utils": "^9.2.1",
|
||||
"@reduxjs/toolkit": "^1.9.5",
|
||||
"@reflet/cron": "^1.3.1",
|
||||
"@runonflux/nat-upnp": "^1.0.2",
|
||||
"accesscontrol": "^2.2.1",
|
||||
"am": "github:unraid/am",
|
||||
"async-exit-hook": "^2.0.1",
|
||||
"btoa": "^1.2.1",
|
||||
"bycontract": "^2.0.11",
|
||||
"bytes": "^3.1.2",
|
||||
"cacheable-lookup": "^6.1.0",
|
||||
"catch-exit": "^1.2.2",
|
||||
"chalk": "^4.1.2",
|
||||
"chokidar": "^3.5.3",
|
||||
"cli-table": "^0.3.11",
|
||||
"command-exists": "^1.2.9",
|
||||
"convert": "^4.10.0",
|
||||
"cors": "^2.8.5",
|
||||
"cross-fetch": "^4.0.0",
|
||||
"docker-event-emitter": "^0.3.0",
|
||||
"dockerode": "^3.3.5",
|
||||
"dotenv": "^16.0.3",
|
||||
"express": "^4.18.2",
|
||||
"find-process": "^1.4.7",
|
||||
"graphql": "^16.6.0",
|
||||
"graphql-fields": "^2.0.3",
|
||||
"graphql-scalars": "^1.21.3",
|
||||
"graphql-subscriptions": "^2.0.0",
|
||||
"graphql-tag": "^2.12.6",
|
||||
"graphql-type-json": "^0.3.2",
|
||||
"graphql-type-uuid": "^0.2.0",
|
||||
"graphql-ws": "^5.12.1",
|
||||
"htpasswd-js": "^1.0.2",
|
||||
"ini": "^4.1.0",
|
||||
"ip": "^1.1.8",
|
||||
"jose": "^4.14.2",
|
||||
"lodash": "^4.17.21",
|
||||
"multi-ini": "^2.2.0",
|
||||
"mustache": "^4.2.0",
|
||||
"nanobus": "^4.5.0",
|
||||
"node-cache": "^5.1.2",
|
||||
"node-window-polyfill": "^1.0.2",
|
||||
"openid-client": "^5.4.0",
|
||||
"p-iteration": "^1.1.8",
|
||||
"p-retry": "^4.6.2",
|
||||
"pidusage": "^3.0.2",
|
||||
"reflect-metadata": "^0.1.13",
|
||||
"request": "^2.88.2",
|
||||
"semver": "^7.4.0",
|
||||
"stoppable": "^1.1.0",
|
||||
"subscriptions-transport-ws": "^0.11.0",
|
||||
"systeminformation": "^5.21.2",
|
||||
"ts-command-line-args": "^2.5.0",
|
||||
"uuid": "^9.0.0",
|
||||
"ws": "^8.13.0",
|
||||
"wtfnode": "^0.9.1",
|
||||
"xhr2": "^0.2.1",
|
||||
"zod": "^3.22.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/runtime": "^7.21.0",
|
||||
"@graphql-codegen/add": "^4.0.1",
|
||||
"@graphql-codegen/cli": "^3.3.0",
|
||||
"@graphql-codegen/fragment-matcher": "^4.0.1",
|
||||
"@graphql-codegen/import-types-preset": "^2.2.6",
|
||||
"@graphql-codegen/typed-document-node": "^4.0.0",
|
||||
"@graphql-codegen/typescript": "^3.0.3",
|
||||
"@graphql-codegen/typescript-operations": "^3.0.3",
|
||||
"@graphql-codegen/typescript-resolvers": "3.2.1",
|
||||
"@graphql-typed-document-node/core": "^3.2.0",
|
||||
"@swc/core": "^1.3.81",
|
||||
"@types/async-exit-hook": "^2.0.0",
|
||||
"@types/btoa": "^1.2.3",
|
||||
"@types/bytes": "^3.1.1",
|
||||
"@types/cli-table": "^0.3.1",
|
||||
"@types/command-exists": "^1.2.0",
|
||||
"@types/dockerode": "^3.3.16",
|
||||
"@types/express": "^4.17.17",
|
||||
"@types/graphql-fields": "^1.3.5",
|
||||
"@types/graphql-type-uuid": "^0.2.3",
|
||||
"@types/ini": "^1.3.31",
|
||||
"@types/lodash": "^4.14.192",
|
||||
"@types/mustache": "^4.2.2",
|
||||
"@types/node": "^18.17.12",
|
||||
"@types/pidusage": "^2.0.2",
|
||||
"@types/pify": "^5.0.1",
|
||||
"@types/semver": "^7.3.13",
|
||||
"@types/sendmail": "^1.4.4",
|
||||
"@types/stoppable": "^1.1.1",
|
||||
"@types/uuid": "^9.0.1",
|
||||
"@types/ws": "^8.5.4",
|
||||
"@types/wtfnode": "^0.7.0",
|
||||
"@typescript-eslint/eslint-plugin": "^5.58.0",
|
||||
"@typescript-eslint/parser": "^5.58.0",
|
||||
"@unraid/eslint-config": "github:unraid/eslint-config",
|
||||
"@vitest/coverage-v8": "^0.34.1",
|
||||
"@vitest/ui": "^0.34.0",
|
||||
"camelcase-keys": "^8.0.2",
|
||||
"cz-conventional-changelog": "3.3.0",
|
||||
"eslint": "^8.38.0",
|
||||
"eslint-import-resolver-typescript": "^3.6.0",
|
||||
"eslint-plugin-import": "^2.27.5",
|
||||
"eslint-plugin-prettier": "^5.0.0",
|
||||
"eslint-plugin-unicorn": "^48.0.1",
|
||||
"eslint-plugin-unused-imports": "^2.0.0",
|
||||
"execa": "^7.1.1",
|
||||
"filter-obj": "^5.1.0",
|
||||
"got": "^13.0.0",
|
||||
"graphql-codegen-typescript-validation-schema": "^0.11.0",
|
||||
"ip-regex": "^5.0.0",
|
||||
"json-difference": "^1.9.1",
|
||||
"log4js": "^6.9.1",
|
||||
"map-obj": "^5.0.2",
|
||||
"p-props": "^5.0.0",
|
||||
"path-exists": "^5.0.0",
|
||||
"path-type": "^5.0.0",
|
||||
"pkg": "^5.8.1",
|
||||
"pretty-bytes": "^6.1.0",
|
||||
"pretty-ms": "^8.0.0",
|
||||
"serialize-error": "^11.0.2",
|
||||
"standard-version": "^9.5.0",
|
||||
"tsup": "^7.0.0",
|
||||
"typescript": "^4.9.4",
|
||||
"typesync": "^0.11.0",
|
||||
"vite-tsconfig-paths": "^4.2.0",
|
||||
"vitest": "^0.34.0",
|
||||
"zx": "^7.2.1"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@vmngr/libvirt": "github:unraid/libvirt"
|
||||
},
|
||||
"config": {
|
||||
"commitizen": {
|
||||
"path": "./node_modules/cz-conventional-changelog"
|
||||
"bin": {
|
||||
"unraid-api": "dist/cli.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"@apollo/client": "^3.11.8",
|
||||
"@apollo/server": "^4.11.2",
|
||||
"@as-integrations/fastify": "^2.1.1",
|
||||
"@fastify/cookie": "^9.4.0",
|
||||
"@graphql-codegen/client-preset": "^4.5.0",
|
||||
"@graphql-tools/load-files": "^7.0.0",
|
||||
"@graphql-tools/merge": "^9.0.8",
|
||||
"@graphql-tools/schema": "^10.0.7",
|
||||
"@graphql-tools/utils": "^10.5.5",
|
||||
"@nestjs/apollo": "^12.2.1",
|
||||
"@nestjs/core": "^10.4.7",
|
||||
"@nestjs/graphql": "^12.2.1",
|
||||
"@nestjs/passport": "^10.0.3",
|
||||
"@nestjs/platform-fastify": "^10.4.7",
|
||||
"@nestjs/schedule": "^4.1.1",
|
||||
"@nestjs/throttler": "^6.2.1",
|
||||
"@reduxjs/toolkit": "^2.3.0",
|
||||
"@reflet/cron": "^1.3.1",
|
||||
"@runonflux/nat-upnp": "^1.0.2",
|
||||
"@types/diff": "^7.0.1",
|
||||
"accesscontrol": "^2.2.1",
|
||||
"bycontract": "^2.0.11",
|
||||
"bytes": "^3.1.2",
|
||||
"cacheable-lookup": "^7.0.0",
|
||||
"camelcase-keys": "^9.1.3",
|
||||
"casbin": "^5.32.0",
|
||||
"catch-exit": "^1.2.2",
|
||||
"chokidar": "^4.0.1",
|
||||
"cli-table": "^0.3.11",
|
||||
"command-exists": "^1.2.9",
|
||||
"convert": "^5.5.1",
|
||||
"cookie": "^1.0.2",
|
||||
"cross-fetch": "^4.0.0",
|
||||
"diff": "^7.0.0",
|
||||
"docker-event-emitter": "^0.3.0",
|
||||
"dockerode": "^3.3.5",
|
||||
"dotenv": "^16.4.5",
|
||||
"execa": "^9.5.1",
|
||||
"exit-hook": "^4.0.0",
|
||||
"filenamify": "^6.0.0",
|
||||
"fs-extra": "^11.2.0",
|
||||
"glob": "^11.0.1",
|
||||
"global-agent": "^3.0.0",
|
||||
"got": "^14.4.4",
|
||||
"graphql": "^16.9.0",
|
||||
"graphql-fields": "^2.0.3",
|
||||
"graphql-scalars": "^1.23.0",
|
||||
"graphql-subscriptions": "^2.0.0",
|
||||
"graphql-tag": "^2.12.6",
|
||||
"graphql-type-json": "^0.3.2",
|
||||
"graphql-type-uuid": "^0.2.0",
|
||||
"graphql-ws": "^5.16.0",
|
||||
"ini": "^4.1.2",
|
||||
"ip": "^2.0.1",
|
||||
"jose": "^5.9.6",
|
||||
"lodash-es": "^4.17.21",
|
||||
"multi-ini": "^2.3.2",
|
||||
"mustache": "^4.2.0",
|
||||
"nest-access-control": "^3.1.0",
|
||||
"nest-authz": "^2.11.0",
|
||||
"nest-commander": "^3.15.0",
|
||||
"nestjs-pino": "^4.1.0",
|
||||
"node-cache": "^5.1.2",
|
||||
"node-window-polyfill": "^1.0.2",
|
||||
"p-retry": "^6.2.0",
|
||||
"passport-custom": "^1.1.1",
|
||||
"passport-http-header-strategy": "^1.1.0",
|
||||
"path-type": "^6.0.0",
|
||||
"pino": "^9.5.0",
|
||||
"pino-http": "^10.3.0",
|
||||
"pino-pretty": "^11.3.0",
|
||||
"pm2": "^5.4.2",
|
||||
"reflect-metadata": "^0.1.14",
|
||||
"request": "^2.88.2",
|
||||
"semver": "^7.6.3",
|
||||
"strftime": "^0.10.3",
|
||||
"systeminformation": "^5.25.11",
|
||||
"uuid": "^11.0.2",
|
||||
"ws": "^8.18.0",
|
||||
"zod": "^3.23.8"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@graphql-codegen/add": "^5.0.3",
|
||||
"@graphql-codegen/cli": "^5.0.3",
|
||||
"@graphql-codegen/fragment-matcher": "^5.0.2",
|
||||
"@graphql-codegen/import-types-preset": "^3.0.0",
|
||||
"@graphql-codegen/typed-document-node": "^5.0.11",
|
||||
"@graphql-codegen/typescript": "^4.1.1",
|
||||
"@graphql-codegen/typescript-operations": "^4.3.1",
|
||||
"@graphql-codegen/typescript-resolvers": "4.4.2",
|
||||
"@graphql-typed-document-node/core": "^3.2.0",
|
||||
"@ianvs/prettier-plugin-sort-imports": "^4.4.0",
|
||||
"@nestjs/testing": "^10.4.7",
|
||||
"@originjs/vite-plugin-commonjs": "^1.0.3",
|
||||
"@rollup/plugin-node-resolve": "^15.3.0",
|
||||
"@swc/core": "^1.10.1",
|
||||
"@types/async-exit-hook": "^2.0.2",
|
||||
"@types/bytes": "^3.1.4",
|
||||
"@types/cli-table": "^0.3.4",
|
||||
"@types/command-exists": "^1.2.3",
|
||||
"@types/cors": "^2.8.17",
|
||||
"@types/dockerode": "^3.3.31",
|
||||
"@types/graphql-fields": "^1.3.9",
|
||||
"@types/graphql-type-uuid": "^0.2.6",
|
||||
"@types/ini": "^4.1.1",
|
||||
"@types/ip": "^1.1.3",
|
||||
"@types/lodash": "^4.17.13",
|
||||
"@types/mustache": "^4.2.5",
|
||||
"@types/node": "^22.9.0",
|
||||
"@types/pify": "^5.0.4",
|
||||
"@types/semver": "^7.5.8",
|
||||
"@types/sendmail": "^1.4.7",
|
||||
"@types/stoppable": "^1.1.3",
|
||||
"@types/strftime": "^0.9.8",
|
||||
"@types/uuid": "^10.0.0",
|
||||
"@types/ws": "^8.5.13",
|
||||
"@types/wtfnode": "^0.7.3",
|
||||
"@vitest/coverage-v8": "^2.1.8",
|
||||
"@vitest/ui": "^2.1.4",
|
||||
"cz-conventional-changelog": "3.3.0",
|
||||
"eslint": "^9.14.0",
|
||||
"eslint-plugin-no-relative-import-paths": "^1.6.1",
|
||||
"eslint-plugin-prettier": "^5.2.3",
|
||||
"graphql-codegen-typescript-validation-schema": "^0.17.0",
|
||||
"jiti": "^2.4.0",
|
||||
"nodemon": "^3.1.7",
|
||||
"rollup-plugin-node-externals": "^7.1.3",
|
||||
"standard-version": "^9.5.0",
|
||||
"typescript": "^5.6.3",
|
||||
"typescript-eslint": "^8.13.0",
|
||||
"unplugin-swc": "^1.5.1",
|
||||
"vite": "^5.4.10",
|
||||
"vite-plugin-node": "^4.0.0",
|
||||
"vite-tsconfig-paths": "^5.1.0",
|
||||
"vitest": "^2.1.8",
|
||||
"zx": "^8.2.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@vmngr/libvirt": "github:unraid/libvirt"
|
||||
},
|
||||
"overrides": {
|
||||
"eslint": {
|
||||
"jiti": "2"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,72 +1,105 @@
|
||||
#!/usr/bin/env zx
|
||||
import { cp, mkdir, stat, writeFile } from 'fs/promises';
|
||||
import { exit } from 'process';
|
||||
import { cd, $ } from 'zx';
|
||||
|
||||
import getTags from './get-tags.mjs'
|
||||
import { pathExists } from 'fs-extra';
|
||||
import { $, cd } from 'zx';
|
||||
|
||||
import { getDeploymentVersion } from './get-deployment-version.mjs';
|
||||
|
||||
try {
|
||||
// Enable colours in output
|
||||
process.env.FORCE_COLOR = '1';
|
||||
// Enable colours in output
|
||||
process.env.FORCE_COLOR = '1';
|
||||
|
||||
// Ensure we have the correct working directory
|
||||
process.env.WORKDIR = process.env.WORKDIR ?? process.env.PWD;
|
||||
cd(process.env.WORKDIR);
|
||||
// Ensure we have the correct working directory
|
||||
process.env.WORKDIR ??= process.env.PWD;
|
||||
cd(process.env.WORKDIR);
|
||||
|
||||
// Clean up last deploy
|
||||
await $`rm -rf ./deploy/release`;
|
||||
await $`rm -rf ./deploy/pre-pack`;
|
||||
await $`mkdir -p ./deploy/release/`;
|
||||
await $`mkdir -p ./deploy/pre-pack/`;
|
||||
await $`rm -rf ./deploy/release/*`;
|
||||
await $`rm -rf ./deploy/pre-pack/*`;
|
||||
// Create deployment directories - ignore if they already exist
|
||||
await mkdir('./deploy/release', { recursive: true });
|
||||
await mkdir('./deploy/pre-pack', { recursive: true });
|
||||
|
||||
// Ensure all deps are installed
|
||||
await $`npm i`;
|
||||
// Build Generated Types
|
||||
await $`npm run codegen`;
|
||||
|
||||
// Build Generated Types
|
||||
await $`npm run codegen`;
|
||||
// Build binary
|
||||
await $`npm run build`;
|
||||
await $`npm run build`;
|
||||
// Copy app files to plugin directory
|
||||
await cp('./dist', './deploy/pre-pack/dist', { recursive: true });
|
||||
|
||||
// Copy binary + extra files to deployment directory
|
||||
await $`cp ./dist/api ./deploy/pre-pack/unraid-api`;
|
||||
await $`cp ./.env.production ./deploy/pre-pack/.env.production`;
|
||||
await $`cp ./.env.staging ./deploy/pre-pack/.env.staging`;
|
||||
// Copy environment to deployment directory
|
||||
const files = [
|
||||
'.env.production',
|
||||
'.env.staging',
|
||||
'tsconfig.json',
|
||||
'codegen.ts',
|
||||
'ecosystem.config.json',
|
||||
'vite.config.ts',
|
||||
];
|
||||
|
||||
// Get package details
|
||||
const { name, version } = await import('../package.json', {
|
||||
assert: { type: 'json' },
|
||||
}).then(pkg => pkg.default);
|
||||
for (const file of files) {
|
||||
await cp(`./${file}`, `./deploy/pre-pack/${file}`);
|
||||
}
|
||||
|
||||
const tags = getTags(process.env);
|
||||
|
||||
// Decide whether to use full version or just tag
|
||||
const isTaggedRelease = tags.isTagged;
|
||||
const gitShaShort = tags.shortSha;
|
||||
|
||||
const deploymentVersion = isTaggedRelease ? version : `${version}+${gitShaShort}`;
|
||||
// Get package details
|
||||
const { name, version, devDependencies, ...rest } = await import('../package.json', {
|
||||
assert: { type: 'json' },
|
||||
}).then((pkg) => pkg.default);
|
||||
|
||||
// Create deployment package.json
|
||||
await $`echo ${JSON.stringify({ name, version: deploymentVersion })} > ./deploy/pre-pack/package.json`;
|
||||
const deploymentVersion = getDeploymentVersion(process.env, version);
|
||||
|
||||
// # Create final tgz
|
||||
await $`cp ./README.md ./deploy/pre-pack/`;
|
||||
cd('./deploy/pre-pack');
|
||||
await $`npm pack`;
|
||||
// Create deployment package.json
|
||||
await writeFile(
|
||||
'./deploy/pre-pack/package.json',
|
||||
JSON.stringify(
|
||||
{
|
||||
name,
|
||||
version: deploymentVersion,
|
||||
...rest,
|
||||
},
|
||||
null,
|
||||
2
|
||||
)
|
||||
);
|
||||
// # Create final tgz
|
||||
await cp('./README.md', './deploy/pre-pack/README.md');
|
||||
// Install production dependencies
|
||||
|
||||
// Move unraid-api.tgz to release directory
|
||||
await $`mv unraid-api-${deploymentVersion}.tgz ../release`;
|
||||
console.log('Installing dependencies...');
|
||||
|
||||
// Set API_VERSION output based on this command
|
||||
await $`echo "::set-output name=API_VERSION::${deploymentVersion}"`;
|
||||
$.verbose = true;
|
||||
|
||||
await cd('./deploy/pre-pack');
|
||||
|
||||
await $`npm install --omit=dev`;
|
||||
|
||||
// Ensure that we don't have any dev dependencies left
|
||||
console.log('Installed dependencies:');
|
||||
await $`npm ls --depth=0`;
|
||||
|
||||
console.log('Dependencies installed, packing...');
|
||||
|
||||
// Now we'll pack everything in the pre-pack directory to the release directory
|
||||
const tarballPath = `../release/unraid-api-${deploymentVersion}.tgz`;
|
||||
await $`tar -czf ${tarballPath} .`;
|
||||
// Ensure the tarball exists
|
||||
if (!(await pathExists(tarballPath))) {
|
||||
console.error(`Failed to create tarball at ${tarballPath}`);
|
||||
process.exit(1);
|
||||
}
|
||||
const packageSize = Math.round((await stat(tarballPath)).size / 1024 / 1024);
|
||||
console.log(`Package created at: ${tarballPath} with size ${packageSize} MB`);
|
||||
} catch (error) {
|
||||
// Error with a command
|
||||
if (Object.keys(error).includes('stderr')) {
|
||||
console.log(`Failed building package. Exit code: ${error.exitCode}`);
|
||||
console.log(`Error: ${error.stderr}`);
|
||||
} else {
|
||||
// Normal js error
|
||||
console.log('Failed building package.');
|
||||
console.log(`Error: ${error.message}`);
|
||||
}
|
||||
// Error with a command
|
||||
if (Object.keys(error).includes('stderr')) {
|
||||
console.log(`Failed building package. Exit code: ${error.exitCode}`);
|
||||
console.log(`Error: ${error.stderr}`);
|
||||
} else {
|
||||
// Normal js error
|
||||
console.log('Failed building package.');
|
||||
console.log(`Error: ${error.message}`);
|
||||
}
|
||||
|
||||
exit(error.exitCode);
|
||||
exit(error.exitCode);
|
||||
}
|
||||
|
||||
33
api/scripts/create-session.sh
Executable file
33
api/scripts/create-session.sh
Executable file
@@ -0,0 +1,33 @@
|
||||
# This script creates a mock session on a server.
|
||||
# During local dev/testing, you should run it in the api container,
|
||||
# so the nest.js api can authenticate cookies against it.
|
||||
#
|
||||
# You should also set a cookie named 'unraid_...' whose value matches
|
||||
# the name of the session you created (where name is sess_<name>).
|
||||
# By default, this is my-session
|
||||
|
||||
sessions_dir=/var/lib/php
|
||||
default_session_name=mock-user-session
|
||||
|
||||
if [ "$1" = "--help" ]; then
|
||||
echo "This script creates a mock session on a server."
|
||||
echo ""
|
||||
echo "Usage: $0 [options]"
|
||||
echo ""
|
||||
echo "Options:"
|
||||
echo " [name] Name of the session to create (default: mock-user-session)"
|
||||
echo " --help Display this help message and exit"
|
||||
echo ""
|
||||
echo "Example: $0 a-session-name"
|
||||
echo ""
|
||||
echo "Current list of sessions:"
|
||||
ls $sessions_dir
|
||||
exit 0
|
||||
fi
|
||||
|
||||
session_name="${1:-$default_session_name}"
|
||||
|
||||
mkdir -p $sessions_dir
|
||||
touch "$sessions_dir/sess_$session_name"
|
||||
|
||||
ls $sessions_dir
|
||||
4
api/scripts/dc.sh
Executable file
4
api/scripts/dc.sh
Executable file
@@ -0,0 +1,4 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Pass all entered params after the docker compose call
|
||||
COMPOSE_PROJECT_NAME="connect" GIT_SHA=$(git rev-parse --short HEAD) IS_TAGGED=$(git describe --tags --abbrev=0 --exact-match || echo '') docker compose -f docker-compose.yml "$@"
|
||||
68
api/scripts/deploy-dev.sh
Executable file
68
api/scripts/deploy-dev.sh
Executable file
@@ -0,0 +1,68 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Path to store the last used server name
|
||||
state_file="$HOME/.deploy_state"
|
||||
|
||||
# Read the last used server name from the state file
|
||||
if [[ -f "$state_file" ]]; then
|
||||
last_server_name=$(cat "$state_file")
|
||||
else
|
||||
last_server_name=""
|
||||
fi
|
||||
|
||||
# Read the server name from the command-line argument or use the last used server name as the default
|
||||
server_name="${1:-$last_server_name}"
|
||||
|
||||
# Check if the server name is provided
|
||||
if [[ -z "$server_name" ]]; then
|
||||
echo "Please provide the SSH server name."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Save the current server name to the state file
|
||||
echo "$server_name" > "$state_file"
|
||||
|
||||
# Source directory path
|
||||
source_directory="./dist"
|
||||
|
||||
if [ ! -d "$source_directory" ]; then
|
||||
echo "The dist directory does not exist. Attempting build..."
|
||||
npm run build
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Build failed!"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Change ownership on copy
|
||||
# Replace the value inside the rsync command with the user's input
|
||||
rsync_command="rsync -avz -e ssh $source_directory root@${server_name}:/usr/local/unraid-api"
|
||||
|
||||
echo "Executing the following command:"
|
||||
echo "$rsync_command"
|
||||
|
||||
# Execute the rsync command and capture the exit code
|
||||
eval "$rsync_command"
|
||||
exit_code=$?
|
||||
|
||||
# Chown the directory
|
||||
ssh root@"${server_name}" "chown -R root:root /usr/local/unraid-api"
|
||||
|
||||
# Run unraid-api restart on remote host
|
||||
ssh root@"${server_name}" "INTROSPECTION=true LOG_LEVEL=trace unraid-api restart"
|
||||
|
||||
# Play built-in sound based on the operating system
|
||||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
# macOS
|
||||
afplay /System/Library/Sounds/Glass.aiff
|
||||
elif [[ "$OSTYPE" == "linux-gnu" ]]; then
|
||||
# Linux
|
||||
paplay /usr/share/sounds/freedesktop/stereo/complete.oga
|
||||
elif [[ "$OSTYPE" == "msys" || "$OSTYPE" == "win32" ]]; then
|
||||
# Windows
|
||||
powershell.exe -c "(New-Object Media.SoundPlayer 'C:\Windows\Media\Windows Default.wav').PlaySync()"
|
||||
fi
|
||||
|
||||
# Exit with the rsync command's exit code
|
||||
exit $exit_code
|
||||
|
||||
29
api/scripts/get-deployment-version.mjs
Normal file
29
api/scripts/get-deployment-version.mjs
Normal file
@@ -0,0 +1,29 @@
|
||||
import { execSync } from 'child_process';
|
||||
|
||||
const runCommand = (command) => {
|
||||
try {
|
||||
return execSync(command, { stdio: 'pipe' }).toString().trim();
|
||||
} catch (error) {
|
||||
console.log('Failed to get value from tag command: ', command, error.message);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
export const getDeploymentVersion = (env = process.env, packageVersion) => {
|
||||
if (env.API_VERSION) {
|
||||
console.log(`Using env var for version: ${env.API_VERSION}`);
|
||||
return env.API_VERSION;
|
||||
} else if (env.GIT_SHA && env.IS_TAGGED) {
|
||||
console.log(`Using env vars for git tags: ${env.GIT_SHA} ${env.IS_TAGGED}`);
|
||||
return env.IS_TAGGED ? packageVersion : `${packageVersion}+${env.GIT_SHA}`;
|
||||
} else {
|
||||
const gitShortSHA = runCommand('git rev-parse --short HEAD');
|
||||
const isCommitTagged = runCommand('git describe --tags --abbrev=0 --exact-match') !== undefined;
|
||||
console.log('gitShortSHA', gitShortSHA, 'isCommitTagged', isCommitTagged);
|
||||
if (!gitShortSHA) {
|
||||
console.error('Failed to get git short SHA');
|
||||
process.exit(1);
|
||||
}
|
||||
return isCommitTagged ? packageVersion : `${packageVersion}+${gitShortSHA}`;
|
||||
}
|
||||
};
|
||||
@@ -1,33 +0,0 @@
|
||||
import { execSync } from 'child_process';
|
||||
|
||||
const runCommand = (command) => {
|
||||
try {
|
||||
return execSync(command, { stdio: 'pipe' }).toString().trim();
|
||||
} catch(error) {
|
||||
console.log('Failed to get value from tag command: ', command, error.message);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
const getTags = (env = process.env) => {
|
||||
|
||||
if (env.GIT_SHA) {
|
||||
return {
|
||||
shortSha: env.GIT_SHA,
|
||||
isTagged: Boolean(env.IS_TAGGED)
|
||||
}
|
||||
} else {
|
||||
const gitShortSHA = runCommand('git rev-parse --short HEAD');
|
||||
const isCommitTagged = runCommand('git describe --tags --abbrev=0 --exact-match') !== undefined;
|
||||
console.log('gitShortSHA', gitShortSHA, 'isCommitTagged', isCommitTagged);
|
||||
if (!gitShortSHA) {
|
||||
throw new Error('Failing build due to missing SHA');
|
||||
}
|
||||
return {
|
||||
shortSha: gitShortSHA,
|
||||
isTagged: isCommitTagged
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default getTags;
|
||||
@@ -1,31 +0,0 @@
|
||||
import { beforeEach, expect, test, vi } from 'vitest';
|
||||
|
||||
// Preloading imports for faster tests
|
||||
import '@app/cli/commands/restart';
|
||||
import '@app/cli/commands/start';
|
||||
import '@app/cli/commands/stop';
|
||||
|
||||
beforeEach(() => {
|
||||
vi.resetAllMocks();
|
||||
});
|
||||
|
||||
test('calls stop and then start', async () => {
|
||||
vi.mock('@app/cli/commands/start');
|
||||
vi.mock('@app/cli/commands/stop');
|
||||
// Call restart
|
||||
const { restart } = await import('@app/cli/commands/restart');
|
||||
const { start } = await import('@app/cli/commands/start');
|
||||
const { stop } = await import('@app/cli/commands/stop');
|
||||
await restart();
|
||||
|
||||
// Check stop was called
|
||||
expect(vi.mocked(stop).mock.calls.length).toBe(1);
|
||||
|
||||
// Check start was called
|
||||
expect(vi.mocked(start).mock.calls.length).toBe(1);
|
||||
|
||||
// Check stop was called first
|
||||
expect(vi.mocked(stop).mock.invocationCallOrder[0]).toBeLessThan(
|
||||
vi.mocked(start).mock.invocationCallOrder[0]
|
||||
);
|
||||
});
|
||||
49
api/src/__test__/common/allowed-origins.test.ts
Normal file
49
api/src/__test__/common/allowed-origins.test.ts
Normal file
@@ -0,0 +1,49 @@
|
||||
import 'reflect-metadata';
|
||||
|
||||
import { expect, test } from 'vitest';
|
||||
|
||||
// Preloading imports for faster tests
|
||||
import '@app/common/allowed-origins';
|
||||
import '@app/store/modules/emhttp';
|
||||
import '@app/store';
|
||||
|
||||
test('Returns allowed origins', async () => {
|
||||
const { store } = await import('@app/store');
|
||||
const { loadStateFiles } = await import('@app/store/modules/emhttp');
|
||||
const { getAllowedOrigins } = await import('@app/common/allowed-origins');
|
||||
const { loadConfigFile } = await import('@app/store/modules/config');
|
||||
|
||||
// Load state files into store
|
||||
await store.dispatch(loadStateFiles());
|
||||
await store.dispatch(loadConfigFile());
|
||||
|
||||
// Get allowed origins
|
||||
expect(getAllowedOrigins()).toMatchInlineSnapshot(`
|
||||
[
|
||||
"/var/run/unraid-notifications.sock",
|
||||
"/var/run/unraid-php.sock",
|
||||
"/var/run/unraid-cli.sock",
|
||||
"http://localhost:8080",
|
||||
"https://localhost:4443",
|
||||
"https://tower.local:4443",
|
||||
"https://192.168.1.150:4443",
|
||||
"https://tower:4443",
|
||||
"https://192-168-1-150.thisisfourtyrandomcharacters012345678900.myunraid.net:4443",
|
||||
"https://85-121-123-122.thisisfourtyrandomcharacters012345678900.myunraid.net:8443",
|
||||
"https://10-252-0-1.hash.myunraid.net:4443",
|
||||
"https://10-252-1-1.hash.myunraid.net:4443",
|
||||
"https://10-253-3-1.hash.myunraid.net:4443",
|
||||
"https://10-253-4-1.hash.myunraid.net:4443",
|
||||
"https://10-253-5-1.hash.myunraid.net:4443",
|
||||
"https://10-100-0-1.hash.myunraid.net:4443",
|
||||
"https://10-100-0-2.hash.myunraid.net:4443",
|
||||
"https://10-123-1-2.hash.myunraid.net:4443",
|
||||
"https://221-123-121-112.hash.myunraid.net:4443",
|
||||
"https://google.com",
|
||||
"https://test.com",
|
||||
"https://connect.myunraid.net",
|
||||
"https://connect-staging.myunraid.net",
|
||||
"https://dev-my.myunraid.net:4000",
|
||||
]
|
||||
`);
|
||||
});
|
||||
@@ -1,120 +0,0 @@
|
||||
import { expect, test, vi } from 'vitest';
|
||||
import { store } from '@app/store';
|
||||
|
||||
import { loadStateFiles } from '@app/store/modules/emhttp';
|
||||
|
||||
vi.mock('@vmngr/libvirt', () => ({
|
||||
ConnectListAllDomainsFlags: {
|
||||
ACTIVE: 0,
|
||||
INACTIVE: 1,
|
||||
},
|
||||
}));
|
||||
|
||||
vi.mock('@app/core/log', () => ({
|
||||
logger: {
|
||||
info: vi.fn(),
|
||||
error: vi.fn(),
|
||||
debug: vi.fn(),
|
||||
trace: vi.fn(),
|
||||
addContext: vi.fn(),
|
||||
removeContext: vi.fn(),
|
||||
},
|
||||
dashboardLogger: {
|
||||
info: vi.fn(),
|
||||
error: vi.fn((...input) => console.log(input)),
|
||||
debug: vi.fn(),
|
||||
trace: vi.fn(),
|
||||
addContext: vi.fn(),
|
||||
removeContext: vi.fn(),
|
||||
},
|
||||
emhttpLogger: {
|
||||
info: vi.fn(),
|
||||
error: vi.fn(),
|
||||
debug: vi.fn(),
|
||||
trace: vi.fn(),
|
||||
addContext: vi.fn(),
|
||||
removeContext: vi.fn(),
|
||||
},
|
||||
}));
|
||||
|
||||
vi.mock('@app/common/two-factor', () => ({
|
||||
checkTwoFactorEnabled: vi.fn(() => ({
|
||||
isRemoteEnabled: false,
|
||||
isLocalEnabled: false,
|
||||
})),
|
||||
}));
|
||||
|
||||
vi.mock('@app/common/dashboard/boot-timestamp', () => ({
|
||||
bootTimestamp: new Date('2022-06-10T04:35:58.276Z'),
|
||||
}));
|
||||
|
||||
test('Returns generated data', async () => {
|
||||
await store.dispatch(loadStateFiles()).unwrap();
|
||||
|
||||
const { generateData } = await import('@app/common/dashboard/generate-data');
|
||||
const result = await generateData();
|
||||
|
||||
expect(result).toMatchInlineSnapshot(`
|
||||
{
|
||||
"apps": {
|
||||
"installed": 0,
|
||||
"started": 0,
|
||||
},
|
||||
"array": {
|
||||
"capacity": {
|
||||
"bytes": {
|
||||
"free": 19495825571000,
|
||||
"total": 41994745901000,
|
||||
"used": 22498920330000,
|
||||
},
|
||||
},
|
||||
"state": "STOPPED",
|
||||
},
|
||||
"config": {
|
||||
"valid": true,
|
||||
},
|
||||
"display": {
|
||||
"case": {
|
||||
"base64": "",
|
||||
"error": "",
|
||||
"icon": "case-model.png",
|
||||
"url": "",
|
||||
},
|
||||
},
|
||||
"os": {
|
||||
"hostname": "Tower",
|
||||
"uptime": "2022-06-10T04:35:58.276Z",
|
||||
},
|
||||
"services": [
|
||||
{
|
||||
"name": "unraid-api",
|
||||
"online": true,
|
||||
"uptime": {
|
||||
"timestamp": "2022-06-10T04:35:58.276Z",
|
||||
},
|
||||
"version": "THIS_WILL_BE_REPLACED_WHEN_BUILT",
|
||||
},
|
||||
{
|
||||
"name": "dynamic-remote-access",
|
||||
"online": false,
|
||||
"uptime": {
|
||||
"timestamp": "2022-06-10T04:35:58.276Z",
|
||||
},
|
||||
"version": "DISABLED",
|
||||
},
|
||||
],
|
||||
"vars": {
|
||||
"flashGuid": "0000-0000-0000-000000000000",
|
||||
"regState": "PRO",
|
||||
"regTy": "PRO",
|
||||
},
|
||||
"versions": {
|
||||
"unraid": "6.11.2",
|
||||
},
|
||||
"vms": {
|
||||
"installed": 0,
|
||||
"started": 0,
|
||||
},
|
||||
}
|
||||
`);
|
||||
}, 10_000);
|
||||
@@ -1,360 +0,0 @@
|
||||
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
||||
|
||||
exports[`Returns default permissions 1`] = `
|
||||
{
|
||||
"admin": {
|
||||
"extends": "user",
|
||||
"permissions": [
|
||||
{
|
||||
"action": "read:any",
|
||||
"attributes": "*",
|
||||
"resource": "apikey",
|
||||
},
|
||||
{
|
||||
"action": "read:any",
|
||||
"attributes": "*",
|
||||
"resource": "array",
|
||||
},
|
||||
{
|
||||
"action": "read:any",
|
||||
"attributes": "*",
|
||||
"resource": "cpu",
|
||||
},
|
||||
{
|
||||
"action": "read:any",
|
||||
"attributes": "*",
|
||||
"resource": "crash-reporting-enabled",
|
||||
},
|
||||
{
|
||||
"action": "read:any",
|
||||
"attributes": "*",
|
||||
"resource": "device",
|
||||
},
|
||||
{
|
||||
"action": "read:any",
|
||||
"attributes": "*",
|
||||
"resource": "device/unassigned",
|
||||
},
|
||||
{
|
||||
"action": "read:any",
|
||||
"attributes": "*",
|
||||
"resource": "disk",
|
||||
},
|
||||
{
|
||||
"action": "read:any",
|
||||
"attributes": "*",
|
||||
"resource": "disk/settings",
|
||||
},
|
||||
{
|
||||
"action": "read:any",
|
||||
"attributes": "*",
|
||||
"resource": "display",
|
||||
},
|
||||
{
|
||||
"action": "read:any",
|
||||
"attributes": "*",
|
||||
"resource": "docker/container",
|
||||
},
|
||||
{
|
||||
"action": "read:any",
|
||||
"attributes": "*",
|
||||
"resource": "docker/network",
|
||||
},
|
||||
{
|
||||
"action": "read:any",
|
||||
"attributes": "*",
|
||||
"resource": "flash",
|
||||
},
|
||||
{
|
||||
"action": "read:any",
|
||||
"attributes": "*",
|
||||
"resource": "info",
|
||||
},
|
||||
{
|
||||
"action": "read:any",
|
||||
"attributes": "*",
|
||||
"resource": "license-key",
|
||||
},
|
||||
{
|
||||
"action": "read:any",
|
||||
"attributes": "*",
|
||||
"resource": "machine-id",
|
||||
},
|
||||
{
|
||||
"action": "read:any",
|
||||
"attributes": "*",
|
||||
"resource": "memory",
|
||||
},
|
||||
{
|
||||
"action": "read:any",
|
||||
"attributes": "*",
|
||||
"resource": "notifications",
|
||||
},
|
||||
{
|
||||
"action": "read:any",
|
||||
"attributes": "*",
|
||||
"resource": "online",
|
||||
},
|
||||
{
|
||||
"action": "read:any",
|
||||
"attributes": "*",
|
||||
"resource": "os",
|
||||
},
|
||||
{
|
||||
"action": "read:any",
|
||||
"attributes": "*",
|
||||
"resource": "owner",
|
||||
},
|
||||
{
|
||||
"action": "read:any",
|
||||
"attributes": "*",
|
||||
"resource": "parity-history",
|
||||
},
|
||||
{
|
||||
"action": "read:any",
|
||||
"attributes": "*",
|
||||
"resource": "permission",
|
||||
},
|
||||
{
|
||||
"action": "read:any",
|
||||
"attributes": "*",
|
||||
"resource": "registration",
|
||||
},
|
||||
{
|
||||
"action": "read:any",
|
||||
"attributes": "*",
|
||||
"resource": "servers",
|
||||
},
|
||||
{
|
||||
"action": "read:any",
|
||||
"attributes": "*",
|
||||
"resource": "service",
|
||||
},
|
||||
{
|
||||
"action": "read:any",
|
||||
"attributes": "*",
|
||||
"resource": "service/emhttpd",
|
||||
},
|
||||
{
|
||||
"action": "read:any",
|
||||
"attributes": "*",
|
||||
"resource": "service/unraid-api",
|
||||
},
|
||||
{
|
||||
"action": "read:any",
|
||||
"attributes": "*",
|
||||
"resource": "services",
|
||||
},
|
||||
{
|
||||
"action": "read:any",
|
||||
"attributes": "*",
|
||||
"resource": "share",
|
||||
},
|
||||
{
|
||||
"action": "read:any",
|
||||
"attributes": "*",
|
||||
"resource": "software-versions",
|
||||
},
|
||||
{
|
||||
"action": "read:any",
|
||||
"attributes": "*",
|
||||
"resource": "unraid-version",
|
||||
},
|
||||
{
|
||||
"action": "read:any",
|
||||
"attributes": "*",
|
||||
"resource": "uptime",
|
||||
},
|
||||
{
|
||||
"action": "read:any",
|
||||
"attributes": "*",
|
||||
"resource": "user",
|
||||
},
|
||||
{
|
||||
"action": "read:any",
|
||||
"attributes": "*",
|
||||
"resource": "vars",
|
||||
},
|
||||
{
|
||||
"action": "read:any",
|
||||
"attributes": "*",
|
||||
"resource": "vms",
|
||||
},
|
||||
{
|
||||
"action": "read:any",
|
||||
"attributes": "*",
|
||||
"resource": "vms/domain",
|
||||
},
|
||||
{
|
||||
"action": "read:any",
|
||||
"attributes": "*",
|
||||
"resource": "vms/network",
|
||||
},
|
||||
],
|
||||
},
|
||||
"guest": {
|
||||
"permissions": [
|
||||
{
|
||||
"action": "read:any",
|
||||
"attributes": "*",
|
||||
"resource": "me",
|
||||
},
|
||||
{
|
||||
"action": "read:any",
|
||||
"attributes": "*",
|
||||
"resource": "welcome",
|
||||
},
|
||||
],
|
||||
},
|
||||
"my_servers": {
|
||||
"extends": "guest",
|
||||
"permissions": [
|
||||
{
|
||||
"action": "read:any",
|
||||
"attributes": "*",
|
||||
"resource": "dashboard",
|
||||
},
|
||||
{
|
||||
"action": "read:own",
|
||||
"attributes": "*",
|
||||
"resource": "two-factor",
|
||||
},
|
||||
{
|
||||
"action": "read:any",
|
||||
"attributes": "*",
|
||||
"resource": "array",
|
||||
},
|
||||
{
|
||||
"action": "read:any",
|
||||
"attributes": "*",
|
||||
"resource": "docker/container",
|
||||
},
|
||||
{
|
||||
"action": "read:any",
|
||||
"attributes": "*",
|
||||
"resource": "docker/network",
|
||||
},
|
||||
{
|
||||
"action": "read:any",
|
||||
"attributes": "*",
|
||||
"resource": "notifications",
|
||||
},
|
||||
{
|
||||
"action": "read:any",
|
||||
"attributes": "*",
|
||||
"resource": "vms/domain",
|
||||
},
|
||||
{
|
||||
"action": "read:any",
|
||||
"attributes": "*",
|
||||
"resource": "unraid-version",
|
||||
},
|
||||
],
|
||||
},
|
||||
"notifier": {
|
||||
"extends": "guest",
|
||||
"permissions": [
|
||||
{
|
||||
"action": "create:own",
|
||||
"attributes": "*",
|
||||
"resource": "notifications",
|
||||
},
|
||||
],
|
||||
},
|
||||
"upc": {
|
||||
"extends": "guest",
|
||||
"permissions": [
|
||||
{
|
||||
"action": "read:own",
|
||||
"attributes": "*",
|
||||
"resource": "apikey",
|
||||
},
|
||||
{
|
||||
"action": "read:own",
|
||||
"attributes": "*",
|
||||
"resource": "cloud",
|
||||
},
|
||||
{
|
||||
"action": "read:any",
|
||||
"attributes": "*",
|
||||
"resource": "config",
|
||||
},
|
||||
{
|
||||
"action": "read:any",
|
||||
"attributes": "*",
|
||||
"resource": "crash-reporting-enabled",
|
||||
},
|
||||
{
|
||||
"action": "read:any",
|
||||
"attributes": "*",
|
||||
"resource": "disk",
|
||||
},
|
||||
{
|
||||
"action": "read:any",
|
||||
"attributes": "*",
|
||||
"resource": "display",
|
||||
},
|
||||
{
|
||||
"action": "read:any",
|
||||
"attributes": "*",
|
||||
"resource": "flash",
|
||||
},
|
||||
{
|
||||
"action": "read:any",
|
||||
"attributes": "*",
|
||||
"resource": "os",
|
||||
},
|
||||
{
|
||||
"action": "read:any",
|
||||
"attributes": "*",
|
||||
"resource": "owner",
|
||||
},
|
||||
{
|
||||
"action": "read:any",
|
||||
"attributes": "*",
|
||||
"resource": "permission",
|
||||
},
|
||||
{
|
||||
"action": "read:any",
|
||||
"attributes": "*",
|
||||
"resource": "registration",
|
||||
},
|
||||
{
|
||||
"action": "read:any",
|
||||
"attributes": "*",
|
||||
"resource": "servers",
|
||||
},
|
||||
{
|
||||
"action": "read:any",
|
||||
"attributes": "*",
|
||||
"resource": "vars",
|
||||
},
|
||||
{
|
||||
"action": "read:own",
|
||||
"attributes": "*",
|
||||
"resource": "connect",
|
||||
},
|
||||
{
|
||||
"action": "update:own",
|
||||
"attributes": "*",
|
||||
"resource": "connect",
|
||||
},
|
||||
],
|
||||
},
|
||||
"user": {
|
||||
"extends": "guest",
|
||||
"permissions": [
|
||||
{
|
||||
"action": "read:own",
|
||||
"attributes": "*",
|
||||
"resource": "apikey",
|
||||
},
|
||||
{
|
||||
"action": "read:any",
|
||||
"attributes": "*",
|
||||
"resource": "permission",
|
||||
},
|
||||
],
|
||||
},
|
||||
}
|
||||
`;
|
||||
@@ -1,209 +1,208 @@
|
||||
import { test, expect, vi } from 'vitest';
|
||||
import { expect, test, vi } from 'vitest';
|
||||
|
||||
vi.mock('@app/core/pubsub', () => ({
|
||||
pubsub: { publish: vi.fn() },
|
||||
}));
|
||||
|
||||
test('Creates an array event', async () => {
|
||||
const { getArrayData } = await import(
|
||||
'@app/core/modules/array/get-array-data'
|
||||
);
|
||||
const { getArrayData } = await import('@app/core/modules/array/get-array-data');
|
||||
const { store } = await import('@app/store');
|
||||
const { loadStateFiles } = await import('@app/store/modules/emhttp');
|
||||
|
||||
const { loadConfigFile } = await import('@app/store/modules/config');
|
||||
// Load state files into store
|
||||
await store.dispatch(loadStateFiles());
|
||||
|
||||
await store.dispatch(loadConfigFile());
|
||||
|
||||
const arrayEvent = getArrayData(store.getState);
|
||||
expect(arrayEvent).toMatchInlineSnapshot(`
|
||||
{
|
||||
"boot": {
|
||||
"comment": "Unraid OS boot device",
|
||||
"critical": null,
|
||||
"device": "sda",
|
||||
"exportable": true,
|
||||
"format": "unknown",
|
||||
"fsFree": 3191407,
|
||||
"fsSize": 4042732,
|
||||
"fsType": "vfat",
|
||||
"fsUsed": 851325,
|
||||
"id": "Cruzer",
|
||||
"idx": 32,
|
||||
"name": "flash",
|
||||
"numErrors": 0,
|
||||
"numReads": 0,
|
||||
"numWrites": 0,
|
||||
"rotational": true,
|
||||
"size": 3956700,
|
||||
"status": "DISK_OK",
|
||||
"temp": null,
|
||||
"transport": "usb",
|
||||
"type": "Flash",
|
||||
"warning": null,
|
||||
expect(arrayEvent).toMatchObject({
|
||||
boot: {
|
||||
comment: 'Unraid OS boot device',
|
||||
critical: null,
|
||||
device: 'sda',
|
||||
exportable: true,
|
||||
format: 'unknown',
|
||||
fsFree: 3191407,
|
||||
fsSize: 4042732,
|
||||
fsType: 'vfat',
|
||||
fsUsed: 851325,
|
||||
id: 'Cruzer',
|
||||
idx: 32,
|
||||
name: 'flash',
|
||||
numErrors: 0,
|
||||
numReads: 0,
|
||||
numWrites: 0,
|
||||
rotational: true,
|
||||
size: 3956700,
|
||||
status: 'DISK_OK',
|
||||
temp: null,
|
||||
transport: 'usb',
|
||||
type: 'Flash',
|
||||
warning: null,
|
||||
},
|
||||
"caches": [
|
||||
{
|
||||
"comment": "",
|
||||
"critical": null,
|
||||
"device": "sdi",
|
||||
"exportable": false,
|
||||
"format": "MBR: 4KiB-aligned",
|
||||
"fsFree": 111810683,
|
||||
"fsSize": 250059317,
|
||||
"fsType": "btrfs",
|
||||
"fsUsed": 137273827,
|
||||
"id": "Samsung_SSD_850_EVO_250GB_S2R5NX0H643734Z",
|
||||
"idx": 30,
|
||||
"name": "cache",
|
||||
"numErrors": 0,
|
||||
"numReads": 0,
|
||||
"numWrites": 0,
|
||||
"rotational": false,
|
||||
"size": 244198552,
|
||||
"status": "DISK_OK",
|
||||
"temp": 22,
|
||||
"transport": "ata",
|
||||
"type": "Cache",
|
||||
"warning": null,
|
||||
},
|
||||
{
|
||||
"comment": null,
|
||||
"critical": null,
|
||||
"device": "nvme0n1",
|
||||
"exportable": false,
|
||||
"format": "MBR: 4KiB-aligned",
|
||||
"fsFree": null,
|
||||
"fsSize": null,
|
||||
"fsType": null,
|
||||
"fsUsed": null,
|
||||
"id": "KINGSTON_SA2000M8250G_50026B7282669D9E",
|
||||
"idx": 31,
|
||||
"name": "cache2",
|
||||
"numErrors": 0,
|
||||
"numReads": 0,
|
||||
"numWrites": 0,
|
||||
"rotational": false,
|
||||
"size": 244198552,
|
||||
"status": "DISK_OK",
|
||||
"temp": 27,
|
||||
"transport": "nvme",
|
||||
"type": "Cache",
|
||||
"warning": null,
|
||||
},
|
||||
caches: [
|
||||
{
|
||||
comment: '',
|
||||
critical: null,
|
||||
device: 'sdi',
|
||||
exportable: false,
|
||||
format: 'MBR: 4KiB-aligned',
|
||||
fsFree: 111810683,
|
||||
fsSize: 250059317,
|
||||
fsType: 'btrfs',
|
||||
fsUsed: 137273827,
|
||||
id: 'Samsung_SSD_850_EVO_250GB_S2R5NX0H643734Z',
|
||||
idx: 30,
|
||||
name: 'cache',
|
||||
numErrors: 0,
|
||||
numReads: 0,
|
||||
numWrites: 0,
|
||||
rotational: false,
|
||||
size: 244198552,
|
||||
status: 'DISK_OK',
|
||||
temp: 22,
|
||||
transport: 'ata',
|
||||
type: 'Cache',
|
||||
warning: null,
|
||||
},
|
||||
{
|
||||
comment: null,
|
||||
critical: null,
|
||||
device: 'nvme0n1',
|
||||
exportable: false,
|
||||
format: 'MBR: 4KiB-aligned',
|
||||
fsFree: null,
|
||||
fsSize: null,
|
||||
fsType: null,
|
||||
fsUsed: null,
|
||||
id: 'KINGSTON_SA2000M8250G_50026B7282669D9E',
|
||||
idx: 31,
|
||||
name: 'cache2',
|
||||
numErrors: 0,
|
||||
numReads: 0,
|
||||
numWrites: 0,
|
||||
rotational: false,
|
||||
size: 244198552,
|
||||
status: 'DISK_OK',
|
||||
temp: 27,
|
||||
transport: 'nvme',
|
||||
type: 'Cache',
|
||||
warning: null,
|
||||
},
|
||||
],
|
||||
"capacity": {
|
||||
"disks": {
|
||||
"free": "27",
|
||||
"total": "30",
|
||||
"used": "3",
|
||||
},
|
||||
"kilobytes": {
|
||||
"free": "19495825571",
|
||||
"total": "41994745901",
|
||||
"used": "22498920330",
|
||||
},
|
||||
capacity: {
|
||||
disks: {
|
||||
free: '27',
|
||||
total: '30',
|
||||
used: '3',
|
||||
},
|
||||
kilobytes: {
|
||||
free: '19495825571',
|
||||
total: '41994745901',
|
||||
used: '22498920330',
|
||||
},
|
||||
},
|
||||
"disks": [
|
||||
{
|
||||
"comment": "Seagate Exos",
|
||||
"critical": 75,
|
||||
"device": "sdf",
|
||||
"exportable": false,
|
||||
"format": "GPT: 4KiB-aligned",
|
||||
"fsFree": 13882739732,
|
||||
"fsSize": 17998742753,
|
||||
"fsType": "xfs",
|
||||
"fsUsed": 4116003021,
|
||||
"id": "ST18000NM000J-2TV103_ZR5B1W9X",
|
||||
"idx": 1,
|
||||
"name": "disk1",
|
||||
"numErrors": 0,
|
||||
"numReads": 0,
|
||||
"numWrites": 0,
|
||||
"rotational": true,
|
||||
"size": 17578328012,
|
||||
"status": "DISK_OK",
|
||||
"temp": 30,
|
||||
"transport": "ata",
|
||||
"type": "Data",
|
||||
"warning": 50,
|
||||
},
|
||||
{
|
||||
"comment": "",
|
||||
"critical": null,
|
||||
"device": "sdj",
|
||||
"exportable": false,
|
||||
"format": "GPT: 4KiB-aligned",
|
||||
"fsFree": 93140746,
|
||||
"fsSize": 11998001574,
|
||||
"fsType": "xfs",
|
||||
"fsUsed": 11904860828,
|
||||
"id": "WDC_WD120EDAZ-11F3RA0_5PJRD45C",
|
||||
"idx": 2,
|
||||
"name": "disk2",
|
||||
"numErrors": 0,
|
||||
"numReads": 0,
|
||||
"numWrites": 0,
|
||||
"rotational": true,
|
||||
"size": 11718885324,
|
||||
"status": "DISK_OK",
|
||||
"temp": 30,
|
||||
"transport": "ata",
|
||||
"type": "Data",
|
||||
"warning": null,
|
||||
},
|
||||
{
|
||||
"comment": "",
|
||||
"critical": null,
|
||||
"device": "sde",
|
||||
"exportable": false,
|
||||
"format": "GPT: 4KiB-aligned",
|
||||
"fsFree": 5519945093,
|
||||
"fsSize": 11998001574,
|
||||
"fsType": "xfs",
|
||||
"fsUsed": 6478056481,
|
||||
"id": "WDC_WD120EMAZ-11BLFA0_5PH8BTYD",
|
||||
"idx": 3,
|
||||
"name": "disk3",
|
||||
"numErrors": 0,
|
||||
"numReads": 0,
|
||||
"numWrites": 0,
|
||||
"rotational": true,
|
||||
"size": 11718885324,
|
||||
"status": "DISK_OK",
|
||||
"temp": 30,
|
||||
"transport": "ata",
|
||||
"type": "Data",
|
||||
"warning": null,
|
||||
},
|
||||
disks: [
|
||||
{
|
||||
comment: 'Seagate Exos',
|
||||
critical: 75,
|
||||
device: 'sdf',
|
||||
exportable: false,
|
||||
format: 'GPT: 4KiB-aligned',
|
||||
fsFree: 13882739732,
|
||||
fsSize: 17998742753,
|
||||
fsType: 'xfs',
|
||||
fsUsed: 4116003021,
|
||||
id: 'ST18000NM000J-2TV103_ZR5B1W9X',
|
||||
idx: 1,
|
||||
name: 'disk1',
|
||||
numErrors: 0,
|
||||
numReads: 0,
|
||||
numWrites: 0,
|
||||
rotational: true,
|
||||
size: 17578328012,
|
||||
status: 'DISK_OK',
|
||||
temp: 30,
|
||||
transport: 'ata',
|
||||
type: 'Data',
|
||||
warning: 50,
|
||||
},
|
||||
{
|
||||
comment: '',
|
||||
critical: null,
|
||||
device: 'sdj',
|
||||
exportable: false,
|
||||
format: 'GPT: 4KiB-aligned',
|
||||
fsFree: 93140746,
|
||||
fsSize: 11998001574,
|
||||
fsType: 'xfs',
|
||||
fsUsed: 11904860828,
|
||||
id: 'WDC_WD120EDAZ-11F3RA0_5PJRD45C',
|
||||
idx: 2,
|
||||
name: 'disk2',
|
||||
numErrors: 0,
|
||||
numReads: 0,
|
||||
numWrites: 0,
|
||||
rotational: true,
|
||||
size: 11718885324,
|
||||
status: 'DISK_OK',
|
||||
temp: 30,
|
||||
transport: 'ata',
|
||||
type: 'Data',
|
||||
warning: null,
|
||||
},
|
||||
{
|
||||
comment: '',
|
||||
critical: null,
|
||||
device: 'sde',
|
||||
exportable: false,
|
||||
format: 'GPT: 4KiB-aligned',
|
||||
fsFree: 5519945093,
|
||||
fsSize: 11998001574,
|
||||
fsType: 'xfs',
|
||||
fsUsed: 6478056481,
|
||||
id: 'WDC_WD120EMAZ-11BLFA0_5PH8BTYD',
|
||||
idx: 3,
|
||||
name: 'disk3',
|
||||
numErrors: 0,
|
||||
numReads: 0,
|
||||
numWrites: 0,
|
||||
rotational: true,
|
||||
size: 11718885324,
|
||||
status: 'DISK_OK',
|
||||
temp: 30,
|
||||
transport: 'ata',
|
||||
type: 'Data',
|
||||
warning: null,
|
||||
},
|
||||
],
|
||||
"parities": [
|
||||
{
|
||||
"comment": null,
|
||||
"critical": null,
|
||||
"device": "sdh",
|
||||
"exportable": false,
|
||||
"format": "GPT: 4KiB-aligned",
|
||||
"fsFree": null,
|
||||
"fsSize": null,
|
||||
"fsType": null,
|
||||
"fsUsed": null,
|
||||
"id": "ST18000NM000J-2TV103_ZR585CPY",
|
||||
"idx": 0,
|
||||
"name": "parity",
|
||||
"numErrors": 0,
|
||||
"numReads": 0,
|
||||
"numWrites": 0,
|
||||
"rotational": true,
|
||||
"size": 17578328012,
|
||||
"status": "DISK_OK",
|
||||
"temp": 25,
|
||||
"transport": "ata",
|
||||
"type": "Parity",
|
||||
"warning": null,
|
||||
},
|
||||
id: expect.any(String),
|
||||
parities: [
|
||||
{
|
||||
comment: null,
|
||||
critical: null,
|
||||
device: 'sdh',
|
||||
exportable: false,
|
||||
format: 'GPT: 4KiB-aligned',
|
||||
fsFree: null,
|
||||
fsSize: null,
|
||||
fsType: null,
|
||||
fsUsed: null,
|
||||
id: 'ST18000NM000J-2TV103_ZR585CPY',
|
||||
idx: 0,
|
||||
name: 'parity',
|
||||
numErrors: 0,
|
||||
numReads: 0,
|
||||
numWrites: 0,
|
||||
rotational: true,
|
||||
size: 17578328012,
|
||||
status: 'DISK_OK',
|
||||
temp: 25,
|
||||
transport: 'ata',
|
||||
type: 'Parity',
|
||||
warning: null,
|
||||
},
|
||||
],
|
||||
"state": "STOPPED",
|
||||
}
|
||||
`);
|
||||
state: 'STOPPED',
|
||||
});
|
||||
});
|
||||
|
||||
22
api/src/__test__/core/notifiers/console.test.ts
Normal file
22
api/src/__test__/core/notifiers/console.test.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
import { expect, test, vi } from 'vitest';
|
||||
|
||||
import { ConsoleNotifier } from '@app/core/notifiers/console';
|
||||
|
||||
vi.mock('@app/core/log', () => ({
|
||||
logger: {
|
||||
info: vi.fn(),
|
||||
error: vi.fn(),
|
||||
debug: vi.fn(),
|
||||
},
|
||||
graphqlLogger: {
|
||||
info: vi.fn(),
|
||||
error: vi.fn(),
|
||||
debug: vi.fn(),
|
||||
},
|
||||
}));
|
||||
|
||||
test('Creates a console notifier', () => {
|
||||
const notifier = new ConsoleNotifier();
|
||||
expect(notifier.level).toBe('info');
|
||||
expect(notifier.template).toBe('{{{ data }}}');
|
||||
});
|
||||
24
api/src/__test__/core/notifiers/unraid-local.test.ts
Normal file
24
api/src/__test__/core/notifiers/unraid-local.test.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import { expect, test, vi } from 'vitest';
|
||||
|
||||
import { UnraidLocalNotifier } from '@app/core/notifiers/unraid-local';
|
||||
|
||||
vi.mock('@app/core/log', () => ({
|
||||
logger: {
|
||||
info: vi.fn(),
|
||||
error: vi.fn(),
|
||||
debug: vi.fn(),
|
||||
},
|
||||
graphqlLogger: {
|
||||
info: vi.fn(),
|
||||
error: vi.fn(),
|
||||
debug: vi.fn(),
|
||||
},
|
||||
}));
|
||||
|
||||
test('Creates an email notifier', () => {
|
||||
const notifier = new UnraidLocalNotifier({ level: 'info' });
|
||||
expect(notifier.level).toBe('normal');
|
||||
expect(notifier.template).toBe('{{ message }}');
|
||||
const rendered = notifier.render({ message: 'Remote access started' });
|
||||
expect(rendered).toEqual('Remote access started');
|
||||
});
|
||||
23
api/src/__test__/core/utils/array/array-is-running.test.ts
Normal file
23
api/src/__test__/core/utils/array/array-is-running.test.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import { expect, test, vi } from 'vitest';
|
||||
|
||||
import type { SliceState } from '@app/store/modules/emhttp';
|
||||
import { getters } from '@app/store';
|
||||
|
||||
test('Returns true if the array is started', async () => {
|
||||
vi.spyOn(getters, 'emhttp').mockImplementation(
|
||||
() => ({ var: { mdState: 'STARTED' } }) as unknown as SliceState
|
||||
);
|
||||
|
||||
const { arrayIsRunning } = await import('@app/core/utils/array/array-is-running');
|
||||
expect(arrayIsRunning()).toBe(true);
|
||||
vi.spyOn(getters, 'emhttp').mockReset();
|
||||
});
|
||||
|
||||
test('Returns false if the array is stopped', async () => {
|
||||
vi.spyOn(getters, 'emhttp').mockImplementation(
|
||||
() => ({ var: { mdState: 'Stopped' } }) as unknown as SliceState
|
||||
);
|
||||
const { arrayIsRunning } = await import('@app/core/utils/array/array-is-running');
|
||||
expect(arrayIsRunning()).toBe(false);
|
||||
vi.spyOn(getters, 'emhttp').mockReset();
|
||||
});
|
||||
160
api/src/__test__/core/utils/files/config-file-normalizer.test.ts
Normal file
160
api/src/__test__/core/utils/files/config-file-normalizer.test.ts
Normal file
@@ -0,0 +1,160 @@
|
||||
import 'reflect-metadata';
|
||||
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
import { expect, test } from 'vitest';
|
||||
|
||||
import { getWriteableConfig } from '@app/core/utils/files/config-file-normalizer';
|
||||
import { initialState } from '@app/store/modules/config';
|
||||
|
||||
test('it creates a FLASH config with NO OPTIONAL values', () => {
|
||||
const basicConfig = initialState;
|
||||
const config = getWriteableConfig(basicConfig, 'flash');
|
||||
expect(config).toMatchInlineSnapshot(`
|
||||
{
|
||||
"api": {
|
||||
"extraOrigins": "",
|
||||
"version": "",
|
||||
},
|
||||
"local": {
|
||||
"sandbox": "no",
|
||||
},
|
||||
"remote": {
|
||||
"accesstoken": "",
|
||||
"apikey": "",
|
||||
"avatar": "",
|
||||
"dynamicRemoteAccessType": "DISABLED",
|
||||
"email": "",
|
||||
"idtoken": "",
|
||||
"localApiKey": "",
|
||||
"refreshtoken": "",
|
||||
"regWizTime": "",
|
||||
"ssoSubIds": "",
|
||||
"upnpEnabled": "",
|
||||
"username": "",
|
||||
"wanaccess": "",
|
||||
"wanport": "",
|
||||
},
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
test('it creates a MEMORY config with NO OPTIONAL values', () => {
|
||||
const basicConfig = initialState;
|
||||
const config = getWriteableConfig(basicConfig, 'memory');
|
||||
expect(config).toMatchInlineSnapshot(`
|
||||
{
|
||||
"api": {
|
||||
"extraOrigins": "",
|
||||
"version": "",
|
||||
},
|
||||
"connectionStatus": {
|
||||
"minigraph": "PRE_INIT",
|
||||
"upnpStatus": "",
|
||||
},
|
||||
"local": {
|
||||
"sandbox": "no",
|
||||
},
|
||||
"remote": {
|
||||
"accesstoken": "",
|
||||
"allowedOrigins": "/var/run/unraid-notifications.sock, /var/run/unraid-php.sock, /var/run/unraid-cli.sock, https://connect.myunraid.net, https://connect-staging.myunraid.net, https://dev-my.myunraid.net:4000",
|
||||
"apikey": "",
|
||||
"avatar": "",
|
||||
"dynamicRemoteAccessType": "DISABLED",
|
||||
"email": "",
|
||||
"idtoken": "",
|
||||
"localApiKey": "",
|
||||
"refreshtoken": "",
|
||||
"regWizTime": "",
|
||||
"ssoSubIds": "",
|
||||
"upnpEnabled": "",
|
||||
"username": "",
|
||||
"wanaccess": "",
|
||||
"wanport": "",
|
||||
},
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
test('it creates a FLASH config with OPTIONAL values', () => {
|
||||
const basicConfig = cloneDeep(initialState);
|
||||
// 2fa & t2fa should be ignored
|
||||
basicConfig.remote['2Fa'] = 'yes';
|
||||
basicConfig.local['2Fa'] = 'yes';
|
||||
basicConfig.local.showT2Fa = 'yes';
|
||||
|
||||
basicConfig.api.extraOrigins = 'myextra.origins';
|
||||
basicConfig.remote.upnpEnabled = 'yes';
|
||||
basicConfig.connectionStatus.upnpStatus = 'Turned On';
|
||||
const config = getWriteableConfig(basicConfig, 'flash');
|
||||
expect(config).toMatchInlineSnapshot(`
|
||||
{
|
||||
"api": {
|
||||
"extraOrigins": "myextra.origins",
|
||||
"version": "",
|
||||
},
|
||||
"local": {
|
||||
"sandbox": "no",
|
||||
},
|
||||
"remote": {
|
||||
"accesstoken": "",
|
||||
"apikey": "",
|
||||
"avatar": "",
|
||||
"dynamicRemoteAccessType": "DISABLED",
|
||||
"email": "",
|
||||
"idtoken": "",
|
||||
"localApiKey": "",
|
||||
"refreshtoken": "",
|
||||
"regWizTime": "",
|
||||
"ssoSubIds": "",
|
||||
"upnpEnabled": "yes",
|
||||
"username": "",
|
||||
"wanaccess": "",
|
||||
"wanport": "",
|
||||
},
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
test('it creates a MEMORY config with OPTIONAL values', () => {
|
||||
const basicConfig = cloneDeep(initialState);
|
||||
// 2fa & t2fa should be ignored
|
||||
basicConfig.remote['2Fa'] = 'yes';
|
||||
basicConfig.local['2Fa'] = 'yes';
|
||||
basicConfig.local.showT2Fa = 'yes';
|
||||
basicConfig.api.extraOrigins = 'myextra.origins';
|
||||
basicConfig.remote.upnpEnabled = 'yes';
|
||||
basicConfig.connectionStatus.upnpStatus = 'Turned On';
|
||||
const config = getWriteableConfig(basicConfig, 'memory');
|
||||
expect(config).toMatchInlineSnapshot(`
|
||||
{
|
||||
"api": {
|
||||
"extraOrigins": "myextra.origins",
|
||||
"version": "",
|
||||
},
|
||||
"connectionStatus": {
|
||||
"minigraph": "PRE_INIT",
|
||||
"upnpStatus": "Turned On",
|
||||
},
|
||||
"local": {
|
||||
"sandbox": "no",
|
||||
},
|
||||
"remote": {
|
||||
"accesstoken": "",
|
||||
"allowedOrigins": "/var/run/unraid-notifications.sock, /var/run/unraid-php.sock, /var/run/unraid-cli.sock, https://connect.myunraid.net, https://connect-staging.myunraid.net, https://dev-my.myunraid.net:4000",
|
||||
"apikey": "",
|
||||
"avatar": "",
|
||||
"dynamicRemoteAccessType": "DISABLED",
|
||||
"email": "",
|
||||
"idtoken": "",
|
||||
"localApiKey": "",
|
||||
"refreshtoken": "",
|
||||
"regWizTime": "",
|
||||
"ssoSubIds": "",
|
||||
"upnpEnabled": "yes",
|
||||
"username": "",
|
||||
"wanaccess": "",
|
||||
"wanport": "",
|
||||
},
|
||||
}
|
||||
`);
|
||||
});
|
||||
@@ -0,0 +1,70 @@
|
||||
import { parse } from 'ini';
|
||||
import { Serializer } from 'multi-ini';
|
||||
import { expect, test } from 'vitest';
|
||||
|
||||
import { safelySerializeObjectToIni } from '@app/core/utils/files/safe-ini-serializer';
|
||||
|
||||
test('MultiIni breaks when serializing an object with a boolean inside', async () => {
|
||||
const objectToSerialize = {
|
||||
root: {
|
||||
anonMode: false,
|
||||
},
|
||||
};
|
||||
const serializer = new Serializer({ keep_quotes: false });
|
||||
expect(serializer.serialize(objectToSerialize)).toMatchInlineSnapshot(`
|
||||
"[root]
|
||||
anonMode=false
|
||||
"
|
||||
`);
|
||||
});
|
||||
|
||||
test('MultiIni can safely serialize an object with a boolean inside', async () => {
|
||||
const objectToSerialize = {
|
||||
root: {
|
||||
anonMode: false,
|
||||
},
|
||||
};
|
||||
expect(safelySerializeObjectToIni(objectToSerialize)).toMatchInlineSnapshot(`
|
||||
"[root]
|
||||
anonMode="false"
|
||||
"
|
||||
`);
|
||||
const result = safelySerializeObjectToIni(objectToSerialize);
|
||||
expect(parse(result)).toMatchInlineSnapshot(`
|
||||
{
|
||||
"root": {
|
||||
"anonMode": false,
|
||||
},
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
test.skip('Can serialize top-level fields', async () => {
|
||||
const objectToSerialize = {
|
||||
id: 'an-id',
|
||||
message: 'hello-world',
|
||||
number: 1,
|
||||
float: 1.1,
|
||||
flag: true,
|
||||
flag2: false,
|
||||
item: undefined,
|
||||
missing: null,
|
||||
empty: {},
|
||||
};
|
||||
|
||||
const expected = `
|
||||
"id=an-id
|
||||
message=hello-world
|
||||
number=1
|
||||
float=1.1
|
||||
flag="true"
|
||||
flag2="false"
|
||||
[empty]
|
||||
"
|
||||
`
|
||||
.split('\n')
|
||||
.map((line) => line.trim())
|
||||
.join('\n');
|
||||
|
||||
expect(safelySerializeObjectToIni(objectToSerialize)).toMatchInlineSnapshot(expected);
|
||||
});
|
||||
@@ -1,23 +1,23 @@
|
||||
import { getBannerPathIfPresent, getCasePathIfPresent } from "@app/core/utils/images/image-file-helpers";
|
||||
import { loadDynamixConfigFile } from "@app/store/actions/load-dynamix-config-file";
|
||||
import { store } from "@app/store/index";
|
||||
import { expect, test } from 'vitest';
|
||||
|
||||
import { expect, test } from "vitest";
|
||||
import { getBannerPathIfPresent, getCasePathIfPresent } from '@app/core/utils/images/image-file-helpers';
|
||||
import { loadDynamixConfigFile } from '@app/store/actions/load-dynamix-config-file';
|
||||
import { store } from '@app/store/index';
|
||||
|
||||
test('get case path returns expected result', () => {
|
||||
expect(getCasePathIfPresent()).resolves.toContain('/dev/dynamix/case-model.png')
|
||||
})
|
||||
test('get case path returns expected result', async () => {
|
||||
await expect(getCasePathIfPresent()).resolves.toContain('/dev/dynamix/case-model.png');
|
||||
});
|
||||
|
||||
test('get banner path returns null (state unloaded)', () => {
|
||||
expect(getBannerPathIfPresent()).resolves.toMatchInlineSnapshot('null')
|
||||
})
|
||||
test('get banner path returns null (state unloaded)', async () => {
|
||||
await expect(getBannerPathIfPresent()).resolves.toMatchInlineSnapshot('null');
|
||||
});
|
||||
|
||||
test('get banner path returns the banner (state loaded)', async() => {
|
||||
await store.dispatch(loadDynamixConfigFile()).unwrap();
|
||||
expect(getBannerPathIfPresent()).resolves.toContain('/dev/dynamix/banner.png');
|
||||
})
|
||||
test('get banner path returns the banner (state loaded)', async () => {
|
||||
await store.dispatch(loadDynamixConfigFile()).unwrap();
|
||||
await expect(getBannerPathIfPresent()).resolves.toContain('/dev/dynamix/banner.png');
|
||||
});
|
||||
|
||||
test('get banner path returns null when no banner (state loaded)', async () => {
|
||||
await store.dispatch(loadDynamixConfigFile()).unwrap();
|
||||
expect(getBannerPathIfPresent('notabanner.png')).resolves.toMatchInlineSnapshot('null');
|
||||
});
|
||||
await expect(getBannerPathIfPresent('notabanner.png')).resolves.toMatchInlineSnapshot('null');
|
||||
});
|
||||
|
||||
8
api/src/__test__/core/utils/misc/clean-stdout.test.ts
Normal file
8
api/src/__test__/core/utils/misc/clean-stdout.test.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
import { expect, test } from 'vitest';
|
||||
|
||||
import { cleanStdout } from '@app/core/utils/misc/clean-stdout';
|
||||
|
||||
test('Returns trimmed stdout from execa command', () => {
|
||||
expect(cleanStdout({ stdout: 'test' })).toBe('test');
|
||||
expect(cleanStdout({ stdout: 'test ' })).toBe('test');
|
||||
});
|
||||
64
api/src/__test__/core/utils/misc/get-key-file.test.ts
Normal file
64
api/src/__test__/core/utils/misc/get-key-file.test.ts
Normal file
@@ -0,0 +1,64 @@
|
||||
import { expect, test } from 'vitest';
|
||||
|
||||
import { store } from '@app/store';
|
||||
import { FileLoadStatus, StateFileKey } from '@app/store/types';
|
||||
|
||||
import '@app/core/utils/misc/get-key-file';
|
||||
import '@app/store/modules/emhttp';
|
||||
|
||||
test('Before loading key returns null', async () => {
|
||||
const { getKeyFile } = await import('@app/core/utils/misc/get-key-file');
|
||||
const { status } = store.getState().registration;
|
||||
|
||||
expect(status).toBe(FileLoadStatus.UNLOADED);
|
||||
await expect(getKeyFile()).resolves.toBe(null);
|
||||
});
|
||||
|
||||
test('Requires emhttp to be loaded to find key file', async () => {
|
||||
const { getKeyFile } = await import('@app/core/utils/misc/get-key-file');
|
||||
const { loadRegistrationKey } = await import('@app/store/modules/registration');
|
||||
|
||||
// Load registration key into store
|
||||
await store.dispatch(loadRegistrationKey());
|
||||
|
||||
// Check if store has state files loaded
|
||||
const { status } = store.getState().registration;
|
||||
expect(status).toBe(FileLoadStatus.LOADED);
|
||||
await expect(getKeyFile()).resolves.toBe(null);
|
||||
});
|
||||
|
||||
test('Returns empty key if key location is empty', async () => {
|
||||
const { getKeyFile } = await import('@app/core/utils/misc/get-key-file');
|
||||
const { updateEmhttpState } = await import('@app/store/modules/emhttp');
|
||||
|
||||
// Set key file location as empty
|
||||
// This should only happen if the user doesn't have a key file
|
||||
store.dispatch(
|
||||
updateEmhttpState({
|
||||
field: StateFileKey.var,
|
||||
state: {
|
||||
regFile: '',
|
||||
},
|
||||
})
|
||||
);
|
||||
|
||||
// Check if store has state files loaded
|
||||
const { status } = store.getState().registration;
|
||||
expect(status).toBe(FileLoadStatus.LOADED);
|
||||
await expect(getKeyFile()).resolves.toBe('');
|
||||
});
|
||||
|
||||
test('Returns decoded key file if key location exists', async () => {
|
||||
const { getKeyFile } = await import('@app/core/utils/misc/get-key-file');
|
||||
const { loadStateFiles } = await import('@app/store/modules/emhttp');
|
||||
|
||||
// Load state files into store
|
||||
await store.dispatch(loadStateFiles());
|
||||
|
||||
// Check if store has state files loaded
|
||||
const { status } = store.getState().registration;
|
||||
expect(status).toBe(FileLoadStatus.LOADED);
|
||||
await expect(getKeyFile()).resolves.toMatchInlineSnapshot(
|
||||
'"hVs1tLjvC9FiiQsIwIQ7G1KszAcexf0IneThhnmf22SB0dGs5WzRkqMiSMmt2DtR5HOXFUD32YyxuzGeUXmky3zKpSu6xhZNKVg5atGM1OfvkzHBMldI3SeBLuUFSgejLbpNUMdTrbk64JJdbzle4O8wiQgkIpAMIGxeYLwLBD4zHBcfyzq40QnxG--HcX6j25eE0xqa2zWj-j0b0rCAXahJV2a3ySCbPzr1MvfPRTVb0rr7KJ-25R592hYrz4H7Sc1B3p0lr6QUxHE6o7bcYrWKDRtIVoZ8SMPpd1_0gzYIcl5GsDFzFumTXUh8NEnl0Q8hwW1YE-tRc6Y_rrvd7w"'
|
||||
);
|
||||
});
|
||||
116
api/src/__test__/core/utils/misc/parse-config.test.ts
Normal file
116
api/src/__test__/core/utils/misc/parse-config.test.ts
Normal file
@@ -0,0 +1,116 @@
|
||||
import { readFile, writeFile } from 'fs/promises';
|
||||
|
||||
import { parse } from 'ini';
|
||||
import { Parser as MultiIniParser } from 'multi-ini';
|
||||
import { expect, test } from 'vitest';
|
||||
|
||||
import { safelySerializeObjectToIni } from '@app/core/utils/files/safe-ini-serializer';
|
||||
import { parseConfig } from '@app/core/utils/misc/parse-config';
|
||||
|
||||
const iniTestData = `["root"]
|
||||
idx="0"
|
||||
name="root"
|
||||
desc="Console and webGui login account"
|
||||
passwd="yes"
|
||||
["xo"]
|
||||
idx="1"
|
||||
name="xo"
|
||||
desc=""
|
||||
passwd="yes"
|
||||
["test_user"]
|
||||
idx="2"
|
||||
name="test_user"
|
||||
desc=""
|
||||
passwd="no"`;
|
||||
|
||||
test('it loads a config from a passed in ini file successfully', () => {
|
||||
const res = parseConfig<any>({
|
||||
file: iniTestData,
|
||||
type: 'ini',
|
||||
});
|
||||
expect(res).toMatchInlineSnapshot(`
|
||||
{
|
||||
"root": {
|
||||
"desc": "Console and webGui login account",
|
||||
"idx": "0",
|
||||
"name": "root",
|
||||
"passwd": "yes",
|
||||
},
|
||||
"testUser": {
|
||||
"desc": "",
|
||||
"idx": "2",
|
||||
"name": "test_user",
|
||||
"passwd": "no",
|
||||
},
|
||||
"xo": {
|
||||
"desc": "",
|
||||
"idx": "1",
|
||||
"name": "xo",
|
||||
"passwd": "yes",
|
||||
},
|
||||
}
|
||||
`);
|
||||
expect(res?.root.desc).toEqual('Console and webGui login account');
|
||||
});
|
||||
|
||||
test('it loads a config from disk properly', () => {
|
||||
const path = './dev/states/var.ini';
|
||||
const res = parseConfig<any>({ filePath: path, type: 'ini' });
|
||||
expect(res.DOMAIN_SHORT).toEqual(undefined);
|
||||
expect(res.domainShort).toEqual('');
|
||||
expect(res.shareCount).toEqual('0');
|
||||
});
|
||||
|
||||
test('Confirm Multi-Ini Parser Still Broken', () => {
|
||||
const parser = new MultiIniParser();
|
||||
const res = parser.parse(iniTestData);
|
||||
expect(res).toMatchInlineSnapshot('{}');
|
||||
});
|
||||
|
||||
test('Combine Ini and Multi-Ini to read and then write a file with quotes', async () => {
|
||||
const parsedFile = parse(iniTestData);
|
||||
expect(parsedFile).toMatchInlineSnapshot(`
|
||||
{
|
||||
"root": {
|
||||
"desc": "Console and webGui login account",
|
||||
"idx": "0",
|
||||
"name": "root",
|
||||
"passwd": "yes",
|
||||
},
|
||||
"test_user": {
|
||||
"desc": "",
|
||||
"idx": "2",
|
||||
"name": "test_user",
|
||||
"passwd": "no",
|
||||
},
|
||||
"xo": {
|
||||
"desc": "",
|
||||
"idx": "1",
|
||||
"name": "xo",
|
||||
"passwd": "yes",
|
||||
},
|
||||
}
|
||||
`);
|
||||
|
||||
const ini = safelySerializeObjectToIni(parsedFile);
|
||||
await writeFile('/tmp/test.ini', ini);
|
||||
const file = await readFile('/tmp/test.ini', 'utf-8');
|
||||
expect(file).toMatchInlineSnapshot(`
|
||||
"[root]
|
||||
idx="0"
|
||||
name="root"
|
||||
desc="Console and webGui login account"
|
||||
passwd="yes"
|
||||
[xo]
|
||||
idx="1"
|
||||
name="xo"
|
||||
desc=""
|
||||
passwd="yes"
|
||||
[test_user]
|
||||
idx="2"
|
||||
name="test_user"
|
||||
desc=""
|
||||
passwd="no"
|
||||
"
|
||||
`);
|
||||
});
|
||||
@@ -1,12 +1,13 @@
|
||||
import { expect, test } from 'vitest';
|
||||
|
||||
import { getShares } from '@app/core/utils/shares/get-shares';
|
||||
import { store } from '@app/store';
|
||||
import { loadStateFiles } from '@app/store/modules/emhttp';
|
||||
|
||||
test('Returns both disk and user shares', async () => {
|
||||
await store.dispatch(loadStateFiles());
|
||||
await store.dispatch(loadStateFiles());
|
||||
|
||||
expect(getShares()).toMatchInlineSnapshot(`
|
||||
expect(getShares()).toMatchInlineSnapshot(`
|
||||
{
|
||||
"disks": [],
|
||||
"users": [
|
||||
@@ -96,8 +97,8 @@ test('Returns both disk and user shares', async () => {
|
||||
});
|
||||
|
||||
test('Returns shares by type', async () => {
|
||||
await store.dispatch(loadStateFiles());
|
||||
expect(getShares('user')).toMatchInlineSnapshot(`
|
||||
await store.dispatch(loadStateFiles());
|
||||
expect(getShares('user')).toMatchInlineSnapshot(`
|
||||
{
|
||||
"allocator": "highwater",
|
||||
"cachePool": "cache",
|
||||
@@ -119,7 +120,7 @@ test('Returns shares by type', async () => {
|
||||
"used": 33619300,
|
||||
}
|
||||
`);
|
||||
expect(getShares('users')).toMatchInlineSnapshot(`
|
||||
expect(getShares('users')).toMatchInlineSnapshot(`
|
||||
[
|
||||
{
|
||||
"allocator": "highwater",
|
||||
@@ -203,12 +204,12 @@ test('Returns shares by type', async () => {
|
||||
},
|
||||
]
|
||||
`);
|
||||
expect(getShares('disk')).toMatchInlineSnapshot('null');
|
||||
expect(getShares('disks')).toMatchInlineSnapshot('[]');
|
||||
expect(getShares('disk')).toMatchInlineSnapshot('null');
|
||||
expect(getShares('disks')).toMatchInlineSnapshot('[]');
|
||||
});
|
||||
|
||||
test('Returns shares by name', async () => {
|
||||
expect(getShares('user', { name: 'domains' })).toMatchInlineSnapshot(`
|
||||
expect(getShares('user', { name: 'domains' })).toMatchInlineSnapshot(`
|
||||
{
|
||||
"allocator": "highwater",
|
||||
"cachePool": "cache",
|
||||
@@ -230,8 +231,8 @@ test('Returns shares by name', async () => {
|
||||
"used": 33619300,
|
||||
}
|
||||
`);
|
||||
expect(getShares('user', { name: 'non-existent-user-share' })).toMatchInlineSnapshot('null');
|
||||
// @TODO: disk shares need to be added to the dev ini files
|
||||
expect(getShares('disk', { name: 'disk1' })).toMatchInlineSnapshot('null');
|
||||
expect(getShares('disk', { name: 'non-existent-disk-share' })).toMatchInlineSnapshot('null');
|
||||
expect(getShares('user', { name: 'non-existent-user-share' })).toMatchInlineSnapshot('null');
|
||||
// @TODO: disk shares need to be added to the dev ini files
|
||||
expect(getShares('disk', { name: 'disk1' })).toMatchInlineSnapshot('null');
|
||||
expect(getShares('disk', { name: 'non-existent-disk-share' })).toMatchInlineSnapshot('null');
|
||||
});
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
import { afterEach, expect, test, vi } from 'vitest';
|
||||
|
||||
import { checkDNS } from '@app/graphql/resolvers/query/cloud/check-dns';
|
||||
import { store } from '@app/store';
|
||||
import { clearKey } from '@app/store/modules/cache';
|
||||
import { CacheKeys } from '@app/store/types';
|
||||
|
||||
afterEach(() => {
|
||||
store.dispatch(clearKey(CacheKeys.checkDns));
|
||||
});
|
||||
|
||||
test('it resolves dns successfully', async () => {
|
||||
// @TODO
|
||||
const dns = await checkDNS('example.com');
|
||||
expect(dns.cloudIp).not.toBeNull();
|
||||
}, 25_000);
|
||||
|
||||
test('testing twice results in a cache hit', async () => {
|
||||
// Hit mothership
|
||||
const getters = await import('@app/store/getters');
|
||||
const dnsSpy = vi.spyOn(getters, 'getDnsCache');
|
||||
const dns = await checkDNS();
|
||||
expect(dns.cloudIp).toBeTypeOf('string');
|
||||
expect(dnsSpy.mock.results[0]).toMatchInlineSnapshot(`
|
||||
{
|
||||
"type": "return",
|
||||
"value": undefined,
|
||||
}
|
||||
`);
|
||||
const dnslookup2 = await checkDNS();
|
||||
expect(dnslookup2.cloudIp).toEqual(dns.cloudIp);
|
||||
expect(dnsSpy.mock.results[1].value.cloudIp).toEqual(dns.cloudIp);
|
||||
expect(store.getState().cache.nodeCache.getTtl(CacheKeys.checkDns)).toBeGreaterThan(500);
|
||||
});
|
||||
@@ -0,0 +1,26 @@
|
||||
import 'reflect-metadata';
|
||||
|
||||
import { expect, test } from 'vitest';
|
||||
|
||||
import packageJson from '@app/../package.json';
|
||||
import { checkMothershipAuthentication } from '@app/graphql/resolvers/query/cloud/check-mothership-authentication';
|
||||
|
||||
test('It fails to authenticate with mothership with no credentials', async () => {
|
||||
try {
|
||||
await expect(
|
||||
checkMothershipAuthentication('BAD', 'BAD')
|
||||
).rejects.toThrowErrorMatchingInlineSnapshot(
|
||||
`[Error: Failed to connect to https://mothership.unraid.net/ws with a "426" HTTP error.]`
|
||||
);
|
||||
expect(packageJson.version).not.toBeNull();
|
||||
await expect(
|
||||
checkMothershipAuthentication(packageJson.version, 'BAD_API_KEY')
|
||||
).rejects.toThrowErrorMatchingInlineSnapshot(`[Error: Invalid credentials]`);
|
||||
} catch (error) {
|
||||
if (error instanceof Error && error.message.includes('Timeout')) {
|
||||
// Test succeeds on timeout
|
||||
return;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
});
|
||||
279
api/src/__test__/graphql/resolvers/subscription/network.test.ts
Normal file
279
api/src/__test__/graphql/resolvers/subscription/network.test.ts
Normal file
@@ -0,0 +1,279 @@
|
||||
import { expect, test } from 'vitest';
|
||||
|
||||
import type { NginxUrlFields } from '@app/graphql/resolvers/subscription/network';
|
||||
import { type Nginx } from '@app/core/types/states/nginx';
|
||||
import {
|
||||
getServerIps,
|
||||
getUrlForField,
|
||||
getUrlForServer,
|
||||
} from '@app/graphql/resolvers/subscription/network';
|
||||
import { store } from '@app/store';
|
||||
import { loadConfigFile } from '@app/store/modules/config';
|
||||
import { loadStateFiles } from '@app/store/modules/emhttp';
|
||||
|
||||
test.each([
|
||||
[{ httpPort: 80, httpsPort: 443, url: 'my-default-url.com' }],
|
||||
[{ httpPort: 123, httpsPort: 443, url: 'my-default-url.com' }],
|
||||
[{ httpPort: 80, httpsPort: 12_345, url: 'my-default-url.com' }],
|
||||
[{ httpPort: 212, httpsPort: 3_233, url: 'my-default-url.com' }],
|
||||
[{ httpPort: 80, httpsPort: 443, url: 'https://BROKEN_URL' }],
|
||||
])('getUrlForField', ({ httpPort, httpsPort, url }) => {
|
||||
const responseInsecure = getUrlForField({
|
||||
port: httpPort,
|
||||
url,
|
||||
});
|
||||
|
||||
const responseSecure = getUrlForField({
|
||||
portSsl: httpsPort,
|
||||
url,
|
||||
});
|
||||
if (httpPort === 80) {
|
||||
expect(responseInsecure.port).toBe('');
|
||||
} else {
|
||||
expect(responseInsecure.port).toBe(httpPort.toString());
|
||||
}
|
||||
|
||||
if (httpsPort === 443) {
|
||||
expect(responseSecure.port).toBe('');
|
||||
} else {
|
||||
expect(responseSecure.port).toBe(httpsPort.toString());
|
||||
}
|
||||
});
|
||||
|
||||
test('getUrlForServer - field exists, ssl disabled', () => {
|
||||
const result = getUrlForServer({
|
||||
nginx: {
|
||||
lanIp: '192.168.1.1',
|
||||
sslEnabled: false,
|
||||
httpPort: 123,
|
||||
httpsPort: 445,
|
||||
} as const as Nginx,
|
||||
field: 'lanIp',
|
||||
});
|
||||
expect(result).toMatchInlineSnapshot('"http://192.168.1.1:123/"');
|
||||
});
|
||||
|
||||
test('getUrlForServer - field exists, ssl yes', () => {
|
||||
const result = getUrlForServer({
|
||||
nginx: {
|
||||
lanIp: '192.168.1.1',
|
||||
sslEnabled: true,
|
||||
sslMode: 'yes',
|
||||
httpPort: 123,
|
||||
httpsPort: 445,
|
||||
} as const as Nginx,
|
||||
field: 'lanIp',
|
||||
});
|
||||
expect(result).toMatchInlineSnapshot('"https://192.168.1.1:445/"');
|
||||
});
|
||||
|
||||
test('getUrlForServer - field exists, ssl yes, port empty', () => {
|
||||
const result = getUrlForServer({
|
||||
nginx: {
|
||||
lanIp: '192.168.1.1',
|
||||
sslEnabled: true,
|
||||
sslMode: 'yes',
|
||||
httpPort: 80,
|
||||
httpsPort: 443,
|
||||
} as const as Nginx,
|
||||
field: 'lanIp',
|
||||
});
|
||||
expect(result).toMatchInlineSnapshot('"https://192.168.1.1/"');
|
||||
});
|
||||
|
||||
test('getUrlForServer - field exists, ssl auto', async () => {
|
||||
const getResult = async () =>
|
||||
getUrlForServer({
|
||||
nginx: {
|
||||
lanIp: '192.168.1.1',
|
||||
sslEnabled: true,
|
||||
sslMode: 'auto',
|
||||
httpPort: 123,
|
||||
httpsPort: 445,
|
||||
} as const as Nginx,
|
||||
field: 'lanIp',
|
||||
});
|
||||
await expect(getResult).rejects.toThrowErrorMatchingInlineSnapshot(
|
||||
`[Error: Cannot get IP Based URL for field: "lanIp" SSL mode auto]`
|
||||
);
|
||||
});
|
||||
|
||||
test('getUrlForServer - field does not exist, ssl disabled', async () => {
|
||||
const getResult = async () =>
|
||||
getUrlForServer({
|
||||
nginx: { lanIp: '192.168.1.1', sslEnabled: false, sslMode: 'no' } as const as Nginx,
|
||||
ports: {
|
||||
port: ':123',
|
||||
portSsl: ':445',
|
||||
defaultUrl: new URL('https://my-default-url.unraid.net'),
|
||||
},
|
||||
// @ts-expect-error Field doesn't exist
|
||||
field: 'idontexist',
|
||||
});
|
||||
await expect(getResult).rejects.toThrowErrorMatchingInlineSnapshot(
|
||||
`[Error: IP URL Resolver: Could not resolve any access URL for field: "idontexist", is FQDN?: false]`
|
||||
);
|
||||
});
|
||||
|
||||
test('getUrlForServer - FQDN - field exists, port non-empty', () => {
|
||||
const result = getUrlForServer({
|
||||
nginx: { lanFqdn: 'my-fqdn.unraid.net', httpsPort: 445 } as const as Nginx,
|
||||
field: 'lanFqdn',
|
||||
});
|
||||
expect(result).toMatchInlineSnapshot('"https://my-fqdn.unraid.net:445/"');
|
||||
});
|
||||
|
||||
test('getUrlForServer - FQDN - field exists, port empty', () => {
|
||||
const result = getUrlForServer({
|
||||
nginx: { lanFqdn: 'my-fqdn.unraid.net', httpPort: 80, httpsPort: 443 } as const as Nginx,
|
||||
field: 'lanFqdn',
|
||||
});
|
||||
expect(result).toMatchInlineSnapshot('"https://my-fqdn.unraid.net/"');
|
||||
});
|
||||
|
||||
test.each([
|
||||
[
|
||||
{
|
||||
nginx: {
|
||||
lanFqdn: 'my-fqdn.unraid.net',
|
||||
sslEnabled: false,
|
||||
sslMode: 'no',
|
||||
httpPort: 80,
|
||||
httpsPort: 443,
|
||||
} as const as Nginx,
|
||||
field: 'lanFqdn' as NginxUrlFields,
|
||||
},
|
||||
],
|
||||
[
|
||||
{
|
||||
nginx: {
|
||||
wanFqdn: 'my-fqdn.unraid.net',
|
||||
sslEnabled: true,
|
||||
sslMode: 'yes',
|
||||
httpPort: 80,
|
||||
httpsPort: 443,
|
||||
} as const as Nginx,
|
||||
field: 'wanFqdn' as NginxUrlFields,
|
||||
},
|
||||
],
|
||||
[
|
||||
{
|
||||
nginx: {
|
||||
wanFqdn6: 'my-fqdn.unraid.net',
|
||||
sslEnabled: true,
|
||||
sslMode: 'auto',
|
||||
httpPort: 80,
|
||||
httpsPort: 443,
|
||||
} as const as Nginx,
|
||||
field: 'wanFqdn6' as NginxUrlFields,
|
||||
},
|
||||
],
|
||||
])('getUrlForServer - FQDN', ({ nginx, field }) => {
|
||||
const result = getUrlForServer({ nginx, field });
|
||||
expect(result.toString()).toBe('https://my-fqdn.unraid.net/');
|
||||
});
|
||||
|
||||
test('getUrlForServer - field does not exist, ssl disabled', async () => {
|
||||
const getResult = async () =>
|
||||
getUrlForServer({
|
||||
nginx: { lanFqdn: 'my-fqdn.unraid.net' } as const as Nginx,
|
||||
ports: { portSsl: '', port: '', defaultUrl: new URL('https://my-default-url.unraid.net') },
|
||||
// @ts-expect-error Field doesn't exist
|
||||
field: 'idontexist',
|
||||
});
|
||||
await expect(getResult).rejects.toThrowErrorMatchingInlineSnapshot(
|
||||
`[Error: IP URL Resolver: Could not resolve any access URL for field: "idontexist", is FQDN?: false]`
|
||||
);
|
||||
});
|
||||
|
||||
test('integration test, loading nginx ini and generating all URLs', async () => {
|
||||
await store.dispatch(loadStateFiles());
|
||||
await store.dispatch(loadConfigFile());
|
||||
|
||||
const urls = getServerIps();
|
||||
expect(urls.urls).toMatchInlineSnapshot(`
|
||||
[
|
||||
{
|
||||
"ipv4": "https://tower.local:4443/",
|
||||
"ipv6": "https://tower.local:4443/",
|
||||
"name": "Default",
|
||||
"type": "DEFAULT",
|
||||
},
|
||||
{
|
||||
"ipv4": "https://192.168.1.150:4443/",
|
||||
"name": "LAN IPv4",
|
||||
"type": "LAN",
|
||||
},
|
||||
{
|
||||
"ipv4": "https://tower:4443/",
|
||||
"name": "LAN Name",
|
||||
"type": "MDNS",
|
||||
},
|
||||
{
|
||||
"ipv4": "https://tower.local:4443/",
|
||||
"name": "LAN MDNS",
|
||||
"type": "MDNS",
|
||||
},
|
||||
{
|
||||
"ipv4": "https://192-168-1-150.thisisfourtyrandomcharacters012345678900.myunraid.net:4443/",
|
||||
"name": "FQDN LAN",
|
||||
"type": "LAN",
|
||||
},
|
||||
{
|
||||
"ipv4": "https://85-121-123-122.thisisfourtyrandomcharacters012345678900.myunraid.net:8443/",
|
||||
"name": "FQDN WAN",
|
||||
"type": "WAN",
|
||||
},
|
||||
{
|
||||
"ipv4": "https://10-252-0-1.hash.myunraid.net:4443/",
|
||||
"name": "FQDN WG 0",
|
||||
"type": "WIREGUARD",
|
||||
},
|
||||
{
|
||||
"ipv4": "https://10-252-1-1.hash.myunraid.net:4443/",
|
||||
"name": "FQDN WG 1",
|
||||
"type": "WIREGUARD",
|
||||
},
|
||||
{
|
||||
"ipv4": "https://10-253-3-1.hash.myunraid.net:4443/",
|
||||
"name": "FQDN WG 2",
|
||||
"type": "WIREGUARD",
|
||||
},
|
||||
{
|
||||
"ipv4": "https://10-253-4-1.hash.myunraid.net:4443/",
|
||||
"name": "FQDN WG 3",
|
||||
"type": "WIREGUARD",
|
||||
},
|
||||
{
|
||||
"ipv4": "https://10-253-5-1.hash.myunraid.net:4443/",
|
||||
"name": "FQDN WG 4",
|
||||
"type": "WIREGUARD",
|
||||
},
|
||||
{
|
||||
"ipv4": "https://10-100-0-1.hash.myunraid.net:4443/",
|
||||
"name": "FQDN TAILSCALE 0",
|
||||
"type": "WIREGUARD",
|
||||
},
|
||||
{
|
||||
"ipv4": "https://10-100-0-2.hash.myunraid.net:4443/",
|
||||
"name": "FQDN TAILSCALE 1",
|
||||
"type": "WIREGUARD",
|
||||
},
|
||||
{
|
||||
"ipv4": "https://10-123-1-2.hash.myunraid.net:4443/",
|
||||
"name": "FQDN CUSTOM 0",
|
||||
"type": "WIREGUARD",
|
||||
},
|
||||
{
|
||||
"ipv4": "https://221-123-121-112.hash.myunraid.net:4443/",
|
||||
"name": "FQDN CUSTOM 1",
|
||||
"type": "WIREGUARD",
|
||||
},
|
||||
]
|
||||
`);
|
||||
expect(urls.errors).toMatchInlineSnapshot(`
|
||||
[
|
||||
[Error: IP URL Resolver: Could not resolve any access URL for field: "lanIp6", is FQDN?: false],
|
||||
]
|
||||
`);
|
||||
});
|
||||
48
api/src/__test__/mothership/index.test.ts
Normal file
48
api/src/__test__/mothership/index.test.ts
Normal file
@@ -0,0 +1,48 @@
|
||||
import { beforeEach, expect, test, vi } from 'vitest';
|
||||
|
||||
// Preloading imports for faster tests
|
||||
import '@app/mothership/utils/convert-to-fuzzy-time';
|
||||
|
||||
vi.mock('fs', () => ({
|
||||
default: {
|
||||
readFileSync: vi.fn().mockReturnValue('my-file'),
|
||||
writeFileSync: vi.fn(),
|
||||
existsSync: vi.fn(),
|
||||
},
|
||||
readFileSync: vi.fn().mockReturnValue('my-file'),
|
||||
existsSync: vi.fn(),
|
||||
}));
|
||||
|
||||
vi.mock('@graphql-tools/schema', () => ({
|
||||
makeExecutableSchema: vi.fn(),
|
||||
}));
|
||||
|
||||
vi.mock('@app/core/log', () => ({
|
||||
default: { relayLogger: { trace: vi.fn() } },
|
||||
relayLogger: { trace: vi.fn() },
|
||||
logger: { trace: vi.fn() },
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
vi.resetModules();
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
const generateTestCases = () => {
|
||||
const cases: Array<{ min: number; max: number }> = [];
|
||||
for (let i = 0; i < 15; i += 1) {
|
||||
const min = Math.round(Math.random() * 100);
|
||||
const max = min + Math.round(Math.random() * 20);
|
||||
cases.push({ min, max });
|
||||
}
|
||||
|
||||
return cases;
|
||||
};
|
||||
|
||||
test.each(generateTestCases())('Successfully converts to fuzzy time %o', async ({ min, max }) => {
|
||||
const { convertToFuzzyTime } = await import('@app/mothership/utils/convert-to-fuzzy-time');
|
||||
|
||||
const res = convertToFuzzyTime(min, max);
|
||||
expect(res).toBeGreaterThanOrEqual(min);
|
||||
expect(res).toBeLessThanOrEqual(max);
|
||||
});
|
||||
6
api/src/__test__/setup/child-process-easy-to-kill.js
Executable file
6
api/src/__test__/setup/child-process-easy-to-kill.js
Executable file
@@ -0,0 +1,6 @@
|
||||
/* eslint-disable */
|
||||
process.title = 'unraid-api';
|
||||
|
||||
setInterval(() => {
|
||||
console.log('I NEED TO DIE');
|
||||
}, 5_000);
|
||||
10
api/src/__test__/setup/child-process-hard-to-kill.js
Normal file
10
api/src/__test__/setup/child-process-hard-to-kill.js
Normal file
@@ -0,0 +1,10 @@
|
||||
/* eslint-disable */
|
||||
process.title = 'unraid-api';
|
||||
setInterval(() => {
|
||||
console.log('I NEED TO DIE (but i am very hard to kill)');
|
||||
}, 5_000);
|
||||
|
||||
process.on('SIGTERM', () => {
|
||||
// Do nothing
|
||||
console.log('you cant kill me haha');
|
||||
});
|
||||
7
api/src/__test__/setup/env-setup.ts
Normal file
7
api/src/__test__/setup/env-setup.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import { config } from 'dotenv';
|
||||
|
||||
config({
|
||||
path: './.env.test',
|
||||
debug: false,
|
||||
encoding: 'utf-8',
|
||||
});
|
||||
6
api/src/__test__/setup/keyserver-mock.ts
Normal file
6
api/src/__test__/setup/keyserver-mock.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
import { vi } from 'vitest';
|
||||
|
||||
vi.mock('@app/core/utils/misc/send-form-to-keyserver', () => {
|
||||
const sendFormToKeyServer = vi.fn().mockResolvedValue({ body: JSON.stringify({ valid: true }) });
|
||||
return { sendFormToKeyServer };
|
||||
});
|
||||
@@ -0,0 +1,36 @@
|
||||
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
||||
|
||||
exports[`Before init returns default values for all fields 1`] = `
|
||||
{
|
||||
"api": {
|
||||
"extraOrigins": "",
|
||||
"version": "",
|
||||
},
|
||||
"connectionStatus": {
|
||||
"minigraph": "PRE_INIT",
|
||||
"upnpStatus": "",
|
||||
},
|
||||
"local": {
|
||||
"sandbox": "no",
|
||||
},
|
||||
"nodeEnv": "test",
|
||||
"remote": {
|
||||
"accesstoken": "",
|
||||
"allowedOrigins": "",
|
||||
"apikey": "",
|
||||
"avatar": "",
|
||||
"dynamicRemoteAccessType": "DISABLED",
|
||||
"email": "",
|
||||
"idtoken": "",
|
||||
"localApiKey": "",
|
||||
"refreshtoken": "",
|
||||
"regWizTime": "",
|
||||
"ssoSubIds": "",
|
||||
"upnpEnabled": "",
|
||||
"username": "",
|
||||
"wanaccess": "",
|
||||
"wanport": "",
|
||||
},
|
||||
"status": "UNLOADED",
|
||||
}
|
||||
`;
|
||||
@@ -6,7 +6,7 @@ exports[`loads notifications properly 1`] = `
|
||||
"description": "Canceled",
|
||||
"id": "/app/dev/notifications/unread/Unraid_Parity_check_1683971161.notify",
|
||||
"importance": "WARNING",
|
||||
"link": undefined,
|
||||
"link": "/",
|
||||
"subject": "Notice [UNRAID] - Parity check finished (0 errors)",
|
||||
"timestamp": "2023-05-13T09:46:01.000Z",
|
||||
"title": "Unraid Parity check",
|
||||
|
||||
@@ -1,48 +1,11 @@
|
||||
import { test, expect } from 'vitest';
|
||||
import { expect, test } from 'vitest';
|
||||
|
||||
import { store } from '@app/store';
|
||||
import { MyServersConfigMemory } from '@app/types/my-servers-config';
|
||||
|
||||
test('Before init returns default values for all fields', async () => {
|
||||
const state = store.getState().config;
|
||||
expect(state).toMatchInlineSnapshot(`
|
||||
{
|
||||
"api": {
|
||||
"extraOrigins": "",
|
||||
"version": "",
|
||||
},
|
||||
"connectionStatus": {
|
||||
"minigraph": "PRE_INIT",
|
||||
"upnpStatus": "",
|
||||
},
|
||||
"local": {
|
||||
"2Fa": "",
|
||||
"showT2Fa": "",
|
||||
},
|
||||
"nodeEnv": "test",
|
||||
"notifier": {
|
||||
"apikey": "",
|
||||
},
|
||||
"remote": {
|
||||
"2Fa": "",
|
||||
"accesstoken": "",
|
||||
"allowedOrigins": "",
|
||||
"apikey": "",
|
||||
"avatar": "",
|
||||
"dynamicRemoteAccessType": "DISABLED",
|
||||
"email": "",
|
||||
"idtoken": "",
|
||||
"refreshtoken": "",
|
||||
"regWizTime": "",
|
||||
"upnpEnabled": "",
|
||||
"username": "",
|
||||
"wanaccess": "",
|
||||
"wanport": "",
|
||||
},
|
||||
"status": "UNLOADED",
|
||||
"upc": {
|
||||
"apikey": "",
|
||||
},
|
||||
}
|
||||
`);
|
||||
expect(state).toMatchSnapshot();
|
||||
}, 10_000);
|
||||
|
||||
test('After init returns values from cfg file for all fields', async () => {
|
||||
@@ -56,7 +19,7 @@ test('After init returns values from cfg file for all fields', async () => {
|
||||
expect(state).toMatchObject(
|
||||
expect.objectContaining({
|
||||
api: {
|
||||
extraOrigins: '',
|
||||
extraOrigins: expect.stringMatching('https://google.com,https://test.com'),
|
||||
version: expect.any(String),
|
||||
},
|
||||
connectionStatus: {
|
||||
@@ -64,15 +27,10 @@ test('After init returns values from cfg file for all fields', async () => {
|
||||
upnpStatus: '',
|
||||
},
|
||||
local: {
|
||||
'2Fa': '',
|
||||
showT2Fa: '',
|
||||
sandbox: expect.any(String),
|
||||
},
|
||||
nodeEnv: 'test',
|
||||
notifier: {
|
||||
apikey: 'unnotify_30994bfaccf839c65bae75f7fa12dd5ee16e69389f754c3b98ed7d5',
|
||||
},
|
||||
remote: {
|
||||
'2Fa': '',
|
||||
accesstoken: '',
|
||||
allowedOrigins: '',
|
||||
apikey: '_______________________BIG_API_KEY_HERE_________________________',
|
||||
@@ -80,25 +38,22 @@ test('After init returns values from cfg file for all fields', async () => {
|
||||
dynamicRemoteAccessType: 'DISABLED',
|
||||
email: 'test@example.com',
|
||||
idtoken: '',
|
||||
localApiKey: '_______________________LOCAL_API_KEY_HERE_________________________',
|
||||
refreshtoken: '',
|
||||
regWizTime: '1611175408732_0951-1653-3509-FBA155FA23C0',
|
||||
ssoSubIds: '',
|
||||
upnpEnabled: 'no',
|
||||
username: 'zspearmint',
|
||||
wanaccess: 'yes',
|
||||
wanport: '8443',
|
||||
},
|
||||
status: 'LOADED',
|
||||
upc: {
|
||||
apikey: 'unupc_fab6ff6ffe51040595c6d9ffb63a353ba16cc2ad7d93f813a2e80a5810',
|
||||
},
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
test('updateUserConfig merges in changes to current state', async () => {
|
||||
const { loadConfigFile, updateUserConfig } = await import(
|
||||
'@app/store/modules/config'
|
||||
);
|
||||
const { loadConfigFile, updateUserConfig } = await import('@app/store/modules/config');
|
||||
|
||||
// Load cfg into store
|
||||
await store.dispatch(loadConfigFile());
|
||||
@@ -114,7 +69,7 @@ test('updateUserConfig merges in changes to current state', async () => {
|
||||
expect(state).toMatchObject(
|
||||
expect.objectContaining({
|
||||
api: {
|
||||
extraOrigins: '',
|
||||
extraOrigins: expect.stringMatching('https://google.com,https://test.com'),
|
||||
version: expect.any(String),
|
||||
},
|
||||
connectionStatus: {
|
||||
@@ -122,15 +77,10 @@ test('updateUserConfig merges in changes to current state', async () => {
|
||||
upnpStatus: '',
|
||||
},
|
||||
local: {
|
||||
'2Fa': '',
|
||||
showT2Fa: '',
|
||||
sandbox: expect.any(String),
|
||||
},
|
||||
nodeEnv: 'test',
|
||||
notifier: {
|
||||
apikey: 'unnotify_30994bfaccf839c65bae75f7fa12dd5ee16e69389f754c3b98ed7d5',
|
||||
},
|
||||
remote: {
|
||||
'2Fa': '',
|
||||
accesstoken: '',
|
||||
allowedOrigins: '',
|
||||
apikey: '_______________________BIG_API_KEY_HERE_________________________',
|
||||
@@ -138,17 +88,16 @@ test('updateUserConfig merges in changes to current state', async () => {
|
||||
dynamicRemoteAccessType: 'DISABLED',
|
||||
email: 'test@example.com',
|
||||
idtoken: '',
|
||||
localApiKey: '_______________________LOCAL_API_KEY_HERE_________________________',
|
||||
refreshtoken: '',
|
||||
regWizTime: '1611175408732_0951-1653-3509-FBA155FA23C0',
|
||||
ssoSubIds: '',
|
||||
upnpEnabled: 'no',
|
||||
username: 'zspearmint',
|
||||
wanaccess: 'yes',
|
||||
wanport: '8443',
|
||||
},
|
||||
status: 'LOADED',
|
||||
upc: {
|
||||
apikey: 'unupc_fab6ff6ffe51040595c6d9ffb63a353ba16cc2ad7d93f813a2e80a5810',
|
||||
},
|
||||
})
|
||||
} as MyServersConfigMemory)
|
||||
);
|
||||
});
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { test, expect } from 'vitest';
|
||||
import { expect, test } from 'vitest';
|
||||
|
||||
import { store } from '@app/store';
|
||||
import { FileLoadStatus } from '@app/store/types';
|
||||
|
||||
@@ -6,9 +7,9 @@ import { FileLoadStatus } from '@app/store/types';
|
||||
import '@app/store/modules/emhttp';
|
||||
|
||||
test('Before init returns default values for all fields', async () => {
|
||||
const { status, ...state } = store.getState().emhttp;
|
||||
expect(status).toBe(FileLoadStatus.UNLOADED);
|
||||
expect(state).toMatchInlineSnapshot(`
|
||||
const { status, ...state } = store.getState().emhttp;
|
||||
expect(status).toBe(FileLoadStatus.UNLOADED);
|
||||
expect(state).toMatchInlineSnapshot(`
|
||||
{
|
||||
"devices": [],
|
||||
"disks": [],
|
||||
@@ -24,16 +25,27 @@ test('Before init returns default values for all fields', async () => {
|
||||
});
|
||||
|
||||
test('After init returns values from cfg file for all fields', async () => {
|
||||
const { loadStateFiles } = await import('@app/store/modules/emhttp');
|
||||
const { loadStateFiles } = await import('@app/store/modules/emhttp');
|
||||
|
||||
// Load state files into store
|
||||
await store.dispatch(loadStateFiles());
|
||||
// Load state files into store
|
||||
await store.dispatch(loadStateFiles());
|
||||
|
||||
// Check if store has state files loaded
|
||||
const { devices, networks, nfsShares, nginx, shares, disks, smbShares, status, users, var: varState } = store.getState().emhttp;
|
||||
expect(status).toBe(FileLoadStatus.LOADED);
|
||||
expect(devices).toMatchInlineSnapshot('[]');
|
||||
expect(networks).toMatchInlineSnapshot(`
|
||||
// Check if store has state files loaded
|
||||
const {
|
||||
devices,
|
||||
networks,
|
||||
nfsShares,
|
||||
nginx,
|
||||
shares,
|
||||
disks,
|
||||
smbShares,
|
||||
status,
|
||||
users,
|
||||
var: varState,
|
||||
} = store.getState().emhttp;
|
||||
expect(status).toBe(FileLoadStatus.LOADED);
|
||||
expect(devices).toMatchInlineSnapshot('[]');
|
||||
expect(networks).toMatchInlineSnapshot(`
|
||||
[
|
||||
{
|
||||
"bonding": true,
|
||||
@@ -99,15 +111,81 @@ test('After init returns values from cfg file for all fields', async () => {
|
||||
},
|
||||
]
|
||||
`);
|
||||
expect(nginx).toMatchInlineSnapshot(`
|
||||
expect(nginx).toMatchInlineSnapshot(`
|
||||
{
|
||||
"certificateName": "*.thisisfourtyrandomcharacters012345678900.myunraid.net",
|
||||
"certificatePath": "/boot/config/ssl/certs/certificate_bundle.pem",
|
||||
"defaultUrl": "https://Tower.local:4443",
|
||||
"fqdnUrls": [
|
||||
{
|
||||
"fqdn": "192-168-1-150.thisisfourtyrandomcharacters012345678900.myunraid.net",
|
||||
"id": null,
|
||||
"interface": "LAN",
|
||||
"isIpv6": false,
|
||||
},
|
||||
{
|
||||
"fqdn": "85-121-123-122.thisisfourtyrandomcharacters012345678900.myunraid.net",
|
||||
"id": null,
|
||||
"interface": "WAN",
|
||||
"isIpv6": false,
|
||||
},
|
||||
{
|
||||
"fqdn": "10-252-0-1.hash.myunraid.net",
|
||||
"id": 0,
|
||||
"interface": "WG",
|
||||
"isIpv6": false,
|
||||
},
|
||||
{
|
||||
"fqdn": "10-252-1-1.hash.myunraid.net",
|
||||
"id": 1,
|
||||
"interface": "WG",
|
||||
"isIpv6": false,
|
||||
},
|
||||
{
|
||||
"fqdn": "10-253-3-1.hash.myunraid.net",
|
||||
"id": 2,
|
||||
"interface": "WG",
|
||||
"isIpv6": false,
|
||||
},
|
||||
{
|
||||
"fqdn": "10-253-4-1.hash.myunraid.net",
|
||||
"id": 3,
|
||||
"interface": "WG",
|
||||
"isIpv6": false,
|
||||
},
|
||||
{
|
||||
"fqdn": "10-253-5-1.hash.myunraid.net",
|
||||
"id": 4,
|
||||
"interface": "WG",
|
||||
"isIpv6": false,
|
||||
},
|
||||
{
|
||||
"fqdn": "10-100-0-1.hash.myunraid.net",
|
||||
"id": 0,
|
||||
"interface": "TAILSCALE",
|
||||
"isIpv6": false,
|
||||
},
|
||||
{
|
||||
"fqdn": "10-100-0-2.hash.myunraid.net",
|
||||
"id": 1,
|
||||
"interface": "TAILSCALE",
|
||||
"isIpv6": false,
|
||||
},
|
||||
{
|
||||
"fqdn": "10-123-1-2.hash.myunraid.net",
|
||||
"id": 0,
|
||||
"interface": "CUSTOM",
|
||||
"isIpv6": false,
|
||||
},
|
||||
{
|
||||
"fqdn": "221-123-121-112.hash.myunraid.net",
|
||||
"id": 1,
|
||||
"interface": "CUSTOM",
|
||||
"isIpv6": true,
|
||||
},
|
||||
],
|
||||
"httpPort": 8080,
|
||||
"httpsPort": 4443,
|
||||
"lanFqdn": "192-168-1-150.thisisfourtyrandomcharacters012345678900.myunraid.net",
|
||||
"lanFqdn6": "",
|
||||
"lanIp": "192.168.1.150",
|
||||
"lanIp6": "",
|
||||
"lanMdns": "Tower.local",
|
||||
@@ -115,34 +193,10 @@ test('After init returns values from cfg file for all fields', async () => {
|
||||
"sslEnabled": true,
|
||||
"sslMode": "yes",
|
||||
"wanAccessEnabled": false,
|
||||
"wanFqdn": "85-121-123-122.thisisfourtyrandomcharacters012345678900.myunraid.net",
|
||||
"wanFqdn6": "",
|
||||
"wanIp": "",
|
||||
"wgFqdns": [
|
||||
{
|
||||
"fqdn": "10-252-0-1.hash.myunraid.net",
|
||||
"id": 0,
|
||||
},
|
||||
{
|
||||
"fqdn": "10-252-1-1.hash.myunraid.net",
|
||||
"id": 1,
|
||||
},
|
||||
{
|
||||
"fqdn": "10-253-3-1.hash.myunraid.net",
|
||||
"id": 3,
|
||||
},
|
||||
{
|
||||
"fqdn": "10-253-4-1.hash.myunraid.net",
|
||||
"id": 4,
|
||||
},
|
||||
{
|
||||
"fqdn": "10-253-5-1.hash.myunraid.net",
|
||||
"id": 55,
|
||||
},
|
||||
],
|
||||
}
|
||||
`);
|
||||
expect(disks).toMatchInlineSnapshot(`
|
||||
expect(disks).toMatchInlineSnapshot(`
|
||||
[
|
||||
{
|
||||
"comment": null,
|
||||
@@ -314,7 +368,7 @@ test('After init returns values from cfg file for all fields', async () => {
|
||||
},
|
||||
]
|
||||
`);
|
||||
expect(shares).toMatchInlineSnapshot(`
|
||||
expect(shares).toMatchInlineSnapshot(`
|
||||
[
|
||||
{
|
||||
"allocator": "highwater",
|
||||
@@ -390,7 +444,7 @@ test('After init returns values from cfg file for all fields', async () => {
|
||||
},
|
||||
]
|
||||
`);
|
||||
expect(nfsShares).toMatchInlineSnapshot(`
|
||||
expect(nfsShares).toMatchInlineSnapshot(`
|
||||
[
|
||||
{
|
||||
"enabled": false,
|
||||
@@ -578,7 +632,7 @@ test('After init returns values from cfg file for all fields', async () => {
|
||||
},
|
||||
]
|
||||
`);
|
||||
expect(smbShares).toMatchInlineSnapshot(`
|
||||
expect(smbShares).toMatchInlineSnapshot(`
|
||||
[
|
||||
{
|
||||
"caseSensitive": "auto",
|
||||
@@ -869,7 +923,7 @@ test('After init returns values from cfg file for all fields', async () => {
|
||||
},
|
||||
]
|
||||
`);
|
||||
expect(users).toMatchInlineSnapshot(`
|
||||
expect(users).toMatchInlineSnapshot(`
|
||||
[
|
||||
{
|
||||
"description": "Console and webGui login account",
|
||||
@@ -894,7 +948,7 @@ test('After init returns values from cfg file for all fields', async () => {
|
||||
},
|
||||
]
|
||||
`);
|
||||
expect(varState).toMatchInlineSnapshot(`
|
||||
expect(varState).toMatchInlineSnapshot(`
|
||||
{
|
||||
"bindMgt": false,
|
||||
"cacheNumDevices": NaN,
|
||||
@@ -984,6 +1038,7 @@ test('After init returns values from cfg file for all fields', async () => {
|
||||
"porttelnet": 23,
|
||||
"queueDepth": "auto",
|
||||
"regCheck": "Valid",
|
||||
"regExp": "",
|
||||
"regFile": "/app/dev/Unraid.net/Pro.key",
|
||||
"regGen": "0",
|
||||
"regGuid": "13FE-4200-C300-58C372A52B19",
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { expect, test } from 'vitest';
|
||||
|
||||
import { setupNotificationWatch } from '@app/core/modules/notifications/setup-notification-watch';
|
||||
import { sleep } from '@app/core/utils/misc/sleep';
|
||||
import { loadDynamixConfigFile } from '@app/store/actions/load-dynamix-config-file';
|
||||
import { store } from '@app/store/index';
|
||||
import { expect, test } from 'vitest';
|
||||
|
||||
test('loads notifications properly', async () => {
|
||||
await store.dispatch(loadDynamixConfigFile()).unwrap();
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import { expect, test } from 'vitest';
|
||||
|
||||
import { store } from '@app/store';
|
||||
|
||||
test('Returns paths', async () => {
|
||||
const { paths } = store.getState();
|
||||
expect(Object.keys(paths)).toMatchInlineSnapshot(`
|
||||
const { paths } = store.getState();
|
||||
expect(Object.keys(paths)).toMatchInlineSnapshot(`
|
||||
[
|
||||
"core",
|
||||
"unraid-api-base",
|
||||
@@ -20,10 +21,13 @@ test('Returns paths', async () => {
|
||||
"myservers-config",
|
||||
"myservers-config-states",
|
||||
"myservers-env",
|
||||
"myservers-keepalive",
|
||||
"keyfile-base",
|
||||
"machine-id",
|
||||
"log-base",
|
||||
"var-run",
|
||||
"auth-sessions",
|
||||
"auth-keys",
|
||||
]
|
||||
`);
|
||||
});
|
||||
|
||||
66
api/src/__test__/store/modules/registration.test.ts
Normal file
66
api/src/__test__/store/modules/registration.test.ts
Normal file
@@ -0,0 +1,66 @@
|
||||
import { expect, test } from 'vitest';
|
||||
|
||||
import { store } from '@app/store';
|
||||
import { loadRegistrationKey } from '@app/store/modules/registration';
|
||||
import { FileLoadStatus, StateFileKey } from '@app/store/types';
|
||||
|
||||
// Preloading imports for faster tests
|
||||
|
||||
test('Before loading key returns null', async () => {
|
||||
const { status, keyFile } = store.getState().registration;
|
||||
expect(status).toBe(FileLoadStatus.UNLOADED);
|
||||
expect(keyFile).toBe(null);
|
||||
});
|
||||
|
||||
test('Requires emhttp to be loaded to find key file', async () => {
|
||||
// Load registration key into store
|
||||
await store.dispatch(loadRegistrationKey());
|
||||
|
||||
// Check if store has state files loaded
|
||||
const { status, keyFile } = store.getState().registration;
|
||||
|
||||
expect(status).toBe(FileLoadStatus.LOADED);
|
||||
expect(keyFile).toBe(null);
|
||||
});
|
||||
|
||||
test('Returns empty key if key location is empty', async () => {
|
||||
const { updateEmhttpState } = await import('@app/store/modules/emhttp');
|
||||
const { loadRegistrationKey } = await import('@app/store/modules/registration');
|
||||
|
||||
// Set key file location as empty
|
||||
// This should only happen if the user doesn't have a key file
|
||||
store.dispatch(
|
||||
updateEmhttpState({
|
||||
field: StateFileKey.var,
|
||||
state: {
|
||||
regFile: '',
|
||||
},
|
||||
})
|
||||
);
|
||||
|
||||
// Load registration key into store
|
||||
await store.dispatch(loadRegistrationKey());
|
||||
|
||||
// Check if store has state files loaded
|
||||
const { status, keyFile } = store.getState().registration;
|
||||
expect(status).toBe(FileLoadStatus.LOADED);
|
||||
expect(keyFile).toBe('');
|
||||
});
|
||||
|
||||
test('Returns decoded key file if key location exists', async () => {
|
||||
const { loadRegistrationKey } = await import('@app/store/modules/registration');
|
||||
const { loadStateFiles } = await import('@app/store/modules/emhttp');
|
||||
|
||||
// Load state files into store
|
||||
await store.dispatch(loadStateFiles());
|
||||
|
||||
// Load registration key into store
|
||||
await store.dispatch(loadRegistrationKey());
|
||||
|
||||
// Check if store has state files loaded
|
||||
const { status, keyFile } = store.getState().registration;
|
||||
expect(status).toBe(FileLoadStatus.LOADED);
|
||||
expect(keyFile).toMatchInlineSnapshot(
|
||||
'"hVs1tLjvC9FiiQsIwIQ7G1KszAcexf0IneThhnmf22SB0dGs5WzRkqMiSMmt2DtR5HOXFUD32YyxuzGeUXmky3zKpSu6xhZNKVg5atGM1OfvkzHBMldI3SeBLuUFSgejLbpNUMdTrbk64JJdbzle4O8wiQgkIpAMIGxeYLwLBD4zHBcfyzq40QnxG--HcX6j25eE0xqa2zWj-j0b0rCAXahJV2a3ySCbPzr1MvfPRTVb0rr7KJ-25R592hYrz4H7Sc1B3p0lr6QUxHE6o7bcYrWKDRtIVoZ8SMPpd1_0gzYIcl5GsDFzFumTXUh8NEnl0Q8hwW1YE-tRc6Y_rrvd7w"'
|
||||
);
|
||||
});
|
||||
@@ -0,0 +1,87 @@
|
||||
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
||||
|
||||
exports[`Returns parsed state file 1`] = `
|
||||
{
|
||||
"certificateName": "*.thisisfourtyrandomcharacters012345678900.myunraid.net",
|
||||
"certificatePath": "/boot/config/ssl/certs/certificate_bundle.pem",
|
||||
"defaultUrl": "https://Tower.local:4443",
|
||||
"fqdnUrls": [
|
||||
{
|
||||
"fqdn": "192-168-1-150.thisisfourtyrandomcharacters012345678900.myunraid.net",
|
||||
"id": null,
|
||||
"interface": "LAN",
|
||||
"isIpv6": false,
|
||||
},
|
||||
{
|
||||
"fqdn": "85-121-123-122.thisisfourtyrandomcharacters012345678900.myunraid.net",
|
||||
"id": null,
|
||||
"interface": "WAN",
|
||||
"isIpv6": false,
|
||||
},
|
||||
{
|
||||
"fqdn": "10-252-0-1.hash.myunraid.net",
|
||||
"id": 0,
|
||||
"interface": "WG",
|
||||
"isIpv6": false,
|
||||
},
|
||||
{
|
||||
"fqdn": "10-252-1-1.hash.myunraid.net",
|
||||
"id": 1,
|
||||
"interface": "WG",
|
||||
"isIpv6": false,
|
||||
},
|
||||
{
|
||||
"fqdn": "10-253-3-1.hash.myunraid.net",
|
||||
"id": 2,
|
||||
"interface": "WG",
|
||||
"isIpv6": false,
|
||||
},
|
||||
{
|
||||
"fqdn": "10-253-4-1.hash.myunraid.net",
|
||||
"id": 3,
|
||||
"interface": "WG",
|
||||
"isIpv6": false,
|
||||
},
|
||||
{
|
||||
"fqdn": "10-253-5-1.hash.myunraid.net",
|
||||
"id": 4,
|
||||
"interface": "WG",
|
||||
"isIpv6": false,
|
||||
},
|
||||
{
|
||||
"fqdn": "10-100-0-1.hash.myunraid.net",
|
||||
"id": 0,
|
||||
"interface": "TAILSCALE",
|
||||
"isIpv6": false,
|
||||
},
|
||||
{
|
||||
"fqdn": "10-100-0-2.hash.myunraid.net",
|
||||
"id": 1,
|
||||
"interface": "TAILSCALE",
|
||||
"isIpv6": false,
|
||||
},
|
||||
{
|
||||
"fqdn": "10-123-1-2.hash.myunraid.net",
|
||||
"id": 0,
|
||||
"interface": "CUSTOM",
|
||||
"isIpv6": false,
|
||||
},
|
||||
{
|
||||
"fqdn": "221-123-121-112.hash.myunraid.net",
|
||||
"id": 1,
|
||||
"interface": "CUSTOM",
|
||||
"isIpv6": true,
|
||||
},
|
||||
],
|
||||
"httpPort": 8080,
|
||||
"httpsPort": 4443,
|
||||
"lanIp": "192.168.1.150",
|
||||
"lanIp6": "",
|
||||
"lanMdns": "Tower.local",
|
||||
"lanName": "Tower",
|
||||
"sslEnabled": true,
|
||||
"sslMode": "yes",
|
||||
"wanAccessEnabled": false,
|
||||
"wanIp": "",
|
||||
}
|
||||
`;
|
||||
18
api/src/__test__/store/state-parsers/devices.test.ts
Normal file
18
api/src/__test__/store/state-parsers/devices.test.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import { join } from 'path';
|
||||
|
||||
import { expect, test } from 'vitest';
|
||||
|
||||
import type { DevicesIni } from '@app/store/state-parsers/devices';
|
||||
import { store } from '@app/store';
|
||||
|
||||
test('Returns parsed state file', async () => {
|
||||
const { parse } = await import('@app/store/state-parsers/devices');
|
||||
const { parseConfig } = await import('@app/core/utils/misc/parse-config');
|
||||
const { paths } = store.getState();
|
||||
const filePath = join(paths.states, 'devs.ini');
|
||||
const stateFile = parseConfig<DevicesIni>({
|
||||
filePath,
|
||||
type: 'ini',
|
||||
});
|
||||
expect(parse(stateFile)).toMatchInlineSnapshot('[]');
|
||||
});
|
||||
83
api/src/__test__/store/state-parsers/network.test.ts
Normal file
83
api/src/__test__/store/state-parsers/network.test.ts
Normal file
@@ -0,0 +1,83 @@
|
||||
import { join } from 'path';
|
||||
|
||||
import { expect, test } from 'vitest';
|
||||
|
||||
import type { NetworkIni } from '@app/store/state-parsers/network';
|
||||
import { store } from '@app/store';
|
||||
|
||||
test('Returns parsed state file', async () => {
|
||||
const { parse } = await import('@app/store/state-parsers/network');
|
||||
const { parseConfig } = await import('@app/core/utils/misc/parse-config');
|
||||
const { paths } = store.getState();
|
||||
const filePath = join(paths.states, 'network.ini');
|
||||
const stateFile = parseConfig<NetworkIni>({
|
||||
filePath,
|
||||
type: 'ini',
|
||||
});
|
||||
expect(parse(stateFile)).toMatchInlineSnapshot(`
|
||||
[
|
||||
{
|
||||
"bonding": true,
|
||||
"bondingMiimon": "100",
|
||||
"bondingMode": "1",
|
||||
"bondname": "",
|
||||
"bondnics": [
|
||||
"eth0",
|
||||
"eth1",
|
||||
"eth2",
|
||||
"eth3",
|
||||
],
|
||||
"brfd": "0",
|
||||
"bridging": true,
|
||||
"brname": "",
|
||||
"brnics": "bond0",
|
||||
"brstp": "0",
|
||||
"description": [
|
||||
"",
|
||||
],
|
||||
"dhcp6Keepresolv": false,
|
||||
"dhcpKeepresolv": false,
|
||||
"dnsServer1": "1.1.1.1",
|
||||
"dnsServer2": "8.8.8.8",
|
||||
"gateway": [
|
||||
"192.168.1.1",
|
||||
],
|
||||
"gateway6": [
|
||||
"",
|
||||
],
|
||||
"ipaddr": [
|
||||
"192.168.1.150",
|
||||
],
|
||||
"ipaddr6": [
|
||||
"",
|
||||
],
|
||||
"metric": [
|
||||
"",
|
||||
],
|
||||
"metric6": [
|
||||
"",
|
||||
],
|
||||
"mtu": "",
|
||||
"netmask": [
|
||||
"255.255.255.0",
|
||||
],
|
||||
"netmask6": [
|
||||
"",
|
||||
],
|
||||
"privacy6": [
|
||||
"",
|
||||
],
|
||||
"protocol": [
|
||||
"",
|
||||
],
|
||||
"type": "access",
|
||||
"useDhcp": [
|
||||
true,
|
||||
],
|
||||
"useDhcp6": [
|
||||
false,
|
||||
],
|
||||
},
|
||||
]
|
||||
`);
|
||||
});
|
||||
205
api/src/__test__/store/state-parsers/nfs.test.ts
Normal file
205
api/src/__test__/store/state-parsers/nfs.test.ts
Normal file
@@ -0,0 +1,205 @@
|
||||
import { join } from 'path';
|
||||
|
||||
import { expect, test } from 'vitest';
|
||||
|
||||
import type { NfsSharesIni } from '@app/store/state-parsers/nfs';
|
||||
import { store } from '@app/store';
|
||||
|
||||
test('Returns parsed state file', async () => {
|
||||
const { parse } = await import('@app/store/state-parsers/nfs');
|
||||
const { parseConfig } = await import('@app/core/utils/misc/parse-config');
|
||||
const { paths } = store.getState();
|
||||
const filePath = join(paths.states, 'sec_nfs.ini');
|
||||
const stateFile = parseConfig<NfsSharesIni>({
|
||||
filePath,
|
||||
type: 'ini',
|
||||
});
|
||||
expect(parse(stateFile)).toMatchInlineSnapshot(`
|
||||
[
|
||||
{
|
||||
"enabled": false,
|
||||
"hostList": "",
|
||||
"name": "disk1",
|
||||
"readList": [],
|
||||
"security": "public",
|
||||
"writeList": [],
|
||||
},
|
||||
{
|
||||
"enabled": false,
|
||||
"hostList": "",
|
||||
"name": "disk2",
|
||||
"readList": [],
|
||||
"security": "public",
|
||||
"writeList": [],
|
||||
},
|
||||
{
|
||||
"enabled": false,
|
||||
"hostList": "",
|
||||
"name": "disk3",
|
||||
"readList": [],
|
||||
"security": "public",
|
||||
"writeList": [],
|
||||
},
|
||||
{
|
||||
"enabled": false,
|
||||
"hostList": "",
|
||||
"name": "disk4",
|
||||
"readList": [],
|
||||
"security": "public",
|
||||
"writeList": [],
|
||||
},
|
||||
{
|
||||
"enabled": false,
|
||||
"hostList": "",
|
||||
"name": "disk5",
|
||||
"readList": [],
|
||||
"security": "public",
|
||||
"writeList": [],
|
||||
},
|
||||
{
|
||||
"enabled": false,
|
||||
"hostList": "",
|
||||
"name": "disk6",
|
||||
"readList": [],
|
||||
"security": "public",
|
||||
"writeList": [],
|
||||
},
|
||||
{
|
||||
"enabled": false,
|
||||
"hostList": "",
|
||||
"name": "disk7",
|
||||
"readList": [],
|
||||
"security": "public",
|
||||
"writeList": [],
|
||||
},
|
||||
{
|
||||
"enabled": false,
|
||||
"hostList": "",
|
||||
"name": "disk8",
|
||||
"readList": [],
|
||||
"security": "public",
|
||||
"writeList": [],
|
||||
},
|
||||
{
|
||||
"enabled": false,
|
||||
"hostList": "",
|
||||
"name": "disk9",
|
||||
"readList": [],
|
||||
"security": "public",
|
||||
"writeList": [],
|
||||
},
|
||||
{
|
||||
"enabled": false,
|
||||
"hostList": "",
|
||||
"name": "disk10",
|
||||
"readList": [],
|
||||
"security": "public",
|
||||
"writeList": [],
|
||||
},
|
||||
{
|
||||
"enabled": false,
|
||||
"hostList": "",
|
||||
"name": "disk11",
|
||||
"readList": [],
|
||||
"security": "public",
|
||||
"writeList": [],
|
||||
},
|
||||
{
|
||||
"enabled": false,
|
||||
"hostList": "",
|
||||
"name": "disk12",
|
||||
"readList": [],
|
||||
"security": "public",
|
||||
"writeList": [],
|
||||
},
|
||||
{
|
||||
"enabled": false,
|
||||
"hostList": "",
|
||||
"name": "disk13",
|
||||
"readList": [],
|
||||
"security": "public",
|
||||
"writeList": [],
|
||||
},
|
||||
{
|
||||
"enabled": false,
|
||||
"hostList": "",
|
||||
"name": "disk14",
|
||||
"readList": [],
|
||||
"security": "public",
|
||||
"writeList": [],
|
||||
},
|
||||
{
|
||||
"enabled": false,
|
||||
"hostList": "",
|
||||
"name": "disk15",
|
||||
"readList": [],
|
||||
"security": "public",
|
||||
"writeList": [],
|
||||
},
|
||||
{
|
||||
"enabled": false,
|
||||
"hostList": "",
|
||||
"name": "disk16",
|
||||
"readList": [],
|
||||
"security": "public",
|
||||
"writeList": [],
|
||||
},
|
||||
{
|
||||
"enabled": false,
|
||||
"hostList": "",
|
||||
"name": "disk17",
|
||||
"readList": [],
|
||||
"security": "public",
|
||||
"writeList": [],
|
||||
},
|
||||
{
|
||||
"enabled": false,
|
||||
"hostList": "",
|
||||
"name": "disk18",
|
||||
"readList": [],
|
||||
"security": "public",
|
||||
"writeList": [],
|
||||
},
|
||||
{
|
||||
"enabled": false,
|
||||
"hostList": "",
|
||||
"name": "disk19",
|
||||
"readList": [],
|
||||
"security": "public",
|
||||
"writeList": [],
|
||||
},
|
||||
{
|
||||
"enabled": false,
|
||||
"hostList": "",
|
||||
"name": "disk20",
|
||||
"readList": [],
|
||||
"security": "public",
|
||||
"writeList": [],
|
||||
},
|
||||
{
|
||||
"enabled": false,
|
||||
"hostList": "",
|
||||
"name": "disk21",
|
||||
"readList": [],
|
||||
"security": "public",
|
||||
"writeList": [],
|
||||
},
|
||||
{
|
||||
"enabled": false,
|
||||
"hostList": "",
|
||||
"name": "disk22",
|
||||
"readList": [],
|
||||
"security": "public",
|
||||
"writeList": [],
|
||||
},
|
||||
{
|
||||
"enabled": false,
|
||||
"hostList": "",
|
||||
"name": "abc",
|
||||
"readList": [],
|
||||
"security": "public",
|
||||
"writeList": [],
|
||||
},
|
||||
]
|
||||
`);
|
||||
});
|
||||
18
api/src/__test__/store/state-parsers/nginx.test.ts
Normal file
18
api/src/__test__/store/state-parsers/nginx.test.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import { join } from 'path';
|
||||
|
||||
import { expect, test } from 'vitest';
|
||||
|
||||
import type { NginxIni } from '@app/store/state-parsers/nginx';
|
||||
import { store } from '@app/store';
|
||||
|
||||
test('Returns parsed state file', async () => {
|
||||
const { parse } = await import('@app/store/state-parsers/nginx');
|
||||
const { parseConfig } = await import('@app/core/utils/misc/parse-config');
|
||||
const { paths } = store.getState();
|
||||
const filePath = join(paths.states, 'nginx.ini');
|
||||
const stateFile = parseConfig<NginxIni>({
|
||||
filePath,
|
||||
type: 'ini',
|
||||
});
|
||||
expect(parse(stateFile)).toMatchSnapshot();
|
||||
});
|
||||
@@ -1,18 +1,20 @@
|
||||
import { join } from 'path';
|
||||
|
||||
import { expect, test } from 'vitest';
|
||||
import { store } from '@app/store';
|
||||
|
||||
import type { SharesIni } from '@app/store/state-parsers/shares';
|
||||
import { store } from '@app/store';
|
||||
|
||||
test('Returns parsed state file', async () => {
|
||||
const { parse } = await import('@app/store/state-parsers/shares');
|
||||
const { parseConfig } = await import('@app/core/utils/misc/parse-config');
|
||||
const { paths } = store.getState();
|
||||
const filePath = join(paths.states, 'shares.ini');
|
||||
const stateFile = parseConfig<SharesIni>({
|
||||
filePath,
|
||||
type: 'ini',
|
||||
});
|
||||
expect(parse(stateFile)).toMatchInlineSnapshot(`
|
||||
const { parse } = await import('@app/store/state-parsers/shares');
|
||||
const { parseConfig } = await import('@app/core/utils/misc/parse-config');
|
||||
const { paths } = store.getState();
|
||||
const filePath = join(paths.states, 'shares.ini');
|
||||
const stateFile = parseConfig<SharesIni>({
|
||||
filePath,
|
||||
type: 'ini',
|
||||
});
|
||||
expect(parse(stateFile)).toMatchInlineSnapshot(`
|
||||
[
|
||||
{
|
||||
"allocator": "highwater",
|
||||
|
||||
@@ -1,18 +1,20 @@
|
||||
import { join } from 'path';
|
||||
|
||||
import { expect, test } from 'vitest';
|
||||
import { store } from '@app/store';
|
||||
|
||||
import type { SlotsIni } from '@app/store/state-parsers/slots';
|
||||
import { store } from '@app/store';
|
||||
|
||||
test('Returns parsed state file', async () => {
|
||||
const { parse } = await import('@app/store/state-parsers/slots');
|
||||
const { parseConfig } = await import('@app/core/utils/misc/parse-config');
|
||||
const { paths } = store.getState();
|
||||
const filePath = join(paths.states, 'disks.ini');
|
||||
const stateFile = parseConfig<SlotsIni>({
|
||||
filePath,
|
||||
type: 'ini',
|
||||
});
|
||||
expect(parse(stateFile)).toMatchInlineSnapshot(`
|
||||
const { parse } = await import('@app/store/state-parsers/slots');
|
||||
const { parseConfig } = await import('@app/core/utils/misc/parse-config');
|
||||
const { paths } = store.getState();
|
||||
const filePath = join(paths.states, 'disks.ini');
|
||||
const stateFile = parseConfig<SlotsIni>({
|
||||
filePath,
|
||||
type: 'ini',
|
||||
});
|
||||
expect(parse(stateFile)).toMatchInlineSnapshot(`
|
||||
[
|
||||
{
|
||||
"comment": null,
|
||||
|
||||
308
api/src/__test__/store/state-parsers/smb.test.ts
Normal file
308
api/src/__test__/store/state-parsers/smb.test.ts
Normal file
@@ -0,0 +1,308 @@
|
||||
import { join } from 'path';
|
||||
|
||||
import { expect, test } from 'vitest';
|
||||
|
||||
import type { SmbIni } from '@app/store/state-parsers/smb';
|
||||
import { store } from '@app/store';
|
||||
|
||||
test('Returns parsed state file', async () => {
|
||||
const { parse } = await import('@app/store/state-parsers/smb');
|
||||
const { parseConfig } = await import('@app/core/utils/misc/parse-config');
|
||||
const { paths } = store.getState();
|
||||
const filePath = join(paths.states, 'sec.ini');
|
||||
const stateFile = parseConfig<SmbIni>({
|
||||
filePath,
|
||||
type: 'ini',
|
||||
});
|
||||
expect(parse(stateFile)).toMatchInlineSnapshot(`
|
||||
[
|
||||
{
|
||||
"caseSensitive": "auto",
|
||||
"enabled": true,
|
||||
"fruit": "no",
|
||||
"name": "disk1",
|
||||
"readList": [],
|
||||
"security": "public",
|
||||
"timemachine": {
|
||||
"volsizelimit": NaN,
|
||||
},
|
||||
"writeList": [],
|
||||
},
|
||||
{
|
||||
"caseSensitive": "auto",
|
||||
"enabled": true,
|
||||
"fruit": "no",
|
||||
"name": "disk2",
|
||||
"readList": [],
|
||||
"security": "public",
|
||||
"timemachine": {
|
||||
"volsizelimit": NaN,
|
||||
},
|
||||
"writeList": [],
|
||||
},
|
||||
{
|
||||
"caseSensitive": "auto",
|
||||
"enabled": true,
|
||||
"fruit": "no",
|
||||
"name": "disk3",
|
||||
"readList": [],
|
||||
"security": "public",
|
||||
"timemachine": {
|
||||
"volsizelimit": NaN,
|
||||
},
|
||||
"writeList": [],
|
||||
},
|
||||
{
|
||||
"caseSensitive": "auto",
|
||||
"enabled": true,
|
||||
"fruit": "no",
|
||||
"name": "disk4",
|
||||
"readList": [],
|
||||
"security": "public",
|
||||
"timemachine": {
|
||||
"volsizelimit": NaN,
|
||||
},
|
||||
"writeList": [],
|
||||
},
|
||||
{
|
||||
"caseSensitive": "auto",
|
||||
"enabled": true,
|
||||
"fruit": "no",
|
||||
"name": "disk5",
|
||||
"readList": [],
|
||||
"security": "public",
|
||||
"timemachine": {
|
||||
"volsizelimit": NaN,
|
||||
},
|
||||
"writeList": [],
|
||||
},
|
||||
{
|
||||
"caseSensitive": "auto",
|
||||
"enabled": true,
|
||||
"fruit": "no",
|
||||
"name": "disk6",
|
||||
"readList": [],
|
||||
"security": "public",
|
||||
"timemachine": {
|
||||
"volsizelimit": NaN,
|
||||
},
|
||||
"writeList": [],
|
||||
},
|
||||
{
|
||||
"caseSensitive": "auto",
|
||||
"enabled": true,
|
||||
"fruit": "no",
|
||||
"name": "disk7",
|
||||
"readList": [],
|
||||
"security": "public",
|
||||
"timemachine": {
|
||||
"volsizelimit": NaN,
|
||||
},
|
||||
"writeList": [],
|
||||
},
|
||||
{
|
||||
"caseSensitive": "auto",
|
||||
"enabled": true,
|
||||
"fruit": "no",
|
||||
"name": "disk8",
|
||||
"readList": [],
|
||||
"security": "public",
|
||||
"timemachine": {
|
||||
"volsizelimit": NaN,
|
||||
},
|
||||
"writeList": [],
|
||||
},
|
||||
{
|
||||
"caseSensitive": "auto",
|
||||
"enabled": true,
|
||||
"fruit": "no",
|
||||
"name": "disk9",
|
||||
"readList": [],
|
||||
"security": "public",
|
||||
"timemachine": {
|
||||
"volsizelimit": NaN,
|
||||
},
|
||||
"writeList": [],
|
||||
},
|
||||
{
|
||||
"caseSensitive": "auto",
|
||||
"enabled": true,
|
||||
"fruit": "no",
|
||||
"name": "disk10",
|
||||
"readList": [],
|
||||
"security": "public",
|
||||
"timemachine": {
|
||||
"volsizelimit": NaN,
|
||||
},
|
||||
"writeList": [],
|
||||
},
|
||||
{
|
||||
"caseSensitive": "auto",
|
||||
"enabled": true,
|
||||
"fruit": "no",
|
||||
"name": "disk11",
|
||||
"readList": [],
|
||||
"security": "public",
|
||||
"timemachine": {
|
||||
"volsizelimit": NaN,
|
||||
},
|
||||
"writeList": [],
|
||||
},
|
||||
{
|
||||
"caseSensitive": "auto",
|
||||
"enabled": true,
|
||||
"fruit": "no",
|
||||
"name": "disk12",
|
||||
"readList": [],
|
||||
"security": "public",
|
||||
"timemachine": {
|
||||
"volsizelimit": NaN,
|
||||
},
|
||||
"writeList": [],
|
||||
},
|
||||
{
|
||||
"caseSensitive": "auto",
|
||||
"enabled": true,
|
||||
"fruit": "no",
|
||||
"name": "disk13",
|
||||
"readList": [],
|
||||
"security": "public",
|
||||
"timemachine": {
|
||||
"volsizelimit": NaN,
|
||||
},
|
||||
"writeList": [],
|
||||
},
|
||||
{
|
||||
"caseSensitive": "auto",
|
||||
"enabled": true,
|
||||
"fruit": "no",
|
||||
"name": "disk14",
|
||||
"readList": [],
|
||||
"security": "public",
|
||||
"timemachine": {
|
||||
"volsizelimit": NaN,
|
||||
},
|
||||
"writeList": [],
|
||||
},
|
||||
{
|
||||
"caseSensitive": "auto",
|
||||
"enabled": true,
|
||||
"fruit": "no",
|
||||
"name": "disk15",
|
||||
"readList": [],
|
||||
"security": "public",
|
||||
"timemachine": {
|
||||
"volsizelimit": NaN,
|
||||
},
|
||||
"writeList": [],
|
||||
},
|
||||
{
|
||||
"caseSensitive": "auto",
|
||||
"enabled": true,
|
||||
"fruit": "no",
|
||||
"name": "disk16",
|
||||
"readList": [],
|
||||
"security": "public",
|
||||
"timemachine": {
|
||||
"volsizelimit": NaN,
|
||||
},
|
||||
"writeList": [],
|
||||
},
|
||||
{
|
||||
"caseSensitive": "auto",
|
||||
"enabled": true,
|
||||
"fruit": "no",
|
||||
"name": "disk17",
|
||||
"readList": [],
|
||||
"security": "public",
|
||||
"timemachine": {
|
||||
"volsizelimit": NaN,
|
||||
},
|
||||
"writeList": [],
|
||||
},
|
||||
{
|
||||
"caseSensitive": "auto",
|
||||
"enabled": true,
|
||||
"fruit": "no",
|
||||
"name": "disk18",
|
||||
"readList": [],
|
||||
"security": "public",
|
||||
"timemachine": {
|
||||
"volsizelimit": NaN,
|
||||
},
|
||||
"writeList": [],
|
||||
},
|
||||
{
|
||||
"caseSensitive": "auto",
|
||||
"enabled": true,
|
||||
"fruit": "no",
|
||||
"name": "disk19",
|
||||
"readList": [],
|
||||
"security": "public",
|
||||
"timemachine": {
|
||||
"volsizelimit": NaN,
|
||||
},
|
||||
"writeList": [],
|
||||
},
|
||||
{
|
||||
"caseSensitive": "auto",
|
||||
"enabled": true,
|
||||
"fruit": "no",
|
||||
"name": "disk20",
|
||||
"readList": [],
|
||||
"security": "public",
|
||||
"timemachine": {
|
||||
"volsizelimit": NaN,
|
||||
},
|
||||
"writeList": [],
|
||||
},
|
||||
{
|
||||
"caseSensitive": "auto",
|
||||
"enabled": true,
|
||||
"fruit": "no",
|
||||
"name": "disk21",
|
||||
"readList": [],
|
||||
"security": "public",
|
||||
"timemachine": {
|
||||
"volsizelimit": NaN,
|
||||
},
|
||||
"writeList": [],
|
||||
},
|
||||
{
|
||||
"caseSensitive": "auto",
|
||||
"enabled": true,
|
||||
"fruit": "no",
|
||||
"name": "disk22",
|
||||
"readList": [],
|
||||
"security": "public",
|
||||
"timemachine": {
|
||||
"volsizelimit": NaN,
|
||||
},
|
||||
"writeList": [],
|
||||
},
|
||||
{
|
||||
"caseSensitive": "auto",
|
||||
"enabled": true,
|
||||
"fruit": "no",
|
||||
"name": "abc",
|
||||
"readList": [],
|
||||
"security": "public",
|
||||
"timemachine": {
|
||||
"volsizelimit": NaN,
|
||||
},
|
||||
"writeList": [],
|
||||
},
|
||||
{
|
||||
"enabled": true,
|
||||
"fruit": "no",
|
||||
"name": "flash",
|
||||
"readList": [],
|
||||
"security": "public",
|
||||
"timemachine": {
|
||||
"volsizelimit": NaN,
|
||||
},
|
||||
"writeList": [],
|
||||
},
|
||||
]
|
||||
`);
|
||||
});
|
||||
42
api/src/__test__/store/state-parsers/users.test.ts
Normal file
42
api/src/__test__/store/state-parsers/users.test.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
import { join } from 'path';
|
||||
|
||||
import { expect, test } from 'vitest';
|
||||
|
||||
import type { UsersIni } from '@app/store/state-parsers/users';
|
||||
import { store } from '@app/store';
|
||||
|
||||
test('Returns parsed state file', async () => {
|
||||
const { parse } = await import('@app/store/state-parsers/users');
|
||||
const { parseConfig } = await import('@app/core/utils/misc/parse-config');
|
||||
const { paths } = store.getState();
|
||||
const filePath = join(paths.states, 'users.ini');
|
||||
const stateFile = parseConfig<UsersIni>({
|
||||
filePath,
|
||||
type: 'ini',
|
||||
});
|
||||
expect(parse(stateFile)).toMatchInlineSnapshot(`
|
||||
[
|
||||
{
|
||||
"description": "Console and webGui login account",
|
||||
"id": "0",
|
||||
"name": "root",
|
||||
"password": true,
|
||||
"role": "admin",
|
||||
},
|
||||
{
|
||||
"description": "",
|
||||
"id": "1",
|
||||
"name": "xo",
|
||||
"password": true,
|
||||
"role": "user",
|
||||
},
|
||||
{
|
||||
"description": "",
|
||||
"id": "2",
|
||||
"name": "test_user",
|
||||
"password": false,
|
||||
"role": "user",
|
||||
},
|
||||
]
|
||||
`);
|
||||
});
|
||||
@@ -1,19 +1,21 @@
|
||||
import { join } from 'path';
|
||||
|
||||
import { expect, test } from 'vitest';
|
||||
import { store } from '@app/store';
|
||||
|
||||
import type { VarIni } from '@app/store/state-parsers/var';
|
||||
import { store } from '@app/store';
|
||||
|
||||
test('Returns parsed state file', async () => {
|
||||
const { parse } = await import('@app/store/state-parsers/var');
|
||||
const { parseConfig } = await import('@app/core/utils/misc/parse-config');
|
||||
const { paths } = store.getState();
|
||||
const filePath = join(paths.states, 'var.ini');
|
||||
const stateFile = parseConfig<VarIni>({
|
||||
filePath,
|
||||
type: 'ini',
|
||||
});
|
||||
const { parse } = await import('@app/store/state-parsers/var');
|
||||
const { parseConfig } = await import('@app/core/utils/misc/parse-config');
|
||||
const { paths } = store.getState();
|
||||
const filePath = join(paths.states, 'var.ini');
|
||||
const stateFile = parseConfig<VarIni>({
|
||||
filePath,
|
||||
type: 'ini',
|
||||
});
|
||||
|
||||
expect(parse(stateFile)).toMatchInlineSnapshot(`
|
||||
expect(parse(stateFile)).toMatchInlineSnapshot(`
|
||||
{
|
||||
"bindMgt": false,
|
||||
"cacheNumDevices": NaN,
|
||||
@@ -103,6 +105,7 @@ test('Returns parsed state file', async () => {
|
||||
"porttelnet": 23,
|
||||
"queueDepth": "auto",
|
||||
"regCheck": "Valid",
|
||||
"regExp": "",
|
||||
"regFile": "/app/dev/Unraid.net/Pro.key",
|
||||
"regGen": "0",
|
||||
"regGuid": "13FE-4200-C300-58C372A52B19",
|
||||
|
||||
30
api/src/__test__/store/sync/registration-sync.test.ts
Normal file
30
api/src/__test__/store/sync/registration-sync.test.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
import { expect, test, vi } from 'vitest';
|
||||
|
||||
vi.mock('@app/core/pubsub', () => ({
|
||||
pubsub: { publish: vi.fn() },
|
||||
}));
|
||||
|
||||
test('Creates a registration event', async () => {
|
||||
const { createRegistrationEvent } = await import('@app/store/sync/registration-sync');
|
||||
const { store } = await import('@app/store');
|
||||
const { loadStateFiles } = await import('@app/store/modules/emhttp');
|
||||
|
||||
// Load state files into store
|
||||
await store.dispatch(loadStateFiles());
|
||||
|
||||
const state = store.getState();
|
||||
const registrationEvent = createRegistrationEvent(state);
|
||||
expect(registrationEvent).toMatchInlineSnapshot(`
|
||||
{
|
||||
"registration": {
|
||||
"guid": "13FE-4200-C300-58C372A52B19",
|
||||
"keyFile": {
|
||||
"contents": null,
|
||||
"location": "/app/dev/Unraid.net/Pro.key",
|
||||
},
|
||||
"state": "PRO",
|
||||
"type": "PRO",
|
||||
},
|
||||
}
|
||||
`);
|
||||
});
|
||||
20
api/src/__test__/upnp/helpers.test.ts
Normal file
20
api/src/__test__/upnp/helpers.test.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import { type Mapping } from '@runonflux/nat-upnp';
|
||||
import { expect, test, vi } from 'vitest';
|
||||
|
||||
import { getWanPortForUpnp } from '@app/upnp/helpers';
|
||||
|
||||
test('it successfully gets a wan port given no exclusions', () => {
|
||||
const port = getWanPortForUpnp(null, 36_000, 38_000);
|
||||
expect(port).toBeGreaterThan(35_999);
|
||||
expect(port).toBeLessThan(38_001);
|
||||
});
|
||||
|
||||
test('it fails to get a wan port given exclusions', () => {
|
||||
const port = getWanPortForUpnp([{ public: { port: 36_000 } }] as Mapping[], 36_000, 36_000);
|
||||
expect(port).toBeNull();
|
||||
});
|
||||
|
||||
test('it succeeds in getting a wan port given exclusions', () => {
|
||||
const port = getWanPortForUpnp([{ public: { port: 36_000 } }] as Mapping[], 30_000, 36_000);
|
||||
expect(port).not.toBeNull();
|
||||
});
|
||||
71
api/src/__test__/utils.test.ts
Normal file
71
api/src/__test__/utils.test.ts
Normal file
@@ -0,0 +1,71 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
|
||||
import { formatDatetime } from '@app/utils';
|
||||
|
||||
describe('formatDatetime', () => {
|
||||
const testDate = new Date('2024-02-14T12:34:56');
|
||||
|
||||
it('formats with default system time format and omits timezone', () => {
|
||||
const result = formatDatetime(testDate);
|
||||
// Default format is %c with timezone omitted
|
||||
expect(result).toMatch('Wed 14 Feb 2024 12:34:56 PM');
|
||||
});
|
||||
|
||||
it('includes timezone when omitTimezone is false', () => {
|
||||
const result = formatDatetime(testDate, { omitTimezone: false });
|
||||
// Should include timezone at the end
|
||||
expect(result).toMatch(/^Wed 14 Feb 2024 12:34:56 PM .+$/);
|
||||
});
|
||||
|
||||
it('formats with custom date and time formats', () => {
|
||||
const result = formatDatetime(testDate, {
|
||||
dateFormat: '%Y-%m-%d',
|
||||
timeFormat: '%H:%M',
|
||||
});
|
||||
expect(result).toBe('2024-02-14 12:34');
|
||||
});
|
||||
|
||||
it('formats with custom date format and default time format', () => {
|
||||
const result = formatDatetime(testDate, {
|
||||
dateFormat: '%d/%m/%Y',
|
||||
});
|
||||
expect(result).toBe('14/02/2024 12:34 PM');
|
||||
});
|
||||
|
||||
describe('Unraid-style date formats', () => {
|
||||
const dateFormats = [
|
||||
'%A, %Y %B %e', // Day, YYYY Month D
|
||||
'%A, %e %B %Y', // Day, D Month YYYY
|
||||
'%A, %B %e, %Y', // Day, Month D, YYYY
|
||||
'%A, %m/%d/%Y', // Day, MM/DD/YYYY
|
||||
'%A, %d-%m-%Y', // Day, DD-MM-YYYY
|
||||
'%A, %d.%m.%Y', // Day, DD.MM.YYYY
|
||||
'%A, %Y-%m-%d', // Day, YYYY-MM-DD
|
||||
];
|
||||
|
||||
const timeFormats = [
|
||||
'%I:%M %p', // 12 hours
|
||||
'%R', // 24 hours
|
||||
];
|
||||
|
||||
it.each(dateFormats)('formats date with %s', (dateFormat) => {
|
||||
const result = formatDatetime(testDate, { dateFormat });
|
||||
expect(result).toMatch(/^Wednesday.*2024.*12:34 PM$/);
|
||||
});
|
||||
|
||||
it.each(timeFormats)('formats time with %s', (timeFormat) => {
|
||||
// specify a non-system-time date format for this test
|
||||
const result = formatDatetime(testDate, { timeFormat, dateFormat: dateFormats[1] });
|
||||
const expectedTime = timeFormat === '%R' ? '12:34' : '12:34 PM';
|
||||
expect(result).toContain(expectedTime);
|
||||
});
|
||||
|
||||
it.each(dateFormats.flatMap((d) => timeFormats.map((t) => [d, t])))(
|
||||
'formats with date format %s and time format %s',
|
||||
(dateFormat, timeFormat) => {
|
||||
const result = formatDatetime(testDate, { dateFormat, timeFormat });
|
||||
expect(result).toMatch(/^Wednesday.*2024.*(?:12:34 PM|12:34)$/);
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -1,11 +1,42 @@
|
||||
import 'wtfnode';
|
||||
#!/usr/bin/env node
|
||||
|
||||
import { am } from 'am';
|
||||
import { main } from '@app/cli/index';
|
||||
import { internalLogger } from '@app/core/log';
|
||||
import '@app/dotenv';
|
||||
|
||||
void am(main, (error: unknown) => {
|
||||
internalLogger.fatal((error as Error).message);
|
||||
// Ensure process is exited
|
||||
process.exit(1);
|
||||
});
|
||||
import { execa } from 'execa';
|
||||
import { CommandFactory } from 'nest-commander';
|
||||
|
||||
import { internalLogger, logger } from '@app/core/log';
|
||||
import { LOG_LEVEL } from '@app/environment';
|
||||
import { CliModule } from '@app/unraid-api/cli/cli.module';
|
||||
import { LogService } from '@app/unraid-api/cli/log.service';
|
||||
|
||||
const getUnraidApiLocation = async () => {
|
||||
try {
|
||||
const shellToUse = await execa('which unraid-api');
|
||||
return shellToUse.stdout.trim();
|
||||
} catch (err) {
|
||||
logger.debug('Could not find unraid-api in PATH, using default location');
|
||||
|
||||
return '/usr/bin/unraid-api';
|
||||
}
|
||||
};
|
||||
|
||||
try {
|
||||
await CommandFactory.run(CliModule, {
|
||||
cliName: 'unraid-api',
|
||||
logger: LOG_LEVEL === 'TRACE' ? new LogService() : false, // - enable this to see nest initialization issues
|
||||
completion: {
|
||||
fig: false,
|
||||
cmd: 'completion-script',
|
||||
nativeShell: { executablePath: await getUnraidApiLocation() },
|
||||
},
|
||||
});
|
||||
process.exit(0);
|
||||
} catch (error) {
|
||||
logger.error('ERROR:', error);
|
||||
internalLogger.error({
|
||||
message: 'Failed to start unraid-api',
|
||||
error,
|
||||
});
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
@@ -1,424 +0,0 @@
|
||||
import ipRegex from 'ip-regex';
|
||||
import readLine from 'readline';
|
||||
import { setEnv } from '@app/cli/set-env';
|
||||
import { getUnraidApiPid } from '@app/cli/get-unraid-api-pid';
|
||||
import { cliLogger } from '@app/core/log';
|
||||
import { getters, store } from '@app/store';
|
||||
import { stdout } from 'process';
|
||||
import { loadConfigFile } from '@app/store/modules/config';
|
||||
import { getApiApolloClient } from '../../graphql/client/api/get-api-client';
|
||||
import {
|
||||
getCloudDocument,
|
||||
getServersDocument,
|
||||
type getServersQuery,
|
||||
type getCloudQuery,
|
||||
} from '../../graphql/generated/api/operations';
|
||||
import {
|
||||
type ApolloQueryResult,
|
||||
type ApolloClient,
|
||||
type NormalizedCacheObject,
|
||||
} from '@apollo/client/core/core.cjs';
|
||||
import { MinigraphStatus } from '@app/graphql/generated/api/types';
|
||||
import { API_VERSION } from '@app/environment';
|
||||
import { loadStateFiles } from '@app/store/modules/emhttp';
|
||||
|
||||
type CloudQueryResult = NonNullable<
|
||||
ApolloQueryResult<getCloudQuery>['data']['cloud']
|
||||
>;
|
||||
type ServersQueryResultServer = NonNullable<
|
||||
ApolloQueryResult<getServersQuery>['data']['servers']
|
||||
>[0];
|
||||
|
||||
type Verbosity = '' | '-v' | '-vv';
|
||||
|
||||
type ServersPayload = {
|
||||
online: ServersQueryResultServer[];
|
||||
offline: ServersQueryResultServer[];
|
||||
invalid: ServersQueryResultServer[];
|
||||
};
|
||||
|
||||
type ReportObject = {
|
||||
os: {
|
||||
serverName: string;
|
||||
version: string;
|
||||
};
|
||||
api: {
|
||||
version: string;
|
||||
status: 'running' | 'stopped';
|
||||
environment: string;
|
||||
nodeVersion: string;
|
||||
};
|
||||
apiKey: 'valid' | 'invalid' | string;
|
||||
servers?: ServersPayload | null;
|
||||
myServers: {
|
||||
status: 'authenticated' | 'signed out';
|
||||
myServersUsername?: string;
|
||||
};
|
||||
minigraph: {
|
||||
status: MinigraphStatus;
|
||||
timeout: number | null;
|
||||
error: string | null;
|
||||
};
|
||||
cloud: {
|
||||
status: string;
|
||||
error?: string;
|
||||
ip?: string;
|
||||
allowedOrigins?: string[] | null;
|
||||
};
|
||||
};
|
||||
|
||||
// This should return the status of the apiKey and mothership
|
||||
export const getCloudData = async (
|
||||
client: ApolloClient<NormalizedCacheObject>
|
||||
): Promise<CloudQueryResult | null> => {
|
||||
try {
|
||||
const cloud = await client.query({ query: getCloudDocument });
|
||||
return cloud.data.cloud ?? null;
|
||||
} catch (error: unknown) {
|
||||
cliLogger.addContext(
|
||||
'error-stack',
|
||||
error instanceof Error ? error.stack : error
|
||||
);
|
||||
cliLogger.trace(
|
||||
'Failed fetching cloud from local graphql with "%s"',
|
||||
error instanceof Error ? error.message : 'Unknown Error'
|
||||
);
|
||||
cliLogger.removeContext('error-stack');
|
||||
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
export const getServersData = async ({
|
||||
client,
|
||||
v,
|
||||
}: {
|
||||
client: ApolloClient<NormalizedCacheObject>;
|
||||
v: Verbosity;
|
||||
}): Promise<ServersPayload | null> => {
|
||||
if (v === '') {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
const servers = await client.query({ query: getServersDocument });
|
||||
const foundServers = servers.data.servers.reduce<ServersPayload>(
|
||||
(acc, curr) => {
|
||||
switch (curr.status) {
|
||||
case 'online':
|
||||
acc.online.push(curr);
|
||||
break;
|
||||
case 'offline':
|
||||
acc.offline.push(curr);
|
||||
break;
|
||||
default:
|
||||
acc.invalid.push(curr);
|
||||
break;
|
||||
}
|
||||
|
||||
return acc;
|
||||
},
|
||||
{ online: [], offline: [], invalid: [] }
|
||||
);
|
||||
return foundServers;
|
||||
} catch (error: unknown) {
|
||||
cliLogger.addContext('error', error);
|
||||
cliLogger.trace(
|
||||
'Failed fetching servers from local graphql with "%s"',
|
||||
error instanceof Error ? error.message : 'Unknown Error'
|
||||
);
|
||||
cliLogger.removeContext('error');
|
||||
return {
|
||||
online: [],
|
||||
offline: [],
|
||||
invalid: [],
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
const hashUrlRegex = () => /(.*)([a-z0-9]{40})(.*)/g;
|
||||
|
||||
export const anonymiseOrigins = (origins?: string[]): string[] => {
|
||||
const originsWithoutSocks =
|
||||
origins?.filter((url) => !url.endsWith('.sock')) ?? [];
|
||||
return originsWithoutSocks
|
||||
.map((origin) =>
|
||||
origin
|
||||
// Replace 40 char hash string with "HASH"
|
||||
.replace(hashUrlRegex(), '$1HASH$3')
|
||||
// Replace ipv4 address using . separator with "IPV4ADDRESS"
|
||||
.replace(ipRegex(), 'IPV4ADDRESS')
|
||||
// Replace ipv4 address using - separator with "IPV4ADDRESS"
|
||||
.replace(
|
||||
new RegExp(ipRegex().toString().replace('\\.', '-')),
|
||||
'/IPV4ADDRESS'
|
||||
)
|
||||
// Report WAN port
|
||||
.replace(
|
||||
`:${getters.config().remote.wanport || 443}`,
|
||||
':WANPORT'
|
||||
)
|
||||
)
|
||||
.filter(Boolean);
|
||||
};
|
||||
|
||||
const getAllowedOrigins = (
|
||||
cloud: CloudQueryResult | null,
|
||||
v: Verbosity
|
||||
): string[] | null => {
|
||||
switch (v) {
|
||||
case '-vv':
|
||||
return (
|
||||
cloud?.allowedOrigins.filter((url) => !url.endsWith('.sock')) ??
|
||||
[]
|
||||
);
|
||||
case '-v':
|
||||
return anonymiseOrigins(cloud?.allowedOrigins ?? []);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
const getReadableCloudDetails = (
|
||||
reportObject: ReportObject,
|
||||
v: Verbosity
|
||||
): string => {
|
||||
const error = reportObject.cloud.error
|
||||
? `\n ERROR [${reportObject.cloud.error}]`
|
||||
: '';
|
||||
const status = reportObject.cloud.status
|
||||
? reportObject.cloud.status
|
||||
: 'disconnected';
|
||||
const ip =
|
||||
reportObject.cloud.ip && v !== ''
|
||||
? `\n IP: [${reportObject.cloud.ip}]`
|
||||
: '';
|
||||
return `
|
||||
STATUS: [${status}] ${ip} ${error}`;
|
||||
};
|
||||
|
||||
const getReadableMinigraphDetails = (reportObject: ReportObject): string => {
|
||||
const statusLine = `STATUS: [${reportObject.minigraph.status}]`;
|
||||
const errorLine = reportObject.minigraph.error
|
||||
? ` ERROR: [${reportObject.minigraph.error}]`
|
||||
: null;
|
||||
const timeoutLine = reportObject.minigraph.timeout
|
||||
? ` TIMEOUT: [${(reportObject.minigraph.timeout || 1) / 1_000}s]`
|
||||
: null; // 1 in case of divide by zero
|
||||
|
||||
return `
|
||||
${statusLine}${errorLine ? `\n${errorLine}` : ''}${
|
||||
timeoutLine ? `\n${timeoutLine}` : ''
|
||||
}`;
|
||||
};
|
||||
|
||||
// Convert server to string output
|
||||
const serverToString = (v: Verbosity) => (server: ServersQueryResultServer) =>
|
||||
`${server?.name ?? 'No Server Name'}${
|
||||
v === '-v' || v === '-vv'
|
||||
? `[owner="${server.owner?.username ?? 'No Owner Found'}"${
|
||||
v === '-vv' ? ` guid="${server.guid ?? 'No GUID'}"]` : ']'
|
||||
}`
|
||||
: ''
|
||||
}`;
|
||||
|
||||
const getReadableServerDetails = (
|
||||
reportObject: ReportObject,
|
||||
v: Verbosity
|
||||
): string => {
|
||||
if (!reportObject.servers) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if (reportObject.api.status === 'stopped') {
|
||||
return '\nSERVERS: API is offline';
|
||||
}
|
||||
|
||||
const invalid =
|
||||
(v === '-v' || v === '-vv') && reportObject.servers.invalid.length > 0
|
||||
? `
|
||||
INVALID: ${reportObject.servers.invalid.map(serverToString(v)).join(',')}`
|
||||
: '';
|
||||
|
||||
return `
|
||||
SERVERS:
|
||||
ONLINE: ${reportObject.servers.online.map(serverToString(v)).join(',')}
|
||||
OFFLINE: ${reportObject.servers.offline
|
||||
.map(serverToString(v))
|
||||
.join(',')}${invalid}`;
|
||||
};
|
||||
|
||||
const getReadableAllowedOrigins = (reportObject: ReportObject): string => {
|
||||
const { cloud } = reportObject;
|
||||
if (cloud?.allowedOrigins) {
|
||||
return `
|
||||
ALLOWED_ORIGINS: ${cloud.allowedOrigins.join(', ').trim()}`;
|
||||
}
|
||||
|
||||
return '';
|
||||
};
|
||||
|
||||
const getVerbosity = (argv: string[]): Verbosity => {
|
||||
if (argv.includes('-v')) {
|
||||
return '-v';
|
||||
}
|
||||
|
||||
if (argv.includes('-vv')) {
|
||||
return '-vv';
|
||||
}
|
||||
|
||||
return '';
|
||||
};
|
||||
|
||||
// eslint-disable-next-line complexity
|
||||
export const report = async (...argv: string[]) => {
|
||||
// Check if the user has raw output enabled
|
||||
const rawOutput = argv.includes('--raw');
|
||||
|
||||
// Check if we have a tty attached to stdout
|
||||
// If we don't then this is being piped to a log file, etc.
|
||||
const hasTty = process.stdout.isTTY;
|
||||
|
||||
// Check if we should show interactive logs
|
||||
// If this has a tty it's interactive
|
||||
// AND
|
||||
// If they don't have --raw
|
||||
const isInteractive = hasTty && !rawOutput;
|
||||
|
||||
const stdoutLogger = readLine.createInterface({
|
||||
input: process.stdin,
|
||||
output: process.stdout,
|
||||
});
|
||||
|
||||
try {
|
||||
setEnv('LOG_TYPE', 'raw');
|
||||
|
||||
// Show loading message
|
||||
if (isInteractive) {
|
||||
stdoutLogger.write('Generating report please wait…');
|
||||
}
|
||||
|
||||
const jsonReport = argv.includes('--json');
|
||||
const v = getVerbosity(argv);
|
||||
|
||||
// Find all processes called "unraid-api" which aren't this process
|
||||
const unraidApiPid = await getUnraidApiPid();
|
||||
|
||||
// Load my servers config file into store
|
||||
await store.dispatch(loadConfigFile());
|
||||
await store.dispatch(loadStateFiles());
|
||||
|
||||
const { config, emhttp } = store.getState();
|
||||
if (!config.upc.apikey) throw new Error('Missing UPC API key');
|
||||
|
||||
const client = getApiApolloClient({ upcApiKey: config.upc.apikey });
|
||||
// Fetch the cloud endpoint
|
||||
const cloud = await getCloudData(client);
|
||||
|
||||
// Log cloud response
|
||||
cliLogger.trace('Cloud response %s', JSON.stringify(cloud, null, 0));
|
||||
|
||||
// Query local graphql using upc's API key
|
||||
// Get the servers array
|
||||
const servers = await getServersData({ client, v });
|
||||
|
||||
// Check if the API key is valid
|
||||
const isApiKeyValid = cloud?.apiKey.valid ?? false;
|
||||
|
||||
const reportObject: ReportObject = {
|
||||
os: {
|
||||
serverName: emhttp.var.name,
|
||||
version: emhttp.var.version
|
||||
},
|
||||
api: {
|
||||
version: API_VERSION,
|
||||
status: unraidApiPid ? 'running' : 'stopped',
|
||||
environment:
|
||||
process.env.ENVIRONMENT ??
|
||||
'THIS_WILL_BE_REPLACED_WHEN_BUILT',
|
||||
nodeVersion: process.version,
|
||||
},
|
||||
apiKey: isApiKeyValid ? 'valid' : cloud?.apiKey.error ?? 'invalid',
|
||||
...(servers ? { servers } : {}),
|
||||
myServers: {
|
||||
status: config?.remote?.username
|
||||
? 'authenticated'
|
||||
: 'signed out',
|
||||
...(config?.remote?.username
|
||||
? { myServersUsername: config?.remote?.username?.includes('@') ? 'REDACTED' : config?.remote.username }
|
||||
: {}),
|
||||
},
|
||||
minigraph: {
|
||||
status: cloud?.minigraphql.status ?? MinigraphStatus.PRE_INIT,
|
||||
timeout: cloud?.minigraphql.timeout ?? null,
|
||||
error:
|
||||
cloud?.minigraphql.error ?? !cloud?.minigraphql.status
|
||||
? 'API Disconnected'
|
||||
: null,
|
||||
},
|
||||
cloud: {
|
||||
status: cloud?.cloud.status ?? 'error',
|
||||
...(cloud?.cloud.error ? { error: cloud.cloud.error } : {}),
|
||||
...(cloud?.cloud.status === 'ok'
|
||||
? { ip: cloud.cloud.ip ?? 'NO_IP' }
|
||||
: {}),
|
||||
...(getAllowedOrigins(cloud, v)
|
||||
? { allowedOrigins: getAllowedOrigins(cloud, v) }
|
||||
: {}),
|
||||
},
|
||||
};
|
||||
|
||||
// If we have trace logs or the user selected --raw don't clear the screen
|
||||
if (process.env.LOG_LEVEL !== 'trace' && isInteractive) {
|
||||
// Clear the original log about the report being generated
|
||||
readLine.cursorTo(process.stdout, 0, 0);
|
||||
readLine.clearScreenDown(process.stdout);
|
||||
}
|
||||
|
||||
if (jsonReport) {
|
||||
stdout.write(JSON.stringify(reportObject) + '\n');
|
||||
stdoutLogger.close();
|
||||
return reportObject;
|
||||
} else {
|
||||
// Generate the actual report
|
||||
const report = `
|
||||
<-----UNRAID-API-REPORT----->
|
||||
SERVER_NAME: ${reportObject.os.serverName}
|
||||
ENVIRONMENT: ${reportObject.api.environment}
|
||||
UNRAID_VERSION: ${reportObject.os.version}
|
||||
UNRAID_API_VERSION: ${reportObject.api.version}
|
||||
UNRAID_API_STATUS: ${reportObject.api.status}
|
||||
API_KEY: ${reportObject.apiKey}
|
||||
MY_SERVERS: ${reportObject.myServers.status}${
|
||||
reportObject.myServers.myServersUsername
|
||||
? `\nMY_SERVERS_USERNAME: ${reportObject.myServers.myServersUsername}`
|
||||
: ''
|
||||
}
|
||||
CLOUD: ${getReadableCloudDetails(reportObject, v)}
|
||||
MINI-GRAPH: ${getReadableMinigraphDetails(
|
||||
reportObject
|
||||
)}${getReadableServerDetails(
|
||||
reportObject,
|
||||
v
|
||||
)}${getReadableAllowedOrigins(reportObject)}
|
||||
</----UNRAID-API-REPORT----->
|
||||
`;
|
||||
|
||||
stdout.write(report);
|
||||
stdoutLogger.close();
|
||||
return report;
|
||||
}
|
||||
} catch (error: unknown) {
|
||||
console.log({ error });
|
||||
if (error instanceof Error) {
|
||||
cliLogger.trace(error);
|
||||
stdoutLogger.write(
|
||||
`\nFailed generating report with "${error.message}"\n`
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
stdout.write(`${error as string}`);
|
||||
stdoutLogger.close();
|
||||
}
|
||||
};
|
||||
@@ -1,87 +0,0 @@
|
||||
import { spawn } from 'child_process';
|
||||
import { addExitCallback } from 'catch-exit';
|
||||
import { cliLogger } from '@app/core/log';
|
||||
import { mainOptions } from '@app/cli/options';
|
||||
import { logToSyslog } from '@app/cli/log-to-syslog';
|
||||
import { getters } from '@app/store';
|
||||
import { getAllUnraidApiPids } from '@app/cli/get-unraid-api-pid';
|
||||
import { API_VERSION } from '@app/environment';
|
||||
|
||||
/**
|
||||
* Start a new API process.
|
||||
*/
|
||||
export const start = async () => {
|
||||
// Set process title
|
||||
process.title = 'unraid-api';
|
||||
const runningProcesses = await getAllUnraidApiPids();
|
||||
if (runningProcesses.length > 0) {
|
||||
cliLogger.info('unraid-api is Already Running!');
|
||||
cliLogger.info('Run "unraid-api restart" to stop all running processes and restart');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// Start API
|
||||
cliLogger.info('Starting unraid-api@v%s', API_VERSION);
|
||||
|
||||
// If we're in debug mode or we're NOT
|
||||
// in debug but ARE in the child process
|
||||
if (mainOptions.debug || process.env._DAEMONIZE_PROCESS) {
|
||||
// Log when the API exits
|
||||
addExitCallback((signal, exitCode, error) => {
|
||||
if (exitCode === 0 || exitCode === 130 || signal === 'SIGTERM') {
|
||||
logToSyslog('👋 Farewell. UNRAID API shutting down!');
|
||||
return;
|
||||
}
|
||||
|
||||
// Log when the API crashes
|
||||
if (signal === 'uncaughtException' && error) {
|
||||
logToSyslog(`⚠️ Caught exception: ${error.message}`);
|
||||
}
|
||||
|
||||
// Log when we crash
|
||||
if (exitCode) {
|
||||
logToSyslog(`⚠️ UNRAID API crashed with exit code ${exitCode}`);
|
||||
return;
|
||||
}
|
||||
|
||||
logToSyslog('🛑 UNRAID API crashed without an exit code?');
|
||||
});
|
||||
|
||||
logToSyslog('✔️ UNRAID API started successfully!');
|
||||
}
|
||||
|
||||
// Load bundled index file
|
||||
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
||||
require('../../index');
|
||||
|
||||
if (!mainOptions.debug) {
|
||||
if ('_DAEMONIZE_PROCESS' in process.env) {
|
||||
// In the child, clean up the tracking environment variable
|
||||
delete process.env._DAEMONIZE_PROCESS;
|
||||
} else {
|
||||
cliLogger.debug('Daemonizing process. %s %o', process.execPath, process.argv);
|
||||
|
||||
// Spawn child
|
||||
// First arg is path (inside PKG), second arg is restart, stop, etc, rest is args to main argument
|
||||
const [path, , ...rest] = process.argv.slice(1);
|
||||
const replacedCommand = [path, 'start', ...rest];
|
||||
const child = spawn(process.execPath, replacedCommand, {
|
||||
// In the parent set the tracking environment variable
|
||||
env: Object.assign(process.env, { _DAEMONIZE_PROCESS: '1' }),
|
||||
// The process MUST have it's cwd set to the
|
||||
// path where it resides within the Nexe VFS
|
||||
cwd: getters.paths()['unraid-api-base'],
|
||||
stdio: 'ignore',
|
||||
detached: true,
|
||||
});
|
||||
|
||||
// Convert process into daemon
|
||||
child.unref();
|
||||
|
||||
cliLogger.debug('Daemonized successfully!');
|
||||
|
||||
// Exit cleanly
|
||||
process.exit(0);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -1,19 +0,0 @@
|
||||
import prettyMs from 'pretty-ms';
|
||||
import pidUsage from 'pidusage';
|
||||
import { cliLogger } from '@app/core/log';
|
||||
import { getUnraidApiPid } from '@app/cli/get-unraid-api-pid';
|
||||
import { setEnv } from '@app/cli/set-env';
|
||||
|
||||
export const status = async () => {
|
||||
setEnv('LOG_TYPE', 'raw');
|
||||
|
||||
// Find all processes called "unraid-api" which aren't this process
|
||||
const unraidApiPid = await getUnraidApiPid();
|
||||
if (!unraidApiPid) {
|
||||
cliLogger.info('Found no running processes.');
|
||||
return;
|
||||
}
|
||||
|
||||
const stats = await pidUsage(unraidApiPid);
|
||||
cliLogger.info(`API has been running for ${prettyMs(stats.elapsed)} and is in "${process.env.ENVIRONMENT ?? 'ERR: Unknown Environment'}" mode!`);
|
||||
};
|
||||
@@ -1,47 +0,0 @@
|
||||
import { cliLogger } from '@app/core/log';
|
||||
import { getAllUnraidApiPids } from '@app/cli/get-unraid-api-pid';
|
||||
import { setEnv } from '@app/cli/set-env';
|
||||
import { sleep } from '@app/core/utils/misc/sleep';
|
||||
import pRetry from 'p-retry';
|
||||
|
||||
/**
|
||||
* Stop a running API process.
|
||||
*/
|
||||
|
||||
export const stop = async () => {
|
||||
setEnv('LOG_TYPE', 'raw');
|
||||
|
||||
try {
|
||||
await pRetry(async (attempts) => {
|
||||
const runningApis = await getAllUnraidApiPids();
|
||||
|
||||
if (runningApis.length > 0) {
|
||||
cliLogger.info('Stopping %s unraid-api process(es)...', runningApis.length);
|
||||
runningApis.forEach(pid => process.kill(pid, 'SIGTERM'));
|
||||
|
||||
const newPids = await getAllUnraidApiPids();
|
||||
|
||||
if (newPids.length > 0) {
|
||||
throw new Error('Not all processes have exited yet');
|
||||
}
|
||||
} else if (attempts < 1) {
|
||||
cliLogger.info('Found no running processes.');
|
||||
}
|
||||
|
||||
return true;
|
||||
}, {
|
||||
retries: 2,
|
||||
minTimeout: 2_000,
|
||||
factor: 1,
|
||||
});
|
||||
} catch (error: unknown) {
|
||||
cliLogger.info('Process did not exit cleanly, forcing shutdown', error);
|
||||
const processes = await getAllUnraidApiPids();
|
||||
for (const pid of processes) {
|
||||
process.kill(pid, 'SIGKILL');
|
||||
await sleep(100);
|
||||
}
|
||||
}
|
||||
|
||||
await sleep(500);
|
||||
};
|
||||
@@ -1,80 +0,0 @@
|
||||
import { copyFile, readFile, writeFile } from 'fs/promises';
|
||||
import { join } from 'path';
|
||||
import { cliLogger } from '@app/core/log';
|
||||
import { getUnraidApiPid } from '@app/cli/get-unraid-api-pid';
|
||||
import { setEnv } from '@app/cli/set-env';
|
||||
import { getters } from '@app/store';
|
||||
import { start } from '@app/cli/commands/start';
|
||||
import { stop } from '@app/cli/commands/stop';
|
||||
|
||||
export const switchEnv = async () => {
|
||||
setEnv('LOG_TYPE', 'raw');
|
||||
|
||||
const paths = getters.paths();
|
||||
const basePath = paths['unraid-api-base'];
|
||||
const envFlashFilePath = paths['myservers-env'];
|
||||
const envFile = await readFile(envFlashFilePath, 'utf-8').catch(() => '');
|
||||
|
||||
let shouldStartAfterRunning = false;
|
||||
if (await getUnraidApiPid()) {
|
||||
cliLogger.info('unraid-api is running, stopping...');
|
||||
// Stop Running Process
|
||||
await stop();
|
||||
shouldStartAfterRunning = true;
|
||||
}
|
||||
|
||||
cliLogger.debug(
|
||||
'Checking %s for current ENV, found %s',
|
||||
envFlashFilePath,
|
||||
envFile
|
||||
);
|
||||
|
||||
// Match the env file env="production" which would be [0] = env="production", [1] = env and [2] = production
|
||||
const matchArray = /([a-zA-Z]+)=["]*([a-zA-Z]+)["]*/.exec(envFile);
|
||||
// Get item from index 2 of the regex match or return undefined
|
||||
const [, , currentEnvInFile] =
|
||||
matchArray && matchArray.length === 3 ? matchArray : [];
|
||||
|
||||
let newEnv = 'production';
|
||||
|
||||
// Switch from staging to production
|
||||
if (currentEnvInFile === 'staging') {
|
||||
newEnv = 'production';
|
||||
}
|
||||
|
||||
// Switch from production to staging
|
||||
if (currentEnvInFile === 'production') {
|
||||
newEnv = 'staging';
|
||||
}
|
||||
|
||||
if (currentEnvInFile) {
|
||||
cliLogger.debug(
|
||||
'Switching from "%s" to "%s"...',
|
||||
currentEnvInFile,
|
||||
newEnv
|
||||
);
|
||||
} else {
|
||||
cliLogger.debug('No ENV found, setting env to "production"...');
|
||||
}
|
||||
|
||||
// Write new env to flash
|
||||
const newEnvLine = `env="${newEnv}"`;
|
||||
await writeFile(envFlashFilePath, newEnvLine);
|
||||
cliLogger.debug('Writing %s to %s', newEnvLine, envFlashFilePath);
|
||||
|
||||
// Copy the new env over to live location before restarting
|
||||
const source = join(basePath, `.env.${newEnv}`);
|
||||
const destination = join(basePath, '.env');
|
||||
|
||||
cliLogger.debug('Copying %s to %s', source, destination);
|
||||
await copyFile(source, destination);
|
||||
|
||||
cliLogger.info('Now using %s', newEnv);
|
||||
if (shouldStartAfterRunning) {
|
||||
cliLogger.debug('Restarting unraid-api');
|
||||
// Start Process
|
||||
await start();
|
||||
} else {
|
||||
cliLogger.info('Run "unraid-api start" to start the API.');
|
||||
}
|
||||
};
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user