Compare commits
652 Commits
Author | SHA1 | Date |
---|---|---|
Ioma Taani | daef238a70 | 3 years ago |
Louis Lam | 5df34cd137 | 3 years ago |
Louis Lam | bf64095cea | 3 years ago |
Louis Lam | 2333d1c7a7 | 3 years ago |
Louis Lam | 95bae8289d | 3 years ago |
Louis Lam | 45f7c647a6 | 3 years ago |
Zegert Boele | dff1056bb1 | 3 years ago |
Zegert Boele | 62222c0336 | 3 years ago |
Louis Lam | 733d0af75f | 3 years ago |
Louis Lam | b88e74fad8 | 3 years ago |
Ivan Bratović | 734762b773 | 3 years ago |
Louis Lam | 0275d7a42b | 3 years ago |
Louis Lam | 41a6d1b701 | 3 years ago |
Louis Lam | c92153c97e | 3 years ago |
Louis Lam | ad82ab0305 | 3 years ago |
Louis Lam | f952d283c6 | 3 years ago |
Louis Lam | e164fabf81 | 3 years ago |
Louis Lam | bc69a331ee | 3 years ago |
Jasper Miller-Waugh | e4506963d9 | 3 years ago |
Zegert Boele | 222540898b | 3 years ago |
Andreas Brett | 8f44b9f618 | 3 years ago |
Louis Lam | 210566c7af | 3 years ago |
Louis Lam | c5e6628803 | 3 years ago |
Louis Lam | 3a1d8ddc11 | 3 years ago |
Nelson Chan | bc5f61b3ec | 3 years ago |
Nelson Chan | 57389fab2c | 3 years ago |
MrEddX | ee2c54cfd1 | 3 years ago |
Louis Lam | 82cde7c847 | 3 years ago |
Louis Lam | 1ba2034701 | 3 years ago |
Louis Lam | dee131c25d | 3 years ago |
Jasper Miller-Waugh | e5d6410caf | 3 years ago |
Louis Lam | e496c3b3be | 3 years ago |
Louis Lam | 69f5112b38 | 3 years ago |
Louis Lam | c094dc0c5b | 3 years ago |
Ivan Bratović | 1fb9b25d13 | 3 years ago |
Ivan Bratović | 9a135deac2 | 3 years ago |
Your Name | 8e6173c05e | 3 years ago |
Louis Lam | dec84282ed | 3 years ago |
Louis Lam | df80f413b5 | 3 years ago |
Louis Lam | 17e59f1d8d | 3 years ago |
Louis Lam | 973c2bb429 | 3 years ago |
Louis Lam | da0eaddeb8 | 3 years ago |
Louis Lam | b2bc8d9db9 | 3 years ago |
Louis Lam | 541068ff3b | 3 years ago |
Louis Lam | 83ee46454a | 3 years ago |
Louis Lam | 75b21c905f | 3 years ago |
Louis Lam | 60e12f4bfa | 3 years ago |
Jasper Miller-Waugh | 191b81ee07 | 3 years ago |
Jagger | f3651a1219 | 3 years ago |
Jasper Miller-Waugh | 12ef9f39c5 | 3 years ago |
Jasper Miller-Waugh | 4004926e64 | 3 years ago |
Adam Stachowicz | 4d3d6d6e25 | 3 years ago |
Adam Stachowicz | d06e5ef6fa | 3 years ago |
Adam Stachowicz | b12b848d97 | 3 years ago |
Adam Stachowicz | bb96a577ca | 3 years ago |
Adam Stachowicz | 8840ca618b | 3 years ago |
Minvinea | 8ec858fd14 | 3 years ago |
Louis Lam | 124c98ce76 | 3 years ago |
Louis Lam | 61135e8500 | 3 years ago |
Louis Lam | 08a58dec2b | 3 years ago |
Louis Lam | 741ed548da | 3 years ago |
Louis Lam | 52d80d3a5d | 3 years ago |
Louis Lam | 586c748d44 | 3 years ago |
Louis Lam | b5d6e96b1d | 3 years ago |
Juan Calderon-Perez | 68b74f07e4 | 3 years ago |
Louis Lam | bc615c2dd8 | 3 years ago |
Louis Lam | e7104737e7 | 3 years ago |
Louis Lam | 1dbf1c3dea | 3 years ago |
Jasper Miller-Waugh | 74688e69aa | 3 years ago |
Jasper Miller-Waugh | b32bfb3ff1 | 3 years ago |
Jasper Miller-Waugh | 24664cde2c | 3 years ago |
Jasper Miller-Waugh | 348c5ec995 | 3 years ago |
Jasper Miller-Waugh | 9143b73f84 | 3 years ago |
Jasper Miller-Waugh | 5e6d945095 | 3 years ago |
Louis | ba93129b18 | 3 years ago |
Louis | cf548df15f | 3 years ago |
Louis | caa2a34177 | 3 years ago |
Adam Stachowicz | 69aa60d1fb | 3 years ago |
Ivan Bratović | eaecd6e571 | 3 years ago |
Adam Stachowicz | f2a27a2cf1 | 3 years ago |
Louis | d4c9431142 | 3 years ago |
Louis | d7f7dba13f | 3 years ago |
Louis | 3e5ae00d25 | 3 years ago |
Louis Lam | 5311bef3eb | 3 years ago |
Louis Lam | c400595f67 | 3 years ago |
Louis Lam | e84f7dac60 | 3 years ago |
SiderealArt | 67a22399bc | 3 years ago |
SiderealArt | 947fc6001e | 3 years ago |
SiderealArt | c87e67ad1b | 3 years ago |
Ivan Bratović | 6f92774a8f | 3 years ago |
Ivan Bratović | 6e76ab7426 | 3 years ago |
Ivan Bratović | b2fbd7e263 | 3 years ago |
Ivan Bratović | 199e6ec82b | 3 years ago |
Adam Stachowicz | 18a99c2016 | 3 years ago |
Louis Lam | e261a27ebe | 3 years ago |
Louis Lam | de5cce9d90 | 3 years ago |
Louis Lam | b85c9186f9 | 3 years ago |
Louis Lam | eb22ad5ffe | 3 years ago |
Louis Lam | f5f4835b74 | 3 years ago |
Louis Lam | 44c1b336dc | 3 years ago |
Louis Lam | 110ec491ee | 3 years ago |
Louis Lam | 640b6e5b1c | 3 years ago |
Louis Lam | 234fba3978 | 3 years ago |
Louis Lam | 1285ccb537 | 3 years ago |
Juan Calderon-Perez | 6c542edfc9 | 3 years ago |
Juan Calderon-Perez | 767807dd22 | 3 years ago |
Juan Calderon-Perez | 546402f3d2 | 3 years ago |
Louis Lam | 698a38e773 | 3 years ago |
Louis Lam | 71884cf42a | 3 years ago |
Louis Lam | d676c782bb | 3 years ago |
Juan Calderon-Perez | dd773aa5a2 | 3 years ago |
Louis Lam | 2852e59ffb | 3 years ago |
MrEddX | cb3da50e7e | 3 years ago |
Louis Lam | f25653d778 | 3 years ago |
Adam Stachowicz | 2e7ad1b7b2 | 3 years ago |
Louis Lam | e0e1ab6fa6 | 3 years ago |
Louis Lam | 8d984881c9 | 3 years ago |
Louis Lam | 955f9ae20a | 3 years ago |
Louis Lam | a9e319517a | 3 years ago |
Louis Lam | 39ad8b4bb7 | 3 years ago |
Andreas Brett | 8fb8cbdaf3 | 3 years ago |
Andreas Brett | 3f3d8b4eb3 | 3 years ago |
Louis Lam | 9123e9461f | 3 years ago |
Louis Lam | 77addfebc8 | 3 years ago |
Louis Lam | 16846c7c6d | 3 years ago |
Louis Lam | d1c4d13903 | 3 years ago |
Louis Lam | 7cd4bfc11d | 3 years ago |
Adam Stachowicz | 1d5c0502ab | 3 years ago |
Adam Stachowicz | a1cda93ad5 | 3 years ago |
Louis Lam | 3bd420f0e0 | 3 years ago |
Louis Lam | 78424b4f2d | 3 years ago |
Louis Lam | f8055ed03d | 3 years ago |
Louis Lam | fe4724fc53 | 3 years ago |
Louis Lam | 7f0dda6a44 | 3 years ago |
Lakr Aream | 43791ee97e | 3 years ago |
Tarun Singh | 6362ef6a9c | 3 years ago |
Adam Stachowicz | 9d3a4e9d1e | 3 years ago |
Tarun Singh | 6c60096f56 | 3 years ago |
Tarun Singh | ba1e025353 | 3 years ago |
Louis Lam | a41a081727 | 3 years ago |
Louis Lam | a5f15f2319 | 3 years ago |
Louis Lam | e69799f613 | 3 years ago |
Louis Lam | 3c795bebe3 | 3 years ago |
Louis Lam | 3a43fec666 | 3 years ago |
Louis Lam | 24c645e437 | 3 years ago |
Louis Lam | 9d31da1fe8 | 3 years ago |
Juan Calderon-Perez | 2e4c42941a | 3 years ago |
Andreas Brett | 4fc2603818 | 3 years ago |
Andreas Brett | 7bc38d4231 | 3 years ago |
Andreas Brett | daad63d70b | 3 years ago |
Andreas Brett | 9ddd2c7365 | 3 years ago |
Adam Stachowicz | fa5ba12e14 | 3 years ago |
Adam Stachowicz | 85053f865e | 3 years ago |
Adam Stachowicz | 1239f6d1a2 | 3 years ago |
Tarun Singh | fed611d1b9 | 3 years ago |
Tarun Singh | bc68088350 | 3 years ago |
Louis Lam | 90200958cd | 3 years ago |
Louis Lam | aa13d74d7a | 3 years ago |
Ponkhy | d82f305f6e | 3 years ago |
Louis Lam | 7c63cbfd84 | 3 years ago |
Juan Calderon-Perez | c7e1267779 | 3 years ago |
Louis Lam | 5d0b54c292 | 3 years ago |
Juan Calderon-Perez | b50b390048 | 3 years ago |
Adam Stachowicz | 65158cb06b | 3 years ago |
Adam Stachowicz | 8fe5e4e605 | 3 years ago |
Adam Stachowicz | ab5ddae2ee | 3 years ago |
Adam Stachowicz | 89c64f4ea2 | 3 years ago |
Juan Calderon-Perez | 40a1ebecc5 | 3 years ago |
Juan Calderon-Perez | e1793596fe | 3 years ago |
Juan Calderon-Perez | c489058a57 | 3 years ago |
Juan Calderon-Perez | 95342ec006 | 3 years ago |
Juan Calderon-Perez | bdebbf8e40 | 3 years ago |
Juan Calderon-Perez | 9a9fca67d5 | 3 years ago |
Nelson Chan | 665bae0806 | 3 years ago |
Nelson Chan | e4be28a9e7 | 3 years ago |
Nelson Chan | 445674aacb | 3 years ago |
Nelson Chan | 2f7b60f5e5 | 3 years ago |
Nelson Chan | b83c59e308 | 3 years ago |
Lakr Aream | ce852dfa02 | 3 years ago |
Louis Lam | c9549c0de2 | 3 years ago |
Louis Lam | 957c292307 | 3 years ago |
kry008 | b5eb17ed93 | 3 years ago |
Louis Lam | d578300104 | 3 years ago |
Louis Lam | b77b33e790 | 3 years ago |
Andreas Brett | 4becb97a5d | 3 years ago |
Andreas Brett | 85e2b36424 | 3 years ago |
Andreas Brett | abdf1ae90a | 3 years ago |
Andreas Brett | 606c967985 | 3 years ago |
Andreas Brett | 93c231b4d9 | 3 years ago |
Andreas Brett | 9ad8e5f56a | 3 years ago |
Louis Lam | 8a481a1be0 | 3 years ago |
Andreas Brett | 657987a013 | 3 years ago |
Louis Lam | d74577608b | 3 years ago |
Louis Lam | 20a399c557 | 3 years ago |
Phuong Nguyen Minh | 060dde9827 | 3 years ago |
DX37 | 1d1601cf24 | 3 years ago |
Louis Lam | ff5f2e8dfb | 3 years ago |
Louis Lam | 5451fb7672 | 3 years ago |
Louis Lam | 56094a43d7 | 3 years ago |
Louis Lam | 68bbe8944a | 3 years ago |
Louis Lam | 8f1da6aa22 | 3 years ago |
Louis Lam | c0d6fe0d76 | 3 years ago |
DX37 | 29e4e41215 | 3 years ago |
Louis Lam | 7a1bb964e9 | 3 years ago |
Louis Lam | 3fe0e9bf1e | 3 years ago |
Louis Lam | 9982887783 | 3 years ago |
Louis Lam | c31efc0ef4 | 3 years ago |
MrEddX | 6463d4b209 | 3 years ago |
Louis Lam | acada8028a | 3 years ago |
MrEddX | d0b0c64b81 | 3 years ago |
Louis Lam | cd04ac4557 | 3 years ago |
Louis Lam | d7d2f7b7fc | 3 years ago |
Daniel Patrón Gómez | 5a05d135b8 | 3 years ago |
Louis Lam | e03ee593e2 | 3 years ago |
Louis Lam | 6c1ee70e15 | 3 years ago |
Louis Lam | 5c3892313e | 3 years ago |
Louis Lam | c57c94642c | 3 years ago |
Louis Lam | 62f168a2a5 | 3 years ago |
Louis Lam | c808f78f09 | 3 years ago |
Louis Lam | 9c80e1c732 | 3 years ago |
Andreas Brett | acc2995d86 | 3 years ago |
Andreas Brett | 7def9dcec7 | 3 years ago |
NeuralMiner | a35569481d | 3 years ago |
NeuralMiner | 9ddffc0f7f | 3 years ago |
NeuralMiner | 76e7c8b276 | 3 years ago |
NeuralMiner | 572a5300aa | 3 years ago |
NeuralMiner | e1f1d4a959 | 3 years ago |
Louis Lam | c6fc385289 | 3 years ago |
Louis Lam | c645658161 | 3 years ago |
Louis Lam | 182597944d | 3 years ago |
Louis Lam | 8eaa8116c3 | 3 years ago |
Louis Lam | 3512faad14 | 3 years ago |
Louis Lam | f11417e854 | 3 years ago |
Juan Calderon-Perez | b5857f7c0c | 3 years ago |
Juan Calderon-Perez | 6277babf25 | 3 years ago |
Louis Lam | 5f36d2acda | 3 years ago |
Louis Lam | cc36ff5210 | 3 years ago |
Louis Lam | c363d3374e | 3 years ago |
Louis Lam | 65a8cb5307 | 3 years ago |
Lukas | f74b2662c5 | 3 years ago |
Louis Lam | 300a95d779 | 3 years ago |
Louis Lam | 23714ab688 | 3 years ago |
Louis Lam | 16b44001e7 | 3 years ago |
Louis Lam | f2f8f33b86 | 3 years ago |
Louis Lam | 6e18f39eb4 | 3 years ago |
Louis Lam | 68d44dd9b3 | 3 years ago |
Louis Lam | 20d59e5a13 | 3 years ago |
Louis Lam | ae31eb6ba9 | 3 years ago |
Andreas Brett | df4682d19b | 3 years ago |
Andreas Brett | 11a1f35cc5 | 3 years ago |
Juan Calderon-Perez | 2a3ce15328 | 3 years ago |
Juan Calderon-Perez | 7cb25255bf | 3 years ago |
Juan Calderon-Perez | c622f7958f | 3 years ago |
Louis Lam | df5efcc71c | 3 years ago |
J. Eckert | 4cd66b20b1 | 3 years ago |
J. Eckert | 1276102c18 | 3 years ago |
Louis Lam | 6944b35ea7 | 3 years ago |
Louis Lam | 88757ebbbe | 3 years ago |
Daniel Patrón Gómez | 0a73b84ae6 | 3 years ago |
Daniel Patrón Gómez | 15f36f96c3 | 3 years ago |
Louis Lam | edcaf93446 | 3 years ago |
Louis Lam | dec175d55f | 3 years ago |
Louis Lam | 9a60f69f66 | 3 years ago |
Daniel Patrón Gómez | 53a008ae2b | 3 years ago |
Bert Verhelst | 1d63dd9ddd | 3 years ago |
Bert Verhelst | 61627545a5 | 3 years ago |
Louis Lam | 176fa6b60d | 3 years ago |
Louis Lam | cb43ecb46e | 3 years ago |
Louis Lam | 2e24312f67 | 3 years ago |
Louis Lam | 6ff3cb275e | 3 years ago |
Louis Lam | 9d364b28b1 | 3 years ago |
Louis Lam | bc3e3f9118 | 3 years ago |
Louis Lam | 0f3ab7b1d8 | 3 years ago |
NeuralMiner | 8cb26d2b31 | 3 years ago |
januridp | d94fbede32 | 3 years ago |
januridp | 76e619c066 | 3 years ago |
januridp | 4e4f94ab98 | 3 years ago |
januridp | ed3a558397 | 3 years ago |
Louis Lam | a419aa527f | 3 years ago |
Louis Lam | 4d26825cbe | 3 years ago |
Louis Lam | 7276f34d90 | 3 years ago |
Louis Lam | e1eeb44e7f | 3 years ago |
Louis Lam | f4b8da0a5c | 3 years ago |
Louis Lam | 4178983df3 | 3 years ago |
Louis Lam | 7ac0ab2e34 | 3 years ago |
Louis Lam | cd211a6be7 | 3 years ago |
Louis Lam | 4e71ab7406 | 3 years ago |
Louis Lam | 76c68071f1 | 3 years ago |
Phuong Nguyen Minh | bda481c61e | 3 years ago |
iooner | 8242a1586d | 3 years ago |
Louis Lam | c593a962c2 | 3 years ago |
Louis Lam | c9b4d2ae2a | 3 years ago |
Louis Lam | 37105d720b | 3 years ago |
Louis Lam | 3b74b727f2 | 3 years ago |
firattemel | 2f0119bc3f | 3 years ago |
Louis Lam | a7d2a34dae | 3 years ago |
Louis Lam | 60acb91fc8 | 3 years ago |
Louis Lam | f51156f18e | 3 years ago |
Louis Lam | 8338881927 | 3 years ago |
Louis Lam | 674b387c95 | 3 years ago |
Louis Lam | 5ff9a64e5e | 3 years ago |
Louis Lam | 4bee57ea7f | 3 years ago |
Louis Lam | f75c9e4f0c | 3 years ago |
xJoker | 8ab4788f80 | 3 years ago |
xJoker | 4e4ab0577e | 3 years ago |
xJoker | 6e04ec436e | 3 years ago |
xJoker | 2d471a5e84 | 3 years ago |
xJoker | cae194f58f | 3 years ago |
Aaron Erkenswick | 655ccc86b9 | 3 years ago |
Louis Lam | e2dbacb383 | 3 years ago |
Lukas | 89b34b5748 | 3 years ago |
Andreas Brett | 86dcc9bc8f | 3 years ago |
Louis Lam | 9b05e86c25 | 3 years ago |
Louis Lam | 145b722aec | 3 years ago |
Louis Lam | 2ff7c4de5d | 3 years ago |
Louis Lam | 79c81395bc | 3 years ago |
Louis Lam | 178e5cd2c0 | 3 years ago |
hrtkpf | 84507268ad | 3 years ago |
wuwenjing | 843992c410 | 3 years ago |
zsxeee | 33f773fcd0 | 3 years ago |
zsxeee | 26841a64f0 | 3 years ago |
Phuong Nguyen Minh | 89c0f8b734 | 3 years ago |
wuwenjing | 57a76e6129 | 3 years ago |
Phuong Nguyen Minh | dc805cff97 | 3 years ago |
giacomo892 | 3fe3450533 | 3 years ago |
Lukas | 330cd6e058 | 3 years ago |
wuwenjing | a2f2253221 | 3 years ago |
Louis Lam | 1e5ce92917 | 3 years ago |
Louis Lam | 0d7c2960b0 | 3 years ago |
Louis Lam | 82343de972 | 3 years ago |
Adam Stachowicz | 521d57c483 | 3 years ago |
Adam Stachowicz | 281671b938 | 3 years ago |
Lukas | 30d8aadf12 | 3 years ago |
KangAlleW | 2939bd4138 | 3 years ago |
KangAlleW | dcf15c3eb7 | 3 years ago |
KangAlleW | 7c9ed98408 | 3 years ago |
KangAlleW | 4b9f0a3fe6 | 3 years ago |
KangAlleW | 5b67fec084 | 3 years ago |
Louis Lam | 407581ee07 | 3 years ago |
Louis Lam | 11c3c636e0 | 3 years ago |
Louis Lam | 911d4ea37b | 3 years ago |
Louis Lam | 4039c6549e | 3 years ago |
giacomo892 | d733ec018e | 3 years ago |
Nelson Chan | 03b07730d3 | 3 years ago |
Louis Lam | dbc87d8ab3 | 3 years ago |
dhfhfk | 05b691d4c9 | 3 years ago |
Louis Lam | 029d6412da | 3 years ago |
Louis Lam | 9f12f95cce | 3 years ago |
Kyungyoon Kim | c1112a32df | 3 years ago |
Kyungyoon Kim | efc78acfeb | 3 years ago |
zsxeee | 9e01959d15 | 3 years ago |
zsxeee | 3fe91c52cb | 3 years ago |
Tomas Rohrer | 5269dcec60 | 3 years ago |
zsxeee | a2cc7d1db9 | 3 years ago |
Louis Lam | 18c5a16783 | 3 years ago |
Andreas Brett | 2538bd04ce | 3 years ago |
Louis Lam | b7528b9a4e | 3 years ago |
Thomas LÉVEIL | 9c058054b9 | 3 years ago |
Louis Lam | c6683e2a9b | 3 years ago |
Louis Lam | b558708be2 | 3 years ago |
Louis Lam | fd0dd2d284 | 3 years ago |
xJoker | 1bc77a06e5 | 3 years ago |
xJoker | 69c623ac2b | 3 years ago |
Atlochowski | 69ffee55dd | 3 years ago |
Slayer | d769c4426c | 3 years ago |
Atlochowski | ebf0671fef | 3 years ago |
Louis Lam | 97af09fd50 | 3 years ago |
Louis Lam | 5b19e3f025 | 3 years ago |
wuwenjing | ce2df137e6 | 3 years ago |
wuwenjing | 6d9b71c054 | 3 years ago |
Atlochowski | a433de74e6 | 3 years ago |
LouisLam | 8e3f43d60b | 3 years ago |
Louis Lam | 2a1fd93444 | 3 years ago |
Andreas Brett | dc1de50a02 | 3 years ago |
Andreas Brett | e223e826a3 | 3 years ago |
Andreas Brett | 0e6d7694ce | 3 years ago |
Andreas Brett | 503d1f0a91 | 3 years ago |
Andreas Brett | 11bcd1e2ed | 3 years ago |
Andreas Brett | 06310423f4 | 3 years ago |
Andreas Brett | e127e168b6 | 3 years ago |
Andreas Brett | b5b391c73b | 3 years ago |
Andreas Brett | 075535ba46 | 3 years ago |
Andreas Brett | 13cf6891ac | 3 years ago |
Louis Lam | ad0cde6554 | 3 years ago |
Louis Lam | 25d18f0da3 | 3 years ago |
RisedSky | e9445bb2e3 | 3 years ago |
RisedSky | ecc25ba596 | 3 years ago |
LouisLam | e5286b0973 | 3 years ago |
LouisLam | 4e94cb9aad | 3 years ago |
Daniel S. Billing | 037fdd73a3 | 3 years ago |
Daniel S. Billing | bb9a936658 | 3 years ago |
Bert Verhelst | 5445c2a2ff | 3 years ago |
Bert Verhelst | dc08510e72 | 3 years ago |
Daniel S. Billing | 62805014df | 3 years ago |
Daniel S. Billing | c79e80442a | 3 years ago |
Daniel S. Billing | f0ff96afd9 | 3 years ago |
Louis Lam | 8083368a81 | 3 years ago |
RisedSky | afb75e07d5 | 3 years ago |
RisedSky | efd3822930 | 3 years ago |
dhfhfk | 2adac64c83 | 3 years ago |
Louis | cee225bcb2 | 3 years ago |
Louis | 8958c21736 | 3 years ago |
Louis | 2286f78f57 | 3 years ago |
Louis | d9eab90a69 | 3 years ago |
Louis Lam | 4ba2025451 | 3 years ago |
LouisLam | 272d4bde45 | 3 years ago |
LouisLam | 0550ceb6d4 | 3 years ago |
LouisLam | 82131f4dd2 | 3 years ago |
Louis Lam | 0c88e4b2f6 | 3 years ago |
Louis Lam | 5c6230da58 | 3 years ago |
Louis Lam | d6753b8833 | 3 years ago |
Louis Lam | 93a021d027 | 3 years ago |
新逸Cary | 54f864a1bb | 3 years ago |
Lukas | d6f7be9112 | 3 years ago |
Bert Verhelst | 5137c80c07 | 3 years ago |
Lukas | 792f3c7c5c | 3 years ago |
Bert Verhelst | 8a739af5ad | 3 years ago |
Lukas | edb75808d8 | 3 years ago |
LouisLam | 56ae6f6117 | 3 years ago |
Lukas | 5e3ea3293c | 3 years ago |
LouisLam | 5c89562650 | 3 years ago |
Louis Lam | 1f7f20526f | 3 years ago |
Louis Lam | 0f5b437015 | 3 years ago |
Nelson Chan | ac80631bcd | 3 years ago |
Nelson Chan | 8caf47988c | 3 years ago |
Robin Schneider | 6fe014fa5e | 3 years ago |
Nelson Chan | 6cf2eb036d | 3 years ago |
MrEddX | 9d7def93a5 | 3 years ago |
Nelson Chan | dca5a59dbc | 3 years ago |
Nelson Chan | 656a4d6270 | 3 years ago |
Louis Lam | 6dd0e082b4 | 3 years ago |
Kyungyoon Kim | 2e95e2016d | 3 years ago |
Louis Lam | 4169127143 | 3 years ago |
LouisLam | cac0a46bac | 3 years ago |
Bert Verhelst | d71d27220b | 3 years ago |
Bert Verhelst | fba4f86552 | 3 years ago |
LouisLam | e023ddf1c2 | 3 years ago |
LouisLam | 23a2d33f8c | 3 years ago |
Bert Verhelst | b8093e909b | 3 years ago |
Bert Verhelst | c3c273f9df | 3 years ago |
Bert Verhelst | daab2a05f5 | 3 years ago |
LouisLam | a15e9077fc | 3 years ago |
Louis Lam | 8431a25a3a | 3 years ago |
Louis Lam | e8cc7ff771 | 3 years ago |
新逸Cary | 5d617012a3 | 3 years ago |
Daniel Patrón Gómez | d7eac1a413 | 3 years ago |
Louis Lam | c589bd836d | 3 years ago |
LouisLam | 5ce09953e2 | 3 years ago |
LouisLam | fc8d1e78b6 | 3 years ago |
LouisLam | 3f26327f95 | 3 years ago |
Louis Lam | efb3f2b19c | 3 years ago |
Lukas | db791c880a | 3 years ago |
新逸Cary | cdda182311 | 3 years ago |
LouisLam | a1c2a1bc52 | 3 years ago |
Louis Lam | 432b156fce | 3 years ago |
LouisLam | 01812cc446 | 3 years ago |
Lukas | dfd63386ba | 3 years ago |
LouisLam | 11abc1f1e0 | 3 years ago |
LouisLam | 288e87bb3d | 3 years ago |
Louis Lam | 79ee0e1ef4 | 3 years ago |
LouisLam | 8ae79ab9bf | 3 years ago |
Lukas | 12b5489eb5 | 3 years ago |
LouisLam | ddad2dcb4a | 3 years ago |
LouisLam | e96121f69a | 3 years ago |
LouisLam | 5b4af550fb | 3 years ago |
Louis Lam | dd183e2ec2 | 3 years ago |
LouisLam | 0fcb310b97 | 3 years ago |
LouisLam | 3a0143ac46 | 3 years ago |
LouisLam | 2ce5c28ed4 | 3 years ago |
Bert Verhelst | ec4b7e4064 | 3 years ago |
Kevin Petit | 5b758a4e98 | 3 years ago |
LouisLam | 7907c07034 | 3 years ago |
LouisLam | adfe640f42 | 3 years ago |
Louis Lam | 469f7a3e32 | 3 years ago |
LouisLam | 9f1e7b0a88 | 3 years ago |
LouisLam | cdf81a36d3 | 3 years ago |
LouisLam | bf4ac0cf17 | 3 years ago |
LouisLam | c0846124c2 | 3 years ago |
LouisLam | 3d30ed3d3b | 3 years ago |
LouisLam | deec15c09e | 3 years ago |
LouisLam | 3423cb5d8e | 3 years ago |
LouisLam | 20af179a82 | 3 years ago |
LouisLam | 3c60800eab | 3 years ago |
LouisLam | 34586d7b8f | 3 years ago |
LouisLam | 2c19aef4dc | 3 years ago |
LouisLam | 67a623be18 | 3 years ago |
LouisLam | e5f6d7f047 | 3 years ago |
LouisLam | b69550f5b9 | 3 years ago |
LouisLam | d08a71ab49 | 3 years ago |
LouisLam | ed67803af8 | 3 years ago |
Louis Lam | a6c839709c | 3 years ago |
Louis Lam | 5eb3c6b194 | 3 years ago |
LouisLam | 8233f3b875 | 3 years ago |
Bert Verhelst | 8be4bf0e16 | 3 years ago |
LouisLam | cccf393ee5 | 3 years ago |
MrEddX | 9f5bf37a96 | 3 years ago |
LouisLam | 18e4702375 | 3 years ago |
MrEddX | 1eb3f63a82 | 3 years ago |
Louis Lam | 8c63536eb8 | 3 years ago |
LouisLam | 3e1788983e | 3 years ago |
LouisLam | a8badb027d | 3 years ago |
MrEddX | 0c6b434d79 | 3 years ago |
Louis Lam | b5bd92ce78 | 3 years ago |
Louis Lam | 3f80cf5e54 | 3 years ago |
Bert Verhelst | 162ef04c41 | 3 years ago |
Nelson Chan | a87595a849 | 3 years ago |
jtagcat | 7626e1f2e4 | 3 years ago |
zsxeee | 7f1edb49bc | 3 years ago |
Gero Gerke | d184733af9 | 3 years ago |
Gero Gerke | 704d63b49f | 3 years ago |
zsxeee | 7002a778f0 | 3 years ago |
zsxeee | 54d2fbcc02 | 3 years ago |
Gero Gerke | fbd4d54812 | 3 years ago |
LouisLam | c8706b9aa1 | 3 years ago |
Louis Lam | 54d7830813 | 3 years ago |
LouisLam | fef26f3d5e | 3 years ago |
LouisLam | cb263f2a08 | 3 years ago |
Louis Lam | 52102d72a0 | 3 years ago |
LouisLam | 2b00e59c7a | 3 years ago |
Louis Lam | 8ea7a693a1 | 3 years ago |
LouisLam | 4ded0c073a | 3 years ago |
Brainpitcher | 7a8b6a03e0 | 3 years ago |
Gero Gerke | 6bebc623f9 | 3 years ago |
Gero Gerke | 34b86352f2 | 3 years ago |
Gero Gerke | 99e8a33118 | 3 years ago |
Gero Gerke | d7cc585101 | 3 years ago |
Gero Gerke | 8c357a04bf | 3 years ago |
DeeJayPee | 044c78aa2d | 3 years ago |
DeeJayPee | 49eaa1a166 | 3 years ago |
DeeJayPee | 215cc07907 | 3 years ago |
LouisLam | 22227be408 | 3 years ago |
Gero Gerke | 5decfb9fad | 3 years ago |
DeeJayPee | f9d7b99367 | 3 years ago |
DeeJayPee | 359fe52c2e | 3 years ago |
DeeJayPee | bc4db6c692 | 3 years ago |
DeeJayPee | f14a798b2c | 3 years ago |
Bert Verhelst | a0ffa42b42 | 3 years ago |
Bert Verhelst | 550825927c | 3 years ago |
LouisLam | c1501742f5 | 3 years ago |
LouisLam | 7c98fe603e | 3 years ago |
LouisLam | b7ae49c644 | 3 years ago |
LouisLam | edad2caf8e | 3 years ago |
LouisLam | 2bf6a04f81 | 3 years ago |
Louis Lam | f0670dde20 | 3 years ago |
Louis Lam | 73068763c0 | 3 years ago |
LouisLam | 73bf1216d1 | 3 years ago |
LouisLam | 98436f91b5 | 3 years ago |
LouisLam | 49720c709c | 3 years ago |
Louis Lam | 842d359ad3 | 3 years ago |
LouisLam | e71f5bf314 | 3 years ago |
LouisLam | 79e0c9e1f1 | 3 years ago |
LouisLam | e6ff957d9d | 3 years ago |
Louis Lam | 865b721b79 | 3 years ago |
LouisLam | b5d987863d | 3 years ago |
Louis Lam | 911690bea8 | 3 years ago |
LouisLam | d25603e629 | 3 years ago |
LouisLam | 259bcf9426 | 3 years ago |
Bert Verhelst | afeb424dc0 | 3 years ago |
Bert Verhelst | 6b44116245 | 3 years ago |
Louis Lam | aa478af286 | 3 years ago |
Adam Stachowicz | 5f8d0faacd | 3 years ago |
Adam Stachowicz | 707e05c330 | 3 years ago |
Adam Stachowicz | 4da63c5fb8 | 3 years ago |
Adam Stachowicz | 8ae64843fc | 3 years ago |
Adam Stachowicz | 23e64b8efd | 3 years ago |
Louis Lam | 8c55a8bf98 | 3 years ago |
Louis Lam | 387a8919f9 | 3 years ago |
Louis Lam | a1edc23b1d | 3 years ago |
Bert Verhelst | 7ee89fab5c | 3 years ago |
Csábi Béla | 980342546e | 3 years ago |
Csábi Béla | 6b60dc9630 | 3 years ago |
Csábi Béla | 8d22b43f24 | 3 years ago |
Csábi Béla | dad58341c6 | 3 years ago |
jtagcat | 275902be38 | 3 years ago |
jtagcat | 38213585f3 | 3 years ago |
LouisLam | 37d1e50ff1 | 3 years ago |
LouisLam | a2a4c70cf5 | 3 years ago |
Louis Lam | 446fc1af0b | 3 years ago |
LouisLam | 51acd107e3 | 3 years ago |
LouisLam | d3517e76c1 | 3 years ago |
Bert Verhelst | 3f0b85e5a8 | 3 years ago |
LouisLam | 2625cbe0d2 | 3 years ago |
LouisLam | c93f42794f | 3 years ago |
Nelson Chan | 668fd58af3 | 3 years ago |
Nelson Chan | b7568e9caa | 3 years ago |
Bert Verhelst | 1c2adf8723 | 3 years ago |
Bert Verhelst | 96129921e9 | 3 years ago |
Louis Lam | 2b1fe815f9 | 3 years ago |
Louis Lam | fcf017d5c7 | 3 years ago |
Bert Verhelst | 843830a38a | 3 years ago |
Bert Verhelst | ee830621dd | 3 years ago |
Bert Verhelst | c2a560e2ed | 3 years ago |
Nelson Chan | 13bdfefa9d | 3 years ago |
Bert Verhelst | 3d6c8b7f05 | 3 years ago |
LouisLam | 2aaed66b38 | 3 years ago |
LouisLam | 7b4c70860c | 3 years ago |
LouisLam | 6513c3e75f | 3 years ago |
LouisLam | 7fa1cb83af | 3 years ago |
Louis Lam | 9d079eeec0 | 3 years ago |
LouisLam | 21dd5ad3dd | 3 years ago |
LouisLam | 3394e1f148 | 3 years ago |
Louis Lam | ee22406301 | 3 years ago |
LouisLam | 8d5eaaf8a7 | 3 years ago |
LouisLam | b246c8e0f2 | 3 years ago |
LouisLam | 1ed4ac9494 | 3 years ago |
zsxeee | 0f2059cde0 | 3 years ago |
zsxeee | 138ddf5608 | 3 years ago |
zsxeee | dcd68213b1 | 3 years ago |
Louis Lam | 9e95d568c2 | 3 years ago |
Louis Lam | fa3da819f8 | 3 years ago |
Louis Lam | 9e1f1f006b | 3 years ago |
Louis Lam | 55cb497301 | 3 years ago |
LouisLam | 8d8d5987e7 | 3 years ago |
LouisLam | 1fa90bffaa | 3 years ago |
LouisLam | 67f221d3c7 | 3 years ago |
Nelson Chan | 05f28fecb2 | 3 years ago |
Nelson Chan | ba4a4aaf1c | 3 years ago |
LouisLam | 6eceb4c744 | 3 years ago |
LouisLam | 3e4154dfb5 | 3 years ago |
Louis Lam | fbc8828ddc | 3 years ago |
Soroosh | f2c7308c96 | 3 years ago |
Denis Freund | efbadd0737 | 3 years ago |
Adam Stachowicz | f9d633e02b | 3 years ago |
Adam Stachowicz | fa9d26416c | 3 years ago |
Adam Stachowicz | 58aa83331e | 3 years ago |
Denis Freund | b67b4d5afd | 3 years ago |
Soroosh | 9f06d54688 | 3 years ago |
Soroosh | 1448de7b19 | 3 years ago |
Soroosh | 47749ca58d | 3 years ago |
Soroosh | 04b7a4a423 | 3 years ago |
Soroosh | 56d8f585fd | 3 years ago |
Soroosh | 07c9d78829 | 3 years ago |
Soroosh | 15c4a8fb02 | 3 years ago |
Soroosh | f41e95921f | 3 years ago |
Soroosh | 647184e5d1 | 3 years ago |
Soroosh | e60426bdcd | 3 years ago |
Soroosh | 251d42f1a6 | 3 years ago |
zsxeee | f24abac7fc | 3 years ago |
Nelson Chan | 32c9dfbb31 | 3 years ago |
zsxeee | 624f632a7a | 3 years ago |
zsxeee | 6e9d12638c | 3 years ago |
zsxeee | 6e55c44773 | 3 years ago |
zsxeee | 601204ae77 | 3 years ago |
zsxeee | 8c941b1d56 | 3 years ago |
zsxeee | ad6fcc2f2e | 3 years ago |
zsxeee | ffbc25722d | 3 years ago |
zsxeee | 2fb3c40307 | 3 years ago |
zsxeee | 66e40d9fcb | 3 years ago |
zsxeee | de8b61ef2b | 3 years ago |
zsxeee | 534ac4b720 | 3 years ago |
zsxeee | e9735d239b | 3 years ago |
DeeJayPee | 29d0db805d | 3 years ago |
185 changed files with 29915 additions and 11129 deletions
@ -1,18 +0,0 @@ |
|||
--- |
|||
name: Ask for help |
|||
about: You can ask any question related to Uptime Kuma. |
|||
title: '' |
|||
labels: help |
|||
assignees: '' |
|||
|
|||
--- |
|||
**Is it a duplicate question?** |
|||
Please search in Issues without filters: https://github.com/louislam/uptime-kuma/issues?q= |
|||
|
|||
**Info** |
|||
Uptime Kuma Version: |
|||
Using Docker?: Yes/No |
|||
Docker Version: |
|||
Node.js Version (Without Docker only): |
|||
OS: |
|||
Browser: |
@ -0,0 +1,68 @@ |
|||
name: "❓ Ask for help" |
|||
description: "Submit any question related to Uptime Kuma" |
|||
#title: "[Help] " |
|||
labels: [help] |
|||
body: |
|||
- type: checkboxes |
|||
id: no-duplicate-issues |
|||
attributes: |
|||
label: "⚠️ Please verify that this bug has NOT been raised before." |
|||
description: "Search in the issues sections by clicking [HERE](https://github.com/louislam/uptime-kuma/issues?q=)" |
|||
options: |
|||
- label: "I checked and didn't find similar issue" |
|||
required: true |
|||
- type: checkboxes |
|||
attributes: |
|||
label: "🛡️ Security Policy" |
|||
description: Please review the security policy before reporting security related issues/bugs. |
|||
options: |
|||
- label: I agree to have read this project [Security Policy](https://github.com/louislam/uptime-kuma/security/policy) |
|||
required: true |
|||
- type: textarea |
|||
id: steps-to-reproduce |
|||
validations: |
|||
required: true |
|||
attributes: |
|||
label: "📝 Describe your problem" |
|||
description: "Please walk us through it step by step." |
|||
placeholder: "Describe what are you asking for..." |
|||
- type: input |
|||
id: uptime-kuma-version |
|||
attributes: |
|||
label: "🐻 Uptime-Kuma Version" |
|||
description: "Which version of Uptime-Kuma are you running? Please do NOT provide the docker tag such as latest or 1" |
|||
placeholder: "Ex. 1.10.0" |
|||
validations: |
|||
required: true |
|||
- type: input |
|||
id: operating-system |
|||
attributes: |
|||
label: "💻 Operating System and Arch" |
|||
description: "Which OS is your server/device running on?" |
|||
placeholder: "Ex. Ubuntu 20.04 x86" |
|||
validations: |
|||
required: true |
|||
- type: input |
|||
id: browser-vendor |
|||
attributes: |
|||
label: "🌐 Browser" |
|||
description: "Which browser are you running on?" |
|||
placeholder: "Ex. Google Chrome 95.0.4638.69" |
|||
validations: |
|||
required: true |
|||
- type: input |
|||
id: docker-version |
|||
attributes: |
|||
label: "🐋 Docker Version" |
|||
description: "If running with Docker, which version are you running?" |
|||
placeholder: "Ex. Docker 20.10.9 / K8S / Podman" |
|||
validations: |
|||
required: false |
|||
- type: input |
|||
id: nodejs-version |
|||
attributes: |
|||
label: "🟩 NodeJS Version" |
|||
description: "If running with Node.js? which version are you running?" |
|||
placeholder: "Ex. 14.18.0" |
|||
validations: |
|||
required: false |
@ -1,42 +0,0 @@ |
|||
--- |
|||
name: Bug report |
|||
about: Create a report to help us improve |
|||
title: '' |
|||
labels: bug |
|||
assignees: '' |
|||
|
|||
--- |
|||
|
|||
**Is it a duplicate question?** |
|||
Please search in Issues without filters: https://github.com/louislam/uptime-kuma/issues?q= |
|||
|
|||
**Describe the bug** |
|||
A clear and concise description of what the bug is. |
|||
|
|||
**To Reproduce** |
|||
Steps to reproduce the behavior: |
|||
|
|||
1. Go to '...' |
|||
2. Click on '....' |
|||
3. Scroll down to '....' |
|||
4. See error |
|||
|
|||
**Expected behavior** |
|||
A clear and concise description of what you expected to happen. |
|||
|
|||
**Info** |
|||
Uptime Kuma Version: |
|||
Using Docker?: Yes/No |
|||
Docker Version: |
|||
Node.js Version (Without Docker only): |
|||
OS: |
|||
Browser: |
|||
|
|||
**Screenshots** |
|||
If applicable, add screenshots to help explain your problem. |
|||
|
|||
**Error Log** |
|||
It is easier for us to find out the problem. |
|||
|
|||
Docker: `docker logs <container id>` |
|||
PM2: `~/.pm2/logs/` (e.g. `/home/ubuntu/.pm2/logs`) |
@ -0,0 +1,99 @@ |
|||
name: "🐛 Bug Report" |
|||
description: "Submit a bug report to help us improve" |
|||
#title: "[Bug] " |
|||
labels: [bug] |
|||
body: |
|||
- type: checkboxes |
|||
id: no-duplicate-issues |
|||
attributes: |
|||
label: "⚠️ Please verify that this bug has NOT been raised before." |
|||
description: "Search in the issues sections by clicking [HERE](https://github.com/louislam/uptime-kuma/issues?q=)" |
|||
options: |
|||
- label: "I checked and didn't find similar issue" |
|||
required: true |
|||
- type: checkboxes |
|||
attributes: |
|||
label: "🛡️ Security Policy" |
|||
description: Please review the security policy before reporting security related issues/bugs. |
|||
options: |
|||
- label: I agree to have read this project [Security Policy](https://github.com/louislam/uptime-kuma/security/policy) |
|||
required: true |
|||
- type: textarea |
|||
id: description |
|||
validations: |
|||
required: false |
|||
attributes: |
|||
label: "Description" |
|||
description: "You could also upload screenshots" |
|||
- type: textarea |
|||
id: steps-to-reproduce |
|||
validations: |
|||
required: true |
|||
attributes: |
|||
label: "👟 Reproduction steps" |
|||
description: "How do you trigger this bug? Please walk us through it step by step." |
|||
placeholder: "..." |
|||
- type: textarea |
|||
id: expected-behavior |
|||
validations: |
|||
required: true |
|||
attributes: |
|||
label: "👀 Expected behavior" |
|||
description: "What did you think would happen?" |
|||
placeholder: "..." |
|||
- type: textarea |
|||
id: actual-behavior |
|||
validations: |
|||
required: true |
|||
attributes: |
|||
label: "😓 Actual Behavior" |
|||
description: "What actually happen?" |
|||
placeholder: "..." |
|||
- type: input |
|||
id: uptime-kuma-version |
|||
attributes: |
|||
label: "🐻 Uptime-Kuma Version" |
|||
description: "Which version of Uptime-Kuma are you running? Please do NOT provide the docker tag such as latest or 1" |
|||
placeholder: "Ex. 1.10.0" |
|||
validations: |
|||
required: true |
|||
- type: input |
|||
id: operating-system |
|||
attributes: |
|||
label: "💻 Operating System and Arch" |
|||
description: "Which OS is your server/device running on?" |
|||
placeholder: "Ex. Ubuntu 20.04 x86" |
|||
validations: |
|||
required: true |
|||
- type: input |
|||
id: browser-vendor |
|||
attributes: |
|||
label: "🌐 Browser" |
|||
description: "Which browser are you running on?" |
|||
placeholder: "Ex. Google Chrome 95.0.4638.69" |
|||
validations: |
|||
required: true |
|||
- type: input |
|||
id: docker-version |
|||
attributes: |
|||
label: "🐋 Docker Version" |
|||
description: "If running with Docker, which version are you running?" |
|||
placeholder: "Ex. Docker 20.10.9 / K8S / Podman" |
|||
validations: |
|||
required: false |
|||
- type: input |
|||
id: nodejs-version |
|||
attributes: |
|||
label: "🟩 NodeJS Version" |
|||
description: "If running with Node.js? which version are you running?" |
|||
placeholder: "Ex. 14.18.0" |
|||
validations: |
|||
required: false |
|||
- type: textarea |
|||
id: logs |
|||
attributes: |
|||
label: "📝 Relevant log output" |
|||
description: Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks. |
|||
render: shell |
|||
validations: |
|||
required: false |
@ -1,22 +0,0 @@ |
|||
--- |
|||
name: Feature request |
|||
about: Suggest an idea for this project |
|||
title: '' |
|||
labels: enhancement |
|||
assignees: '' |
|||
|
|||
--- |
|||
**Is it a duplicate question?** |
|||
Please search in Issues without filters: https://github.com/louislam/uptime-kuma/issues?q= |
|||
|
|||
**Is your feature request related to a problem? Please describe.** |
|||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] |
|||
|
|||
**Describe the solution you'd like** |
|||
A clear and concise description of what you want to happen. |
|||
|
|||
**Describe alternatives you've considered** |
|||
A clear and concise description of any alternative solutions or features you've considered. |
|||
|
|||
**Additional context** |
|||
Add any other context or screenshots about the feature request here. |
@ -0,0 +1,59 @@ |
|||
name: 🚀 Feature Request |
|||
description: "Submit a proposal for a new feature" |
|||
#title: "[Feature] " |
|||
labels: [feature-request] |
|||
body: |
|||
- type: checkboxes |
|||
id: no-duplicate-issues |
|||
attributes: |
|||
label: "⚠️ Please verify that this feature request has NOT been suggested before." |
|||
description: "Search in the issues sections by clicking [HERE](https://github.com/louislam/uptime-kuma/issues?q=)" |
|||
options: |
|||
- label: "I checked and didn't find similar feature request" |
|||
required: true |
|||
- type: dropdown |
|||
id: feature-area |
|||
attributes: |
|||
label: "🏷️ Feature Request Type" |
|||
description: "What kind of feature request is this?" |
|||
multiple: true |
|||
options: |
|||
- API |
|||
- New Notification |
|||
- New Monitor |
|||
- UI Feature |
|||
- Other |
|||
validations: |
|||
required: true |
|||
- type: textarea |
|||
id: feature-description |
|||
validations: |
|||
required: true |
|||
attributes: |
|||
label: "🔖 Feature description" |
|||
description: "A clear and concise description of what the feature request is." |
|||
placeholder: "You should add ..." |
|||
- type: textarea |
|||
id: solution |
|||
validations: |
|||
required: true |
|||
attributes: |
|||
label: "✔️ Solution" |
|||
description: "A clear and concise description of what you want to happen." |
|||
placeholder: "In my use-case, ..." |
|||
- type: textarea |
|||
id: alternatives |
|||
validations: |
|||
required: false |
|||
attributes: |
|||
label: "❓ Alternatives" |
|||
description: "A clear and concise description of any alternative solutions or features you've considered." |
|||
placeholder: "I have considered ..." |
|||
- type: textarea |
|||
id: additional-context |
|||
validations: |
|||
required: false |
|||
attributes: |
|||
label: "📝 Additional Context" |
|||
description: "Add any other context or screenshots about the feature request here." |
|||
placeholder: "..." |
@ -0,0 +1,28 @@ |
|||
# Description |
|||
|
|||
Fixes #(issue) |
|||
|
|||
## Type of change |
|||
|
|||
Please delete options that are not relevant. |
|||
|
|||
- Bug fix (non-breaking change which fixes an issue) |
|||
- User Interface |
|||
- New feature (non-breaking change which adds functionality) |
|||
- Breaking change (fix or feature that would cause existing functionality to not work as expected) |
|||
- Translation update |
|||
- Other |
|||
- This change requires a documentation update |
|||
|
|||
## Checklist |
|||
|
|||
- [ ] My code follows the style guidelines of this project |
|||
- [ ] I ran ESLint and other linters for modified files |
|||
- [ ] I have performed a self-review of my own code and test it |
|||
- [ ] I have commented my code, particularly in hard-to-understand areas |
|||
- [ ] My changes generate no new warnings |
|||
- [ ] My code needed automated testing. I have added them (this is optional task) |
|||
|
|||
## Screenshots (if any) |
|||
|
|||
Please do not use any external image service. Instead, just paste in or drag and drop the image here and it will be uploaded automatically. |
@ -0,0 +1,35 @@ |
|||
# This workflow will do a clean install of node dependencies, cache/restore them, build the source code and run tests across different versions of node |
|||
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions |
|||
|
|||
name: Auto Test |
|||
|
|||
on: |
|||
push: |
|||
branches: [ master ] |
|||
pull_request: |
|||
branches: [ master ] |
|||
|
|||
jobs: |
|||
auto-test: |
|||
runs-on: ${{ matrix.os }} |
|||
|
|||
strategy: |
|||
matrix: |
|||
os: [macos-latest, ubuntu-latest, windows-latest] |
|||
node-version: [14.x, 16.x, 17.x] |
|||
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/ |
|||
|
|||
steps: |
|||
- uses: actions/checkout@v2 |
|||
|
|||
- name: Use Node.js ${{ matrix.node-version }} |
|||
uses: actions/setup-node@v2 |
|||
with: |
|||
node-version: ${{ matrix.node-version }} |
|||
cache: 'npm' |
|||
- run: npm run install-legacy |
|||
- run: npm run build |
|||
- run: npm test |
|||
env: |
|||
HEADLESS_TEST: 1 |
|||
JUST_FOR_TEST: ${{ secrets.JUST_FOR_TEST }} |
@ -0,0 +1,22 @@ |
|||
name: 'Automatically close stale issues and PRs' |
|||
on: |
|||
schedule: |
|||
- cron: '0 0 * * *' |
|||
#Run once a day at midnight |
|||
|
|||
jobs: |
|||
stale: |
|||
runs-on: ubuntu-latest |
|||
steps: |
|||
- uses: actions/stale@v4 |
|||
with: |
|||
stale-issue-message: 'We are clearing up our old issues and your ticket has been open for 6 months with no activity. Remove stale label or comment or this will be closed in 7 days.' |
|||
stale-pr-message: 'We are clearing up our old Pull Requests and yours has been open for 6 months with no activity. Remove stale label or comment or this will be closed in 7 days.' |
|||
close-issue-message: 'This issue was closed because it has been stalled for 7 days with no activity.' |
|||
close-pr-message: 'This PR was closed because it has been stalled for 7 days with no activity.' |
|||
days-before-stale: 180 |
|||
days-before-close: 7 |
|||
exempt-issue-labels: 'News,Medium,High,discussion,bug,doc,' |
|||
exempt-pr-labels: 'awaiting-approval,work-in-progress,enhancement,' |
|||
exempt-issue-assignees: 'louislam' |
|||
exempt-pr-assignees: 'louislam' |
@ -1,15 +1,31 @@ |
|||
# Security Policy |
|||
|
|||
## Reporting a Vulnerability |
|||
|
|||
Please report security issues to uptime@kuma.pet. |
|||
|
|||
Do not use the issue tracker or discuss it in the public as it will cause more damage. |
|||
|
|||
## Supported Versions |
|||
|
|||
Use this section to tell people about which versions of your project are |
|||
currently being supported with security updates. |
|||
|
|||
### Uptime Kuma Versions |
|||
|
|||
| Version | Supported | |
|||
| ------- | ------------------ | |
|||
| 1.x.x | :white_check_mark: | |
|||
| 1.9.X | :white_check_mark: | |
|||
| <= 1.8.X | ❌ | |
|||
|
|||
## Reporting a Vulnerability |
|||
Please report security issues to uptime@kuma.pet. |
|||
### Upgradable Docker Tags |
|||
|
|||
Do not use the issue tracker or discuss it in the public as it will cause more damage. |
|||
| Tag | Supported | |
|||
| ------- | ------------------ | |
|||
| 1 | :white_check_mark: | |
|||
| 1-debian | :white_check_mark: | |
|||
| 1-alpine | :white_check_mark: | |
|||
| latest | :white_check_mark: | |
|||
| debian | :white_check_mark: | |
|||
| alpine | :white_check_mark: | |
|||
| All other tags | ❌ | |
|||
|
@ -0,0 +1,11 @@ |
|||
const config = {}; |
|||
|
|||
if (process.env.TEST_FRONTEND) { |
|||
config.presets = ["@babel/preset-env"]; |
|||
} |
|||
|
|||
if (process.env.TEST_BACKEND) { |
|||
config.plugins = ["babel-plugin-rewire"]; |
|||
} |
|||
|
|||
module.exports = config; |
@ -0,0 +1,5 @@ |
|||
module.exports = { |
|||
"rootDir": "..", |
|||
"testRegex": "./test/backend.spec.js", |
|||
}; |
|||
|
@ -0,0 +1,5 @@ |
|||
module.exports = { |
|||
"rootDir": "..", |
|||
"testRegex": "./test/frontend.spec.js", |
|||
}; |
|||
|
@ -0,0 +1,6 @@ |
|||
module.exports = { |
|||
"launch": { |
|||
"headless": process.env.HEADLESS_TEST || false, |
|||
"userDataDir": "./data/test-chrome-profile", |
|||
} |
|||
}; |
@ -0,0 +1,11 @@ |
|||
module.exports = { |
|||
"verbose": true, |
|||
"preset": "jest-puppeteer", |
|||
"globals": { |
|||
"__DEV__": true |
|||
}, |
|||
"testRegex": "./test/e2e.spec.js", |
|||
"rootDir": "..", |
|||
"testTimeout": 30000, |
|||
}; |
|||
|
@ -0,0 +1,24 @@ |
|||
import legacy from "@vitejs/plugin-legacy"; |
|||
import vue from "@vitejs/plugin-vue"; |
|||
import { defineConfig } from "vite"; |
|||
|
|||
const postCssScss = require("postcss-scss"); |
|||
const postcssRTLCSS = require("postcss-rtlcss"); |
|||
|
|||
// https://vitejs.dev/config/
|
|||
export default defineConfig({ |
|||
plugins: [ |
|||
vue(), |
|||
legacy({ |
|||
targets: ["ie > 11"], |
|||
additionalLegacyPolyfills: ["regenerator-runtime/runtime"] |
|||
}) |
|||
], |
|||
css: { |
|||
postcss: { |
|||
"parser": postCssScss, |
|||
"map": false, |
|||
"plugins": [postcssRTLCSS] |
|||
} |
|||
}, |
|||
}); |
@ -0,0 +1,7 @@ |
|||
-- You should not modify if this have pushed to Github, unless it does serious wrong with the db. |
|||
BEGIN TRANSACTION; |
|||
|
|||
ALTER TABLE user |
|||
ADD twofa_last_token VARCHAR(6); |
|||
|
|||
COMMIT; |
@ -0,0 +1,13 @@ |
|||
-- You should not modify if this have pushed to Github, unless it does serious wrong with the db. |
|||
BEGIN TRANSACTION; |
|||
|
|||
ALTER TABLE monitor |
|||
ADD method TEXT default 'GET' not null; |
|||
|
|||
ALTER TABLE monitor |
|||
ADD body TEXT default null; |
|||
|
|||
ALTER TABLE monitor |
|||
ADD headers TEXT default null; |
|||
|
|||
COMMIT; |
@ -0,0 +1,7 @@ |
|||
-- You should not modify if this have pushed to Github, unless it does serious wrong with the db. |
|||
BEGIN TRANSACTION; |
|||
|
|||
ALTER TABLE monitor |
|||
ADD push_token VARCHAR(20) DEFAULT NULL; |
|||
|
|||
COMMIT; |
@ -0,0 +1,18 @@ |
|||
-- You should not modify if this have pushed to Github, unless it does serious wrong with the db. |
|||
BEGIN TRANSACTION; |
|||
|
|||
CREATE TABLE [notification_sent_history] ( |
|||
[id] INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, |
|||
[type] VARCHAR(50) NOT NULL, |
|||
[monitor_id] INTEGER NOT NULL, |
|||
[days] INTEGER NOT NULL, |
|||
UNIQUE([type], [monitor_id], [days]) |
|||
); |
|||
|
|||
CREATE INDEX [good_index] ON [notification_sent_history] ( |
|||
[type], |
|||
[monitor_id], |
|||
[days] |
|||
); |
|||
|
|||
COMMIT; |
@ -0,0 +1,8 @@ |
|||
# DON'T UPDATE TO alpine3.13, 1.14, see #41. |
|||
FROM node:14-alpine3.12 |
|||
WORKDIR /app |
|||
|
|||
# Install apprise, iputils for non-root ping, setpriv |
|||
RUN apk add --no-cache iputils setpriv dumb-init python3 py3-cryptography py3-pip py3-six py3-yaml py3-click py3-markdown py3-requests py3-requests-oauthlib && \ |
|||
pip3 --no-cache-dir install apprise && \ |
|||
rm -rf /root/.cache |
@ -0,0 +1,12 @@ |
|||
# DON'T UPDATE TO node:14-bullseye-slim, see #372. |
|||
# If the image changed, the second stage image should be changed too |
|||
FROM node:14-buster-slim |
|||
WORKDIR /app |
|||
|
|||
# Install Apprise, add sqlite3 cli for debugging in the future, iputils-ping for ping, util-linux for setpriv |
|||
# Stupid python3 and python3-pip actually install a lot of useless things into Debian, specific --no-install-recommends to skip them, make the base even smaller than alpine! |
|||
RUN apt update && \ |
|||
apt --yes --no-install-recommends install python3 python3-pip python3-cryptography python3-six python3-yaml python3-click python3-markdown python3-requests python3-requests-oauthlib \ |
|||
sqlite3 iputils-ping util-linux dumb-init && \ |
|||
pip3 --no-cache-dir install apprise && \ |
|||
rm -rf /var/lib/apt/lists/* |
@ -0,0 +1,52 @@ |
|||
FROM louislam/uptime-kuma:base-debian AS build |
|||
WORKDIR /app |
|||
|
|||
ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=1 |
|||
|
|||
COPY . . |
|||
RUN npm ci --production && \ |
|||
chmod +x /app/extra/entrypoint.sh |
|||
|
|||
|
|||
FROM louislam/uptime-kuma:base-debian AS release |
|||
WORKDIR /app |
|||
|
|||
# Copy app files from build layer |
|||
COPY --from=build /app /app |
|||
|
|||
EXPOSE 3001 |
|||
VOLUME ["/app/data"] |
|||
HEALTHCHECK --interval=60s --timeout=30s --start-period=180s --retries=5 CMD node extra/healthcheck.js |
|||
ENTRYPOINT ["/usr/bin/dumb-init", "--", "extra/entrypoint.sh"] |
|||
CMD ["node", "server/server.js"] |
|||
|
|||
|
|||
FROM release AS nightly |
|||
RUN npm run mark-as-nightly |
|||
|
|||
|
|||
# Upload the artifact to Github |
|||
FROM louislam/uptime-kuma:base-debian AS upload-artifact |
|||
WORKDIR / |
|||
RUN apt update && \ |
|||
apt --yes install curl file |
|||
|
|||
COPY --from=build /app /app |
|||
|
|||
ARG VERSION=1.9.1 |
|||
ARG GITHUB_TOKEN |
|||
ARG TARGETARCH |
|||
ARG PLATFORM=debian |
|||
ARG FILE=$PLATFORM-$TARGETARCH-$VERSION.tar.gz |
|||
ARG DIST=dist.tar.gz |
|||
|
|||
RUN chmod +x /app/extra/upload-github-release-asset.sh |
|||
|
|||
# Full Build |
|||
# RUN tar -zcvf $FILE app |
|||
# RUN /app/extra/upload-github-release-asset.sh github_api_token=$GITHUB_TOKEN owner=louislam repo=uptime-kuma tag=$VERSION filename=$FILE |
|||
|
|||
# Dist only |
|||
RUN cd /app && tar -zcvf $DIST dist |
|||
RUN /app/extra/upload-github-release-asset.sh github_api_token=$GITHUB_TOKEN owner=louislam repo=uptime-kuma tag=$VERSION filename=/app/$DIST |
|||
|
@ -0,0 +1,25 @@ |
|||
FROM louislam/uptime-kuma:base-alpine AS build |
|||
WORKDIR /app |
|||
|
|||
ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=1 |
|||
|
|||
COPY . . |
|||
RUN npm ci --production && \ |
|||
chmod +x /app/extra/entrypoint.sh |
|||
|
|||
|
|||
FROM louislam/uptime-kuma:base-alpine AS release |
|||
WORKDIR /app |
|||
|
|||
# Copy app files from build layer |
|||
COPY --from=build /app /app |
|||
|
|||
EXPOSE 3001 |
|||
VOLUME ["/app/data"] |
|||
HEALTHCHECK --interval=60s --timeout=30s --start-period=180s --retries=5 CMD node extra/healthcheck.js |
|||
ENTRYPOINT ["/usr/bin/dumb-init", "--", "extra/entrypoint.sh"] |
|||
CMD ["node", "server/server.js"] |
|||
|
|||
|
|||
FROM release AS nightly |
|||
RUN npm run mark-as-nightly |
@ -1,33 +0,0 @@ |
|||
# DON'T UPDATE TO node:14-bullseye-slim, see #372. |
|||
# If the image changed, the second stage image should be changed too |
|||
FROM node:14-buster-slim AS build |
|||
WORKDIR /app |
|||
|
|||
COPY . . |
|||
RUN npm install --legacy-peer-deps && \ |
|||
npm run build && \ |
|||
npm prune --production && \ |
|||
chmod +x /app/extra/entrypoint.sh |
|||
|
|||
|
|||
FROM node:14-buster-slim AS release |
|||
WORKDIR /app |
|||
|
|||
# Install Apprise, add sqlite3 cli for debugging in the future, iputils-ping for ping, util-linux for setpriv |
|||
RUN apt update && \ |
|||
apt --yes install python3 python3-pip python3-cryptography python3-six python3-yaml python3-click python3-markdown python3-requests python3-requests-oauthlib \ |
|||
sqlite3 iputils-ping util-linux dumb-init && \ |
|||
pip3 --no-cache-dir install apprise && \ |
|||
rm -rf /var/lib/apt/lists/* |
|||
|
|||
# Copy app files from build layer |
|||
COPY --from=build /app /app |
|||
|
|||
EXPOSE 3001 |
|||
VOLUME ["/app/data"] |
|||
HEALTHCHECK --interval=60s --timeout=30s --start-period=180s --retries=5 CMD node extra/healthcheck.js |
|||
ENTRYPOINT ["/usr/bin/dumb-init", "--", "extra/entrypoint.sh"] |
|||
CMD ["node", "server/server.js"] |
|||
|
|||
FROM release AS nightly |
|||
RUN npm run mark-as-nightly |
@ -1,30 +0,0 @@ |
|||
# DON'T UPDATE TO alpine3.13, 1.14, see #41. |
|||
FROM node:14-alpine3.12 AS build |
|||
WORKDIR /app |
|||
|
|||
COPY . . |
|||
RUN npm install --legacy-peer-deps && \ |
|||
npm run build && \ |
|||
npm prune --production && \ |
|||
chmod +x /app/extra/entrypoint.sh |
|||
|
|||
|
|||
FROM node:14-alpine3.12 AS release |
|||
WORKDIR /app |
|||
|
|||
# Install apprise, iputils for non-root ping, setpriv |
|||
RUN apk add --no-cache iputils setpriv dumb-init python3 py3-cryptography py3-pip py3-six py3-yaml py3-click py3-markdown py3-requests py3-requests-oauthlib && \ |
|||
pip3 --no-cache-dir install apprise && \ |
|||
rm -rf /root/.cache |
|||
|
|||
# Copy app files from build layer |
|||
COPY --from=build /app /app |
|||
|
|||
EXPOSE 3001 |
|||
VOLUME ["/app/data"] |
|||
HEALTHCHECK --interval=60s --timeout=30s --start-period=180s --retries=5 CMD node extra/healthcheck.js |
|||
ENTRYPOINT ["/usr/bin/dumb-init", "--", "extra/entrypoint.sh"] |
|||
CMD ["node", "server/server.js"] |
|||
|
|||
FROM release AS nightly |
|||
RUN npm run mark-as-nightly |
@ -0,0 +1,6 @@ |
|||
module.exports = { |
|||
apps: [{ |
|||
name: "uptime-kuma", |
|||
script: "./server/server.js", |
|||
}] |
|||
} |
@ -0,0 +1,59 @@ |
|||
console.log("Downloading dist"); |
|||
const https = require("https"); |
|||
const tar = require("tar"); |
|||
|
|||
const packageJSON = require("../package.json"); |
|||
const fs = require("fs"); |
|||
const version = packageJSON.version; |
|||
|
|||
const filename = "dist.tar.gz"; |
|||
|
|||
const url = `https://github.com/louislam/uptime-kuma/releases/download/${version}/${filename}`; |
|||
download(url); |
|||
|
|||
function download(url) { |
|||
console.log(url); |
|||
|
|||
https.get(url, (response) => { |
|||
if (response.statusCode === 200) { |
|||
console.log("Extracting dist..."); |
|||
|
|||
if (fs.existsSync("./dist")) { |
|||
|
|||
if (fs.existsSync("./dist-backup")) { |
|||
fs.rmdirSync("./dist-backup", { |
|||
recursive: true |
|||
}); |
|||
} |
|||
|
|||
fs.renameSync("./dist", "./dist-backup"); |
|||
} |
|||
|
|||
const tarStream = tar.x({ |
|||
cwd: "./", |
|||
}); |
|||
|
|||
tarStream.on("close", () => { |
|||
if (fs.existsSync("./dist-backup")) { |
|||
fs.rmdirSync("./dist-backup", { |
|||
recursive: true |
|||
}); |
|||
} |
|||
console.log("Done"); |
|||
}); |
|||
|
|||
tarStream.on("error", () => { |
|||
if (fs.existsSync("./dist-backup")) { |
|||
fs.renameSync("./dist-backup", "./dist"); |
|||
} |
|||
console.error("Error from tarStream"); |
|||
}); |
|||
|
|||
response.pipe(tarStream); |
|||
} else if (response.statusCode === 302) { |
|||
download(response.headers.location); |
|||
} else { |
|||
console.log("dist not found"); |
|||
} |
|||
}); |
|||
} |
@ -0,0 +1,64 @@ |
|||
#!/usr/bin/env bash |
|||
# |
|||
# Author: Stefan Buck |
|||
# License: MIT |
|||
# https://gist.github.com/stefanbuck/ce788fee19ab6eb0b4447a85fc99f447 |
|||
# |
|||
# |
|||
# This script accepts the following parameters: |
|||
# |
|||
# * owner |
|||
# * repo |
|||
# * tag |
|||
# * filename |
|||
# * github_api_token |
|||
# |
|||
# Script to upload a release asset using the GitHub API v3. |
|||
# |
|||
# Example: |
|||
# |
|||
# upload-github-release-asset.sh github_api_token=TOKEN owner=stefanbuck repo=playground tag=v0.1.0 filename=./build.zip |
|||
# |
|||
|
|||
# Check dependencies. |
|||
set -e |
|||
xargs=$(which gxargs || which xargs) |
|||
|
|||
# Validate settings. |
|||
[ "$TRACE" ] && set -x |
|||
|
|||
CONFIG=$@ |
|||
|
|||
for line in $CONFIG; do |
|||
eval "$line" |
|||
done |
|||
|
|||
# Define variables. |
|||
GH_API="https://api.github.com" |
|||
GH_REPO="$GH_API/repos/$owner/$repo" |
|||
GH_TAGS="$GH_REPO/releases/tags/$tag" |
|||
AUTH="Authorization: token $github_api_token" |
|||
WGET_ARGS="--content-disposition --auth-no-challenge --no-cookie" |
|||
CURL_ARGS="-LJO#" |
|||
|
|||
if [[ "$tag" == 'LATEST' ]]; then |
|||
GH_TAGS="$GH_REPO/releases/latest" |
|||
fi |
|||
|
|||
# Validate token. |
|||
curl -o /dev/null -sH "$AUTH" $GH_REPO || { echo "Error: Invalid repo, token or network issue!"; exit 1; } |
|||
|
|||
# Read asset tags. |
|||
response=$(curl -sH "$AUTH" $GH_TAGS) |
|||
|
|||
# Get ID of the asset based on given filename. |
|||
eval $(echo "$response" | grep -m 1 "id.:" | grep -w id | tr : = | tr -cd '[[:alnum:]]=') |
|||
[ "$id" ] || { echo "Error: Failed to get release id for tag: $tag"; echo "$response" | awk 'length($0)<100' >&2; exit 1; } |
|||
|
|||
# Upload asset |
|||
echo "Uploading asset... " |
|||
|
|||
# Construct url |
|||
GH_ASSET="https://uploads.github.com/repos/$owner/$repo/releases/$id/assets?name=$(basename $filename)" |
|||
|
|||
curl "$GITHUB_OAUTH_BASIC" --data-binary @"$filename" -H "Authorization: token $github_api_token" -H "Content-Type: application/octet-stream" $GH_ASSET |
@ -1,32 +0,0 @@ |
|||
# Uptime-Kuma K8s Deployment |
|||
|
|||
⚠ Warning: K8s deployment is provided by contributors. I have no experience with K8s and I can't fix error in the future. I only test Docker and Node.js. Use at your own risk. |
|||
|
|||
## How does it work? |
|||
|
|||
Kustomize is a tool which builds a complete deployment file for all config elements. |
|||
You can edit the files in the ```uptime-kuma``` folder except the ```kustomization.yml``` until you know what you're doing. |
|||
If you want to choose another namespace you can edit the ```kustomization.yml``` in the ```kubernetes```-Folder and change the ```namespace: uptime-kuma``` to something you like. |
|||
|
|||
It creates a certificate with the specified Issuer and creates the Ingress for the Uptime-Kuma ClusterIP-Service. |
|||
|
|||
## What do I have to edit? |
|||
|
|||
You have to edit the ```ingressroute.yml``` to your needs. |
|||
This ingressroute.yml is for the [nginx-ingress-controller](https://kubernetes.github.io/ingress-nginx/) in combination with the [cert-manager](https://cert-manager.io/). |
|||
|
|||
- Host |
|||
- Secrets and secret names |
|||
- (Cluster)Issuer (optional) |
|||
- The Version in the Deployment-File |
|||
- Update: |
|||
- Change to newer version and run the above commands, it will update the pods one after another |
|||
|
|||
## How To use |
|||
|
|||
- Install [kustomize](https://kubectl.docs.kubernetes.io/installation/kustomize/) |
|||
- Edit files mentioned above to your needs |
|||
- Run ```kustomize build > apply.yml``` |
|||
- Run ```kubectl apply -f apply.yml``` |
|||
|
|||
Now you should see some k8s magic and Uptime-Kuma should be available at the specified address. |
@ -1,10 +0,0 @@ |
|||
namespace: uptime-kuma |
|||
namePrefix: uptime-kuma- |
|||
|
|||
commonLabels: |
|||
app: uptime-kuma |
|||
|
|||
bases: |
|||
- uptime-kuma |
|||
|
|||
|
@ -1,45 +0,0 @@ |
|||
apiVersion: apps/v1 |
|||
kind: Deployment |
|||
metadata: |
|||
labels: |
|||
component: uptime-kuma |
|||
name: deployment |
|||
spec: |
|||
selector: |
|||
matchLabels: |
|||
component: uptime-kuma |
|||
replicas: 1 |
|||
strategy: |
|||
type: Recreate |
|||
|
|||
template: |
|||
metadata: |
|||
labels: |
|||
component: uptime-kuma |
|||
spec: |
|||
containers: |
|||
- name: app |
|||
image: louislam/uptime-kuma:1 |
|||
ports: |
|||
- containerPort: 3001 |
|||
volumeMounts: |
|||
- mountPath: /app/data |
|||
name: storage |
|||
livenessProbe: |
|||
exec: |
|||
command: |
|||
- node |
|||
- extra/healthcheck.js |
|||
initialDelaySeconds: 180 |
|||
periodSeconds: 60 |
|||
timeoutSeconds: 30 |
|||
readinessProbe: |
|||
httpGet: |
|||
path: / |
|||
port: 3001 |
|||
scheme: HTTP |
|||
|
|||
volumes: |
|||
- name: storage |
|||
persistentVolumeClaim: |
|||
claimName: pvc |
@ -1,39 +0,0 @@ |
|||
apiVersion: networking.k8s.io/v1 |
|||
kind: Ingress |
|||
metadata: |
|||
annotations: |
|||
kubernetes.io/ingress.class: nginx |
|||
cert-manager.io/cluster-issuer: letsencrypt-prod |
|||
nginx.ingress.kubernetes.io/proxy-read-timeout: "3600" |
|||
nginx.ingress.kubernetes.io/proxy-send-timeout: "3600" |
|||
nginx.ingress.kubernetes.io/server-snippets: | |
|||
location / { |
|||
proxy_set_header Upgrade $http_upgrade; |
|||
proxy_http_version 1.1; |
|||
proxy_set_header X-Forwarded-Host $http_host; |
|||
proxy_set_header X-Forwarded-Proto $scheme; |
|||
proxy_set_header X-Forwarded-For $remote_addr; |
|||
proxy_set_header Host $host; |
|||
proxy_set_header Connection "upgrade"; |
|||
proxy_set_header X-Real-IP $remote_addr; |
|||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; |
|||
proxy_set_header Upgrade $http_upgrade; |
|||
proxy_cache_bypass $http_upgrade; |
|||
} |
|||
name: ingress |
|||
spec: |
|||
tls: |
|||
- hosts: |
|||
- example.com |
|||
secretName: example-com-tls |
|||
rules: |
|||
- host: example.com |
|||
http: |
|||
paths: |
|||
- path: / |
|||
pathType: Prefix |
|||
backend: |
|||
service: |
|||
name: service |
|||
port: |
|||
number: 3001 |
@ -1,5 +0,0 @@ |
|||
resources: |
|||
- deployment.yml |
|||
- service.yml |
|||
- ingressroute.yml |
|||
- pvc.yml |
@ -1,10 +0,0 @@ |
|||
apiVersion: v1 |
|||
kind: PersistentVolumeClaim |
|||
metadata: |
|||
name: pvc |
|||
spec: |
|||
accessModes: |
|||
- ReadWriteOnce |
|||
resources: |
|||
requests: |
|||
storage: 4Gi |
@ -1,13 +0,0 @@ |
|||
apiVersion: v1 |
|||
kind: Service |
|||
metadata: |
|||
name: service |
|||
spec: |
|||
selector: |
|||
component: uptime-kuma |
|||
type: ClusterIP |
|||
ports: |
|||
- name: http |
|||
port: 3001 |
|||
targetPort: 3001 |
|||
protocol: TCP |
File diff suppressed because it is too large
@ -0,0 +1,7 @@ |
|||
const args = require("args-parser")(process.argv); |
|||
const demoMode = args["demo"] || false; |
|||
|
|||
module.exports = { |
|||
args, |
|||
demoMode |
|||
}; |
@ -0,0 +1,31 @@ |
|||
const path = require("path"); |
|||
const Bree = require("bree"); |
|||
const { SHARE_ENV } = require("worker_threads"); |
|||
|
|||
const jobs = [ |
|||
{ |
|||
name: "clear-old-data", |
|||
interval: "at 03:14", |
|||
}, |
|||
]; |
|||
|
|||
const initBackgroundJobs = function (args) { |
|||
const bree = new Bree({ |
|||
root: path.resolve("server", "jobs"), |
|||
jobs, |
|||
worker: { |
|||
env: SHARE_ENV, |
|||
workerData: args, |
|||
}, |
|||
workerMessageHandler: (message) => { |
|||
console.log("[Background Job]:", message); |
|||
} |
|||
}); |
|||
|
|||
bree.start(); |
|||
return bree; |
|||
}; |
|||
|
|||
module.exports = { |
|||
initBackgroundJobs |
|||
}; |
@ -0,0 +1,40 @@ |
|||
const { log, exit, connectDb } = require("./util-worker"); |
|||
const { R } = require("redbean-node"); |
|||
const { setSetting, setting } = require("../util-server"); |
|||
|
|||
const DEFAULT_KEEP_PERIOD = 180; |
|||
|
|||
(async () => { |
|||
await connectDb(); |
|||
|
|||
let period = await setting("keepDataPeriodDays"); |
|||
|
|||
// Set Default Period
|
|||
if (period == null) { |
|||
await setSetting("keepDataPeriodDays", DEFAULT_KEEP_PERIOD, "general"); |
|||
period = DEFAULT_KEEP_PERIOD; |
|||
} |
|||
|
|||
// Try parse setting
|
|||
let parsedPeriod; |
|||
try { |
|||
parsedPeriod = parseInt(period); |
|||
} catch (_) { |
|||
log("Failed to parse setting, resetting to default.."); |
|||
await setSetting("keepDataPeriodDays", DEFAULT_KEEP_PERIOD, "general"); |
|||
parsedPeriod = DEFAULT_KEEP_PERIOD; |
|||
} |
|||
|
|||
log(`Clearing Data older than ${parsedPeriod} days...`); |
|||
|
|||
try { |
|||
await R.exec( |
|||
"DELETE FROM heartbeat WHERE time < DATETIME('now', '-' || ? || ' days') ", |
|||
[parsedPeriod] |
|||
); |
|||
} catch (e) { |
|||
log(`Failed to clear old data: ${e.message}`); |
|||
} |
|||
|
|||
exit(); |
|||
})(); |
@ -0,0 +1,39 @@ |
|||
const { parentPort, workerData } = require("worker_threads"); |
|||
const Database = require("../database"); |
|||
const path = require("path"); |
|||
|
|||
const log = function (any) { |
|||
if (parentPort) { |
|||
parentPort.postMessage(any); |
|||
} |
|||
}; |
|||
|
|||
const exit = function (error) { |
|||
if (error && error != 0) { |
|||
process.exit(error); |
|||
} else { |
|||
if (parentPort) { |
|||
parentPort.postMessage("done"); |
|||
} else { |
|||
process.exit(0); |
|||
} |
|||
} |
|||
}; |
|||
|
|||
const connectDb = async function () { |
|||
const dbPath = path.join( |
|||
process.env.DATA_DIR || workerData["data-dir"] || "./data/" |
|||
); |
|||
|
|||
Database.init({ |
|||
"data-dir": dbPath, |
|||
}); |
|||
|
|||
await Database.connect(); |
|||
}; |
|||
|
|||
module.exports = { |
|||
log, |
|||
exit, |
|||
connectDb, |
|||
}; |
@ -0,0 +1,108 @@ |
|||
const NotificationProvider = require("./notification-provider"); |
|||
const { DOWN, UP } = require("../../src/util"); |
|||
const { default: axios } = require("axios"); |
|||
const Crypto = require("crypto"); |
|||
const qs = require("qs"); |
|||
|
|||
class AliyunSMS extends NotificationProvider { |
|||
name = "AliyunSMS"; |
|||
|
|||
async send(notification, msg, monitorJSON = null, heartbeatJSON = null) { |
|||
let okMsg = "Sent Successfully."; |
|||
|
|||
try { |
|||
if (heartbeatJSON != null) { |
|||
let msgBody = JSON.stringify({ |
|||
name: monitorJSON["name"], |
|||
time: heartbeatJSON["time"], |
|||
status: this.statusToString(heartbeatJSON["status"]), |
|||
msg: heartbeatJSON["msg"], |
|||
}); |
|||
if (this.sendSms(notification, msgBody)) { |
|||
return okMsg; |
|||
} |
|||
} else { |
|||
let msgBody = JSON.stringify({ |
|||
name: "", |
|||
time: "", |
|||
status: "", |
|||
msg: msg, |
|||
}); |
|||
if (this.sendSms(notification, msgBody)) { |
|||
return okMsg; |
|||
} |
|||
} |
|||
} catch (error) { |
|||
this.throwGeneralAxiosError(error); |
|||
} |
|||
} |
|||
|
|||
async sendSms(notification, msgbody) { |
|||
let params = { |
|||
PhoneNumbers: notification.phonenumber, |
|||
TemplateCode: notification.templateCode, |
|||
SignName: notification.signName, |
|||
TemplateParam: msgbody, |
|||
AccessKeyId: notification.accessKeyId, |
|||
Format: "JSON", |
|||
SignatureMethod: "HMAC-SHA1", |
|||
SignatureVersion: "1.0", |
|||
SignatureNonce: Math.random().toString(), |
|||
Timestamp: new Date().toISOString(), |
|||
Action: "SendSms", |
|||
Version: "2017-05-25", |
|||
}; |
|||
|
|||
params.Signature = this.sign(params, notification.secretAccessKey); |
|||
let config = { |
|||
method: "POST", |
|||
url: "http://dysmsapi.aliyuncs.com/", |
|||
headers: { |
|||
"Content-Type": "application/x-www-form-urlencoded", |
|||
}, |
|||
data: qs.stringify(params), |
|||
}; |
|||
|
|||
let result = await axios(config); |
|||
if (result.data.Message == "OK") { |
|||
return true; |
|||
} |
|||
return false; |
|||
} |
|||
|
|||
/** Aliyun request sign */ |
|||
sign(param, AccessKeySecret) { |
|||
let param2 = {}; |
|||
let data = []; |
|||
|
|||
let oa = Object.keys(param).sort(); |
|||
|
|||
for (let i = 0; i < oa.length; i++) { |
|||
let key = oa[i]; |
|||
param2[key] = param[key]; |
|||
} |
|||
|
|||
for (let key in param2) { |
|||
data.push(`${encodeURIComponent(key)}=${encodeURIComponent(param2[key])}`); |
|||
} |
|||
|
|||
let StringToSign = `POST&${encodeURIComponent("/")}&${encodeURIComponent(data.join("&"))}`; |
|||
return Crypto |
|||
.createHmac("sha1", `${AccessKeySecret}&`) |
|||
.update(Buffer.from(StringToSign)) |
|||
.digest("base64"); |
|||
} |
|||
|
|||
statusToString(status) { |
|||
switch (status) { |
|||
case DOWN: |
|||
return "DOWN"; |
|||
case UP: |
|||
return "UP"; |
|||
default: |
|||
return status; |
|||
} |
|||
} |
|||
} |
|||
|
|||
module.exports = AliyunSMS; |
@ -0,0 +1,89 @@ |
|||
//
|
|||
// bark.js
|
|||
// UptimeKuma
|
|||
//
|
|||
// Created by Lakr Aream on 2021/10/24.
|
|||
// Copyright © 2021 Lakr Aream. All rights reserved.
|
|||
//
|
|||
|
|||
const NotificationProvider = require("./notification-provider"); |
|||
const { DOWN, UP } = require("../../src/util"); |
|||
const { default: axios } = require("axios"); |
|||
|
|||
// bark is an APN bridge that sends notifications to Apple devices.
|
|||
|
|||
const barkNotificationGroup = "UptimeKuma"; |
|||
const barkNotificationAvatar = "https://github.com/louislam/uptime-kuma/raw/master/public/icon.png"; |
|||
const barkNotificationSound = "telegraph"; |
|||
const successMessage = "Successes!"; |
|||
|
|||
class Bark extends NotificationProvider { |
|||
name = "Bark"; |
|||
|
|||
async send(notification, msg, monitorJSON = null, heartbeatJSON = null) { |
|||
try { |
|||
var barkEndpoint = notification.barkEndpoint; |
|||
|
|||
// check if the endpoint has a "/" suffix, if so, delete it first
|
|||
if (barkEndpoint.endsWith("/")) { |
|||
barkEndpoint = barkEndpoint.substring(0, barkEndpoint.length - 1); |
|||
} |
|||
|
|||
if (msg != null && heartbeatJSON != null && heartbeatJSON["status"] == UP) { |
|||
let title = "UptimeKuma Monitor Up"; |
|||
return await this.postNotification(title, msg, barkEndpoint); |
|||
} |
|||
|
|||
if (msg != null && heartbeatJSON != null && heartbeatJSON["status"] == DOWN) { |
|||
let title = "UptimeKuma Monitor Down"; |
|||
return await this.postNotification(title, msg, barkEndpoint); |
|||
} |
|||
|
|||
if (msg != null) { |
|||
let title = "UptimeKuma Message"; |
|||
return await this.postNotification(title, msg, barkEndpoint); |
|||
} |
|||
|
|||
} catch (error) { |
|||
throw error; |
|||
} |
|||
} |
|||
|
|||
// add additional parameter for better on device styles (iOS 15 optimized)
|
|||
appendAdditionalParameters(postUrl) { |
|||
// grouping all our notifications
|
|||
postUrl += "?group=" + barkNotificationGroup; |
|||
// set icon to uptime kuma icon, 11kb should be fine
|
|||
postUrl += "&icon=" + barkNotificationAvatar; |
|||
// picked a sound, this should follow system's mute status when arrival
|
|||
postUrl += "&sound=" + barkNotificationSound; |
|||
return postUrl; |
|||
} |
|||
|
|||
// thrown if failed to check result, result code should be in range 2xx
|
|||
checkResult(result) { |
|||
if (result.status == null) { |
|||
throw new Error("Bark notification failed with invalid response!"); |
|||
} |
|||
if (result.status < 200 || result.status >= 300) { |
|||
throw new Error("Bark notification failed with status code " + result.status); |
|||
} |
|||
} |
|||
|
|||
async postNotification(title, subtitle, endpoint) { |
|||
// url encode title and subtitle
|
|||
title = encodeURIComponent(title); |
|||
subtitle = encodeURIComponent(subtitle); |
|||
let postUrl = endpoint + "/" + title + "/" + subtitle; |
|||
postUrl = this.appendAdditionalParameters(postUrl); |
|||
let result = await axios.get(postUrl); |
|||
this.checkResult(result); |
|||
if (result.statusText != null) { |
|||
return "Bark notification succeed: " + result.statusText; |
|||
} |
|||
// because returned in range 200 ..< 300
|
|||
return successMessage; |
|||
} |
|||
} |
|||
|
|||
module.exports = Bark; |
@ -0,0 +1,42 @@ |
|||
const NotificationProvider = require("./notification-provider"); |
|||
const axios = require("axios"); |
|||
|
|||
class ClickSendSMS extends NotificationProvider { |
|||
|
|||
name = "clicksendsms"; |
|||
|
|||
async send(notification, msg, monitorJSON = null, heartbeatJSON = null) { |
|||
let okMsg = "Sent Successfully."; |
|||
try { |
|||
console.log({ notification }); |
|||
let config = { |
|||
headers: { |
|||
"Content-Type": "application/json", |
|||
"Authorization": "Basic " + Buffer.from(notification.clicksendsmsLogin + ":" + notification.clicksendsmsPassword).toString('base64'), |
|||
"Accept": "text/json", |
|||
} |
|||
}; |
|||
let data = { |
|||
messages: [ |
|||
{ |
|||
"body": msg.replace(/[^\x00-\x7F]/g, ""), |
|||
"to": notification.clicksendsmsToNumber, |
|||
"source": "uptime-kuma", |
|||
"from": notification.clicksendsmsSenderName, |
|||
} |
|||
] |
|||
}; |
|||
let resp = await axios.post("https://rest.clicksend.com/v3/sms/send", data, config); |
|||
if (resp.data.data.messages[0].status !== "SUCCESS") { |
|||
let error = "Something gone wrong. Api returned " + resp.data.data.messages[0].status + "."; |
|||
this.throwGeneralAxiosError(error); |
|||
} |
|||
|
|||
return okMsg; |
|||
} catch (error) { |
|||
this.throwGeneralAxiosError(error); |
|||
} |
|||
} |
|||
} |
|||
|
|||
module.exports = ClickSendSMS; |
@ -0,0 +1,79 @@ |
|||
const NotificationProvider = require("./notification-provider"); |
|||
const { DOWN, UP } = require("../../src/util"); |
|||
const { default: axios } = require("axios"); |
|||
const Crypto = require("crypto"); |
|||
|
|||
class DingDing extends NotificationProvider { |
|||
name = "DingDing"; |
|||
|
|||
async send(notification, msg, monitorJSON = null, heartbeatJSON = null) { |
|||
let okMsg = "Sent Successfully."; |
|||
|
|||
try { |
|||
if (heartbeatJSON != null) { |
|||
let params = { |
|||
msgtype: "markdown", |
|||
markdown: { |
|||
title: monitorJSON["name"], |
|||
text: `## [${this.statusToString(heartbeatJSON["status"])}] \n > ${heartbeatJSON["msg"]} \n > Time(UTC):${heartbeatJSON["time"]}`, |
|||
} |
|||
}; |
|||
if (this.sendToDingDing(notification, params)) { |
|||
return okMsg; |
|||
} |
|||
} else { |
|||
let params = { |
|||
msgtype: "text", |
|||
text: { |
|||
content: msg |
|||
} |
|||
}; |
|||
if (this.sendToDingDing(notification, params)) { |
|||
return okMsg; |
|||
} |
|||
} |
|||
} catch (error) { |
|||
this.throwGeneralAxiosError(error); |
|||
} |
|||
} |
|||
|
|||
async sendToDingDing(notification, params) { |
|||
let timestamp = Date.now(); |
|||
|
|||
let config = { |
|||
method: "POST", |
|||
headers: { |
|||
"Content-Type": "application/json", |
|||
}, |
|||
url: `${notification.webHookUrl}×tamp=${timestamp}&sign=${encodeURIComponent(this.sign(timestamp, notification.secretKey))}`, |
|||
data: JSON.stringify(params), |
|||
}; |
|||
|
|||
let result = await axios(config); |
|||
if (result.data.errmsg == "ok") { |
|||
return true; |
|||
} |
|||
return false; |
|||
} |
|||
|
|||
/** DingDing sign */ |
|||
sign(timestamp, secretKey) { |
|||
return Crypto |
|||
.createHmac("sha256", Buffer.from(secretKey, "utf8")) |
|||
.update(Buffer.from(`${timestamp}\n${secretKey}`, "utf8")) |
|||
.digest("base64"); |
|||
} |
|||
|
|||
statusToString(status) { |
|||
switch (status) { |
|||
case DOWN: |
|||
return "DOWN"; |
|||
case UP: |
|||
return "UP"; |
|||
default: |
|||
return status; |
|||
} |
|||
} |
|||
} |
|||
|
|||
module.exports = DingDing; |
@ -0,0 +1,83 @@ |
|||
const NotificationProvider = require("./notification-provider"); |
|||
const axios = require("axios"); |
|||
const { DOWN, UP } = require("../../src/util"); |
|||
|
|||
class Feishu extends NotificationProvider { |
|||
name = "Feishu"; |
|||
|
|||
async send(notification, msg, monitorJSON = null, heartbeatJSON = null) { |
|||
let okMsg = "Sent Successfully."; |
|||
let feishuWebHookUrl = notification.feishuWebHookUrl; |
|||
|
|||
try { |
|||
if (heartbeatJSON == null) { |
|||
let testdata = { |
|||
msg_type: "text", |
|||
content: { |
|||
text: msg, |
|||
}, |
|||
}; |
|||
await axios.post(feishuWebHookUrl, testdata); |
|||
return okMsg; |
|||
} |
|||
|
|||
if (heartbeatJSON["status"] == DOWN) { |
|||
let downdata = { |
|||
msg_type: "post", |
|||
content: { |
|||
post: { |
|||
zh_cn: { |
|||
title: "UptimeKuma Alert: [Down] " + monitorJSON["name"], |
|||
content: [ |
|||
[ |
|||
{ |
|||
tag: "text", |
|||
text: |
|||
"[Down] " + |
|||
heartbeatJSON["msg"] + |
|||
"\nTime (UTC): " + |
|||
heartbeatJSON["time"], |
|||
}, |
|||
], |
|||
], |
|||
}, |
|||
}, |
|||
}, |
|||
}; |
|||
await axios.post(feishuWebHookUrl, downdata); |
|||
return okMsg; |
|||
} |
|||
|
|||
if (heartbeatJSON["status"] == UP) { |
|||
let updata = { |
|||
msg_type: "post", |
|||
content: { |
|||
post: { |
|||
zh_cn: { |
|||
title: "UptimeKuma Alert: [Up] " + monitorJSON["name"], |
|||
content: [ |
|||
[ |
|||
{ |
|||
tag: "text", |
|||
text: |
|||
"[Up] " + |
|||
heartbeatJSON["msg"] + |
|||
"\nTime (UTC): " + |
|||
heartbeatJSON["time"], |
|||
}, |
|||
], |
|||
], |
|||
}, |
|||
}, |
|||
}, |
|||
}; |
|||
await axios.post(feishuWebHookUrl, updata); |
|||
return okMsg; |
|||
} |
|||
} catch (error) { |
|||
this.throwGeneralAxiosError(error); |
|||
} |
|||
} |
|||
} |
|||
|
|||
module.exports = Feishu; |
@ -0,0 +1,45 @@ |
|||
const NotificationProvider = require("./notification-provider"); |
|||
const axios = require("axios"); |
|||
const Crypto = require("crypto"); |
|||
const { debug } = require("../../src/util"); |
|||
|
|||
class Matrix extends NotificationProvider { |
|||
name = "matrix"; |
|||
|
|||
async send(notification, msg, monitorJSON = null, heartbeatJSON = null) { |
|||
let okMsg = "Sent Successfully."; |
|||
|
|||
const size = 20; |
|||
const randomString = encodeURIComponent( |
|||
Crypto |
|||
.randomBytes(size) |
|||
.toString("base64") |
|||
.slice(0, size) |
|||
); |
|||
|
|||
debug("Random String: " + randomString); |
|||
|
|||
const roomId = encodeURIComponent(notification.internalRoomId); |
|||
|
|||
debug("Matrix Room ID: " + roomId); |
|||
|
|||
try { |
|||
let config = { |
|||
headers: { |
|||
"Authorization": `Bearer ${notification.accessToken}`, |
|||
} |
|||
}; |
|||
let data = { |
|||
"msgtype": "m.text", |
|||
"body": msg |
|||
}; |
|||
|
|||
await axios.put(`${notification.homeserverUrl}/_matrix/client/r0/rooms/${roomId}/send/m.room.message/${randomString}`, data, config); |
|||
return okMsg; |
|||
} catch (error) { |
|||
this.throwGeneralAxiosError(error); |
|||
} |
|||
} |
|||
} |
|||
|
|||
module.exports = Matrix; |
@ -0,0 +1,41 @@ |
|||
const NotificationProvider = require("./notification-provider"); |
|||
const axios = require("axios"); |
|||
|
|||
class PromoSMS extends NotificationProvider { |
|||
|
|||
name = "promosms"; |
|||
|
|||
async send(notification, msg, monitorJSON = null, heartbeatJSON = null) { |
|||
let okMsg = "Sent Successfully."; |
|||
|
|||
try { |
|||
let config = { |
|||
headers: { |
|||
"Content-Type": "application/json", |
|||
"Authorization": "Basic " + Buffer.from(notification.promosmsLogin + ":" + notification.promosmsPassword).toString('base64'), |
|||
"Accept": "text/json", |
|||
} |
|||
}; |
|||
let data = { |
|||
"recipients": [ notification.promosmsPhoneNumber ], |
|||
//Lets remove non ascii char
|
|||
"text": msg.replace(/[^\x00-\x7F]/g, ""), |
|||
"type": Number(notification.promosmsSMSType), |
|||
"sender": notification.promosmsSenderName |
|||
}; |
|||
|
|||
let resp = await axios.post("https://promosms.com/api/rest/v3_2/sms", data, config); |
|||
|
|||
if (resp.data.response.status !== 0) { |
|||
let error = "Something gone wrong. Api returned " + resp.data.response.status + "."; |
|||
this.throwGeneralAxiosError(error); |
|||
} |
|||
|
|||
return okMsg; |
|||
} catch (error) { |
|||
this.throwGeneralAxiosError(error); |
|||
} |
|||
} |
|||
} |
|||
|
|||
module.exports = PromoSMS; |
@ -0,0 +1,39 @@ |
|||
const { RateLimiter } = require("limiter"); |
|||
const { debug } = require("../src/util"); |
|||
|
|||
class KumaRateLimiter { |
|||
constructor(config) { |
|||
this.errorMessage = config.errorMessage; |
|||
this.rateLimiter = new RateLimiter(config); |
|||
} |
|||
|
|||
async pass(callback, num = 1) { |
|||
const remainingRequests = await this.removeTokens(num); |
|||
debug("Rate Limit (remainingRequests):" + remainingRequests); |
|||
if (remainingRequests < 0) { |
|||
if (callback) { |
|||
callback({ |
|||
ok: false, |
|||
msg: this.errorMessage, |
|||
}); |
|||
} |
|||
return false; |
|||
} |
|||
return true; |
|||
} |
|||
|
|||
async removeTokens(num = 1) { |
|||
return await this.rateLimiter.removeTokens(num); |
|||
} |
|||
} |
|||
|
|||
const loginRateLimiter = new KumaRateLimiter({ |
|||
tokensPerInterval: 20, |
|||
interval: "minute", |
|||
fireImmediately: true, |
|||
errorMessage: "Too frequently, try again later." |
|||
}); |
|||
|
|||
module.exports = { |
|||
loginRateLimiter |
|||
}; |
@ -0,0 +1,37 @@ |
|||
const { checkLogin } = require("../util-server"); |
|||
const Database = require("../database"); |
|||
|
|||
module.exports = (socket) => { |
|||
|
|||
// Post or edit incident
|
|||
socket.on("getDatabaseSize", async (callback) => { |
|||
try { |
|||
checkLogin(socket); |
|||
callback({ |
|||
ok: true, |
|||
size: Database.getSize(), |
|||
}); |
|||
} catch (error) { |
|||
callback({ |
|||
ok: false, |
|||
msg: error.message, |
|||
}); |
|||
} |
|||
}); |
|||
|
|||
socket.on("shrinkDatabase", async (callback) => { |
|||
try { |
|||
checkLogin(socket); |
|||
Database.shrink(); |
|||
callback({ |
|||
ok: true, |
|||
}); |
|||
} catch (error) { |
|||
callback({ |
|||
ok: false, |
|||
msg: error.message, |
|||
}); |
|||
} |
|||
}); |
|||
|
|||
}; |
@ -1,7 +1,12 @@ |
|||
<template> |
|||
<router-view /> |
|||
<router-view /> |
|||
</template> |
|||
|
|||
<script> |
|||
export default {} |
|||
import { setPageLocale } from "./util-frontend"; |
|||
export default { |
|||
created() { |
|||
setPageLocale(); |
|||
}, |
|||
}; |
|||
</script> |
|||
|
@ -0,0 +1,5 @@ |
|||
html[lang='fa'] { |
|||
#app { |
|||
font-family: 'IRANSans', 'Iranian Sans','B Nazanin', 'Tahoma', ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, segoe ui, Roboto, helvetica neue, Arial, noto sans, sans-serif, apple color emoji, segoe ui emoji, segoe ui symbol, noto color emoji; |
|||
} |
|||
} |
@ -0,0 +1,73 @@ |
|||
@import "vars.scss"; |
|||
@import "node_modules/vue-multiselect/dist/vue-multiselect"; |
|||
|
|||
.multiselect__tags { |
|||
border-radius: 1.5rem; |
|||
border: 1px solid #ced4da; |
|||
min-height: 38px; |
|||
padding: 6px 40px 0 8px; |
|||
} |
|||
|
|||
.multiselect--active .multiselect__tags { |
|||
border-radius: 1rem; |
|||
} |
|||
|
|||
.multiselect__option--highlight { |
|||
background: $primary !important; |
|||
} |
|||
|
|||
.multiselect__option--highlight::after { |
|||
background: $primary !important; |
|||
} |
|||
|
|||
.multiselect__tag { |
|||
border-radius: $border-radius; |
|||
margin-bottom: 0; |
|||
padding: 6px 26px 6px 10px; |
|||
background: $primary !important; |
|||
} |
|||
|
|||
.multiselect__placeholder { |
|||
font-size: 1rem; |
|||
padding-left: 6px; |
|||
padding-top: 0; |
|||
padding-bottom: 0; |
|||
margin-bottom: 0; |
|||
opacity: 0.67; |
|||
} |
|||
|
|||
.multiselect__input, |
|||
.multiselect__single { |
|||
line-height: 14px; |
|||
margin-bottom: 0; |
|||
} |
|||
|
|||
.dark { |
|||
.multiselect__tag { |
|||
color: $dark-font-color2; |
|||
} |
|||
|
|||
.multiselect__tags { |
|||
background-color: $dark-bg2; |
|||
border-color: $dark-border-color; |
|||
} |
|||
|
|||
.multiselect__input, |
|||
.multiselect__single { |
|||
background-color: $dark-bg2; |
|||
color: $dark-font-color; |
|||
} |
|||
|
|||
.multiselect__content-wrapper { |
|||
background-color: $dark-bg2; |
|||
border-color: $dark-border-color; |
|||
} |
|||
|
|||
.multiselect--above .multiselect__content-wrapper { |
|||
border-color: $dark-border-color; |
|||
} |
|||
|
|||
.multiselect__option--selected { |
|||
background-color: $dark-bg; |
|||
} |
|||
} |
@ -0,0 +1,52 @@ |
|||
<template> |
|||
<div> |
|||
<h4>{{ $t("Certificate Info") }}</h4> |
|||
{{ $t("Certificate Chain") }}: |
|||
<div |
|||
v-if="valid" |
|||
class="rounded d-inline-flex ms-2 text-white tag-valid" |
|||
> |
|||
{{ $t("Valid") }} |
|||
</div> |
|||
<div |
|||
v-if="!valid" |
|||
class="rounded d-inline-flex ms-2 text-white tag-invalid" |
|||
> |
|||
{{ $t("Invalid") }} |
|||
</div> |
|||
<certificate-info-row :cert="certInfo" /> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
import CertificateInfoRow from "./CertificateInfoRow.vue"; |
|||
export default { |
|||
components: { |
|||
CertificateInfoRow, |
|||
}, |
|||
props: { |
|||
certInfo: { |
|||
type: Object, |
|||
required: true, |
|||
}, |
|||
valid: { |
|||
type: Boolean, |
|||
required: true, |
|||
}, |
|||
}, |
|||
}; |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
@import "../assets/vars.scss"; |
|||
|
|||
.tag-valid { |
|||
padding: 2px 25px; |
|||
background-color: $primary; |
|||
} |
|||
|
|||
.tag-invalid { |
|||
padding: 2px 25px; |
|||
background-color: $danger; |
|||
} |
|||
</style> |
@ -0,0 +1,122 @@ |
|||
<template> |
|||
<div> |
|||
<div class="d-flex flex-row align-items-center p-1 overflow-hidden"> |
|||
<div class="m-3 ps-3"> |
|||
<div class="cert-icon"> |
|||
<font-awesome-icon icon="file" /> |
|||
<font-awesome-icon class="award-icon" icon="award" /> |
|||
</div> |
|||
</div> |
|||
<div class="m-3"> |
|||
<table class="text-start"> |
|||
<tbody> |
|||
<tr class="my-3"> |
|||
<td class="px-3">Subject:</td> |
|||
<td>{{ formatSubject(cert.subject) }}</td> |
|||
</tr> |
|||
<tr class="my-3"> |
|||
<td class="px-3">Valid To:</td> |
|||
<td><Datetime :value="cert.validTo" /></td> |
|||
</tr> |
|||
<tr class="my-3"> |
|||
<td class="px-3">Days Remaining:</td> |
|||
<td>{{ cert.daysRemaining }}</td> |
|||
</tr> |
|||
<tr class="my-3"> |
|||
<td class="px-3">Issuer:</td> |
|||
<td>{{ formatSubject(cert.issuer) }}</td> |
|||
</tr> |
|||
<tr class="my-3"> |
|||
<td class="px-3">Fingerprint:</td> |
|||
<td>{{ cert.fingerprint }}</td> |
|||
</tr> |
|||
</tbody> |
|||
</table> |
|||
</div> |
|||
</div> |
|||
<div class="d-flex"> |
|||
<font-awesome-icon |
|||
v-if="cert.issuerCertificate" |
|||
class="m-2 ps-6 link-icon" |
|||
icon="link" |
|||
/> |
|||
</div> |
|||
<certificate-info-row |
|||
v-if="cert.issuerCertificate" |
|||
:cert="cert.issuerCertificate" |
|||
/> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
import Datetime from "../components/Datetime.vue"; |
|||
export default { |
|||
name: "CertificateInfoRow", |
|||
components: { |
|||
Datetime, |
|||
}, |
|||
props: { |
|||
cert: { |
|||
type: Object, |
|||
required: true, |
|||
}, |
|||
}, |
|||
methods: { |
|||
formatSubject(subject) { |
|||
if (subject.O && subject.CN && subject.C) { |
|||
return `${subject.CN} - ${subject.O} (${subject.C})`; |
|||
} else if (subject.O && subject.CN) { |
|||
return `${subject.CN} - ${subject.O}`; |
|||
} else if (subject.CN) { |
|||
return subject.CN; |
|||
} else { |
|||
return "no info"; |
|||
} |
|||
}, |
|||
}, |
|||
}; |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
@import "../assets/vars.scss"; |
|||
|
|||
table { |
|||
overflow: hidden; |
|||
} |
|||
|
|||
.cert-icon { |
|||
position: relative; |
|||
font-size: 70px; |
|||
color: $link-color; |
|||
opacity: 0.5; |
|||
|
|||
.dark & { |
|||
color: $dark-font-color; |
|||
opacity: 0.3; |
|||
} |
|||
} |
|||
|
|||
.award-icon { |
|||
position: absolute; |
|||
font-size: 0.5em; |
|||
bottom: 20%; |
|||
left: 12%; |
|||
color: white; |
|||
|
|||
.dark & { |
|||
color: $dark-bg; |
|||
} |
|||
} |
|||
|
|||
.link-icon { |
|||
font-size: 20px; |
|||
margin-left: 50px !important; |
|||
color: $link-color; |
|||
opacity: 0.5; |
|||
|
|||
.dark & { |
|||
color: $dark-font-color; |
|||
opacity: 0.3; |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,122 @@ |
|||
<template> |
|||
<div class="input-group"> |
|||
<input |
|||
:id="id" |
|||
ref="input" |
|||
v-model="model" |
|||
:type="type" |
|||
class="form-control" |
|||
:placeholder="placeholder" |
|||
:autocomplete="autocomplete" |
|||
:required="required" |
|||
:readonly="readonly" |
|||
:disabled="disabled" |
|||
> |
|||
|
|||
<a class="btn btn-outline-primary" @click="copyToClipboard(model)"> |
|||
<font-awesome-icon :icon="icon" /> |
|||
</a> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
|
|||
let timeout; |
|||
|
|||
export default { |
|||
props: { |
|||
id: { |
|||
type: String, |
|||
default: "" |
|||
}, |
|||
type: { |
|||
type: String, |
|||
default: "text" |
|||
}, |
|||
modelValue: { |
|||
type: String, |
|||
default: "" |
|||
}, |
|||
placeholder: { |
|||
type: String, |
|||
default: "" |
|||
}, |
|||
autocomplete: { |
|||
type: String, |
|||
default: undefined, |
|||
}, |
|||
required: { |
|||
type: Boolean |
|||
}, |
|||
readonly: { |
|||
type: String, |
|||
default: undefined, |
|||
}, |
|||
disabled: { |
|||
type: String, |
|||
default: undefined, |
|||
}, |
|||
}, |
|||
data() { |
|||
return { |
|||
visibility: "password", |
|||
icon: "copy", |
|||
}; |
|||
}, |
|||
computed: { |
|||
model: { |
|||
get() { |
|||
return this.modelValue; |
|||
}, |
|||
set(value) { |
|||
this.$emit("update:modelValue", value); |
|||
} |
|||
} |
|||
}, |
|||
created() { |
|||
|
|||
}, |
|||
methods: { |
|||
|
|||
showInput() { |
|||
this.visibility = "text"; |
|||
}, |
|||
|
|||
hideInput() { |
|||
this.visibility = "password"; |
|||
}, |
|||
|
|||
copyToClipboard(textToCopy) { |
|||
this.icon = "check"; |
|||
|
|||
clearTimeout(timeout); |
|||
timeout = setTimeout(() => { |
|||
this.icon = "copy"; |
|||
}, 3000); |
|||
|
|||
// navigator clipboard api needs a secure context (https) |
|||
if (navigator.clipboard && window.isSecureContext) { |
|||
// navigator clipboard api method' |
|||
return navigator.clipboard.writeText(textToCopy); |
|||
} else { |
|||
// text area method |
|||
let textArea = document.createElement("textarea"); |
|||
textArea.value = textToCopy; |
|||
// make the textarea out of viewport |
|||
textArea.style.position = "fixed"; |
|||
textArea.style.left = "-999999px"; |
|||
textArea.style.top = "-999999px"; |
|||
document.body.appendChild(textArea); |
|||
textArea.focus(); |
|||
textArea.select(); |
|||
return new Promise((res, rej) => { |
|||
// here the magic happens |
|||
document.execCommand("copy") ? res() : rej(); |
|||
textArea.remove(); |
|||
}); |
|||
} |
|||
} |
|||
|
|||
} |
|||
}; |
|||
</script> |
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue