mirror of
https://github.com/OneUptime/oneuptime.git
synced 2026-04-06 08:42:13 +02:00
Compare commits
643 Commits
nativewind
...
8.0.5584
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cd6bac1111 | ||
|
|
0a791bba01 | ||
|
|
51ac869650 | ||
|
|
ce4a49fbd2 | ||
|
|
ca252d8e64 | ||
|
|
0fc63385a5 | ||
|
|
b5c0953c8b | ||
|
|
9deaf19d4c | ||
|
|
ac239ffe4d | ||
|
|
84ac063445 | ||
|
|
904311b124 | ||
|
|
c1562872a0 | ||
|
|
503d5ff946 | ||
|
|
271fa4c9ad | ||
|
|
a57902dd07 | ||
|
|
9336a33e47 | ||
|
|
fe034807d7 | ||
|
|
f08adc7b78 | ||
|
|
e767b3f4b7 | ||
|
|
c874f4f3e2 | ||
|
|
cb3fb984ec | ||
|
|
51882a595a | ||
|
|
8d5f8454c4 | ||
|
|
a036830009 | ||
|
|
76c6ffeb51 | ||
|
|
92c9de7ca9 | ||
|
|
e752340a16 | ||
|
|
3f7d7d4347 | ||
|
|
30651f1ca7 | ||
|
|
a04fa51c37 | ||
|
|
5c5a4ca787 | ||
|
|
62fe797b93 | ||
|
|
1ee2f17b28 | ||
|
|
9e714af5c2 | ||
|
|
74e18a2861 | ||
|
|
cd9b3c1386 | ||
|
|
40a7fc5d02 | ||
|
|
49ccb8fd75 | ||
|
|
5c3923f534 | ||
|
|
7a94684cec | ||
|
|
893ccf3331 | ||
|
|
b5f354da75 | ||
|
|
b128be0c13 | ||
|
|
a0fae9b514 | ||
|
|
04fc51b873 | ||
|
|
2cb45d18c9 | ||
|
|
495f59f36b | ||
|
|
21da644555 | ||
|
|
02e7bd6f3e | ||
|
|
254795261d | ||
|
|
53f0cd144c | ||
|
|
679864dbaa | ||
|
|
c6acc85d7d | ||
|
|
5ea2426ea4 | ||
|
|
1144783f4d | ||
|
|
d68bc56d1b | ||
|
|
5170254473 | ||
|
|
84353e1a05 | ||
|
|
62d74c1d84 | ||
|
|
654f64aaf7 | ||
|
|
150af5b65d | ||
|
|
3740636136 | ||
|
|
d40deae7ef | ||
|
|
669ed24249 | ||
|
|
ae341eae08 | ||
|
|
241ff7671d | ||
|
|
b7492f0706 | ||
|
|
fcd076d057 | ||
|
|
b924d68c51 | ||
|
|
4713a42829 | ||
|
|
9399907bfc | ||
|
|
2a84fd6751 | ||
|
|
4efd3d0428 | ||
|
|
535ae01dee | ||
|
|
b04b59b0a9 | ||
|
|
92025ce415 | ||
|
|
4893b01f38 | ||
|
|
0f8436b92f | ||
|
|
5e4aa44f2a | ||
|
|
0290355cfc | ||
|
|
64360fc3fe | ||
|
|
dd07cb6312 | ||
|
|
46e5aae8e4 | ||
|
|
626b6d93a8 | ||
|
|
e570030319 | ||
|
|
97d3a34abc | ||
|
|
848c441419 | ||
|
|
5b7e52a94e | ||
|
|
77e3394638 | ||
|
|
93721350c6 | ||
|
|
1bc6eca55c | ||
|
|
29560e3a4a | ||
|
|
03cc76ab07 | ||
|
|
dade1d0403 | ||
|
|
8a3feab3d0 | ||
|
|
7864bbb87b | ||
|
|
d112d87b80 | ||
|
|
2f8fcabce4 | ||
|
|
0023560588 | ||
|
|
0bc14acde9 | ||
|
|
3f3956edd6 | ||
|
|
93755da2e8 | ||
|
|
0657222ea7 | ||
|
|
ca352826ca | ||
|
|
3cbd99042b | ||
|
|
2f102acdc2 | ||
|
|
b76811d152 | ||
|
|
2335935a3e | ||
|
|
c324fe03d3 | ||
|
|
d5bc83a5a1 | ||
|
|
e2baa449f5 | ||
|
|
51b88eb065 | ||
|
|
b0d95bb7df | ||
|
|
8bf8c891ab | ||
|
|
fcf919c70b | ||
|
|
f0f3d32d31 | ||
|
|
444e8f17b6 | ||
|
|
3aabf44b4e | ||
|
|
c11fcc3c8e | ||
|
|
52519c9af8 | ||
|
|
2483cf9499 | ||
|
|
634e21b13c | ||
|
|
aad933b9eb | ||
|
|
9356f2964e | ||
|
|
aae70ead3b | ||
|
|
8a482dce10 | ||
|
|
9fdf46889c | ||
|
|
40ca9dc04c | ||
|
|
74937f2208 | ||
|
|
c02ab56477 | ||
|
|
3f99b9680f | ||
|
|
b08c39037d | ||
|
|
f7cc3c00da | ||
|
|
ac4286935a | ||
|
|
90a0b2e4a8 | ||
|
|
9b22c48d27 | ||
|
|
9c9dad5da0 | ||
|
|
e986f74025 | ||
|
|
deb2e81b21 | ||
|
|
0f8b322892 | ||
|
|
23c7de3ecd | ||
|
|
ad144a6240 | ||
|
|
debfef0388 | ||
|
|
bb85c9f8c8 | ||
|
|
25ab1cdbf9 | ||
|
|
44b8a9ddc9 | ||
|
|
c388ff9550 | ||
|
|
321d1680e6 | ||
|
|
6c0e9f0fed | ||
|
|
99349ecb30 | ||
|
|
258bbbd9cf | ||
|
|
1094a07fc6 | ||
|
|
14a5671645 | ||
|
|
5a41c66953 | ||
|
|
af605fce4c | ||
|
|
f8ef6c69fe | ||
|
|
e1848f44f7 | ||
|
|
825bd39dda | ||
|
|
b99905dfe8 | ||
|
|
a4bf40a2c1 | ||
|
|
711998b048 | ||
|
|
132e044c07 | ||
|
|
8ecc307451 | ||
|
|
c85c29989f | ||
|
|
95726e0f21 | ||
|
|
adc15992e9 | ||
|
|
58d83a2a80 | ||
|
|
5461cd4502 | ||
|
|
478465a65b | ||
|
|
bef57b784d | ||
|
|
601eed0e70 | ||
|
|
dc1215f28b | ||
|
|
f617330484 | ||
|
|
888d8d6fbf | ||
|
|
79a9bb2229 | ||
|
|
0578f9f1be | ||
|
|
ebbddbd797 | ||
|
|
6cdaaf1489 | ||
|
|
93e62befbb | ||
|
|
bccd2f484b | ||
|
|
c01fc9ee64 | ||
|
|
be9dcbd01e | ||
|
|
48f85df04c | ||
|
|
fc08578ff2 | ||
|
|
ea9a245b82 | ||
|
|
f49b1995df | ||
|
|
351fc4828b | ||
|
|
04cb7da6d6 | ||
|
|
c6e2f41351 | ||
|
|
e524dfda6d | ||
|
|
30b6353714 | ||
|
|
29be9b399f | ||
|
|
36cdeec916 | ||
|
|
a80b7ba88c | ||
|
|
b31d1076b8 | ||
|
|
788e82497c | ||
|
|
3409b0f66e | ||
|
|
cafed35795 | ||
|
|
69ae1eb310 | ||
|
|
4335c46e3e | ||
|
|
863f1ae82e | ||
|
|
0755c15886 | ||
|
|
72ed43563e | ||
|
|
15ded6cd46 | ||
|
|
9e238dc660 | ||
|
|
9f3ccc7d74 | ||
|
|
9e5db22235 | ||
|
|
e31417c5bf | ||
|
|
bf6e97c35d | ||
|
|
28073ba819 | ||
|
|
4909a5c980 | ||
|
|
c4adc24562 | ||
|
|
597344483a | ||
|
|
05d9b79ba2 | ||
|
|
af14edb175 | ||
|
|
0255bd37d0 | ||
|
|
2e6b463bd7 | ||
|
|
95e355ff7d | ||
|
|
cccdcdaf93 | ||
|
|
9256f8b4bd | ||
|
|
b27acbfd38 | ||
|
|
ad9771f222 | ||
|
|
20a3eab3a0 | ||
|
|
fbe198f0c0 | ||
|
|
bb48776e02 | ||
|
|
0f92342742 | ||
|
|
6ed41b87dd | ||
|
|
12364415aa | ||
|
|
1a3301e715 | ||
|
|
8be7b68faf | ||
|
|
47f9d3914e | ||
|
|
8a1afbe7dc | ||
|
|
87ac6f3106 | ||
|
|
2df32e4cdd | ||
|
|
2e2adffe17 | ||
|
|
2a15cf8676 | ||
|
|
d249579c1c | ||
|
|
05681b108b | ||
|
|
36867a0b8c | ||
|
|
0e5a832628 | ||
|
|
46f69fdde5 | ||
|
|
70e6c0abe1 | ||
|
|
c5938956af | ||
|
|
e9bfe74b5d | ||
|
|
55085a5e6c | ||
|
|
9cb48a41e7 | ||
|
|
dd8179c0a7 | ||
|
|
f9f84d4104 | ||
|
|
827663675d | ||
|
|
0e8d7f2d6b | ||
|
|
0dd9dfb505 | ||
|
|
b3c68df77e | ||
|
|
06d0510667 | ||
|
|
059b7db474 | ||
|
|
ff17d990d1 | ||
|
|
2e6658542b | ||
|
|
04a4d6e4de | ||
|
|
2f595fe490 | ||
|
|
303554d644 | ||
|
|
2ca45b143d | ||
|
|
b5722256c5 | ||
|
|
0d231a6132 | ||
|
|
ecc1d841e2 | ||
|
|
cddf534449 | ||
|
|
a4ba662211 | ||
|
|
604bc33fb3 | ||
|
|
a1ae1bee89 | ||
|
|
775b8846c7 | ||
|
|
3837208023 | ||
|
|
b45910a22e | ||
|
|
c787d7eca0 | ||
|
|
9771c4cd69 | ||
|
|
4471d6bec4 | ||
|
|
95e24d9ae0 | ||
|
|
f8a7330f79 | ||
|
|
ae177c920f | ||
|
|
9faa38454d | ||
|
|
a4198ec409 | ||
|
|
24d184debf | ||
|
|
f307c904b0 | ||
|
|
2d20b7fd13 | ||
|
|
fd738b23d0 | ||
|
|
deffa6489d | ||
|
|
e5f1d5553e | ||
|
|
d2ee3c5409 | ||
|
|
9a1ecd7fe0 | ||
|
|
b41d8ab5ab | ||
|
|
b809e1c43b | ||
|
|
743f8721f3 | ||
|
|
c0aa2b7905 | ||
|
|
4ac5819e6a | ||
|
|
158663c44b | ||
|
|
3d2bcfa579 | ||
|
|
21984c8684 | ||
|
|
ad63d18f0a | ||
|
|
e5af008079 | ||
|
|
3e72b2a9a4 | ||
|
|
6d66c6c369 | ||
|
|
9544dc2a6c | ||
|
|
a22e3b63e0 | ||
|
|
5f1f0cde4a | ||
|
|
3025880d6d | ||
|
|
00994b56c5 | ||
|
|
d56fd8bf69 | ||
|
|
1229d5d204 | ||
|
|
c4f1f4e711 | ||
|
|
7b8986b011 | ||
|
|
46e6176e6a | ||
|
|
61f9572956 | ||
|
|
3adc6901da | ||
|
|
d7f1bfb52a | ||
|
|
53968e681c | ||
|
|
3b8c854744 | ||
|
|
669ed2580c | ||
|
|
2f29c2e24c | ||
|
|
f0a2f454e2 | ||
|
|
d8206e12de | ||
|
|
f84434ada4 | ||
|
|
d5fbe0443e | ||
|
|
2732cd65ed | ||
|
|
7624523446 | ||
|
|
5851286548 | ||
|
|
123d9b07bc | ||
|
|
9edc6ac428 | ||
|
|
72fc633bf1 | ||
|
|
3264322054 | ||
|
|
d8fedc0b19 | ||
|
|
fc7cc5fe7f | ||
|
|
5b4eb72521 | ||
|
|
d84cfe9b09 | ||
|
|
0e8926a786 | ||
|
|
12ff3062de | ||
|
|
30aad2866f | ||
|
|
3de636ab9e | ||
|
|
a1bf9cbaae | ||
|
|
12c800b81f | ||
|
|
677e687662 | ||
|
|
93719d67be | ||
|
|
7d23209198 | ||
|
|
4461127a36 | ||
|
|
8326bf2c9e | ||
|
|
be9d2f6beb | ||
|
|
214dae6204 | ||
|
|
71c845d94e | ||
|
|
87d709dd05 | ||
|
|
25332f99fd | ||
|
|
1ac6e71f7e | ||
|
|
f1efd65ada | ||
|
|
bc338f41c7 | ||
|
|
39153735b5 | ||
|
|
ae9a78f1f4 | ||
|
|
f224ad6092 | ||
|
|
1abb8bc83f | ||
|
|
46704b7c5a | ||
|
|
143d91ceab | ||
|
|
ea58cacd1b | ||
|
|
5e19849ac8 | ||
|
|
f7c05645a9 | ||
|
|
1c1a48b78f | ||
|
|
13860be56d | ||
|
|
38c29664ea | ||
|
|
df1507b314 | ||
|
|
65c999b5fc | ||
|
|
803d0436ca | ||
|
|
b98e7f13a5 | ||
|
|
0785f11abe | ||
|
|
f0d9f7c594 | ||
|
|
dc9463f73d | ||
|
|
37c8e8b6b6 | ||
|
|
763dfaa1c9 | ||
|
|
c2e0d402d5 | ||
|
|
cdc1526fbf | ||
|
|
13ebd34e8f | ||
|
|
3b97c23039 | ||
|
|
7c15424565 | ||
|
|
6817443d9a | ||
|
|
f40a6395a6 | ||
|
|
81eb735aab | ||
|
|
923339710b | ||
|
|
1f9ec3011c | ||
|
|
668093b09c | ||
|
|
f39f51e8ee | ||
|
|
0bff616ca9 | ||
|
|
709b9b8343 | ||
|
|
aa93252407 | ||
|
|
b4e7ffce43 | ||
|
|
1053d22d3f | ||
|
|
a37bdb303d | ||
|
|
860af1bbf3 | ||
|
|
d5e72c1af2 | ||
|
|
6cc6fc4bf1 | ||
|
|
f890f24650 | ||
|
|
d077e55241 | ||
|
|
a4b7c99b8a | ||
|
|
671be425ae | ||
|
|
d2d7a51842 | ||
|
|
1142a20d64 | ||
|
|
8d0d7dc759 | ||
|
|
cedf06ba42 | ||
|
|
b347e18749 | ||
|
|
50e9a53547 | ||
|
|
d0de004498 | ||
|
|
65c4998048 | ||
|
|
5e7a3795c7 | ||
|
|
cf83319a90 | ||
|
|
87dc9d88d0 | ||
|
|
444cf040a6 | ||
|
|
2754657a6f | ||
|
|
38ca6b1e9e | ||
|
|
f481ef4f5e | ||
|
|
ad9adca473 | ||
|
|
819bd54a1f | ||
|
|
e212079b4a | ||
|
|
bb09dafbcc | ||
|
|
60c472cc09 | ||
|
|
0e272f0f31 | ||
|
|
f5de74611d | ||
|
|
03d157b850 | ||
|
|
da21cfc1ff | ||
|
|
2781bf0583 | ||
|
|
69b16c1c85 | ||
|
|
727f009d79 | ||
|
|
65d916f349 | ||
|
|
4373c7b49c | ||
|
|
34737fbba4 | ||
|
|
90fcfd1c7e | ||
|
|
b55320f02c | ||
|
|
34dc078197 | ||
|
|
2eacc90714 | ||
|
|
9d93d59f91 | ||
|
|
d84039e621 | ||
|
|
4eb46cf8a0 | ||
|
|
1ef27b7f52 | ||
|
|
412bd370df | ||
|
|
1131b80a52 | ||
|
|
8b55f5c348 | ||
|
|
159e5c4023 | ||
|
|
4970538d43 | ||
|
|
d7ca021d52 | ||
|
|
27eff7f415 | ||
|
|
50543ec7bf | ||
|
|
94c39408ed | ||
|
|
7219e1850f | ||
|
|
3180ed7149 | ||
|
|
79f32b80c8 | ||
|
|
cebfde6bf2 | ||
|
|
ca644d9dc7 | ||
|
|
ca4d9cb176 | ||
|
|
56204e02a9 | ||
|
|
c8e8a6d687 | ||
|
|
5bd2204eee | ||
|
|
72a31ed268 | ||
|
|
ee188dd050 | ||
|
|
3807aad63b | ||
|
|
055ec956fd | ||
|
|
e7767e59d1 | ||
|
|
f643e907b4 | ||
|
|
2eec57befd | ||
|
|
dd653f8deb | ||
|
|
f403c6a9e9 | ||
|
|
35f9b7f5c4 | ||
|
|
3c487ff9b9 | ||
|
|
41fca346b9 | ||
|
|
91b54ced67 | ||
|
|
ebdd97b8e9 | ||
|
|
8eb1eac629 | ||
|
|
a075b3c4dd | ||
|
|
738f901a51 | ||
|
|
683a8f5a58 | ||
|
|
160eba1ea4 | ||
|
|
89b65d1e02 | ||
|
|
caf709a38a | ||
|
|
d57433e4a0 | ||
|
|
5e2aa4e622 | ||
|
|
6cb51dd54b | ||
|
|
53ea843bdc | ||
|
|
71eeaf7ecd | ||
|
|
1d0168fcc6 | ||
|
|
99c3d440c5 | ||
|
|
5959ce728f | ||
|
|
0cb9e382a6 | ||
|
|
0c6d561b7c | ||
|
|
4291a76dd4 | ||
|
|
05b1f0ea82 | ||
|
|
b943505b1d | ||
|
|
1ed236eb91 | ||
|
|
44795182c9 | ||
|
|
50267534e0 | ||
|
|
f60836a4dc | ||
|
|
303294bb5e | ||
|
|
1212a8e4be | ||
|
|
25c626d2d4 | ||
|
|
ff6f9c89fa | ||
|
|
7f6e905c74 | ||
|
|
2cc64838aa | ||
|
|
3de5c8da8c | ||
|
|
7403ffa053 | ||
|
|
fa473474a2 | ||
|
|
20cbcf9a74 | ||
|
|
e6fd4b8304 | ||
|
|
4a3a743dcd | ||
|
|
6f1e2234d3 | ||
|
|
07189b4567 | ||
|
|
b1bc02cec4 | ||
|
|
6f7795aa31 | ||
|
|
50ee87c86f | ||
|
|
a75c6b6a43 | ||
|
|
f6168c969e | ||
|
|
2b0f9f2e7a | ||
|
|
14377c68fe | ||
|
|
9176fa2c9b | ||
|
|
4f29fef5f6 | ||
|
|
f28c7695ab | ||
|
|
bc234deb0e | ||
|
|
546b4a4fb3 | ||
|
|
1300c4e667 | ||
|
|
988d5d327c | ||
|
|
f2510a7b89 | ||
|
|
a2f16ca0eb | ||
|
|
1448288395 | ||
|
|
734481df6c | ||
|
|
43c534b76a | ||
|
|
1b593403b6 | ||
|
|
54e60cc380 | ||
|
|
28d9879dbd | ||
|
|
22c417ac92 | ||
|
|
401926c792 | ||
|
|
90bc4de84a | ||
|
|
93fd2a9ed7 | ||
|
|
231451e359 | ||
|
|
3073891a38 | ||
|
|
2b62d31e8b | ||
|
|
bc43e6e6ea | ||
|
|
2204ebde26 | ||
|
|
57a8547e14 | ||
|
|
53a70e1b93 | ||
|
|
3eb72ef7f9 | ||
|
|
2a471133c5 | ||
|
|
34e92679b2 | ||
|
|
8b0c2a7320 | ||
|
|
353d894394 | ||
|
|
09e4f0ff97 | ||
|
|
247c4bc637 | ||
|
|
72e2edd49d | ||
|
|
1be494169d | ||
|
|
3796053403 | ||
|
|
f316bfb9fd | ||
|
|
40f9613bd3 | ||
|
|
a3bb9f003f | ||
|
|
70714b2f21 | ||
|
|
a62543bff0 | ||
|
|
826a2006d0 | ||
|
|
a4075fe349 | ||
|
|
eb70a923f3 | ||
|
|
11d39898d3 | ||
|
|
8e5907d523 | ||
|
|
c9e57fcb19 | ||
|
|
8c6bc331a4 | ||
|
|
20129e606a | ||
|
|
55e0eede68 | ||
|
|
ffa603503d | ||
|
|
18429caabe | ||
|
|
ccbfef1cfe | ||
|
|
4789a15ce7 | ||
|
|
9633307de0 | ||
|
|
ee5c2a0f33 | ||
|
|
5c3b181507 | ||
|
|
6bbf2f866c | ||
|
|
60e4b51ec9 | ||
|
|
f244f872d4 | ||
|
|
3e910c1308 | ||
|
|
2b0067fd17 | ||
|
|
cb23b6b55b | ||
|
|
4406d52307 | ||
|
|
03b6bec6d0 | ||
|
|
ff0bd88b02 | ||
|
|
94290c77db | ||
|
|
003e44d331 | ||
|
|
b4cf798246 | ||
|
|
e607367809 | ||
|
|
82a7b5794c | ||
|
|
37c1674029 | ||
|
|
cd2a5222b8 | ||
|
|
875d6c5df9 | ||
|
|
7eea90a55a | ||
|
|
c401b86a2e | ||
|
|
e96f781157 | ||
|
|
73cc5f8f9e | ||
|
|
0ee9876de9 | ||
|
|
b76a75479d | ||
|
|
79b9cf4c06 | ||
|
|
a6da59c966 | ||
|
|
b84695feb9 | ||
|
|
b77973441d | ||
|
|
27e9c07c57 | ||
|
|
cbf8684d8c | ||
|
|
87057757a5 | ||
|
|
23b587f0f6 | ||
|
|
81c7a4eeb7 | ||
|
|
549dbfd6c7 | ||
|
|
a2eac673eb | ||
|
|
086a0a661d | ||
|
|
da0620eafa | ||
|
|
ca90ab0db4 | ||
|
|
94dacc20db | ||
|
|
7e887bd4cd | ||
|
|
b50dfcdf1c | ||
|
|
e2bc0ea4aa | ||
|
|
7d018b94d3 | ||
|
|
9fb7a70dc9 | ||
|
|
a37b3fc0b3 | ||
|
|
c06ef5ddfc | ||
|
|
0fb7174e94 | ||
|
|
84a7cd976d | ||
|
|
f7c8c00f04 | ||
|
|
51c3fcd3ca | ||
|
|
74c3dde7f1 | ||
|
|
6bf45f6f31 | ||
|
|
4de4ad8022 | ||
|
|
e263900115 | ||
|
|
34aaa34fb3 | ||
|
|
9f72a8e554 | ||
|
|
8dfabfd96f | ||
|
|
14cdc3ea86 | ||
|
|
cd6abe63ea | ||
|
|
aeb6d53b9d | ||
|
|
efa7224718 | ||
|
|
a2c406d7cc | ||
|
|
1933e37beb | ||
|
|
0b0336f9ea | ||
|
|
9304079a1c | ||
|
|
1e2dcf332b | ||
|
|
ca860f54a8 | ||
|
|
513e4146ed | ||
|
|
43d31ddbe9 | ||
|
|
18231f42aa | ||
|
|
60291cc218 | ||
|
|
036b29da51 | ||
|
|
d0d59147ae | ||
|
|
565fbe6cd3 | ||
|
|
12c3f9b25c | ||
|
|
9ee0e0f3cb | ||
|
|
50be2a666c |
65
.github/workflows/build.yml
vendored
65
.github/workflows/build.yml
vendored
@@ -31,7 +31,7 @@ jobs:
|
||||
with:
|
||||
timeout_minutes: 45
|
||||
max_attempts: 3
|
||||
command: sudo docker build -f ./Accounts/Dockerfile .
|
||||
command: sudo docker build --no-cache -f ./Accounts/Dockerfile .
|
||||
|
||||
docker-build-isolated-vm:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -54,7 +54,7 @@ jobs:
|
||||
with:
|
||||
timeout_minutes: 45
|
||||
max_attempts: 3
|
||||
command: sudo docker build -f ./IsolatedVM/Dockerfile .
|
||||
command: sudo docker build --no-cache -f ./IsolatedVM/Dockerfile .
|
||||
|
||||
docker-build-home:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -77,7 +77,7 @@ jobs:
|
||||
with:
|
||||
timeout_minutes: 45
|
||||
max_attempts: 3
|
||||
command: sudo docker build -f ./Home/Dockerfile .
|
||||
command: sudo docker build --no-cache -f ./Home/Dockerfile .
|
||||
|
||||
docker-build-worker:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -100,7 +100,7 @@ jobs:
|
||||
with:
|
||||
timeout_minutes: 45
|
||||
max_attempts: 3
|
||||
command: sudo docker build -f ./Worker/Dockerfile .
|
||||
command: sudo docker build --no-cache -f ./Worker/Dockerfile .
|
||||
|
||||
docker-build-workflow:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -123,7 +123,7 @@ jobs:
|
||||
with:
|
||||
timeout_minutes: 45
|
||||
max_attempts: 3
|
||||
command: sudo docker build -f ./Workflow/Dockerfile .
|
||||
command: sudo docker build --no-cache -f ./Workflow/Dockerfile .
|
||||
|
||||
docker-build-api-reference:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -146,7 +146,7 @@ jobs:
|
||||
with:
|
||||
timeout_minutes: 45
|
||||
max_attempts: 3
|
||||
command: sudo docker build -f ./APIReference/Dockerfile .
|
||||
command: sudo docker build --no-cache -f ./APIReference/Dockerfile .
|
||||
|
||||
docker-build-docs:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -169,7 +169,7 @@ jobs:
|
||||
with:
|
||||
timeout_minutes: 45
|
||||
max_attempts: 3
|
||||
command: sudo docker build -f ./Docs/Dockerfile .
|
||||
command: sudo docker build --no-cache -f ./Docs/Dockerfile .
|
||||
|
||||
|
||||
docker-build-otel-collector:
|
||||
@@ -193,7 +193,7 @@ jobs:
|
||||
with:
|
||||
timeout_minutes: 45
|
||||
max_attempts: 3
|
||||
command: sudo docker build -f ./OTelCollector/Dockerfile .
|
||||
command: sudo docker build --no-cache -f ./OTelCollector/Dockerfile .
|
||||
|
||||
docker-build-app:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -217,7 +217,7 @@ jobs:
|
||||
with:
|
||||
timeout_minutes: 45
|
||||
max_attempts: 3
|
||||
command: sudo docker build -f ./App/Dockerfile .
|
||||
command: sudo docker build --no-cache -f ./App/Dockerfile .
|
||||
|
||||
|
||||
docker-build-copilot:
|
||||
@@ -241,7 +241,7 @@ jobs:
|
||||
with:
|
||||
timeout_minutes: 45
|
||||
max_attempts: 3
|
||||
command: sudo docker build -f ./Copilot/Dockerfile .
|
||||
command: sudo docker build --no-cache -f ./Copilot/Dockerfile .
|
||||
|
||||
docker-build-e2e:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -265,7 +265,7 @@ jobs:
|
||||
with:
|
||||
timeout_minutes: 45
|
||||
max_attempts: 3
|
||||
command: sudo docker build -f ./E2E/Dockerfile .
|
||||
command: sudo docker build --no-cache -f ./E2E/Dockerfile .
|
||||
|
||||
docker-build-admin-dashboard:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -288,7 +288,7 @@ jobs:
|
||||
with:
|
||||
timeout_minutes: 45
|
||||
max_attempts: 3
|
||||
command: sudo docker build -f ./AdminDashboard/Dockerfile .
|
||||
command: sudo docker build --no-cache -f ./AdminDashboard/Dockerfile .
|
||||
|
||||
docker-build-dashboard:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -311,7 +311,7 @@ jobs:
|
||||
with:
|
||||
timeout_minutes: 45
|
||||
max_attempts: 3
|
||||
command: sudo docker build -f ./Dashboard/Dockerfile .
|
||||
command: sudo docker build --no-cache -f ./Dashboard/Dockerfile .
|
||||
|
||||
docker-build-probe:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -334,7 +334,7 @@ jobs:
|
||||
with:
|
||||
timeout_minutes: 45
|
||||
max_attempts: 3
|
||||
command: sudo docker build -f ./Probe/Dockerfile .
|
||||
command: sudo docker build --no-cache -f ./Probe/Dockerfile .
|
||||
|
||||
docker-build-probe-ingest:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -357,7 +357,7 @@ jobs:
|
||||
with:
|
||||
timeout_minutes: 45
|
||||
max_attempts: 3
|
||||
command: sudo docker build -f ./ProbeIngest/Dockerfile .
|
||||
command: sudo docker build --no-cache -f ./ProbeIngest/Dockerfile .
|
||||
|
||||
docker-build-server-monitor-ingest:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -380,9 +380,9 @@ jobs:
|
||||
with:
|
||||
timeout_minutes: 45
|
||||
max_attempts: 3
|
||||
command: sudo docker build -f ./ServerMonitorIngest/Dockerfile .
|
||||
command: sudo docker build --no-cache -f ./ServerMonitorIngest/Dockerfile .
|
||||
|
||||
docker-build-open-telemetry-ingest:
|
||||
docker-build-telemetry:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
CI_PIPELINE_ID: ${{github.run_number}}
|
||||
@@ -403,7 +403,7 @@ jobs:
|
||||
with:
|
||||
timeout_minutes: 45
|
||||
max_attempts: 3
|
||||
command: sudo docker build -f ./OpenTelemetryIngest/Dockerfile .
|
||||
command: sudo docker build --no-cache -f ./Telemetry/Dockerfile .
|
||||
|
||||
docker-build-incoming-request-ingest:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -426,30 +426,7 @@ jobs:
|
||||
with:
|
||||
timeout_minutes: 45
|
||||
max_attempts: 3
|
||||
command: sudo docker build -f ./IncomingRequestIngest/Dockerfile .
|
||||
|
||||
docker-build-fluent-ingest:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
CI_PIPELINE_ID: ${{github.run_number}}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Preinstall
|
||||
uses: nick-fields/retry@v3
|
||||
with:
|
||||
timeout_minutes: 10
|
||||
max_attempts: 3
|
||||
command: npm run prerun
|
||||
|
||||
# build image probe api
|
||||
- name: build docker image
|
||||
uses: nick-fields/retry@v3
|
||||
with:
|
||||
timeout_minutes: 45
|
||||
max_attempts: 3
|
||||
command: sudo docker build -f ./FluentIngest/Dockerfile .
|
||||
command: sudo docker build --no-cache -f ./IncomingRequestIngest/Dockerfile .
|
||||
|
||||
docker-build-status-page:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -472,7 +449,7 @@ jobs:
|
||||
with:
|
||||
timeout_minutes: 45
|
||||
max_attempts: 3
|
||||
command: sudo docker build -f ./StatusPage/Dockerfile .
|
||||
command: sudo docker build --no-cache -f ./StatusPage/Dockerfile .
|
||||
|
||||
docker-build-test-server:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -495,4 +472,4 @@ jobs:
|
||||
with:
|
||||
timeout_minutes: 45
|
||||
max_attempts: 3
|
||||
command: sudo docker build -f ./TestServer/Dockerfile .
|
||||
command: sudo docker build --no-cache -f ./TestServer/Dockerfile .
|
||||
|
||||
24
.github/workflows/compile.yml
vendored
24
.github/workflows/compile.yml
vendored
@@ -319,7 +319,7 @@ jobs:
|
||||
max_attempts: 3
|
||||
command: cd ServerMonitorIngest && npm install && npm run compile && npm run dep-check
|
||||
|
||||
compile-open-telemetry-ingest:
|
||||
compile-telemetry:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
CI_PIPELINE_ID: ${{github.run_number}}
|
||||
@@ -329,12 +329,12 @@ jobs:
|
||||
with:
|
||||
node-version: latest
|
||||
- run: cd Common && npm install
|
||||
- name: Compile Open Telemetry Ingest
|
||||
- name: Compile Telemetry
|
||||
uses: nick-fields/retry@v3
|
||||
with:
|
||||
timeout_minutes: 30
|
||||
max_attempts: 3
|
||||
command: cd OpenTelemetryIngest && npm install && npm run compile && npm run dep-check
|
||||
command: cd Telemetry && npm install && npm run compile && npm run dep-check
|
||||
|
||||
|
||||
compile-incoming-request-ingest:
|
||||
@@ -354,24 +354,6 @@ jobs:
|
||||
max_attempts: 3
|
||||
command: cd IncomingRequestIngest && npm install && npm run compile && npm run dep-check
|
||||
|
||||
compile-fluent-ingest:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
CI_PIPELINE_ID: ${{github.run_number}}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: latest
|
||||
- run: cd Common && npm install
|
||||
- name: Compile Fluent Ingest
|
||||
uses: nick-fields/retry@v3
|
||||
with:
|
||||
timeout_minutes: 30
|
||||
max_attempts: 3
|
||||
command: cd FluentIngest && npm install && npm run compile && npm run dep-check
|
||||
|
||||
|
||||
compile-status-page:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
|
||||
49
.github/workflows/npm-audit-fix.yml
vendored
Normal file
49
.github/workflows/npm-audit-fix.yml
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
name: NPM Audit Fix
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 0 * * *'
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
|
||||
jobs:
|
||||
npm-audit-fix:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 20
|
||||
|
||||
- name: Run npm audit fix across packages
|
||||
run: npm run audit-fix
|
||||
|
||||
- name: Detect changes
|
||||
id: changes
|
||||
run: |
|
||||
if git status --porcelain | grep .; then
|
||||
echo "has_changes=true" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "has_changes=false" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
- name: Create pull request
|
||||
if: steps.changes.outputs.has_changes == 'true'
|
||||
uses: peter-evans/create-pull-request@v6
|
||||
with:
|
||||
commit-message: "chore: npm audit fix"
|
||||
title: "chore: npm audit fix"
|
||||
body: |
|
||||
Automated npm audit fix run.
|
||||
Workflow: ${{ github.workflow }}
|
||||
Run ID: ${{ github.run_id }}
|
||||
branch: chore/npm-audit-fix
|
||||
delete-branch: true
|
||||
606
.github/workflows/release.yml
vendored
606
.github/workflows/release.yml
vendored
@@ -168,7 +168,19 @@ jobs:
|
||||
run: |
|
||||
cd MCP
|
||||
echo "📦 Package information:"
|
||||
npm publish --dry-run
|
||||
set +e
|
||||
VERIFY_OUTPUT=$(npm publish --dry-run 2>&1)
|
||||
VERIFY_EXIT=$?
|
||||
set -e
|
||||
echo "$VERIFY_OUTPUT"
|
||||
if [ $VERIFY_EXIT -ne 0 ]; then
|
||||
if echo "$VERIFY_OUTPUT" | grep -q "You cannot publish over the previously published versions"; then
|
||||
echo "⚠️ npm publish --dry-run skipped: version already published"
|
||||
else
|
||||
echo "❌ npm publish --dry-run failed"
|
||||
exit $VERIFY_EXIT
|
||||
fi
|
||||
fi
|
||||
echo "📋 Package.json bin configuration:"
|
||||
cat package.json | grep -A 5 -B 5 '"bin"'
|
||||
echo "📁 Build directory contents:"
|
||||
@@ -177,8 +189,21 @@ jobs:
|
||||
- name: Publish to npm
|
||||
run: |
|
||||
cd MCP
|
||||
npm publish --access public
|
||||
echo "✅ Published @oneuptime/mcp-server@${{ steps.version.outputs.version }} to npm"
|
||||
set +e
|
||||
PUBLISH_OUTPUT=$(npm publish --access public 2>&1)
|
||||
PUBLISH_EXIT=$?
|
||||
set -e
|
||||
echo "$PUBLISH_OUTPUT"
|
||||
if [ $PUBLISH_EXIT -ne 0 ]; then
|
||||
if echo "$PUBLISH_OUTPUT" | grep -q "You cannot publish over the previously published versions"; then
|
||||
echo "⚠️ npm publish skipped: version already published"
|
||||
else
|
||||
echo "❌ npm publish failed"
|
||||
exit $PUBLISH_EXIT
|
||||
fi
|
||||
else
|
||||
echo "✅ Published @oneuptime/mcp-server@${{ steps.version.outputs.version }} to npm"
|
||||
fi
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
@@ -205,13 +230,26 @@ jobs:
|
||||
timeout_minutes: 45
|
||||
max_attempts: 3
|
||||
command: |
|
||||
VERSION="${{ steps.version.outputs.version }}"
|
||||
docker buildx build \
|
||||
--no-cache \
|
||||
--platform linux/amd64,linux/arm64 \
|
||||
--file ./MCP/Dockerfile.tpl \
|
||||
--tag oneuptime/mcp-server:${{ steps.version.outputs.version }} \
|
||||
--tag ghcr.io/oneuptime/mcp-server:${{ steps.version.outputs.version }} \
|
||||
--tag oneuptime/mcp-server:${VERSION} \
|
||||
--tag ghcr.io/oneuptime/mcp-server:${VERSION} \
|
||||
--build-arg GIT_SHA=${{ github.sha }} \
|
||||
--build-arg APP_VERSION=${{ steps.version.outputs.version }} \
|
||||
--build-arg APP_VERSION=${VERSION} \
|
||||
--build-arg IS_ENTERPRISE_EDITION=false \
|
||||
--push .
|
||||
docker buildx build \
|
||||
--no-cache \
|
||||
--platform linux/amd64,linux/arm64 \
|
||||
--file ./MCP/Dockerfile.tpl \
|
||||
--tag oneuptime/mcp-server:enterprise-${VERSION} \
|
||||
--tag ghcr.io/oneuptime/mcp-server:enterprise-${VERSION} \
|
||||
--build-arg GIT_SHA=${{ github.sha }} \
|
||||
--build-arg APP_VERSION=${VERSION} \
|
||||
--build-arg IS_ENTERPRISE_EDITION=true \
|
||||
--push .
|
||||
echo "✅ Pushed Docker images to Docker Hub and GitHub Container Registry"
|
||||
|
||||
@@ -282,14 +320,28 @@ jobs:
|
||||
timeout_minutes: 45
|
||||
max_attempts: 3
|
||||
command: |
|
||||
VERSION="${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}}"
|
||||
docker buildx build \
|
||||
--no-cache \
|
||||
--file ./Nginx/Dockerfile \
|
||||
--platform linux/amd64,linux/arm64 \
|
||||
--push \
|
||||
--tag oneuptime/nginx:${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}} \
|
||||
--tag ghcr.io/oneuptime/nginx:${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}} \
|
||||
--tag oneuptime/nginx:${VERSION} \
|
||||
--tag ghcr.io/oneuptime/nginx:${VERSION} \
|
||||
--build-arg GIT_SHA=${{ github.sha }} \
|
||||
--build-arg APP_VERSION=${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}} \
|
||||
--build-arg APP_VERSION=${VERSION} \
|
||||
--build-arg IS_ENTERPRISE_EDITION=false \
|
||||
.
|
||||
docker buildx build \
|
||||
--no-cache \
|
||||
--file ./Nginx/Dockerfile \
|
||||
--platform linux/amd64,linux/arm64 \
|
||||
--push \
|
||||
--tag oneuptime/nginx:enterprise-${VERSION} \
|
||||
--tag ghcr.io/oneuptime/nginx:enterprise-${VERSION} \
|
||||
--build-arg GIT_SHA=${{ github.sha }} \
|
||||
--build-arg APP_VERSION=${VERSION} \
|
||||
--build-arg IS_ENTERPRISE_EDITION=true \
|
||||
.
|
||||
|
||||
e2e-docker-image-deploy:
|
||||
@@ -352,14 +404,28 @@ jobs:
|
||||
timeout_minutes: 45
|
||||
max_attempts: 3
|
||||
command: |
|
||||
VERSION="${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}}"
|
||||
docker buildx build \
|
||||
--no-cache \
|
||||
--file ./E2E/Dockerfile \
|
||||
--platform linux/amd64,linux/arm64 \
|
||||
--push \
|
||||
--tag oneuptime/e2e:${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}} \
|
||||
--tag ghcr.io/oneuptime/e2e:${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}} \
|
||||
--tag oneuptime/e2e:${VERSION} \
|
||||
--tag ghcr.io/oneuptime/e2e:${VERSION} \
|
||||
--build-arg GIT_SHA=${{ github.sha }} \
|
||||
--build-arg APP_VERSION=${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}} \
|
||||
--build-arg APP_VERSION=${VERSION} \
|
||||
--build-arg IS_ENTERPRISE_EDITION=false \
|
||||
.
|
||||
docker buildx build \
|
||||
--no-cache \
|
||||
--file ./E2E/Dockerfile \
|
||||
--platform linux/amd64,linux/arm64 \
|
||||
--push \
|
||||
--tag oneuptime/e2e:enterprise-${VERSION} \
|
||||
--tag ghcr.io/oneuptime/e2e:enterprise-${VERSION} \
|
||||
--build-arg GIT_SHA=${{ github.sha }} \
|
||||
--build-arg APP_VERSION=${VERSION} \
|
||||
--build-arg IS_ENTERPRISE_EDITION=true \
|
||||
.
|
||||
|
||||
isolated-vm-docker-image-deploy:
|
||||
@@ -422,14 +488,28 @@ jobs:
|
||||
timeout_minutes: 45
|
||||
max_attempts: 3
|
||||
command: |
|
||||
VERSION="${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}}"
|
||||
docker buildx build \
|
||||
--no-cache \
|
||||
--file ./IsolatedVM/Dockerfile \
|
||||
--platform linux/amd64,linux/arm64 \
|
||||
--push \
|
||||
--tag oneuptime/isolated-vm:${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}} \
|
||||
--tag ghcr.io/oneuptime/isolated-vm:${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}} \
|
||||
--tag oneuptime/isolated-vm:${VERSION} \
|
||||
--tag ghcr.io/oneuptime/isolated-vm:${VERSION} \
|
||||
--build-arg GIT_SHA=${{ github.sha }} \
|
||||
--build-arg APP_VERSION=${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}} \
|
||||
--build-arg APP_VERSION=${VERSION} \
|
||||
--build-arg IS_ENTERPRISE_EDITION=false \
|
||||
.
|
||||
docker buildx build \
|
||||
--no-cache \
|
||||
--file ./IsolatedVM/Dockerfile \
|
||||
--platform linux/amd64,linux/arm64 \
|
||||
--push \
|
||||
--tag oneuptime/isolated-vm:enterprise-${VERSION} \
|
||||
--tag ghcr.io/oneuptime/isolated-vm:enterprise-${VERSION} \
|
||||
--build-arg GIT_SHA=${{ github.sha }} \
|
||||
--build-arg APP_VERSION=${VERSION} \
|
||||
--build-arg IS_ENTERPRISE_EDITION=true \
|
||||
.
|
||||
|
||||
home-docker-image-deploy:
|
||||
@@ -492,14 +572,28 @@ jobs:
|
||||
timeout_minutes: 45
|
||||
max_attempts: 3
|
||||
command: |
|
||||
VERSION="${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}}"
|
||||
docker buildx build \
|
||||
--no-cache \
|
||||
--file ./Home/Dockerfile \
|
||||
--platform linux/amd64,linux/arm64 \
|
||||
--push \
|
||||
--tag oneuptime/home:${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}} \
|
||||
--tag ghcr.io/oneuptime/home:${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}} \
|
||||
--tag oneuptime/home:${VERSION} \
|
||||
--tag ghcr.io/oneuptime/home:${VERSION} \
|
||||
--build-arg GIT_SHA=${{ github.sha }} \
|
||||
--build-arg APP_VERSION=${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}} \
|
||||
--build-arg APP_VERSION=${VERSION} \
|
||||
--build-arg IS_ENTERPRISE_EDITION=false \
|
||||
.
|
||||
docker buildx build \
|
||||
--no-cache \
|
||||
--file ./Home/Dockerfile \
|
||||
--platform linux/amd64,linux/arm64 \
|
||||
--push \
|
||||
--tag oneuptime/home:enterprise-${VERSION} \
|
||||
--tag ghcr.io/oneuptime/home:enterprise-${VERSION} \
|
||||
--build-arg GIT_SHA=${{ github.sha }} \
|
||||
--build-arg APP_VERSION=${VERSION} \
|
||||
--build-arg IS_ENTERPRISE_EDITION=true \
|
||||
.
|
||||
|
||||
|
||||
@@ -565,14 +659,28 @@ jobs:
|
||||
timeout_minutes: 45
|
||||
max_attempts: 3
|
||||
command: |
|
||||
VERSION="${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}}"
|
||||
docker buildx build \
|
||||
--no-cache \
|
||||
--file ./TestServer/Dockerfile \
|
||||
--platform linux/amd64,linux/arm64 \
|
||||
--push \
|
||||
--tag oneuptime/test-server:${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}} \
|
||||
--tag ghcr.io/oneuptime/test-server:${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}} \
|
||||
--tag oneuptime/test-server:${VERSION} \
|
||||
--tag ghcr.io/oneuptime/test-server:${VERSION} \
|
||||
--build-arg GIT_SHA=${{ github.sha }} \
|
||||
--build-arg APP_VERSION=${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}} \
|
||||
--build-arg APP_VERSION=${VERSION} \
|
||||
--build-arg IS_ENTERPRISE_EDITION=false \
|
||||
.
|
||||
docker buildx build \
|
||||
--no-cache \
|
||||
--file ./TestServer/Dockerfile \
|
||||
--platform linux/amd64,linux/arm64 \
|
||||
--push \
|
||||
--tag oneuptime/test-server:enterprise-${VERSION} \
|
||||
--tag ghcr.io/oneuptime/test-server:enterprise-${VERSION} \
|
||||
--build-arg GIT_SHA=${{ github.sha }} \
|
||||
--build-arg APP_VERSION=${VERSION} \
|
||||
--build-arg IS_ENTERPRISE_EDITION=true \
|
||||
.
|
||||
|
||||
otel-collector-docker-image-deploy:
|
||||
@@ -635,14 +743,28 @@ jobs:
|
||||
timeout_minutes: 45
|
||||
max_attempts: 3
|
||||
command: |
|
||||
VERSION="${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}}"
|
||||
docker buildx build \
|
||||
--no-cache \
|
||||
--file ./OTelCollector/Dockerfile \
|
||||
--platform linux/amd64,linux/arm64 \
|
||||
--push \
|
||||
--tag oneuptime/otel-collector:${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}} \
|
||||
--tag ghcr.io/oneuptime/otel-collector:${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}} \
|
||||
--tag oneuptime/otel-collector:${VERSION} \
|
||||
--tag ghcr.io/oneuptime/otel-collector:${VERSION} \
|
||||
--build-arg GIT_SHA=${{ github.sha }} \
|
||||
--build-arg APP_VERSION=${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}} \
|
||||
--build-arg APP_VERSION=${VERSION} \
|
||||
--build-arg IS_ENTERPRISE_EDITION=false \
|
||||
.
|
||||
docker buildx build \
|
||||
--no-cache \
|
||||
--file ./OTelCollector/Dockerfile \
|
||||
--platform linux/amd64,linux/arm64 \
|
||||
--push \
|
||||
--tag oneuptime/otel-collector:enterprise-${VERSION} \
|
||||
--tag ghcr.io/oneuptime/otel-collector:enterprise-${VERSION} \
|
||||
--build-arg GIT_SHA=${{ github.sha }} \
|
||||
--build-arg APP_VERSION=${VERSION} \
|
||||
--build-arg IS_ENTERPRISE_EDITION=true \
|
||||
.
|
||||
|
||||
|
||||
@@ -707,14 +829,28 @@ jobs:
|
||||
timeout_minutes: 45
|
||||
max_attempts: 3
|
||||
command: |
|
||||
VERSION="${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}}"
|
||||
docker buildx build \
|
||||
--no-cache \
|
||||
--file ./StatusPage/Dockerfile \
|
||||
--platform linux/amd64,linux/arm64 \
|
||||
--push \
|
||||
--tag oneuptime/status-page:${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}} \
|
||||
--tag ghcr.io/oneuptime/status-page:${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}} \
|
||||
--tag oneuptime/status-page:${VERSION} \
|
||||
--tag ghcr.io/oneuptime/status-page:${VERSION} \
|
||||
--build-arg GIT_SHA=${{ github.sha }} \
|
||||
--build-arg APP_VERSION=${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}} \
|
||||
--build-arg APP_VERSION=${VERSION} \
|
||||
--build-arg IS_ENTERPRISE_EDITION=false \
|
||||
.
|
||||
docker buildx build \
|
||||
--no-cache \
|
||||
--file ./StatusPage/Dockerfile \
|
||||
--platform linux/amd64,linux/arm64 \
|
||||
--push \
|
||||
--tag oneuptime/status-page:enterprise-${VERSION} \
|
||||
--tag ghcr.io/oneuptime/status-page:enterprise-${VERSION} \
|
||||
--build-arg GIT_SHA=${{ github.sha }} \
|
||||
--build-arg APP_VERSION=${VERSION} \
|
||||
--build-arg IS_ENTERPRISE_EDITION=true \
|
||||
.
|
||||
|
||||
test-docker-image-deploy:
|
||||
@@ -777,14 +913,28 @@ jobs:
|
||||
timeout_minutes: 45
|
||||
max_attempts: 3
|
||||
command: |
|
||||
VERSION="${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}}"
|
||||
docker buildx build \
|
||||
--no-cache \
|
||||
--file ./Tests/Dockerfile \
|
||||
--platform linux/amd64,linux/arm64 \
|
||||
--push \
|
||||
--tag oneuptime/test:${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}} \
|
||||
--tag ghcr.io/oneuptime/test:${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}} \
|
||||
--tag oneuptime/test:${VERSION} \
|
||||
--tag ghcr.io/oneuptime/test:${VERSION} \
|
||||
--build-arg GIT_SHA=${{ github.sha }} \
|
||||
--build-arg APP_VERSION=${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}} \
|
||||
--build-arg APP_VERSION=${VERSION} \
|
||||
--build-arg IS_ENTERPRISE_EDITION=false \
|
||||
.
|
||||
docker buildx build \
|
||||
--no-cache \
|
||||
--file ./Tests/Dockerfile \
|
||||
--platform linux/amd64,linux/arm64 \
|
||||
--push \
|
||||
--tag oneuptime/test:enterprise-${VERSION} \
|
||||
--tag ghcr.io/oneuptime/test:enterprise-${VERSION} \
|
||||
--build-arg GIT_SHA=${{ github.sha }} \
|
||||
--build-arg APP_VERSION=${VERSION} \
|
||||
--build-arg IS_ENTERPRISE_EDITION=true \
|
||||
.
|
||||
|
||||
probe-ingest-docker-image-deploy:
|
||||
@@ -847,14 +997,28 @@ jobs:
|
||||
timeout_minutes: 45
|
||||
max_attempts: 3
|
||||
command: |
|
||||
VERSION="${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}}"
|
||||
docker buildx build \
|
||||
--no-cache \
|
||||
--file ./ProbeIngest/Dockerfile \
|
||||
--platform linux/amd64,linux/arm64 \
|
||||
--push \
|
||||
--tag oneuptime/probe-ingest:${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}} \
|
||||
--tag ghcr.io/oneuptime/probe-ingest:${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}} \
|
||||
--tag oneuptime/probe-ingest:${VERSION} \
|
||||
--tag ghcr.io/oneuptime/probe-ingest:${VERSION} \
|
||||
--build-arg GIT_SHA=${{ github.sha }} \
|
||||
--build-arg APP_VERSION=${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}} \
|
||||
--build-arg APP_VERSION=${VERSION} \
|
||||
--build-arg IS_ENTERPRISE_EDITION=false \
|
||||
.
|
||||
docker buildx build \
|
||||
--no-cache \
|
||||
--file ./ProbeIngest/Dockerfile \
|
||||
--platform linux/amd64,linux/arm64 \
|
||||
--push \
|
||||
--tag oneuptime/probe-ingest:enterprise-${VERSION} \
|
||||
--tag ghcr.io/oneuptime/probe-ingest:enterprise-${VERSION} \
|
||||
--build-arg GIT_SHA=${{ github.sha }} \
|
||||
--build-arg APP_VERSION=${VERSION} \
|
||||
--build-arg IS_ENTERPRISE_EDITION=true \
|
||||
.
|
||||
|
||||
|
||||
@@ -918,19 +1082,33 @@ jobs:
|
||||
timeout_minutes: 45
|
||||
max_attempts: 3
|
||||
command: |
|
||||
VERSION="${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}}"
|
||||
docker buildx build \
|
||||
--no-cache \
|
||||
--file ./ServerMonitorIngest/Dockerfile \
|
||||
--platform linux/amd64,linux/arm64 \
|
||||
--push \
|
||||
--tag oneuptime/server-monitor-ingest:${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}} \
|
||||
--tag ghcr.io/oneuptime/server-monitor-ingest:${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}} \
|
||||
--tag oneuptime/server-monitor-ingest:${VERSION} \
|
||||
--tag ghcr.io/oneuptime/server-monitor-ingest:${VERSION} \
|
||||
--build-arg GIT_SHA=${{ github.sha }} \
|
||||
--build-arg APP_VERSION=${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}} \
|
||||
--build-arg APP_VERSION=${VERSION} \
|
||||
--build-arg IS_ENTERPRISE_EDITION=false \
|
||||
.
|
||||
docker buildx build \
|
||||
--no-cache \
|
||||
--file ./ServerMonitorIngest/Dockerfile \
|
||||
--platform linux/amd64,linux/arm64 \
|
||||
--push \
|
||||
--tag oneuptime/server-monitor-ingest:enterprise-${VERSION} \
|
||||
--tag ghcr.io/oneuptime/server-monitor-ingest:enterprise-${VERSION} \
|
||||
--build-arg GIT_SHA=${{ github.sha }} \
|
||||
--build-arg APP_VERSION=${VERSION} \
|
||||
--build-arg IS_ENTERPRISE_EDITION=true \
|
||||
.
|
||||
|
||||
|
||||
|
||||
open-telemetry-ingest-docker-image-deploy:
|
||||
telemetry-docker-image-deploy:
|
||||
needs: [generate-build-number, read-version]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
@@ -939,8 +1117,8 @@ jobs:
|
||||
uses: docker/metadata-action@v4
|
||||
with:
|
||||
images: |
|
||||
oneuptime/open-telemetry-ingest
|
||||
ghcr.io/oneuptime/open-telemetry-ingest
|
||||
oneuptime/telemetry
|
||||
ghcr.io/oneuptime/telemetry
|
||||
tags: |
|
||||
type=raw,value=release,enable=true
|
||||
type=semver,value=${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}},pattern={{version}},enable=true
|
||||
@@ -966,7 +1144,7 @@ jobs:
|
||||
max_attempts: 3
|
||||
command: npm run prerun
|
||||
|
||||
# Build and deploy open-telemetry-ingest.
|
||||
# Build and deploy telemetry.
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: nick-fields/retry@v3
|
||||
@@ -990,14 +1168,28 @@ jobs:
|
||||
timeout_minutes: 45
|
||||
max_attempts: 3
|
||||
command: |
|
||||
VERSION="${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}}"
|
||||
docker buildx build \
|
||||
--file ./OpenTelemetryIngest/Dockerfile \
|
||||
--no-cache \
|
||||
--file ./Telemetry/Dockerfile \
|
||||
--platform linux/amd64,linux/arm64 \
|
||||
--push \
|
||||
--tag oneuptime/open-telemetry-ingest:${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}} \
|
||||
--tag ghcr.io/oneuptime/open-telemetry-ingest:${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}} \
|
||||
--tag oneuptime/telemetry:${VERSION} \
|
||||
--tag ghcr.io/oneuptime/telemetry:${VERSION} \
|
||||
--build-arg GIT_SHA=${{ github.sha }} \
|
||||
--build-arg APP_VERSION=${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}} \
|
||||
--build-arg APP_VERSION=${VERSION} \
|
||||
--build-arg IS_ENTERPRISE_EDITION=false \
|
||||
.
|
||||
docker buildx build \
|
||||
--no-cache \
|
||||
--file ./Telemetry/Dockerfile \
|
||||
--platform linux/amd64,linux/arm64 \
|
||||
--push \
|
||||
--tag oneuptime/telemetry:enterprise-${VERSION} \
|
||||
--tag ghcr.io/oneuptime/telemetry:enterprise-${VERSION} \
|
||||
--build-arg GIT_SHA=${{ github.sha }} \
|
||||
--build-arg APP_VERSION=${VERSION} \
|
||||
--build-arg IS_ENTERPRISE_EDITION=true \
|
||||
.
|
||||
|
||||
|
||||
@@ -1061,84 +1253,28 @@ jobs:
|
||||
timeout_minutes: 45
|
||||
max_attempts: 3
|
||||
command: |
|
||||
VERSION="${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}}"
|
||||
docker buildx build \
|
||||
--no-cache \
|
||||
--file ./IncomingRequestIngest/Dockerfile \
|
||||
--platform linux/amd64,linux/arm64 \
|
||||
--push \
|
||||
--tag oneuptime/incoming-request-ingest:${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}} \
|
||||
--tag ghcr.io/oneuptime/incoming-request-ingest:${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}} \
|
||||
--tag oneuptime/incoming-request-ingest:${VERSION} \
|
||||
--tag ghcr.io/oneuptime/incoming-request-ingest:${VERSION} \
|
||||
--build-arg GIT_SHA=${{ github.sha }} \
|
||||
--build-arg APP_VERSION=${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}} \
|
||||
--build-arg APP_VERSION=${VERSION} \
|
||||
--build-arg IS_ENTERPRISE_EDITION=false \
|
||||
.
|
||||
|
||||
fluent-ingest-docker-image-deploy:
|
||||
needs: [generate-build-number, read-version]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Docker Meta
|
||||
id: meta
|
||||
uses: docker/metadata-action@v4
|
||||
with:
|
||||
images: |
|
||||
oneuptime/fluent-ingest
|
||||
ghcr.io/oneuptime/fluent-ingest
|
||||
tags: |
|
||||
type=raw,value=release,enable=true
|
||||
type=semver,value=${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}},pattern={{version}},enable=true
|
||||
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.ref }}
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: latest
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v2
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
|
||||
- name: Generate Dockerfile from Dockerfile.tpl
|
||||
uses: nick-fields/retry@v3
|
||||
with:
|
||||
timeout_minutes: 10
|
||||
max_attempts: 3
|
||||
command: npm run prerun
|
||||
|
||||
# Build and deploy fluent-ingest.
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: nick-fields/retry@v3
|
||||
with:
|
||||
timeout_minutes: 5
|
||||
max_attempts: 3
|
||||
command: |
|
||||
echo "${{ secrets.DOCKERHUB_PASSWORD }}" | docker login --username "${{ secrets.DOCKERHUB_USERNAME }}" --password-stdin
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: nick-fields/retry@v3
|
||||
with:
|
||||
timeout_minutes: 5
|
||||
max_attempts: 3
|
||||
command: |
|
||||
echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io --username "${{ github.repository_owner }}" --password-stdin
|
||||
|
||||
- name: Build and push
|
||||
uses: nick-fields/retry@v3
|
||||
with:
|
||||
timeout_minutes: 45
|
||||
max_attempts: 3
|
||||
command: |
|
||||
docker buildx build \
|
||||
--file ./FluentIngest/Dockerfile \
|
||||
--no-cache \
|
||||
--file ./IncomingRequestIngest/Dockerfile \
|
||||
--platform linux/amd64,linux/arm64 \
|
||||
--push \
|
||||
--tag oneuptime/fluent-ingest:${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}} \
|
||||
--tag ghcr.io/oneuptime/fluent-ingest:${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}} \
|
||||
--tag oneuptime/incoming-request-ingest:enterprise-${VERSION} \
|
||||
--tag ghcr.io/oneuptime/incoming-request-ingest:enterprise-${VERSION} \
|
||||
--build-arg GIT_SHA=${{ github.sha }} \
|
||||
--build-arg APP_VERSION=${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}} \
|
||||
--build-arg APP_VERSION=${VERSION} \
|
||||
--build-arg IS_ENTERPRISE_EDITION=true \
|
||||
.
|
||||
|
||||
probe-docker-image-deploy:
|
||||
@@ -1201,14 +1337,28 @@ jobs:
|
||||
timeout_minutes: 45
|
||||
max_attempts: 3
|
||||
command: |
|
||||
VERSION="${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}}"
|
||||
docker buildx build \
|
||||
--no-cache \
|
||||
--file ./Probe/Dockerfile \
|
||||
--platform linux/amd64,linux/arm64 \
|
||||
--push \
|
||||
--tag oneuptime/probe:${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}} \
|
||||
--tag ghcr.io/oneuptime/probe:${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}} \
|
||||
--tag oneuptime/probe:${VERSION} \
|
||||
--tag ghcr.io/oneuptime/probe:${VERSION} \
|
||||
--build-arg GIT_SHA=${{ github.sha }} \
|
||||
--build-arg APP_VERSION=${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}} \
|
||||
--build-arg APP_VERSION=${VERSION} \
|
||||
--build-arg IS_ENTERPRISE_EDITION=false \
|
||||
.
|
||||
docker buildx build \
|
||||
--no-cache \
|
||||
--file ./Probe/Dockerfile \
|
||||
--platform linux/amd64,linux/arm64 \
|
||||
--push \
|
||||
--tag oneuptime/probe:enterprise-${VERSION} \
|
||||
--tag ghcr.io/oneuptime/probe:enterprise-${VERSION} \
|
||||
--build-arg GIT_SHA=${{ github.sha }} \
|
||||
--build-arg APP_VERSION=${VERSION} \
|
||||
--build-arg IS_ENTERPRISE_EDITION=true \
|
||||
.
|
||||
|
||||
admin-dashboard-docker-image-deploy:
|
||||
@@ -1271,14 +1421,28 @@ jobs:
|
||||
timeout_minutes: 45
|
||||
max_attempts: 3
|
||||
command: |
|
||||
VERSION="${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}}"
|
||||
docker buildx build \
|
||||
--no-cache \
|
||||
--file ./AdminDashboard/Dockerfile \
|
||||
--platform linux/amd64,linux/arm64 \
|
||||
--push \
|
||||
--tag oneuptime/admin-dashboard:${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}} \
|
||||
--tag ghcr.io/oneuptime/admin-dashboard:${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}} \
|
||||
--tag oneuptime/admin-dashboard:${VERSION} \
|
||||
--tag ghcr.io/oneuptime/admin-dashboard:${VERSION} \
|
||||
--build-arg GIT_SHA=${{ github.sha }} \
|
||||
--build-arg APP_VERSION=${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}} \
|
||||
--build-arg APP_VERSION=${VERSION} \
|
||||
--build-arg IS_ENTERPRISE_EDITION=false \
|
||||
.
|
||||
docker buildx build \
|
||||
--no-cache \
|
||||
--file ./AdminDashboard/Dockerfile \
|
||||
--platform linux/amd64,linux/arm64 \
|
||||
--push \
|
||||
--tag oneuptime/admin-dashboard:enterprise-${VERSION} \
|
||||
--tag ghcr.io/oneuptime/admin-dashboard:enterprise-${VERSION} \
|
||||
--build-arg GIT_SHA=${{ github.sha }} \
|
||||
--build-arg APP_VERSION=${VERSION} \
|
||||
--build-arg IS_ENTERPRISE_EDITION=true \
|
||||
.
|
||||
|
||||
|
||||
@@ -1342,14 +1506,28 @@ jobs:
|
||||
timeout_minutes: 45
|
||||
max_attempts: 3
|
||||
command: |
|
||||
VERSION="${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}}"
|
||||
docker buildx build \
|
||||
--no-cache \
|
||||
--file ./Dashboard/Dockerfile \
|
||||
--platform linux/amd64,linux/arm64 \
|
||||
--push \
|
||||
--tag oneuptime/dashboard:${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}} \
|
||||
--tag ghcr.io/oneuptime/dashboard:${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}} \
|
||||
--tag oneuptime/dashboard:${VERSION} \
|
||||
--tag ghcr.io/oneuptime/dashboard:${VERSION} \
|
||||
--build-arg GIT_SHA=${{ github.sha }} \
|
||||
--build-arg APP_VERSION=${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}} \
|
||||
--build-arg APP_VERSION=${VERSION} \
|
||||
--build-arg IS_ENTERPRISE_EDITION=false \
|
||||
.
|
||||
docker buildx build \
|
||||
--no-cache \
|
||||
--file ./Dashboard/Dockerfile \
|
||||
--platform linux/amd64,linux/arm64 \
|
||||
--push \
|
||||
--tag oneuptime/dashboard:enterprise-${VERSION} \
|
||||
--tag ghcr.io/oneuptime/dashboard:enterprise-${VERSION} \
|
||||
--build-arg GIT_SHA=${{ github.sha }} \
|
||||
--build-arg APP_VERSION=${VERSION} \
|
||||
--build-arg IS_ENTERPRISE_EDITION=true \
|
||||
.
|
||||
|
||||
app-docker-image-deploy:
|
||||
@@ -1412,14 +1590,28 @@ jobs:
|
||||
timeout_minutes: 45
|
||||
max_attempts: 3
|
||||
command: |
|
||||
VERSION="${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}}"
|
||||
docker buildx build \
|
||||
--no-cache \
|
||||
--file ./App/Dockerfile \
|
||||
--platform linux/amd64,linux/arm64 \
|
||||
--push \
|
||||
--tag oneuptime/app:${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}} \
|
||||
--tag ghcr.io/oneuptime/app:${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}} \
|
||||
--tag oneuptime/app:${VERSION} \
|
||||
--tag ghcr.io/oneuptime/app:${VERSION} \
|
||||
--build-arg GIT_SHA=${{ github.sha }} \
|
||||
--build-arg APP_VERSION=${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}} \
|
||||
--build-arg APP_VERSION=${VERSION} \
|
||||
--build-arg IS_ENTERPRISE_EDITION=false \
|
||||
.
|
||||
docker buildx build \
|
||||
--no-cache \
|
||||
--file ./App/Dockerfile \
|
||||
--platform linux/amd64,linux/arm64 \
|
||||
--push \
|
||||
--tag oneuptime/app:enterprise-${VERSION} \
|
||||
--tag ghcr.io/oneuptime/app:enterprise-${VERSION} \
|
||||
--build-arg GIT_SHA=${{ github.sha }} \
|
||||
--build-arg APP_VERSION=${VERSION} \
|
||||
--build-arg IS_ENTERPRISE_EDITION=true \
|
||||
.
|
||||
|
||||
|
||||
@@ -1483,14 +1675,28 @@ jobs:
|
||||
timeout_minutes: 45
|
||||
max_attempts: 3
|
||||
command: |
|
||||
VERSION="${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}}"
|
||||
docker buildx build \
|
||||
--no-cache \
|
||||
--file ./Copilot/Dockerfile \
|
||||
--platform linux/amd64,linux/arm64 \
|
||||
--push \
|
||||
--tag oneuptime/copilot:${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}} \
|
||||
--tag ghcr.io/oneuptime/copilot:${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}} \
|
||||
--tag oneuptime/copilot:${VERSION} \
|
||||
--tag ghcr.io/oneuptime/copilot:${VERSION} \
|
||||
--build-arg GIT_SHA=${{ github.sha }} \
|
||||
--build-arg APP_VERSION=${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}} \
|
||||
--build-arg APP_VERSION=${VERSION} \
|
||||
--build-arg IS_ENTERPRISE_EDITION=false \
|
||||
.
|
||||
docker buildx build \
|
||||
--no-cache \
|
||||
--file ./Copilot/Dockerfile \
|
||||
--platform linux/amd64,linux/arm64 \
|
||||
--push \
|
||||
--tag oneuptime/copilot:enterprise-${VERSION} \
|
||||
--tag ghcr.io/oneuptime/copilot:enterprise-${VERSION} \
|
||||
--build-arg GIT_SHA=${{ github.sha }} \
|
||||
--build-arg APP_VERSION=${VERSION} \
|
||||
--build-arg IS_ENTERPRISE_EDITION=true \
|
||||
.
|
||||
|
||||
accounts-docker-image-deploy:
|
||||
@@ -1553,14 +1759,28 @@ jobs:
|
||||
timeout_minutes: 45
|
||||
max_attempts: 3
|
||||
command: |
|
||||
VERSION="${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}}"
|
||||
docker buildx build \
|
||||
--no-cache \
|
||||
--file ./Accounts/Dockerfile \
|
||||
--platform linux/amd64,linux/arm64 \
|
||||
--push \
|
||||
--tag oneuptime/accounts:${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}} \
|
||||
--tag ghcr.io/oneuptime/accounts:${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}} \
|
||||
--tag oneuptime/accounts:${VERSION} \
|
||||
--tag ghcr.io/oneuptime/accounts:${VERSION} \
|
||||
--build-arg GIT_SHA=${{ github.sha }} \
|
||||
--build-arg APP_VERSION=${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}} \
|
||||
--build-arg APP_VERSION=${VERSION} \
|
||||
--build-arg IS_ENTERPRISE_EDITION=false \
|
||||
.
|
||||
docker buildx build \
|
||||
--no-cache \
|
||||
--file ./Accounts/Dockerfile \
|
||||
--platform linux/amd64,linux/arm64 \
|
||||
--push \
|
||||
--tag oneuptime/accounts:enterprise-${VERSION} \
|
||||
--tag ghcr.io/oneuptime/accounts:enterprise-${VERSION} \
|
||||
--build-arg GIT_SHA=${{ github.sha }} \
|
||||
--build-arg APP_VERSION=${VERSION} \
|
||||
--build-arg IS_ENTERPRISE_EDITION=true \
|
||||
.
|
||||
|
||||
|
||||
@@ -1667,14 +1887,28 @@ jobs:
|
||||
timeout_minutes: 45
|
||||
max_attempts: 3
|
||||
command: |
|
||||
VERSION="${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}}"
|
||||
docker buildx build \
|
||||
--no-cache \
|
||||
--file ./LLM/Dockerfile \
|
||||
--platform linux/amd64 \
|
||||
--push \
|
||||
--tag oneuptime/llm:${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}} \
|
||||
--tag ghcr.io/oneuptime/llm:${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}} \
|
||||
--tag oneuptime/llm:${VERSION} \
|
||||
--tag ghcr.io/oneuptime/llm:${VERSION} \
|
||||
--build-arg GIT_SHA=${{ github.sha }} \
|
||||
--build-arg APP_VERSION=${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}} \
|
||||
--build-arg APP_VERSION=${VERSION} \
|
||||
--build-arg IS_ENTERPRISE_EDITION=false \
|
||||
./LLM
|
||||
docker buildx build \
|
||||
--no-cache \
|
||||
--file ./LLM/Dockerfile \
|
||||
--platform linux/amd64 \
|
||||
--push \
|
||||
--tag oneuptime/llm:enterprise-${VERSION} \
|
||||
--tag ghcr.io/oneuptime/llm:enterprise-${VERSION} \
|
||||
--build-arg GIT_SHA=${{ github.sha }} \
|
||||
--build-arg APP_VERSION=${VERSION} \
|
||||
--build-arg IS_ENTERPRISE_EDITION=true \
|
||||
./LLM
|
||||
|
||||
docs-docker-image-deploy:
|
||||
@@ -1739,14 +1973,28 @@ jobs:
|
||||
timeout_minutes: 45
|
||||
max_attempts: 3
|
||||
command: |
|
||||
VERSION="${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}}"
|
||||
docker buildx build \
|
||||
--no-cache \
|
||||
--file ./Docs/Dockerfile \
|
||||
--platform linux/amd64,linux/arm64 \
|
||||
--push \
|
||||
--tag oneuptime/docs:${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}} \
|
||||
--tag ghcr.io/oneuptime/docs:${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}} \
|
||||
--tag oneuptime/docs:${VERSION} \
|
||||
--tag ghcr.io/oneuptime/docs:${VERSION} \
|
||||
--build-arg GIT_SHA=${{ github.sha }} \
|
||||
--build-arg APP_VERSION=${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}} \
|
||||
--build-arg APP_VERSION=${VERSION} \
|
||||
--build-arg IS_ENTERPRISE_EDITION=false \
|
||||
.
|
||||
docker buildx build \
|
||||
--no-cache \
|
||||
--file ./Docs/Dockerfile \
|
||||
--platform linux/amd64,linux/arm64 \
|
||||
--push \
|
||||
--tag oneuptime/docs:enterprise-${VERSION} \
|
||||
--tag ghcr.io/oneuptime/docs:enterprise-${VERSION} \
|
||||
--build-arg GIT_SHA=${{ github.sha }} \
|
||||
--build-arg APP_VERSION=${VERSION} \
|
||||
--build-arg IS_ENTERPRISE_EDITION=true \
|
||||
.
|
||||
|
||||
|
||||
@@ -1814,14 +2062,28 @@ jobs:
|
||||
timeout_minutes: 45
|
||||
max_attempts: 3
|
||||
command: |
|
||||
VERSION="${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}}"
|
||||
docker buildx build \
|
||||
--no-cache \
|
||||
--file ./Worker/Dockerfile \
|
||||
--platform linux/amd64,linux/arm64 \
|
||||
--push \
|
||||
--tag oneuptime/worker:${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}} \
|
||||
--tag ghcr.io/oneuptime/worker:${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}} \
|
||||
--tag oneuptime/worker:${VERSION} \
|
||||
--tag ghcr.io/oneuptime/worker:${VERSION} \
|
||||
--build-arg GIT_SHA=${{ github.sha }} \
|
||||
--build-arg APP_VERSION=${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}} \
|
||||
--build-arg APP_VERSION=${VERSION} \
|
||||
--build-arg IS_ENTERPRISE_EDITION=false \
|
||||
.
|
||||
docker buildx build \
|
||||
--no-cache \
|
||||
--file ./Worker/Dockerfile \
|
||||
--platform linux/amd64,linux/arm64 \
|
||||
--push \
|
||||
--tag oneuptime/worker:enterprise-${VERSION} \
|
||||
--tag ghcr.io/oneuptime/worker:enterprise-${VERSION} \
|
||||
--build-arg GIT_SHA=${{ github.sha }} \
|
||||
--build-arg APP_VERSION=${VERSION} \
|
||||
--build-arg IS_ENTERPRISE_EDITION=true \
|
||||
.
|
||||
|
||||
|
||||
@@ -1889,14 +2151,28 @@ jobs:
|
||||
timeout_minutes: 45
|
||||
max_attempts: 3
|
||||
command: |
|
||||
VERSION="${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}}"
|
||||
docker buildx build \
|
||||
--no-cache \
|
||||
--file ./Workflow/Dockerfile \
|
||||
--platform linux/amd64,linux/arm64 \
|
||||
--push \
|
||||
--tag oneuptime/workflow:${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}} \
|
||||
--tag ghcr.io/oneuptime/workflow:${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}} \
|
||||
--tag oneuptime/workflow:${VERSION} \
|
||||
--tag ghcr.io/oneuptime/workflow:${VERSION} \
|
||||
--build-arg GIT_SHA=${{ github.sha }} \
|
||||
--build-arg APP_VERSION=${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}} \
|
||||
--build-arg APP_VERSION=${VERSION} \
|
||||
--build-arg IS_ENTERPRISE_EDITION=false \
|
||||
.
|
||||
docker buildx build \
|
||||
--no-cache \
|
||||
--file ./Workflow/Dockerfile \
|
||||
--platform linux/amd64,linux/arm64 \
|
||||
--push \
|
||||
--tag oneuptime/workflow:enterprise-${VERSION} \
|
||||
--tag ghcr.io/oneuptime/workflow:enterprise-${VERSION} \
|
||||
--build-arg GIT_SHA=${{ github.sha }} \
|
||||
--build-arg APP_VERSION=${VERSION} \
|
||||
--build-arg IS_ENTERPRISE_EDITION=true \
|
||||
.
|
||||
|
||||
|
||||
@@ -2024,14 +2300,28 @@ jobs:
|
||||
timeout_minutes: 45
|
||||
max_attempts: 3
|
||||
command: |
|
||||
VERSION="${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}}"
|
||||
docker buildx build \
|
||||
--no-cache \
|
||||
--file ./APIReference/Dockerfile \
|
||||
--platform linux/amd64,linux/arm64 \
|
||||
--push \
|
||||
--tag oneuptime/api-reference:${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}} \
|
||||
--tag ghcr.io/oneuptime/api-reference:${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}} \
|
||||
--tag oneuptime/api-reference:${VERSION} \
|
||||
--tag ghcr.io/oneuptime/api-reference:${VERSION} \
|
||||
--build-arg GIT_SHA=${{ github.sha }} \
|
||||
--build-arg APP_VERSION=${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}} \
|
||||
--build-arg APP_VERSION=${VERSION} \
|
||||
--build-arg IS_ENTERPRISE_EDITION=false \
|
||||
.
|
||||
docker buildx build \
|
||||
--no-cache \
|
||||
--file ./APIReference/Dockerfile \
|
||||
--platform linux/amd64,linux/arm64 \
|
||||
--push \
|
||||
--tag oneuptime/api-reference:enterprise-${VERSION} \
|
||||
--tag ghcr.io/oneuptime/api-reference:enterprise-${VERSION} \
|
||||
--build-arg GIT_SHA=${{ github.sha }} \
|
||||
--build-arg APP_VERSION=${VERSION} \
|
||||
--build-arg IS_ENTERPRISE_EDITION=true \
|
||||
.
|
||||
|
||||
push-release-tags:
|
||||
@@ -2050,9 +2340,8 @@ jobs:
|
||||
- test-docker-image-deploy
|
||||
- probe-ingest-docker-image-deploy
|
||||
- server-monitor-ingest-docker-image-deploy
|
||||
- open-telemetry-ingest-docker-image-deploy
|
||||
- telemetry-docker-image-deploy
|
||||
- incoming-request-ingest-docker-image-deploy
|
||||
- fluent-ingest-docker-image-deploy
|
||||
- probe-docker-image-deploy
|
||||
- admin-dashboard-docker-image-deploy
|
||||
- dashboard-docker-image-deploy
|
||||
@@ -2082,9 +2371,8 @@ jobs:
|
||||
"test",
|
||||
"probe-ingest",
|
||||
"server-monitor-ingest",
|
||||
"open-telemetry-ingest",
|
||||
"telemetry",
|
||||
"incoming-request-ingest",
|
||||
"fluent-ingest",
|
||||
"probe",
|
||||
"admin-dashboard",
|
||||
"dashboard",
|
||||
@@ -2122,7 +2410,7 @@ jobs:
|
||||
VERSION="${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}}"
|
||||
docker buildx imagetools create \
|
||||
--tag oneuptime/${{ matrix.image }}:release \
|
||||
oneuptime/${{ matrix.image }}:${VERSION}
|
||||
ghcr.io/oneuptime/${{ matrix.image }}:${VERSION}
|
||||
|
||||
- name: Create GHCR release tag from version
|
||||
run: |
|
||||
@@ -2130,13 +2418,27 @@ jobs:
|
||||
docker buildx imagetools create \
|
||||
--tag ghcr.io/oneuptime/${{ matrix.image }}:release \
|
||||
ghcr.io/oneuptime/${{ matrix.image }}:${VERSION}
|
||||
|
||||
- name: Create Docker Hub enterprise release tag from version
|
||||
run: |
|
||||
VERSION="${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}}"
|
||||
docker buildx imagetools create \
|
||||
--tag oneuptime/${{ matrix.image }}:enterprise-release \
|
||||
ghcr.io/oneuptime/${{ matrix.image }}:enterprise-${VERSION}
|
||||
|
||||
- name: Create GHCR enterprise release tag from version
|
||||
run: |
|
||||
VERSION="${{needs.read-version.outputs.major_minor}}.${{needs.generate-build-number.outputs.build_number}}"
|
||||
docker buildx imagetools create \
|
||||
--tag ghcr.io/oneuptime/${{ matrix.image }}:enterprise-release \
|
||||
ghcr.io/oneuptime/${{ matrix.image }}:enterprise-${VERSION}
|
||||
|
||||
|
||||
|
||||
|
||||
test-e2e-release-saas:
|
||||
runs-on: ubuntu-latest
|
||||
needs: [open-telemetry-ingest-docker-image-deploy, publish-mcp-server, copilot-docker-image-deploy, fluent-ingest-docker-image-deploy, docs-docker-image-deploy, api-reference-docker-image-deploy, workflow-docker-image-deploy, llm-docker-image-deploy, accounts-docker-image-deploy, admin-dashboard-docker-image-deploy, app-docker-image-deploy, dashboard-docker-image-deploy, probe-ingest-docker-image-deploy, server-monitor-ingest-docker-image-deploy, isolated-vm-docker-image-deploy, home-docker-image-deploy, worker-docker-image-deploy, otel-collector-docker-image-deploy, probe-docker-image-deploy, status-page-docker-image-deploy, test-docker-image-deploy, test-server-docker-image-deploy, publish-npm-packages, e2e-docker-image-deploy, helm-chart-deploy, generate-build-number, read-version, nginx-docker-image-deploy, incoming-request-ingest-docker-image-deploy]
|
||||
needs: [telemetry-docker-image-deploy, publish-mcp-server, copilot-docker-image-deploy, docs-docker-image-deploy, api-reference-docker-image-deploy, workflow-docker-image-deploy, llm-docker-image-deploy, accounts-docker-image-deploy, admin-dashboard-docker-image-deploy, app-docker-image-deploy, dashboard-docker-image-deploy, probe-ingest-docker-image-deploy, server-monitor-ingest-docker-image-deploy, isolated-vm-docker-image-deploy, home-docker-image-deploy, worker-docker-image-deploy, otel-collector-docker-image-deploy, probe-docker-image-deploy, status-page-docker-image-deploy, test-docker-image-deploy, test-server-docker-image-deploy, publish-npm-packages, e2e-docker-image-deploy, helm-chart-deploy, generate-build-number, read-version, nginx-docker-image-deploy, incoming-request-ingest-docker-image-deploy]
|
||||
env:
|
||||
CI_PIPELINE_ID: ${{github.run_number}}
|
||||
steps:
|
||||
@@ -2223,7 +2525,7 @@ jobs:
|
||||
test-e2e-release-self-hosted:
|
||||
runs-on: ubuntu-latest
|
||||
# After all the jobs runs
|
||||
needs: [open-telemetry-ingest-docker-image-deploy, publish-mcp-server, copilot-docker-image-deploy, incoming-request-ingest-docker-image-deploy, fluent-ingest-docker-image-deploy, docs-docker-image-deploy, api-reference-docker-image-deploy, workflow-docker-image-deploy, llm-docker-image-deploy, accounts-docker-image-deploy, admin-dashboard-docker-image-deploy, app-docker-image-deploy, dashboard-docker-image-deploy, probe-ingest-docker-image-deploy, server-monitor-ingest-docker-image-deploy, isolated-vm-docker-image-deploy, home-docker-image-deploy, worker-docker-image-deploy, otel-collector-docker-image-deploy, probe-docker-image-deploy, status-page-docker-image-deploy, test-docker-image-deploy, test-server-docker-image-deploy, publish-npm-packages, e2e-docker-image-deploy, helm-chart-deploy, generate-build-number, read-version, nginx-docker-image-deploy]
|
||||
needs: [telemetry-docker-image-deploy, publish-mcp-server, copilot-docker-image-deploy, incoming-request-ingest-docker-image-deploy, docs-docker-image-deploy, api-reference-docker-image-deploy, workflow-docker-image-deploy, llm-docker-image-deploy, accounts-docker-image-deploy, admin-dashboard-docker-image-deploy, app-docker-image-deploy, dashboard-docker-image-deploy, probe-ingest-docker-image-deploy, server-monitor-ingest-docker-image-deploy, isolated-vm-docker-image-deploy, home-docker-image-deploy, worker-docker-image-deploy, otel-collector-docker-image-deploy, probe-docker-image-deploy, status-page-docker-image-deploy, test-docker-image-deploy, test-server-docker-image-deploy, publish-npm-packages, e2e-docker-image-deploy, helm-chart-deploy, generate-build-number, read-version, nginx-docker-image-deploy]
|
||||
env:
|
||||
CI_PIPELINE_ID: ${{github.run_number}}
|
||||
steps:
|
||||
|
||||
698
.github/workflows/test-release.yaml
vendored
698
.github/workflows/test-release.yaml
vendored
File diff suppressed because it is too large
Load Diff
20
.github/workflows/test.fluent-ingest.yaml
vendored
20
.github/workflows/test.fluent-ingest.yaml
vendored
@@ -1,20 +0,0 @@
|
||||
name: Fluent Ingest Test
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
branches-ignore:
|
||||
- 'hotfix-*' # excludes hotfix branches
|
||||
- 'release'
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
CI_PIPELINE_ID: ${{github.run_number}}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: latest
|
||||
- run: cd FluentIngest && npm install && npm run test
|
||||
@@ -1,4 +1,4 @@
|
||||
name: OpenTelemetryIngest Test
|
||||
name: Telemetry Test
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
@@ -17,5 +17,6 @@ jobs:
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: latest
|
||||
- run: cd OpenTelemetryIngest && npm install && npm run test
|
||||
- run: cd Common && npm install
|
||||
- run: cd Telemetry && npm install && npm run test
|
||||
|
||||
18
.vscode/launch.json
vendored
18
.vscode/launch.json
vendored
@@ -205,8 +205,8 @@
|
||||
},
|
||||
{
|
||||
"address": "127.0.0.1",
|
||||
"localRoot": "${workspaceFolder}/OpenTelemetryIngest",
|
||||
"name": "OpenTelemetryIngest: Debug with Docker",
|
||||
"localRoot": "${workspaceFolder}/Telemetry",
|
||||
"name": "Telemetry: Debug with Docker",
|
||||
"port": 9938,
|
||||
"remoteRoot": "/usr/src/app",
|
||||
"request": "attach",
|
||||
@@ -217,20 +217,6 @@
|
||||
"restart": true,
|
||||
"autoAttachChildProcesses": true
|
||||
},
|
||||
{
|
||||
"address": "127.0.0.1",
|
||||
"localRoot": "${workspaceFolder}/FluentIngest",
|
||||
"name": "Fluent Ingest: Debug with Docker",
|
||||
"port": 9937,
|
||||
"remoteRoot": "/usr/src/app",
|
||||
"request": "attach",
|
||||
"skipFiles": [
|
||||
"<node_internals>/**"
|
||||
],
|
||||
"type": "node",
|
||||
"restart": true,
|
||||
"autoAttachChildProcesses": true
|
||||
},
|
||||
{
|
||||
"address": "127.0.0.1",
|
||||
"localRoot": "${workspaceFolder}/IsolatedVM",
|
||||
|
||||
@@ -14,9 +14,11 @@ RUN npm config set fetch-retry-maxtimeout 600000
|
||||
|
||||
ARG GIT_SHA
|
||||
ARG APP_VERSION
|
||||
ARG IS_ENTERPRISE_EDITION=false
|
||||
|
||||
ENV GIT_SHA=${GIT_SHA}
|
||||
ENV APP_VERSION=${APP_VERSION}
|
||||
ENV IS_ENTERPRISE_EDITION=${IS_ENTERPRISE_EDITION}
|
||||
ENV PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1
|
||||
|
||||
|
||||
|
||||
363
APIReference/package-lock.json
generated
363
APIReference/package-lock.json
generated
@@ -31,25 +31,26 @@
|
||||
"@elastic/elasticsearch": "^8.12.1",
|
||||
"@monaco-editor/react": "^4.4.6",
|
||||
"@opentelemetry/api": "^1.9.0",
|
||||
"@opentelemetry/api-logs": "^0.52.1",
|
||||
"@opentelemetry/api-logs": "^0.206.0",
|
||||
"@opentelemetry/context-zone": "^1.25.1",
|
||||
"@opentelemetry/exporter-logs-otlp-http": "^0.52.1",
|
||||
"@opentelemetry/exporter-metrics-otlp-proto": "^0.52.1",
|
||||
"@opentelemetry/exporter-trace-otlp-http": "^0.52.1",
|
||||
"@opentelemetry/exporter-trace-otlp-proto": "^0.52.1",
|
||||
"@opentelemetry/exporter-logs-otlp-http": "^0.207.0",
|
||||
"@opentelemetry/exporter-metrics-otlp-proto": "^0.207.0",
|
||||
"@opentelemetry/exporter-trace-otlp-http": "^0.207.0",
|
||||
"@opentelemetry/exporter-trace-otlp-proto": "^0.207.0",
|
||||
"@opentelemetry/id-generator-aws-xray": "^1.2.2",
|
||||
"@opentelemetry/instrumentation": "^0.52.1",
|
||||
"@opentelemetry/instrumentation-fetch": "^0.52.1",
|
||||
"@opentelemetry/instrumentation-xml-http-request": "^0.52.1",
|
||||
"@opentelemetry/instrumentation": "^0.207.0",
|
||||
"@opentelemetry/instrumentation-fetch": "^0.207.0",
|
||||
"@opentelemetry/instrumentation-xml-http-request": "^0.207.0",
|
||||
"@opentelemetry/resources": "^1.25.1",
|
||||
"@opentelemetry/sdk-logs": "^0.52.1",
|
||||
"@opentelemetry/sdk-logs": "^0.207.0",
|
||||
"@opentelemetry/sdk-metrics": "^1.25.1",
|
||||
"@opentelemetry/sdk-node": "^0.52.1",
|
||||
"@opentelemetry/sdk-trace-node": "^1.25.1",
|
||||
"@opentelemetry/sdk-node": "^0.207.0",
|
||||
"@opentelemetry/sdk-trace-web": "^1.25.1",
|
||||
"@opentelemetry/semantic-conventions": "^1.26.0",
|
||||
"@opentelemetry/semantic-conventions": "^1.37.0",
|
||||
"@remixicon/react": "^4.2.0",
|
||||
"@simplewebauthn/server": "^13.2.2",
|
||||
"@tippyjs/react": "^4.2.6",
|
||||
"@types/archiver": "^6.0.3",
|
||||
"@types/crypto-js": "^4.2.2",
|
||||
"@types/qrcode": "^1.5.5",
|
||||
"@types/react-highlight": "^0.12.8",
|
||||
@@ -58,8 +59,10 @@
|
||||
"@types/web-push": "^3.6.4",
|
||||
"acme-client": "^5.3.0",
|
||||
"airtable": "^0.12.2",
|
||||
"axios": "^1.7.2",
|
||||
"bullmq": "^5.3.3",
|
||||
"archiver": "^7.0.1",
|
||||
"axios": "^1.12.0",
|
||||
"botbuilder": "^4.23.3",
|
||||
"bullmq": "^5.61.0",
|
||||
"cookie-parser": "^1.4.7",
|
||||
"cors": "^2.8.5",
|
||||
"cron-parser": "^4.8.1",
|
||||
@@ -80,26 +83,26 @@
|
||||
"moment": "^2.30.1",
|
||||
"moment-timezone": "^0.5.45",
|
||||
"node-cron": "^3.0.3",
|
||||
"nodemailer": "^6.9.10",
|
||||
"nodemailer": "^7.0.7",
|
||||
"otpauth": "^9.3.1",
|
||||
"pg": "^8.7.3",
|
||||
"playwright": "^1.50.0",
|
||||
"posthog-js": "^1.139.6",
|
||||
"pg": "^8.16.3",
|
||||
"playwright": "^1.56.0",
|
||||
"posthog-js": "^1.275.3",
|
||||
"prop-types": "^15.8.1",
|
||||
"qrcode": "^1.5.3",
|
||||
"react": "^18.3.1",
|
||||
"react-beautiful-dnd": "^13.1.1",
|
||||
"react-big-calendar": "^1.13.0",
|
||||
"react-big-calendar": "^1.19.4",
|
||||
"react-color": "^2.19.3",
|
||||
"react-dom": "^18.3.1",
|
||||
"react-dropzone": "^14.2.2",
|
||||
"react-error-boundary": "^4.0.13",
|
||||
"react-highlight": "^0.15.0",
|
||||
"react-markdown": "^8.0.3",
|
||||
"react-router-dom": "^6.24.1",
|
||||
"react-router-dom": "^6.30.1",
|
||||
"react-select": "^5.4.0",
|
||||
"react-spinners": "^0.14.1",
|
||||
"react-syntax-highlighter": "^15.5.0",
|
||||
"react-syntax-highlighter": "^16.0.0",
|
||||
"react-toggle": "^4.1.3",
|
||||
"reactflow": "^11.11.4",
|
||||
"recharts": "^2.12.7",
|
||||
@@ -111,16 +114,16 @@
|
||||
"socket.io": "^4.7.4",
|
||||
"socket.io-client": "^4.7.5",
|
||||
"stripe": "^10.17.0",
|
||||
"tailwind-merge": "^2.5.2",
|
||||
"tailwind-merge": "^2.6.0",
|
||||
"tippy.js": "^6.3.7",
|
||||
"twilio": "^4.22.0",
|
||||
"typeorm": "^0.3.20",
|
||||
"typeorm": "^0.3.26",
|
||||
"typeorm-extension": "^2.2.13",
|
||||
"universal-cookie": "^7.2.1",
|
||||
"use-async-effect": "^2.2.6",
|
||||
"uuid": "^8.3.2",
|
||||
"web-push": "^3.6.7",
|
||||
"zod": "^3.25.30"
|
||||
"zod": "^3.25.76"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@faker-js/faker": "^8.0.2",
|
||||
@@ -243,89 +246,20 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/code-frame": {
|
||||
"version": "7.23.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz",
|
||||
"integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==",
|
||||
"version": "7.27.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz",
|
||||
"integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/highlight": "^7.23.4",
|
||||
"chalk": "^2.4.2"
|
||||
"@babel/helper-validator-identifier": "^7.27.1",
|
||||
"js-tokens": "^4.0.0",
|
||||
"picocolors": "^1.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/code-frame/node_modules/ansi-styles": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
|
||||
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"color-convert": "^1.9.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/code-frame/node_modules/chalk": {
|
||||
"version": "2.4.2",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
|
||||
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"ansi-styles": "^3.2.1",
|
||||
"escape-string-regexp": "^1.0.5",
|
||||
"supports-color": "^5.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/code-frame/node_modules/color-convert": {
|
||||
"version": "1.9.3",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
|
||||
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"color-name": "1.1.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/code-frame/node_modules/color-name": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
|
||||
"integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@babel/code-frame/node_modules/escape-string-regexp": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
|
||||
"integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/code-frame/node_modules/has-flag": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
|
||||
"integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/code-frame/node_modules/supports-color": {
|
||||
"version": "5.5.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
|
||||
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"has-flag": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/compat-data": {
|
||||
"version": "7.23.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.5.tgz",
|
||||
@@ -501,19 +435,21 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/helper-string-parser": {
|
||||
"version": "7.23.4",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz",
|
||||
"integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==",
|
||||
"version": "7.27.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz",
|
||||
"integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/helper-validator-identifier": {
|
||||
"version": "7.22.20",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz",
|
||||
"integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==",
|
||||
"version": "7.28.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz",
|
||||
"integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
@@ -528,109 +464,28 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/helpers": {
|
||||
"version": "7.23.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.6.tgz",
|
||||
"integrity": "sha512-wCfsbN4nBidDRhpDhvcKlzHWCTlgJYUUdSJfzXb2NuBssDSIjc3xcb+znA7l+zYsFljAcGM0aFkN40cR3lXiGA==",
|
||||
"version": "7.28.4",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.4.tgz",
|
||||
"integrity": "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/template": "^7.22.15",
|
||||
"@babel/traverse": "^7.23.6",
|
||||
"@babel/types": "^7.23.6"
|
||||
"@babel/template": "^7.27.2",
|
||||
"@babel/types": "^7.28.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/highlight": {
|
||||
"version": "7.23.4",
|
||||
"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz",
|
||||
"integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/helper-validator-identifier": "^7.22.20",
|
||||
"chalk": "^2.4.2",
|
||||
"js-tokens": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/highlight/node_modules/ansi-styles": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
|
||||
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"color-convert": "^1.9.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/highlight/node_modules/chalk": {
|
||||
"version": "2.4.2",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
|
||||
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"ansi-styles": "^3.2.1",
|
||||
"escape-string-regexp": "^1.0.5",
|
||||
"supports-color": "^5.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/highlight/node_modules/color-convert": {
|
||||
"version": "1.9.3",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
|
||||
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"color-name": "1.1.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/highlight/node_modules/color-name": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
|
||||
"integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@babel/highlight/node_modules/escape-string-regexp": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
|
||||
"integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/highlight/node_modules/has-flag": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
|
||||
"integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/highlight/node_modules/supports-color": {
|
||||
"version": "5.5.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
|
||||
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"has-flag": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/parser": {
|
||||
"version": "7.23.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.6.tgz",
|
||||
"integrity": "sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==",
|
||||
"version": "7.28.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.5.tgz",
|
||||
"integrity": "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/types": "^7.28.5"
|
||||
},
|
||||
"bin": {
|
||||
"parser": "bin/babel-parser.js"
|
||||
},
|
||||
@@ -801,14 +656,15 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/template": {
|
||||
"version": "7.22.15",
|
||||
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz",
|
||||
"integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==",
|
||||
"version": "7.27.2",
|
||||
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz",
|
||||
"integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/code-frame": "^7.22.13",
|
||||
"@babel/parser": "^7.22.15",
|
||||
"@babel/types": "^7.22.15"
|
||||
"@babel/code-frame": "^7.27.1",
|
||||
"@babel/parser": "^7.27.2",
|
||||
"@babel/types": "^7.27.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
@@ -836,14 +692,14 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/types": {
|
||||
"version": "7.23.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.6.tgz",
|
||||
"integrity": "sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg==",
|
||||
"version": "7.28.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.5.tgz",
|
||||
"integrity": "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-string-parser": "^7.23.4",
|
||||
"@babel/helper-validator-identifier": "^7.22.20",
|
||||
"to-fast-properties": "^2.0.0"
|
||||
"@babel/helper-string-parser": "^7.27.1",
|
||||
"@babel/helper-validator-identifier": "^7.28.5"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
@@ -1760,21 +1616,23 @@
|
||||
}
|
||||
},
|
||||
"node_modules/brace-expansion": {
|
||||
"version": "1.1.11",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
||||
"version": "1.1.12",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
|
||||
"integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"balanced-match": "^1.0.0",
|
||||
"concat-map": "0.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/braces": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
|
||||
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
|
||||
"integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"fill-range": "^7.0.1"
|
||||
"fill-range": "^7.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
@@ -2004,10 +1862,11 @@
|
||||
"integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ=="
|
||||
},
|
||||
"node_modules/cross-spawn": {
|
||||
"version": "7.0.3",
|
||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
|
||||
"integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
|
||||
"version": "7.0.6",
|
||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
|
||||
"integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"path-key": "^3.1.0",
|
||||
"shebang-command": "^2.0.0",
|
||||
@@ -2076,9 +1935,10 @@
|
||||
}
|
||||
},
|
||||
"node_modules/ejs": {
|
||||
"version": "3.1.9",
|
||||
"resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.9.tgz",
|
||||
"integrity": "sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ==",
|
||||
"version": "3.1.10",
|
||||
"resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz",
|
||||
"integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"jake": "^10.8.5"
|
||||
},
|
||||
@@ -2225,9 +2085,10 @@
|
||||
}
|
||||
},
|
||||
"node_modules/filelist/node_modules/brace-expansion": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
|
||||
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
|
||||
"integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"balanced-match": "^1.0.0"
|
||||
}
|
||||
@@ -2244,10 +2105,11 @@
|
||||
}
|
||||
},
|
||||
"node_modules/fill-range": {
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
|
||||
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
|
||||
"version": "7.1.1",
|
||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
|
||||
"integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"to-regex-range": "^5.0.1"
|
||||
},
|
||||
@@ -2542,6 +2404,7 @@
|
||||
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
|
||||
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.12.0"
|
||||
}
|
||||
@@ -3239,13 +3102,15 @@
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
|
||||
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/js-yaml": {
|
||||
"version": "3.14.1",
|
||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
|
||||
"integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
|
||||
"version": "3.14.2",
|
||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz",
|
||||
"integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"argparse": "^1.0.7",
|
||||
"esprima": "^4.0.0"
|
||||
@@ -3398,12 +3263,13 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/micromatch": {
|
||||
"version": "4.0.5",
|
||||
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
|
||||
"integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
|
||||
"version": "4.0.8",
|
||||
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
|
||||
"integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"braces": "^3.0.2",
|
||||
"braces": "^3.0.3",
|
||||
"picomatch": "^2.3.1"
|
||||
},
|
||||
"engines": {
|
||||
@@ -3684,10 +3550,11 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/picocolors": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
|
||||
"integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
|
||||
"dev": true
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
|
||||
"integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/picomatch": {
|
||||
"version": "2.3.1",
|
||||
@@ -4107,20 +3974,12 @@
|
||||
"integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/to-fast-properties": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
|
||||
"integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/to-regex-range": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
||||
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"is-number": "^7.0.0"
|
||||
},
|
||||
|
||||
@@ -108,7 +108,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="[&>:first-child]:mt-0 [&>:last-child]:mb-0">
|
||||
<%- include('../partials/code', {title: "Example Pagination Request", requestUrl: "/api/monitors/get-list?skip=0&limit=3", requestType: "GET", code: pageData.requestCode }) -%>
|
||||
<%- include('../partials/code', {title: "Example Pagination Request", requestUrl: "/api/monitors/get-list?skip=0&limit=3", requestType: "POST", code: pageData.requestCode }) -%>
|
||||
<%- include('../partials/code', {title: "Example Pagination Response" , requestUrl: "", requestType: "", code: pageData.responseCode }) -%>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -14,9 +14,11 @@ RUN npm config set fetch-retry-maxtimeout 600000
|
||||
|
||||
ARG GIT_SHA
|
||||
ARG APP_VERSION
|
||||
ARG IS_ENTERPRISE_EDITION=false
|
||||
|
||||
ENV GIT_SHA=${GIT_SHA}
|
||||
ENV APP_VERSION=${APP_VERSION}
|
||||
ENV IS_ENTERPRISE_EDITION=${IS_ENTERPRISE_EDITION}
|
||||
ENV PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1
|
||||
|
||||
|
||||
|
||||
127
Accounts/package-lock.json
generated
127
Accounts/package-lock.json
generated
@@ -12,7 +12,7 @@
|
||||
"ejs": "^3.1.10",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
"react-router-dom": "^6.23.1",
|
||||
"react-router-dom": "^6.30.1",
|
||||
"use-async-effect": "^2.2.7"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -35,25 +35,26 @@
|
||||
"@elastic/elasticsearch": "^8.12.1",
|
||||
"@monaco-editor/react": "^4.4.6",
|
||||
"@opentelemetry/api": "^1.9.0",
|
||||
"@opentelemetry/api-logs": "^0.52.1",
|
||||
"@opentelemetry/api-logs": "^0.206.0",
|
||||
"@opentelemetry/context-zone": "^1.25.1",
|
||||
"@opentelemetry/exporter-logs-otlp-http": "^0.52.1",
|
||||
"@opentelemetry/exporter-metrics-otlp-proto": "^0.52.1",
|
||||
"@opentelemetry/exporter-trace-otlp-http": "^0.52.1",
|
||||
"@opentelemetry/exporter-trace-otlp-proto": "^0.52.1",
|
||||
"@opentelemetry/exporter-logs-otlp-http": "^0.207.0",
|
||||
"@opentelemetry/exporter-metrics-otlp-proto": "^0.207.0",
|
||||
"@opentelemetry/exporter-trace-otlp-http": "^0.207.0",
|
||||
"@opentelemetry/exporter-trace-otlp-proto": "^0.207.0",
|
||||
"@opentelemetry/id-generator-aws-xray": "^1.2.2",
|
||||
"@opentelemetry/instrumentation": "^0.52.1",
|
||||
"@opentelemetry/instrumentation-fetch": "^0.52.1",
|
||||
"@opentelemetry/instrumentation-xml-http-request": "^0.52.1",
|
||||
"@opentelemetry/instrumentation": "^0.207.0",
|
||||
"@opentelemetry/instrumentation-fetch": "^0.207.0",
|
||||
"@opentelemetry/instrumentation-xml-http-request": "^0.207.0",
|
||||
"@opentelemetry/resources": "^1.25.1",
|
||||
"@opentelemetry/sdk-logs": "^0.52.1",
|
||||
"@opentelemetry/sdk-logs": "^0.207.0",
|
||||
"@opentelemetry/sdk-metrics": "^1.25.1",
|
||||
"@opentelemetry/sdk-node": "^0.52.1",
|
||||
"@opentelemetry/sdk-trace-node": "^1.25.1",
|
||||
"@opentelemetry/sdk-node": "^0.207.0",
|
||||
"@opentelemetry/sdk-trace-web": "^1.25.1",
|
||||
"@opentelemetry/semantic-conventions": "^1.26.0",
|
||||
"@opentelemetry/semantic-conventions": "^1.37.0",
|
||||
"@remixicon/react": "^4.2.0",
|
||||
"@simplewebauthn/server": "^13.2.2",
|
||||
"@tippyjs/react": "^4.2.6",
|
||||
"@types/archiver": "^6.0.3",
|
||||
"@types/crypto-js": "^4.2.2",
|
||||
"@types/qrcode": "^1.5.5",
|
||||
"@types/react-highlight": "^0.12.8",
|
||||
@@ -62,8 +63,10 @@
|
||||
"@types/web-push": "^3.6.4",
|
||||
"acme-client": "^5.3.0",
|
||||
"airtable": "^0.12.2",
|
||||
"axios": "^1.7.2",
|
||||
"bullmq": "^5.3.3",
|
||||
"archiver": "^7.0.1",
|
||||
"axios": "^1.12.0",
|
||||
"botbuilder": "^4.23.3",
|
||||
"bullmq": "^5.61.0",
|
||||
"cookie-parser": "^1.4.7",
|
||||
"cors": "^2.8.5",
|
||||
"cron-parser": "^4.8.1",
|
||||
@@ -84,26 +87,26 @@
|
||||
"moment": "^2.30.1",
|
||||
"moment-timezone": "^0.5.45",
|
||||
"node-cron": "^3.0.3",
|
||||
"nodemailer": "^6.9.10",
|
||||
"nodemailer": "^7.0.7",
|
||||
"otpauth": "^9.3.1",
|
||||
"pg": "^8.7.3",
|
||||
"playwright": "^1.50.0",
|
||||
"posthog-js": "^1.139.6",
|
||||
"pg": "^8.16.3",
|
||||
"playwright": "^1.56.0",
|
||||
"posthog-js": "^1.275.3",
|
||||
"prop-types": "^15.8.1",
|
||||
"qrcode": "^1.5.3",
|
||||
"react": "^18.3.1",
|
||||
"react-beautiful-dnd": "^13.1.1",
|
||||
"react-big-calendar": "^1.13.0",
|
||||
"react-big-calendar": "^1.19.4",
|
||||
"react-color": "^2.19.3",
|
||||
"react-dom": "^18.3.1",
|
||||
"react-dropzone": "^14.2.2",
|
||||
"react-error-boundary": "^4.0.13",
|
||||
"react-highlight": "^0.15.0",
|
||||
"react-markdown": "^8.0.3",
|
||||
"react-router-dom": "^6.24.1",
|
||||
"react-router-dom": "^6.30.1",
|
||||
"react-select": "^5.4.0",
|
||||
"react-spinners": "^0.14.1",
|
||||
"react-syntax-highlighter": "^15.5.0",
|
||||
"react-syntax-highlighter": "^16.0.0",
|
||||
"react-toggle": "^4.1.3",
|
||||
"reactflow": "^11.11.4",
|
||||
"recharts": "^2.12.7",
|
||||
@@ -115,16 +118,16 @@
|
||||
"socket.io": "^4.7.4",
|
||||
"socket.io-client": "^4.7.5",
|
||||
"stripe": "^10.17.0",
|
||||
"tailwind-merge": "^2.5.2",
|
||||
"tailwind-merge": "^2.6.0",
|
||||
"tippy.js": "^6.3.7",
|
||||
"twilio": "^4.22.0",
|
||||
"typeorm": "^0.3.20",
|
||||
"typeorm": "^0.3.26",
|
||||
"typeorm-extension": "^2.2.13",
|
||||
"universal-cookie": "^7.2.1",
|
||||
"use-async-effect": "^2.2.6",
|
||||
"uuid": "^8.3.2",
|
||||
"web-push": "^3.6.7",
|
||||
"zod": "^3.25.30"
|
||||
"zod": "^3.25.76"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@faker-js/faker": "^8.0.2",
|
||||
@@ -344,9 +347,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@remix-run/router": {
|
||||
"version": "1.16.1",
|
||||
"resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.16.1.tgz",
|
||||
"integrity": "sha512-es2g3dq6Nb07iFxGk5GuHN20RwBZOsuDQN7izWIisUcv9r+d2C5jQxqmgkdebXgReWfiyUabcki6Fg77mSNrig==",
|
||||
"version": "1.23.0",
|
||||
"resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.23.0.tgz",
|
||||
"integrity": "sha512-O3rHJzAQKamUz1fvE0Qaw0xSFqsA/yafi2iqeE0pvdFtCO1viYx8QL6f3Ln/aCCTLxs68SLf0KPM9eSeM8yBnA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
@@ -522,21 +525,23 @@
|
||||
}
|
||||
},
|
||||
"node_modules/brace-expansion": {
|
||||
"version": "1.1.11",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
||||
"version": "1.1.12",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
|
||||
"integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"balanced-match": "^1.0.0",
|
||||
"concat-map": "0.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/braces": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
|
||||
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
|
||||
"integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"fill-range": "^7.0.1"
|
||||
"fill-range": "^7.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
@@ -683,9 +688,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/filelist/node_modules/brace-expansion": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
|
||||
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
|
||||
"integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"balanced-match": "^1.0.0"
|
||||
@@ -704,10 +709,11 @@
|
||||
}
|
||||
},
|
||||
"node_modules/fill-range": {
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
|
||||
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
|
||||
"version": "7.1.1",
|
||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
|
||||
"integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"to-regex-range": "^5.0.1"
|
||||
},
|
||||
@@ -794,6 +800,7 @@
|
||||
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
|
||||
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.12.0"
|
||||
}
|
||||
@@ -958,12 +965,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/react-router": {
|
||||
"version": "6.23.1",
|
||||
"resolved": "https://registry.npmjs.org/react-router/-/react-router-6.23.1.tgz",
|
||||
"integrity": "sha512-fzcOaRF69uvqbbM7OhvQyBTFDVrrGlsFdS3AL+1KfIBtGETibHzi3FkoTRyiDJnWNc2VxrfvR+657ROHjaNjqQ==",
|
||||
"version": "6.30.1",
|
||||
"resolved": "https://registry.npmjs.org/react-router/-/react-router-6.30.1.tgz",
|
||||
"integrity": "sha512-X1m21aEmxGXqENEPG3T6u0Th7g0aS4ZmoNynhbs+Cn+q+QGTLt+d5IQ2bHAXKzKcxGJjxACpVbnYQSCRcfxHlQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@remix-run/router": "1.16.1"
|
||||
"@remix-run/router": "1.23.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
@@ -973,13 +980,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/react-router-dom": {
|
||||
"version": "6.23.1",
|
||||
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.23.1.tgz",
|
||||
"integrity": "sha512-utP+K+aSTtEdbWpC+4gxhdlPFwuEfDKq8ZrPFU65bbRJY+l706qjR7yaidBpo3MSeA/fzwbXWbKBI6ftOnP3OQ==",
|
||||
"version": "6.30.1",
|
||||
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.30.1.tgz",
|
||||
"integrity": "sha512-llKsgOkZdbPU1Eg3zK8lCn+sjD9wMRZZPuzmdWWX5SUs8OFkN5HnFVC0u5KMeMaC9aoancFI/KoLuKPqN+hxHw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@remix-run/router": "1.16.1",
|
||||
"react-router": "6.23.1"
|
||||
"@remix-run/router": "1.23.0",
|
||||
"react-router": "6.30.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
@@ -1009,6 +1016,16 @@
|
||||
"loose-envify": "^1.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/semver": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz",
|
||||
"integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
}
|
||||
},
|
||||
"node_modules/simple-update-notifier": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-1.1.0.tgz",
|
||||
@@ -1021,15 +1038,6 @@
|
||||
"node": ">=8.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/simple-update-notifier/node_modules/semver": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz",
|
||||
"integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
}
|
||||
},
|
||||
"node_modules/supports-color": {
|
||||
"version": "5.5.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
|
||||
@@ -1047,6 +1055,7 @@
|
||||
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
||||
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"is-number": "^7.0.0"
|
||||
},
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
"ejs": "^3.1.10",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
"react-router-dom": "^6.23.1",
|
||||
"react-router-dom": "^6.30.1",
|
||||
"use-async-effect": "^2.2.7"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -12,6 +12,7 @@ import FormFieldSchemaType from "Common/UI/Components/Forms/Types/FormFieldSchem
|
||||
import Link from "Common/UI/Components/Link/Link";
|
||||
import { DASHBOARD_URL } from "Common/UI/Config";
|
||||
import OneUptimeLogo from "Common/UI/Images/logos/OneUptimeSVG/3-transparent.svg";
|
||||
import EditionLabel from "Common/UI/Components/EditionLabel/EditionLabel";
|
||||
import UiAnalytics from "Common/UI/Utils/Analytics";
|
||||
import LoginUtil from "Common/UI/Utils/Login";
|
||||
import UserTotpAuth from "Common/Models/DatabaseModels/UserTotpAuth";
|
||||
@@ -192,6 +193,9 @@ const LoginPage: () => JSX.Element = () => {
|
||||
src={OneUptimeLogo}
|
||||
alt="OneUptime"
|
||||
/>
|
||||
<div className="mt-4 flex justify-center">
|
||||
<EditionLabel />
|
||||
</div>
|
||||
{!showTwoFactorAuth && (
|
||||
<>
|
||||
<h2 className="mt-6 text-center text-2xl tracking-tight text-gray-900">
|
||||
|
||||
@@ -14,9 +14,11 @@ RUN npm config set fetch-retry-maxtimeout 600000
|
||||
|
||||
ARG GIT_SHA
|
||||
ARG APP_VERSION
|
||||
ARG IS_ENTERPRISE_EDITION=false
|
||||
|
||||
ENV GIT_SHA=${GIT_SHA}
|
||||
ENV APP_VERSION=${APP_VERSION}
|
||||
ENV IS_ENTERPRISE_EDITION=${IS_ENTERPRISE_EDITION}
|
||||
ENV PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1
|
||||
|
||||
|
||||
|
||||
@@ -1,13 +1,74 @@
|
||||
import { PromiseVoidFunction } from "Common/Types/FunctionTypes";
|
||||
import Express, { ExpressApplication } from "Common/Server/Utils/Express";
|
||||
import Express, {
|
||||
ExpressApplication,
|
||||
ExpressRequest,
|
||||
ExpressResponse,
|
||||
} from "Common/Server/Utils/Express";
|
||||
import logger from "Common/Server/Utils/Logger";
|
||||
import App from "Common/Server/Utils/StartServer";
|
||||
import Response from "Common/Server/Utils/Response";
|
||||
import UserMiddleware from "Common/Server/Middleware/UserAuthorization";
|
||||
import JSONWebToken from "Common/Server/Utils/JsonWebToken";
|
||||
import NotAuthorizedException from "Common/Types/Exception/NotAuthorizedException";
|
||||
import { JSONObject } from "Common/Types/JSON";
|
||||
import "ejs";
|
||||
import JSONWebTokenData from "Common/Types/JsonWebTokenData";
|
||||
|
||||
export const APP_NAME: string = "admin";
|
||||
|
||||
const app: ExpressApplication = Express.getExpressApp();
|
||||
|
||||
type EnsureMasterAdminAccessFunction = (
|
||||
req: ExpressRequest,
|
||||
res: ExpressResponse,
|
||||
) => Promise<JSONObject>;
|
||||
|
||||
const ensureMasterAdminAccess: EnsureMasterAdminAccessFunction = async (
|
||||
req: ExpressRequest,
|
||||
res: ExpressResponse,
|
||||
): Promise<JSONObject> => {
|
||||
try {
|
||||
const accessToken: string | undefined =
|
||||
UserMiddleware.getAccessTokenFromExpressRequest(req);
|
||||
|
||||
if (!accessToken) {
|
||||
Response.sendErrorResponse(
|
||||
req,
|
||||
res,
|
||||
new NotAuthorizedException(
|
||||
"Unauthorized: Only master admins can access the admin dashboard.",
|
||||
),
|
||||
);
|
||||
return {};
|
||||
}
|
||||
|
||||
const authData: JSONWebTokenData = JSONWebToken.decode(accessToken);
|
||||
|
||||
if (!authData.isMasterAdmin) {
|
||||
Response.sendErrorResponse(
|
||||
req,
|
||||
res,
|
||||
new NotAuthorizedException(
|
||||
"Unauthorized: Only master admins can access the admin dashboard.",
|
||||
),
|
||||
);
|
||||
return {};
|
||||
}
|
||||
|
||||
return {};
|
||||
} catch (error) {
|
||||
logger.error(error);
|
||||
Response.sendErrorResponse(
|
||||
req,
|
||||
res,
|
||||
new NotAuthorizedException(
|
||||
"Unauthorized: Only master admins can access the admin dashboard.",
|
||||
),
|
||||
);
|
||||
return {};
|
||||
}
|
||||
};
|
||||
|
||||
const init: PromiseVoidFunction = async (): Promise<void> => {
|
||||
try {
|
||||
// init the app
|
||||
@@ -19,6 +80,7 @@ const init: PromiseVoidFunction = async (): Promise<void> => {
|
||||
liveCheck: async () => {},
|
||||
readyCheck: async () => {},
|
||||
},
|
||||
getVariablesToRenderIndexPage: ensureMasterAdminAccess,
|
||||
});
|
||||
|
||||
// add default routes
|
||||
|
||||
128
AdminDashboard/package-lock.json
generated
128
AdminDashboard/package-lock.json
generated
@@ -12,7 +12,7 @@
|
||||
"ejs": "^3.1.10",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
"react-router-dom": "^6.23.1"
|
||||
"react-router-dom": "^6.30.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^16.11.35",
|
||||
@@ -34,25 +34,26 @@
|
||||
"@elastic/elasticsearch": "^8.12.1",
|
||||
"@monaco-editor/react": "^4.4.6",
|
||||
"@opentelemetry/api": "^1.9.0",
|
||||
"@opentelemetry/api-logs": "^0.52.1",
|
||||
"@opentelemetry/api-logs": "^0.206.0",
|
||||
"@opentelemetry/context-zone": "^1.25.1",
|
||||
"@opentelemetry/exporter-logs-otlp-http": "^0.52.1",
|
||||
"@opentelemetry/exporter-metrics-otlp-proto": "^0.52.1",
|
||||
"@opentelemetry/exporter-trace-otlp-http": "^0.52.1",
|
||||
"@opentelemetry/exporter-trace-otlp-proto": "^0.52.1",
|
||||
"@opentelemetry/exporter-logs-otlp-http": "^0.207.0",
|
||||
"@opentelemetry/exporter-metrics-otlp-proto": "^0.207.0",
|
||||
"@opentelemetry/exporter-trace-otlp-http": "^0.207.0",
|
||||
"@opentelemetry/exporter-trace-otlp-proto": "^0.207.0",
|
||||
"@opentelemetry/id-generator-aws-xray": "^1.2.2",
|
||||
"@opentelemetry/instrumentation": "^0.52.1",
|
||||
"@opentelemetry/instrumentation-fetch": "^0.52.1",
|
||||
"@opentelemetry/instrumentation-xml-http-request": "^0.52.1",
|
||||
"@opentelemetry/instrumentation": "^0.207.0",
|
||||
"@opentelemetry/instrumentation-fetch": "^0.207.0",
|
||||
"@opentelemetry/instrumentation-xml-http-request": "^0.207.0",
|
||||
"@opentelemetry/resources": "^1.25.1",
|
||||
"@opentelemetry/sdk-logs": "^0.52.1",
|
||||
"@opentelemetry/sdk-logs": "^0.207.0",
|
||||
"@opentelemetry/sdk-metrics": "^1.25.1",
|
||||
"@opentelemetry/sdk-node": "^0.52.1",
|
||||
"@opentelemetry/sdk-trace-node": "^1.25.1",
|
||||
"@opentelemetry/sdk-node": "^0.207.0",
|
||||
"@opentelemetry/sdk-trace-web": "^1.25.1",
|
||||
"@opentelemetry/semantic-conventions": "^1.26.0",
|
||||
"@opentelemetry/semantic-conventions": "^1.37.0",
|
||||
"@remixicon/react": "^4.2.0",
|
||||
"@simplewebauthn/server": "^13.2.2",
|
||||
"@tippyjs/react": "^4.2.6",
|
||||
"@types/archiver": "^6.0.3",
|
||||
"@types/crypto-js": "^4.2.2",
|
||||
"@types/qrcode": "^1.5.5",
|
||||
"@types/react-highlight": "^0.12.8",
|
||||
@@ -61,8 +62,10 @@
|
||||
"@types/web-push": "^3.6.4",
|
||||
"acme-client": "^5.3.0",
|
||||
"airtable": "^0.12.2",
|
||||
"axios": "^1.7.2",
|
||||
"bullmq": "^5.3.3",
|
||||
"archiver": "^7.0.1",
|
||||
"axios": "^1.12.0",
|
||||
"botbuilder": "^4.23.3",
|
||||
"bullmq": "^5.61.0",
|
||||
"cookie-parser": "^1.4.7",
|
||||
"cors": "^2.8.5",
|
||||
"cron-parser": "^4.8.1",
|
||||
@@ -83,26 +86,26 @@
|
||||
"moment": "^2.30.1",
|
||||
"moment-timezone": "^0.5.45",
|
||||
"node-cron": "^3.0.3",
|
||||
"nodemailer": "^6.9.10",
|
||||
"nodemailer": "^7.0.7",
|
||||
"otpauth": "^9.3.1",
|
||||
"pg": "^8.7.3",
|
||||
"playwright": "^1.50.0",
|
||||
"posthog-js": "^1.139.6",
|
||||
"pg": "^8.16.3",
|
||||
"playwright": "^1.56.0",
|
||||
"posthog-js": "^1.275.3",
|
||||
"prop-types": "^15.8.1",
|
||||
"qrcode": "^1.5.3",
|
||||
"react": "^18.3.1",
|
||||
"react-beautiful-dnd": "^13.1.1",
|
||||
"react-big-calendar": "^1.13.0",
|
||||
"react-big-calendar": "^1.19.4",
|
||||
"react-color": "^2.19.3",
|
||||
"react-dom": "^18.3.1",
|
||||
"react-dropzone": "^14.2.2",
|
||||
"react-error-boundary": "^4.0.13",
|
||||
"react-highlight": "^0.15.0",
|
||||
"react-markdown": "^8.0.3",
|
||||
"react-router-dom": "^6.24.1",
|
||||
"react-router-dom": "^6.30.1",
|
||||
"react-select": "^5.4.0",
|
||||
"react-spinners": "^0.14.1",
|
||||
"react-syntax-highlighter": "^15.5.0",
|
||||
"react-syntax-highlighter": "^16.0.0",
|
||||
"react-toggle": "^4.1.3",
|
||||
"reactflow": "^11.11.4",
|
||||
"recharts": "^2.12.7",
|
||||
@@ -114,16 +117,16 @@
|
||||
"socket.io": "^4.7.4",
|
||||
"socket.io-client": "^4.7.5",
|
||||
"stripe": "^10.17.0",
|
||||
"tailwind-merge": "^2.5.2",
|
||||
"tailwind-merge": "^2.6.0",
|
||||
"tippy.js": "^6.3.7",
|
||||
"twilio": "^4.22.0",
|
||||
"typeorm": "^0.3.20",
|
||||
"typeorm": "^0.3.26",
|
||||
"typeorm-extension": "^2.2.13",
|
||||
"universal-cookie": "^7.2.1",
|
||||
"use-async-effect": "^2.2.6",
|
||||
"uuid": "^8.3.2",
|
||||
"web-push": "^3.6.7",
|
||||
"zod": "^3.25.30"
|
||||
"zod": "^3.25.76"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@faker-js/faker": "^8.0.2",
|
||||
@@ -343,9 +346,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@remix-run/router": {
|
||||
"version": "1.16.1",
|
||||
"resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.16.1.tgz",
|
||||
"integrity": "sha512-es2g3dq6Nb07iFxGk5GuHN20RwBZOsuDQN7izWIisUcv9r+d2C5jQxqmgkdebXgReWfiyUabcki6Fg77mSNrig==",
|
||||
"version": "1.23.0",
|
||||
"resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.23.0.tgz",
|
||||
"integrity": "sha512-O3rHJzAQKamUz1fvE0Qaw0xSFqsA/yafi2iqeE0pvdFtCO1viYx8QL6f3Ln/aCCTLxs68SLf0KPM9eSeM8yBnA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
@@ -491,21 +494,23 @@
|
||||
}
|
||||
},
|
||||
"node_modules/brace-expansion": {
|
||||
"version": "1.1.11",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
||||
"version": "1.1.12",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
|
||||
"integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"balanced-match": "^1.0.0",
|
||||
"concat-map": "0.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/braces": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
|
||||
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
|
||||
"integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"fill-range": "^7.0.1"
|
||||
"fill-range": "^7.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
@@ -601,9 +606,10 @@
|
||||
}
|
||||
},
|
||||
"node_modules/filelist/node_modules/brace-expansion": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
|
||||
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
|
||||
"integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"balanced-match": "^1.0.0"
|
||||
}
|
||||
@@ -620,10 +626,11 @@
|
||||
}
|
||||
},
|
||||
"node_modules/fill-range": {
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
|
||||
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
|
||||
"version": "7.1.1",
|
||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
|
||||
"integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"to-regex-range": "^5.0.1"
|
||||
},
|
||||
@@ -710,6 +717,7 @@
|
||||
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
|
||||
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.12.0"
|
||||
}
|
||||
@@ -937,12 +945,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/react-router": {
|
||||
"version": "6.23.1",
|
||||
"resolved": "https://registry.npmjs.org/react-router/-/react-router-6.23.1.tgz",
|
||||
"integrity": "sha512-fzcOaRF69uvqbbM7OhvQyBTFDVrrGlsFdS3AL+1KfIBtGETibHzi3FkoTRyiDJnWNc2VxrfvR+657ROHjaNjqQ==",
|
||||
"version": "6.30.1",
|
||||
"resolved": "https://registry.npmjs.org/react-router/-/react-router-6.30.1.tgz",
|
||||
"integrity": "sha512-X1m21aEmxGXqENEPG3T6u0Th7g0aS4ZmoNynhbs+Cn+q+QGTLt+d5IQ2bHAXKzKcxGJjxACpVbnYQSCRcfxHlQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@remix-run/router": "1.16.1"
|
||||
"@remix-run/router": "1.23.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
@@ -952,13 +960,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/react-router-dom": {
|
||||
"version": "6.23.1",
|
||||
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.23.1.tgz",
|
||||
"integrity": "sha512-utP+K+aSTtEdbWpC+4gxhdlPFwuEfDKq8ZrPFU65bbRJY+l706qjR7yaidBpo3MSeA/fzwbXWbKBI6ftOnP3OQ==",
|
||||
"version": "6.30.1",
|
||||
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.30.1.tgz",
|
||||
"integrity": "sha512-llKsgOkZdbPU1Eg3zK8lCn+sjD9wMRZZPuzmdWWX5SUs8OFkN5HnFVC0u5KMeMaC9aoancFI/KoLuKPqN+hxHw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@remix-run/router": "1.16.1",
|
||||
"react-router": "6.23.1"
|
||||
"@remix-run/router": "1.23.0",
|
||||
"react-router": "6.30.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
@@ -988,6 +996,16 @@
|
||||
"loose-envify": "^1.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/semver": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz",
|
||||
"integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
}
|
||||
},
|
||||
"node_modules/simple-update-notifier": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-1.1.0.tgz",
|
||||
@@ -1000,15 +1018,6 @@
|
||||
"node": ">=8.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/simple-update-notifier/node_modules/semver": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz",
|
||||
"integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
}
|
||||
},
|
||||
"node_modules/supports-color": {
|
||||
"version": "5.5.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
|
||||
@@ -1026,6 +1035,7 @@
|
||||
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
||||
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"is-number": "^7.0.0"
|
||||
},
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
"ejs": "^3.1.10",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
"react-router-dom": "^6.23.1"
|
||||
"react-router-dom": "^6.30.1"
|
||||
},
|
||||
"scripts": {
|
||||
"dev-build": "NODE_ENV=development node esbuild.config.js",
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
<link rel="icon" type="image/png" sizes="194x194" href="/favicon-194x194.png">
|
||||
<link rel="icon" type="image/png" sizes="192x192" href="/android-chrome-192x192.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
|
||||
<link rel="manifest" href="/site.webmanifest">
|
||||
<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#5bbad5">
|
||||
<meta name="msapplication-TileColor" content="#121212">
|
||||
<meta name="theme-color" content="#121212">
|
||||
@@ -1,56 +0,0 @@
|
||||
{
|
||||
"name": "OneUptime Account",
|
||||
"short_name": "OneUptime",
|
||||
"icons": [
|
||||
{
|
||||
"src": "/accounts/assets/img/favicons/android-chrome-36x36.png",
|
||||
"sizes": "36x36",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/accounts/assets/img/favicons/android-chrome-48x48.png",
|
||||
"sizes": "48x48",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/accounts/assets/img/favicons/android-chrome-72x72.png",
|
||||
"sizes": "72x72",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/accounts/assets/img/favicons/android-chrome-96x96.png",
|
||||
"sizes": "96x96",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/accounts/assets/img/favicons/android-chrome-144x144.png",
|
||||
"sizes": "144x144",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/accounts/assets/img/favicons/android-chrome-192x192.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/accounts/assets/img/favicons/android-chrome-256x256.png",
|
||||
"sizes": "256x256",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/accounts/assets/img/favicons/android-chrome-384x384.png",
|
||||
"sizes": "384x384",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/accounts/assets/img/favicons/android-chrome-512x512.png",
|
||||
"sizes": "512x512",
|
||||
"type": "image/png"
|
||||
}
|
||||
],
|
||||
"start_url": ".",
|
||||
"theme_color": "#121212",
|
||||
"background_color": "#121212",
|
||||
"display": "standalone"
|
||||
}
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
{
|
||||
"short_name": "React App",
|
||||
"name": "Create React App Sample",
|
||||
"icons": [
|
||||
{
|
||||
"src": "./assets/img/favicons/favicon.ico",
|
||||
"sizes": "64x64 32x32 24x24 16x16",
|
||||
"type": "image/x-icon"
|
||||
},
|
||||
{
|
||||
"src": "logo192.png",
|
||||
"type": "image/png",
|
||||
"sizes": "192x192"
|
||||
},
|
||||
{
|
||||
"src": "logo512.png",
|
||||
"type": "image/png",
|
||||
"sizes": "512x512"
|
||||
}
|
||||
],
|
||||
"start_url": ".",
|
||||
"display": "standalone",
|
||||
"theme_color": "#000000",
|
||||
"background_color": "#ffffff"
|
||||
}
|
||||
@@ -26,6 +26,7 @@ import {
|
||||
} from "react-router-dom";
|
||||
import UserView from "./Pages/Users/View/Index";
|
||||
import UserDelete from "./Pages/Users/View/Delete";
|
||||
import UserSettings from "./Pages/Users/View/Settings";
|
||||
import ProjectView from "./Pages/Projects/View/Index";
|
||||
import ProjectDelete from "./Pages/Projects/View/Delete";
|
||||
|
||||
@@ -71,6 +72,11 @@ const App: () => JSX.Element = () => {
|
||||
element={<UserView />}
|
||||
/>
|
||||
|
||||
<PageRoute
|
||||
path={RouteMap[PageMap.USER_SETTINGS]?.toString() || ""}
|
||||
element={<UserSettings />}
|
||||
/>
|
||||
|
||||
<PageRoute
|
||||
path={RouteMap[PageMap.USER_DELETE]?.toString() || ""}
|
||||
element={<UserDelete />}
|
||||
|
||||
@@ -3,6 +3,7 @@ import Logo from "./Logo";
|
||||
import UserProfile from "./UserProfile";
|
||||
import Button, { ButtonStyleType } from "Common/UI/Components/Button/Button";
|
||||
import Header from "Common/UI/Components/Header/Header";
|
||||
import EditionLabel from "Common/UI/Components/EditionLabel/EditionLabel";
|
||||
import { DASHBOARD_URL } from "Common/UI/Config";
|
||||
import Navigation from "Common/UI/Utils/Navigation";
|
||||
import React, { FunctionComponent, ReactElement } from "react";
|
||||
@@ -27,6 +28,7 @@ const DashboardHeader: FunctionComponent = (): ReactElement => {
|
||||
}
|
||||
rightComponents={
|
||||
<>
|
||||
<EditionLabel className="mr-3 hidden md:inline-flex" />
|
||||
<Button
|
||||
title="Exit Admin"
|
||||
buttonStyle={ButtonStyleType.NORMAL}
|
||||
|
||||
@@ -68,6 +68,9 @@ const buildWhatsAppSetupMarkdown: BuildWhatsAppSetupMarkdown = (): string => {
|
||||
WhatsAppTemplateIds,
|
||||
) as Array<keyof typeof WhatsAppTemplateIds>;
|
||||
|
||||
const appApiBaseUrl: string = APP_API_URL.toString().replace(/\/$/, "");
|
||||
const primaryWebhookUrl: string = `${appApiBaseUrl}/notification/whatsapp/webhook`;
|
||||
|
||||
const description: string =
|
||||
"Follow these steps to connect Meta WhatsApp with OneUptime so notifications can be delivered via WhatsApp.";
|
||||
|
||||
@@ -75,6 +78,7 @@ const buildWhatsAppSetupMarkdown: BuildWhatsAppSetupMarkdown = (): string => {
|
||||
"Meta Business Manager admin access for the WhatsApp Business Account.",
|
||||
"A WhatsApp Business phone number approved for API messaging.",
|
||||
"Admin access to OneUptime with permission to edit global notification settings.",
|
||||
"A webhook verify token string that you'll configure identically in Meta and OneUptime.",
|
||||
];
|
||||
|
||||
const setupStepsList: Array<string> = [
|
||||
@@ -82,7 +86,7 @@ const buildWhatsAppSetupMarkdown: BuildWhatsAppSetupMarkdown = (): string => {
|
||||
"From **Business Settings → Accounts → WhatsApp Accounts**, create or select the account that owns your sender phone number.",
|
||||
"In Buisness Portfolio, create a system user and assign it to the WhatsApp Business Account with the role of **Admin**.",
|
||||
"Generate a token for this system user and this will be your long-lived access token. Make sure to select the **whatsapp_business_management** and **whatsapp_business_messaging** permissions when generating the token.",
|
||||
"Paste the access token and phone number ID into the **Meta WhatsApp Settings** card above, then save.",
|
||||
"Paste the access token, phone number ID, and webhook verify token into the **Meta WhatsApp Settings** card above, then save.",
|
||||
"For the **Business Account ID**, go to **Business Settings → Business Info** (or **Business Settings → WhatsApp Accounts → Settings**) and copy the **WhatsApp Business Account ID** value.",
|
||||
"To locate the **App ID** and **App Secret**, open [Meta for Developers](https://developers.facebook.com/apps/), select your WhatsApp app, then navigate to **Settings → Basic**. The App ID is shown at the top; click **Show** next to **App Secret** to reveal and copy it.",
|
||||
"Create each template listed below in the Meta WhatsApp Manager. Make sure the template name, language, and variables match exactly. You can however change the content to your preference. Please make sure it's approved by Meta.",
|
||||
@@ -169,12 +173,25 @@ const buildWhatsAppSetupMarkdown: BuildWhatsAppSetupMarkdown = (): string => {
|
||||
.filter(Boolean)
|
||||
.join("\n");
|
||||
|
||||
const webhookSection: string = [
|
||||
"### Configure Meta Webhook Subscription",
|
||||
"1. In the OneUptime Admin Dashboard, open **Settings → WhatsApp → Meta WhatsApp Settings** and enter a strong value in **Webhook Verify Token**. Save the form so the encrypted token is stored in Global Config.",
|
||||
"2. Keep that verify token handy—Meta does not generate one for you. You'll paste the exact same value when configuring the callback.",
|
||||
"3. In [Meta for Developers](https://developers.facebook.com/apps/), select your WhatsApp app and navigate to **WhatsApp → Configuration → Webhooks**.",
|
||||
`4. Click **Configure**, then supply one of the following callback URLs when Meta asks for your endpoint:\n - \`${primaryWebhookUrl}\`\n `,
|
||||
"5. Paste the verify token from step 1 into Meta's **Verify Token** field and submit. Meta will call the callback URL and expect that value to match before it approves the subscription.",
|
||||
"6. After verification succeeds, subscribe to the **messages** field (and any other WhatsApp webhook categories you need) so delivery status updates are forwarded to OneUptime.",
|
||||
]
|
||||
.filter(Boolean)
|
||||
.join("\n\n");
|
||||
|
||||
return [
|
||||
description,
|
||||
"### Prerequisites",
|
||||
prerequisitesMarkdown,
|
||||
"### Setup Steps",
|
||||
setupStepsMarkdown,
|
||||
webhookSection,
|
||||
"### Required WhatsApp Templates",
|
||||
templateSummaryTable,
|
||||
"### Template Bodies",
|
||||
@@ -271,6 +288,18 @@ const SettingsWhatsApp: FunctionComponent = (): ReactElement => {
|
||||
"Optional Business Account ID that owns the WhatsApp templates.",
|
||||
placeholder: "123456789012345",
|
||||
},
|
||||
{
|
||||
field: {
|
||||
metaWhatsAppWebhookVerifyToken: true,
|
||||
},
|
||||
title: "Webhook Verify Token",
|
||||
stepId: "meta-credentials",
|
||||
fieldType: FormFieldSchemaType.EncryptedText,
|
||||
required: false,
|
||||
description:
|
||||
"Secret token configured in Meta to validate webhook subscription requests.",
|
||||
placeholder: "Webhook verify token",
|
||||
},
|
||||
{
|
||||
field: {
|
||||
metaWhatsAppAppId: true,
|
||||
@@ -324,6 +353,14 @@ const SettingsWhatsApp: FunctionComponent = (): ReactElement => {
|
||||
fieldType: FieldType.Text,
|
||||
placeholder: "Not Configured",
|
||||
},
|
||||
{
|
||||
field: {
|
||||
metaWhatsAppWebhookVerifyToken: true,
|
||||
},
|
||||
title: "Webhook Verify Token",
|
||||
fieldType: FieldType.HiddenText,
|
||||
placeholder: "Not Configured",
|
||||
},
|
||||
{
|
||||
field: {
|
||||
metaWhatsAppAppId: true,
|
||||
|
||||
94
AdminDashboard/src/Pages/Users/View/Settings.tsx
Normal file
94
AdminDashboard/src/Pages/Users/View/Settings.tsx
Normal file
@@ -0,0 +1,94 @@
|
||||
import PageMap from "../../../Utils/PageMap";
|
||||
import RouteMap, { RouteUtil } from "../../../Utils/RouteMap";
|
||||
import Route from "Common/Types/API/Route";
|
||||
import ObjectID from "Common/Types/ObjectID";
|
||||
import Navigation from "Common/UI/Utils/Navigation";
|
||||
import React, { FunctionComponent, ReactElement } from "react";
|
||||
import SideMenuComponent from "./SideMenu";
|
||||
import User from "Common/Models/DatabaseModels/User";
|
||||
import ModelPage from "Common/UI/Components/Page/ModelPage";
|
||||
import CardModelDetail from "Common/UI/Components/ModelDetail/CardModelDetail";
|
||||
import FormFieldSchemaType from "Common/UI/Components/Forms/Types/FormFieldSchemaType";
|
||||
import FieldType from "Common/UI/Components/Types/FieldType";
|
||||
|
||||
const UserSettings: FunctionComponent = (): ReactElement => {
|
||||
const modelId: ObjectID = Navigation.getLastParamAsObjectID(1);
|
||||
|
||||
return (
|
||||
<ModelPage<User>
|
||||
modelId={modelId}
|
||||
modelNameField="email"
|
||||
modelType={User}
|
||||
title={"User"}
|
||||
breadcrumbLinks={[
|
||||
{
|
||||
title: "Admin Dashboard",
|
||||
to: RouteUtil.populateRouteParams(RouteMap[PageMap.HOME] as Route),
|
||||
},
|
||||
{
|
||||
title: "Users",
|
||||
to: RouteUtil.populateRouteParams(RouteMap[PageMap.USERS] as Route),
|
||||
},
|
||||
{
|
||||
title: "User",
|
||||
to: RouteUtil.populateRouteParams(
|
||||
RouteMap[PageMap.USER_VIEW] as Route,
|
||||
{
|
||||
modelId: modelId,
|
||||
},
|
||||
),
|
||||
},
|
||||
{
|
||||
title: "Settings",
|
||||
to: RouteUtil.populateRouteParams(
|
||||
RouteMap[PageMap.USER_SETTINGS] as Route,
|
||||
{
|
||||
modelId: modelId,
|
||||
},
|
||||
),
|
||||
},
|
||||
]}
|
||||
sideMenu={<SideMenuComponent modelId={modelId} />}
|
||||
>
|
||||
<CardModelDetail<User>
|
||||
name="user-master-admin-settings"
|
||||
cardProps={{
|
||||
title: "Master Admin Access",
|
||||
description:
|
||||
"Grant or revoke master admin access for this user. Master admins can manage every project and workspace.",
|
||||
}}
|
||||
isEditable={true}
|
||||
editButtonText="Update Access"
|
||||
formFields={[
|
||||
{
|
||||
field: {
|
||||
isMasterAdmin: true,
|
||||
},
|
||||
title: "Master Admin",
|
||||
description:
|
||||
"Enable to give this user full access to the entire platform.",
|
||||
fieldType: FormFieldSchemaType.Toggle,
|
||||
required: true,
|
||||
},
|
||||
]}
|
||||
modelDetailProps={{
|
||||
modelType: User,
|
||||
id: "user-master-admin-settings-detail",
|
||||
fields: [
|
||||
{
|
||||
field: {
|
||||
isMasterAdmin: true,
|
||||
},
|
||||
title: "Master Admin",
|
||||
fieldType: FieldType.Boolean,
|
||||
placeholder: "No",
|
||||
},
|
||||
],
|
||||
modelId: modelId,
|
||||
}}
|
||||
/>
|
||||
</ModelPage>
|
||||
);
|
||||
};
|
||||
|
||||
export default UserSettings;
|
||||
@@ -30,6 +30,18 @@ const SideMenuComponent: FunctionComponent<SideMenuProps> = (
|
||||
}}
|
||||
icon={IconProp.Info}
|
||||
/>
|
||||
<SideMenuItem
|
||||
link={{
|
||||
title: "Settings",
|
||||
to: RouteUtil.populateRouteParams(
|
||||
RouteMap[PageMap.USER_SETTINGS] as Route,
|
||||
{
|
||||
modelId: props.modelId,
|
||||
},
|
||||
),
|
||||
}}
|
||||
icon={IconProp.Settings}
|
||||
/>
|
||||
</SideMenuSection>
|
||||
|
||||
<SideMenuSection title="Advanced">
|
||||
|
||||
@@ -6,6 +6,7 @@ enum PageMap {
|
||||
|
||||
USERS = "USERS",
|
||||
USER_VIEW = "USER_VIEW",
|
||||
USER_SETTINGS = "USER_SETTINGS",
|
||||
USER_DELETE = "USER_DELETE",
|
||||
|
||||
PROJECTS = "PROJECTS",
|
||||
|
||||
@@ -18,6 +18,9 @@ const RouteMap: Dictionary<Route> = {
|
||||
|
||||
[PageMap.USERS]: new Route(`/admin/users`),
|
||||
[PageMap.USER_VIEW]: new Route(`/admin/users/${RouteParams.ModelID}`),
|
||||
[PageMap.USER_SETTINGS]: new Route(
|
||||
`/admin/users/${RouteParams.ModelID}/settings`,
|
||||
),
|
||||
[PageMap.USER_DELETE]: new Route(
|
||||
`/admin/users/${RouteParams.ModelID}/delete`,
|
||||
),
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
<!-- End Google Tag Manager -->
|
||||
<% } %>
|
||||
|
||||
<link rel="manifest" href="/admin/assets/img/favicons/ma">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/admin/assets/img/favicons/apple-touch-icon.png">
|
||||
<link rel="shortcut icon" href="/admin/assets/img/favicons/favicon.ico">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/admin/assets/img/favicons/favicon-32x32.png">
|
||||
@@ -75,20 +74,6 @@
|
||||
|
||||
<title>OneUptime Admin Dashboard</title>
|
||||
|
||||
|
||||
<!--
|
||||
manifest.json provides metadata used when your web app is installed on a
|
||||
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
|
||||
-->
|
||||
<!--
|
||||
Notice the use of %PUBLIC_URL% in the tags above.
|
||||
It will be replaced with the URL of the `public` folder during the build.
|
||||
Only files inside the `public` folder can be referenced from the HTML.
|
||||
|
||||
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
|
||||
work correctly both with client-side routing and a non-root public URL.
|
||||
Learn how to configure a non-root public URL by running `npm run build`.
|
||||
-->
|
||||
</head>
|
||||
<body class="h-full bg-gray-50">
|
||||
<% if(typeof enableGoogleTagManager !== 'undefined' ? enableGoogleTagManager : false){ %>
|
||||
|
||||
@@ -14,9 +14,11 @@ RUN npm config set fetch-retry-maxtimeout 600000
|
||||
|
||||
ARG GIT_SHA
|
||||
ARG APP_VERSION
|
||||
ARG IS_ENTERPRISE_EDITION=false
|
||||
|
||||
ENV GIT_SHA=${GIT_SHA}
|
||||
ENV APP_VERSION=${APP_VERSION}
|
||||
ENV IS_ENTERPRISE_EDITION=${IS_ENTERPRISE_EDITION}
|
||||
ENV PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1
|
||||
|
||||
|
||||
|
||||
@@ -14,9 +14,11 @@ import TelemetryAPI from "Common/Server/API/TelemetryAPI";
|
||||
import ProbeAPI from "Common/Server/API/ProbeAPI";
|
||||
import ProjectAPI from "Common/Server/API/ProjectAPI";
|
||||
import ProjectSsoAPI from "Common/Server/API/ProjectSSO";
|
||||
import WhatsAppLogAPI from "./WhatsAppLogAPI";
|
||||
|
||||
// Import API
|
||||
import ResellerPlanAPI from "Common/Server/API/ResellerPlanAPI";
|
||||
import EnterpriseLicenseAPI from "Common/Server/API/EnterpriseLicenseAPI";
|
||||
import MonitorAPI from "Common/Server/API/MonitorAPI";
|
||||
import ShortLinkAPI from "Common/Server/API/ShortLinkAPI";
|
||||
import StatusPageAPI from "Common/Server/API/StatusPageAPI";
|
||||
@@ -27,12 +29,17 @@ import UserCallAPI from "Common/Server/API/UserCallAPI";
|
||||
import UserTotpAuthAPI from "Common/Server/API/UserTotpAuthAPI";
|
||||
import UserWebAuthnAPI from "Common/Server/API/UserWebAuthnAPI";
|
||||
import MonitorTest from "Common/Models/DatabaseModels/MonitorTest";
|
||||
import IncidentInternalNoteAPI from "Common/Server/API/IncidentInternalNoteAPI";
|
||||
import IncidentPublicNoteAPI from "Common/Server/API/IncidentPublicNoteAPI";
|
||||
import ScheduledMaintenanceInternalNoteAPI from "Common/Server/API/ScheduledMaintenanceInternalNoteAPI";
|
||||
import ScheduledMaintenancePublicNoteAPI from "Common/Server/API/ScheduledMaintenancePublicNoteAPI";
|
||||
// User Notification methods.
|
||||
import UserEmailAPI from "Common/Server/API/UserEmailAPI";
|
||||
import UserNotificationLogTimelineAPI from "Common/Server/API/UserOnCallLogTimelineAPI";
|
||||
import UserSMSAPI from "Common/Server/API/UserSmsAPI";
|
||||
import UserWhatsAppAPI from "Common/Server/API/UserWhatsAppAPI";
|
||||
import UserPushAPI from "Common/Server/API/UserPushAPI";
|
||||
import UserAPI from "Common/Server/API/UserAPI";
|
||||
import ApiKeyPermissionService, {
|
||||
Service as ApiKeyPermissionServiceType,
|
||||
} from "Common/Server/Services/ApiKeyPermissionService";
|
||||
@@ -58,9 +65,7 @@ import EmailVerificationTokenService, {
|
||||
import AlertCustomFieldService, {
|
||||
Service as AlertCustomFieldServiceType,
|
||||
} from "Common/Server/Services/AlertCustomFieldService";
|
||||
import AlertInternalNoteService, {
|
||||
Service as AlertInternalNoteServiceType,
|
||||
} from "Common/Server/Services/AlertInternalNoteService";
|
||||
import AlertInternalNoteAPI from "Common/Server/API/AlertInternalNoteAPI";
|
||||
import AlertNoteTemplateService, {
|
||||
Service as AlertNoteTemplateServiceType,
|
||||
} from "Common/Server/Services/AlertNoteTemplateService";
|
||||
@@ -91,12 +96,12 @@ import AlertStateTimelineService, {
|
||||
import IncidentCustomFieldService, {
|
||||
Service as IncidentCustomFieldServiceType,
|
||||
} from "Common/Server/Services/IncidentCustomFieldService";
|
||||
import IncidentInternalNoteService, {
|
||||
Service as IncidentInternalNoteServiceType,
|
||||
} from "Common/Server/Services/IncidentInternalNoteService";
|
||||
import IncidentNoteTemplateService, {
|
||||
Service as IncidentNoteTemplateServiceType,
|
||||
} from "Common/Server/Services/IncidentNoteTemplateService";
|
||||
import IncidentPostmortemTemplateService, {
|
||||
Service as IncidentPostmortemTemplateServiceType,
|
||||
} from "Common/Server/Services/IncidentPostmortemTemplateService";
|
||||
import TableViewService, {
|
||||
Service as TableViewServiceType,
|
||||
} from "Common/Server/Services/TableViewService";
|
||||
@@ -106,9 +111,6 @@ import IncidentOwnerTeamService, {
|
||||
import IncidentOwnerUserService, {
|
||||
Service as IncidentOwnerUserServiceType,
|
||||
} from "Common/Server/Services/IncidentOwnerUserService";
|
||||
import IncidentPublicNoteService, {
|
||||
Service as IncidentPublicNoteServiceType,
|
||||
} from "Common/Server/Services/IncidentPublicNoteService";
|
||||
import IncidentService, {
|
||||
Service as IncidentServiceType,
|
||||
} from "Common/Server/Services/IncidentService";
|
||||
@@ -140,9 +142,6 @@ import LogService, {
|
||||
LogService as LogServiceType,
|
||||
} from "Common/Server/Services/LogService";
|
||||
|
||||
import TelemetryAttributeService, {
|
||||
TelemetryAttributeService as TelemetryAttributeServiceType,
|
||||
} from "Common/Server/Services/TelemetryAttributeService";
|
||||
import CopilotActionTypePriorityService, {
|
||||
Service as CopilotActionTypePriorityServiceType,
|
||||
} from "Common/Server/Services/CopilotActionTypePriorityService";
|
||||
@@ -230,9 +229,6 @@ import ResellerService, {
|
||||
import ScheduledMaintenanceCustomFieldService, {
|
||||
Service as ScheduledMaintenanceCustomFieldServiceType,
|
||||
} from "Common/Server/Services/ScheduledMaintenanceCustomFieldService";
|
||||
import ScheduledMaintenanceInternalNoteService, {
|
||||
Service as ScheduledMaintenanceInternalNoteServiceType,
|
||||
} from "Common/Server/Services/ScheduledMaintenanceInternalNoteService";
|
||||
import ScheduledMaintenanceNoteTemplateService, {
|
||||
Service as ScheduledMaintenanceNoteTemplateServiceType,
|
||||
} from "Common/Server/Services/ScheduledMaintenanceNoteTemplateService";
|
||||
@@ -242,9 +238,6 @@ import ScheduledMaintenanceOwnerTeamService, {
|
||||
import ScheduledMaintenanceOwnerUserService, {
|
||||
Service as ScheduledMaintenanceOwnerUserServiceType,
|
||||
} from "Common/Server/Services/ScheduledMaintenanceOwnerUserService";
|
||||
import ScheduledMaintenancePublicNoteService, {
|
||||
Service as ScheduledMaintenancePublicNoteServiceType,
|
||||
} from "Common/Server/Services/ScheduledMaintenancePublicNoteService";
|
||||
import ScheduledMaintenanceService, {
|
||||
Service as ScheduledMaintenanceServiceType,
|
||||
} from "Common/Server/Services/ScheduledMaintenanceService";
|
||||
@@ -285,18 +278,13 @@ import ShortLinkService, {
|
||||
import SmsLogService, {
|
||||
Service as SmsLogServiceType,
|
||||
} from "Common/Server/Services/SmsLogService";
|
||||
import WhatsAppLogService, {
|
||||
Service as WhatsAppLogServiceType,
|
||||
} from "Common/Server/Services/WhatsAppLogService";
|
||||
import PushNotificationLogService, {
|
||||
Service as PushNotificationLogServiceType,
|
||||
} from "Common/Server/Services/PushNotificationLogService";
|
||||
import SpanService, {
|
||||
SpanService as SpanServiceType,
|
||||
} from "Common/Server/Services/SpanService";
|
||||
import StatusPageAnnouncementService, {
|
||||
Service as StatusPageAnnouncementServiceType,
|
||||
} from "Common/Server/Services/StatusPageAnnouncementService";
|
||||
import StatusPageAnnouncementAPI from "Common/Server/API/StatusPageAnnouncementAPI";
|
||||
import StatusPageCustomFieldService, {
|
||||
Service as StatusPageCustomFieldServiceType,
|
||||
} from "Common/Server/Services/StatusPageCustomFieldService";
|
||||
@@ -354,9 +342,6 @@ import UserNotificationSettingService, {
|
||||
import UserOnCallLogService, {
|
||||
Service as UserNotificationLogServiceType,
|
||||
} from "Common/Server/Services/UserOnCallLogService";
|
||||
import UserService, {
|
||||
Service as UserServiceType,
|
||||
} from "Common/Server/Services/UserService";
|
||||
import WorkflowLogService, {
|
||||
Service as WorkflowLogServiceType,
|
||||
} from "Common/Server/Services/WorkflowLogService";
|
||||
@@ -382,6 +367,7 @@ import TelemetryExceptionService, {
|
||||
import ExceptionInstanceService, {
|
||||
ExceptionInstanceService as ExceptionInstanceServiceType,
|
||||
} from "Common/Server/Services/ExceptionInstanceService";
|
||||
import AcmeChallengeAPI from "Common/Server/API/AcmeChallengeAPI";
|
||||
|
||||
import FeatureSet from "Common/Server/Types/FeatureSet";
|
||||
import Express, { ExpressApplication } from "Common/Server/Utils/Express";
|
||||
@@ -400,7 +386,6 @@ import Dashboard from "Common/Models/DatabaseModels/Dashboard";
|
||||
|
||||
import Alert from "Common/Models/DatabaseModels/Alert";
|
||||
import AlertCustomField from "Common/Models/DatabaseModels/AlertCustomField";
|
||||
import AlertInternalNote from "Common/Models/DatabaseModels/AlertInternalNote";
|
||||
import AlertNoteTemplate from "Common/Models/DatabaseModels/AlertNoteTemplate";
|
||||
import AlertOwnerTeam from "Common/Models/DatabaseModels/AlertOwnerTeam";
|
||||
import AlertOwnerUser from "Common/Models/DatabaseModels/AlertOwnerUser";
|
||||
@@ -410,11 +395,10 @@ import AlertStateTimeline from "Common/Models/DatabaseModels/AlertStateTimeline"
|
||||
|
||||
import Incident from "Common/Models/DatabaseModels/Incident";
|
||||
import IncidentCustomField from "Common/Models/DatabaseModels/IncidentCustomField";
|
||||
import IncidentInternalNote from "Common/Models/DatabaseModels/IncidentInternalNote";
|
||||
import IncidentNoteTemplate from "Common/Models/DatabaseModels/IncidentNoteTemplate";
|
||||
import IncidentPostmortemTemplate from "Common/Models/DatabaseModels/IncidentPostmortemTemplate";
|
||||
import IncidentOwnerTeam from "Common/Models/DatabaseModels/IncidentOwnerTeam";
|
||||
import IncidentOwnerUser from "Common/Models/DatabaseModels/IncidentOwnerUser";
|
||||
import IncidentPublicNote from "Common/Models/DatabaseModels/IncidentPublicNote";
|
||||
import IncidentSeverity from "Common/Models/DatabaseModels/IncidentSeverity";
|
||||
import IncidentState from "Common/Models/DatabaseModels/IncidentState";
|
||||
import IncidentStateTimeline from "Common/Models/DatabaseModels/IncidentStateTimeline";
|
||||
@@ -449,11 +433,9 @@ import PromoCode from "Common/Models/DatabaseModels/PromoCode";
|
||||
import Reseller from "Common/Models/DatabaseModels/Reseller";
|
||||
import ScheduledMaintenance from "Common/Models/DatabaseModels/ScheduledMaintenance";
|
||||
import ScheduledMaintenanceCustomField from "Common/Models/DatabaseModels/ScheduledMaintenanceCustomField";
|
||||
import ScheduledMaintenanceInternalNote from "Common/Models/DatabaseModels/ScheduledMaintenanceInternalNote";
|
||||
import ScheduledMaintenanceNoteTemplate from "Common/Models/DatabaseModels/ScheduledMaintenanceNoteTemplate";
|
||||
import ScheduledMaintenanceOwnerTeam from "Common/Models/DatabaseModels/ScheduledMaintenanceOwnerTeam";
|
||||
import ScheduledMaintenanceOwnerUser from "Common/Models/DatabaseModels/ScheduledMaintenanceOwnerUser";
|
||||
import ScheduledMaintenancePublicNote from "Common/Models/DatabaseModels/ScheduledMaintenancePublicNote";
|
||||
import ScheduledMaintenanceState from "Common/Models/DatabaseModels/ScheduledMaintenanceState";
|
||||
import ScheduledMaintenanceStateTimeline from "Common/Models/DatabaseModels/ScheduledMaintenanceStateTimeline";
|
||||
import ServiceCatalog from "Common/Models/DatabaseModels/ServiceCatalog";
|
||||
@@ -462,8 +444,6 @@ import ServiceCatalogOwnerUser from "Common/Models/DatabaseModels/ServiceCatalog
|
||||
import ServiceCopilotCodeRepository from "Common/Models/DatabaseModels/ServiceCopilotCodeRepository";
|
||||
import ShortLink from "Common/Models/DatabaseModels/ShortLink";
|
||||
import SmsLog from "Common/Models/DatabaseModels/SmsLog";
|
||||
import WhatsAppLog from "Common/Models/DatabaseModels/WhatsAppLog";
|
||||
import StatusPageAnnouncement from "Common/Models/DatabaseModels/StatusPageAnnouncement";
|
||||
// Custom Fields API
|
||||
import StatusPageCustomField from "Common/Models/DatabaseModels/StatusPageCustomField";
|
||||
import StatusPageFooterLink from "Common/Models/DatabaseModels/StatusPageFooterLink";
|
||||
@@ -482,7 +462,6 @@ import TeamPermission from "Common/Models/DatabaseModels/TeamPermission";
|
||||
import TeamComplianceSetting from "Common/Models/DatabaseModels/TeamComplianceSetting";
|
||||
import TelemetryService from "Common/Models/DatabaseModels/TelemetryService";
|
||||
import TelemetryUsageBilling from "Common/Models/DatabaseModels/TelemetryUsageBilling";
|
||||
import User from "Common/Models/DatabaseModels/User";
|
||||
import UserNotificationRule from "Common/Models/DatabaseModels/UserNotificationRule";
|
||||
import UserNotificationSetting from "Common/Models/DatabaseModels/UserNotificationSetting";
|
||||
import UserOnCallLog from "Common/Models/DatabaseModels/UserOnCallLog";
|
||||
@@ -492,7 +471,6 @@ import WorkflowVariable from "Common/Models/DatabaseModels/WorkflowVariable";
|
||||
import ProbeOwnerTeam from "Common/Models/DatabaseModels/ProbeOwnerTeam";
|
||||
import ProbeOwnerUser from "Common/Models/DatabaseModels/ProbeOwnerUser";
|
||||
import ServiceCatalogDependency from "Common/Models/DatabaseModels/ServiceCatalogDependency";
|
||||
import TelemetryAttribute from "Common/Models/AnalyticsModels/TelemetryAttribute";
|
||||
import ExceptionInstance from "Common/Models/AnalyticsModels/ExceptionInstance";
|
||||
import TelemetyException from "Common/Models/DatabaseModels/TelemetryException";
|
||||
import CopilotActionTypePriority from "Common/Models/DatabaseModels/CopilotActionTypePriority";
|
||||
@@ -618,10 +596,7 @@ const BaseAPIFeatureSet: FeatureSet = {
|
||||
|
||||
app.use(
|
||||
`/${APP_NAME.toLocaleLowerCase()}`,
|
||||
new BaseAnalyticsAPI<TelemetryAttribute, TelemetryAttributeServiceType>(
|
||||
TelemetryAttribute,
|
||||
TelemetryAttributeService,
|
||||
).getRouter(),
|
||||
new AcmeChallengeAPI().getRouter(),
|
||||
);
|
||||
|
||||
app.use(`/${APP_NAME.toLocaleLowerCase()}`, OpenAPI.getRouter());
|
||||
@@ -852,10 +827,7 @@ const BaseAPIFeatureSet: FeatureSet = {
|
||||
|
||||
app.use(
|
||||
`/${APP_NAME.toLocaleLowerCase()}`,
|
||||
new BaseAPI<AlertInternalNote, AlertInternalNoteServiceType>(
|
||||
AlertInternalNote,
|
||||
AlertInternalNoteService,
|
||||
).getRouter(),
|
||||
new AlertInternalNoteAPI().getRouter(),
|
||||
);
|
||||
|
||||
app.use(
|
||||
@@ -1052,10 +1024,7 @@ const BaseAPIFeatureSet: FeatureSet = {
|
||||
|
||||
app.use(
|
||||
`/${APP_NAME.toLocaleLowerCase()}`,
|
||||
new BaseAPI<StatusPageAnnouncement, StatusPageAnnouncementServiceType>(
|
||||
StatusPageAnnouncement,
|
||||
StatusPageAnnouncementService,
|
||||
).getRouter(),
|
||||
new StatusPageAnnouncementAPI().getRouter(),
|
||||
);
|
||||
|
||||
app.use(
|
||||
@@ -1403,6 +1372,17 @@ const BaseAPIFeatureSet: FeatureSet = {
|
||||
).getRouter(),
|
||||
);
|
||||
|
||||
app.use(
|
||||
`/${APP_NAME.toLocaleLowerCase()}`,
|
||||
new BaseAPI<
|
||||
IncidentPostmortemTemplate,
|
||||
IncidentPostmortemTemplateServiceType
|
||||
>(
|
||||
IncidentPostmortemTemplate,
|
||||
IncidentPostmortemTemplateService,
|
||||
).getRouter(),
|
||||
);
|
||||
|
||||
app.use(
|
||||
`/${APP_NAME.toLocaleLowerCase()}`,
|
||||
new BaseAPI<
|
||||
@@ -1545,10 +1525,7 @@ const BaseAPIFeatureSet: FeatureSet = {
|
||||
|
||||
app.use(
|
||||
`/${APP_NAME.toLocaleLowerCase()}`,
|
||||
new BaseAPI<WhatsAppLog, WhatsAppLogServiceType>(
|
||||
WhatsAppLog,
|
||||
WhatsAppLogService,
|
||||
).getRouter(),
|
||||
new WhatsAppLogAPI().getRouter(),
|
||||
);
|
||||
|
||||
app.use(
|
||||
@@ -1648,6 +1625,10 @@ const BaseAPIFeatureSet: FeatureSet = {
|
||||
`/${APP_NAME.toLocaleLowerCase()}`,
|
||||
new ResellerPlanAPI().getRouter(),
|
||||
);
|
||||
app.use(
|
||||
`/${APP_NAME.toLocaleLowerCase()}`,
|
||||
new EnterpriseLicenseAPI().getRouter(),
|
||||
);
|
||||
app.use(`/${APP_NAME.toLocaleLowerCase()}`, new SlackAPI().getRouter());
|
||||
app.use(
|
||||
`/${APP_NAME.toLocaleLowerCase()}`,
|
||||
@@ -1716,40 +1697,22 @@ const BaseAPIFeatureSet: FeatureSet = {
|
||||
|
||||
app.use(
|
||||
`/${APP_NAME.toLocaleLowerCase()}`,
|
||||
new BaseAPI<
|
||||
ScheduledMaintenancePublicNote,
|
||||
ScheduledMaintenancePublicNoteServiceType
|
||||
>(
|
||||
ScheduledMaintenancePublicNote,
|
||||
ScheduledMaintenancePublicNoteService,
|
||||
).getRouter(),
|
||||
new ScheduledMaintenancePublicNoteAPI().getRouter(),
|
||||
);
|
||||
|
||||
app.use(
|
||||
`/${APP_NAME.toLocaleLowerCase()}`,
|
||||
new BaseAPI<
|
||||
ScheduledMaintenanceInternalNote,
|
||||
ScheduledMaintenanceInternalNoteServiceType
|
||||
>(
|
||||
ScheduledMaintenanceInternalNote,
|
||||
ScheduledMaintenanceInternalNoteService,
|
||||
).getRouter(),
|
||||
new ScheduledMaintenanceInternalNoteAPI().getRouter(),
|
||||
);
|
||||
|
||||
app.use(
|
||||
`/${APP_NAME.toLocaleLowerCase()}`,
|
||||
new BaseAPI<IncidentPublicNote, IncidentPublicNoteServiceType>(
|
||||
IncidentPublicNote,
|
||||
IncidentPublicNoteService,
|
||||
).getRouter(),
|
||||
new IncidentPublicNoteAPI().getRouter(),
|
||||
);
|
||||
|
||||
app.use(
|
||||
`/${APP_NAME.toLocaleLowerCase()}`,
|
||||
new BaseAPI<IncidentInternalNote, IncidentInternalNoteServiceType>(
|
||||
IncidentInternalNote,
|
||||
IncidentInternalNoteService,
|
||||
).getRouter(),
|
||||
new IncidentInternalNoteAPI().getRouter(),
|
||||
);
|
||||
|
||||
app.use(
|
||||
@@ -1866,10 +1829,7 @@ const BaseAPIFeatureSet: FeatureSet = {
|
||||
app.use(`/${APP_NAME.toLocaleLowerCase()}`, TelemetryAPI);
|
||||
|
||||
//attach api's
|
||||
app.use(
|
||||
`/${APP_NAME.toLocaleLowerCase()}`,
|
||||
new BaseAPI<User, UserServiceType>(User, UserService).getRouter(),
|
||||
);
|
||||
app.use(`/${APP_NAME.toLocaleLowerCase()}`, new UserAPI().getRouter());
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
14
App/FeatureSet/BaseAPI/WhatsAppLogAPI.ts
Normal file
14
App/FeatureSet/BaseAPI/WhatsAppLogAPI.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import BaseAPI from "Common/Server/API/BaseAPI";
|
||||
import WhatsAppLog from "Common/Models/DatabaseModels/WhatsAppLog";
|
||||
import WhatsAppLogService, {
|
||||
Service as WhatsAppLogServiceType,
|
||||
} from "Common/Server/Services/WhatsAppLogService";
|
||||
|
||||
export default class WhatsAppLogAPI extends BaseAPI<
|
||||
WhatsAppLog,
|
||||
WhatsAppLogServiceType
|
||||
> {
|
||||
public constructor() {
|
||||
super(WhatsAppLog, WhatsAppLogService);
|
||||
}
|
||||
}
|
||||
@@ -25,24 +25,70 @@ import EmailVerificationTokenService from "Common/Server/Services/EmailVerificat
|
||||
import MailService from "Common/Server/Services/MailService";
|
||||
import UserService from "Common/Server/Services/UserService";
|
||||
import UserTotpAuthService from "Common/Server/Services/UserTotpAuthService";
|
||||
import UserSessionService, {
|
||||
SessionMetadata,
|
||||
} from "Common/Server/Services/UserSessionService";
|
||||
import CookieUtil from "Common/Server/Utils/Cookie";
|
||||
import Express, {
|
||||
ExpressRequest,
|
||||
ExpressResponse,
|
||||
ExpressRouter,
|
||||
NextFunction,
|
||||
extractDeviceInfo,
|
||||
getClientIp,
|
||||
headerValueToString,
|
||||
} from "Common/Server/Utils/Express";
|
||||
import logger from "Common/Server/Utils/Logger";
|
||||
import Response from "Common/Server/Utils/Response";
|
||||
import TotpAuth from "Common/Server/Utils/TotpAuth";
|
||||
import EmailVerificationToken from "Common/Models/DatabaseModels/EmailVerificationToken";
|
||||
import User from "Common/Models/DatabaseModels/User";
|
||||
import UserSession from "Common/Models/DatabaseModels/UserSession";
|
||||
import UserTotpAuth from "Common/Models/DatabaseModels/UserTotpAuth";
|
||||
import UserWebAuthn from "Common/Models/DatabaseModels/UserWebAuthn";
|
||||
import UserWebAuthnService from "Common/Server/Services/UserWebAuthnService";
|
||||
import NotAuthenticatedException from "Common/Types/Exception/NotAuthenticatedException";
|
||||
|
||||
const router: ExpressRouter = Express.getRouter();
|
||||
|
||||
const ACCESS_TOKEN_EXPIRY_SECONDS: number = 15 * 60;
|
||||
|
||||
type FinalizeUserLoginInput = {
|
||||
req: ExpressRequest;
|
||||
res: ExpressResponse;
|
||||
user: User;
|
||||
isGlobalLogin: boolean;
|
||||
};
|
||||
|
||||
const finalizeUserLogin: (
|
||||
data: FinalizeUserLoginInput,
|
||||
) => Promise<SessionMetadata> = async (
|
||||
data: FinalizeUserLoginInput,
|
||||
): Promise<SessionMetadata> => {
|
||||
const { req, res, user, isGlobalLogin } = data;
|
||||
|
||||
const sessionMetadata: SessionMetadata =
|
||||
await UserSessionService.createSession({
|
||||
userId: user.id!,
|
||||
isGlobalLogin,
|
||||
ipAddress: getClientIp(req),
|
||||
userAgent: headerValueToString(req.headers["user-agent"]),
|
||||
...extractDeviceInfo(req),
|
||||
});
|
||||
|
||||
CookieUtil.setUserCookie({
|
||||
expressResponse: res,
|
||||
user,
|
||||
isGlobalLogin,
|
||||
sessionId: sessionMetadata.session.id!,
|
||||
refreshToken: sessionMetadata.refreshToken,
|
||||
refreshTokenExpiresAt: sessionMetadata.refreshTokenExpiresAt,
|
||||
accessTokenExpiresInSeconds: ACCESS_TOKEN_EXPIRY_SECONDS,
|
||||
});
|
||||
|
||||
return sessionMetadata;
|
||||
};
|
||||
|
||||
router.post(
|
||||
"/signup",
|
||||
async (
|
||||
@@ -185,9 +231,9 @@ router.post(
|
||||
if (savedUser) {
|
||||
// Refresh Permissions for this user here.
|
||||
await AccessTokenService.refreshUserAllPermissions(savedUser.id!);
|
||||
|
||||
CookieUtil.setUserCookie({
|
||||
expressResponse: res,
|
||||
await finalizeUserLogin({
|
||||
req,
|
||||
res,
|
||||
user: savedUser,
|
||||
isGlobalLogin: true,
|
||||
});
|
||||
@@ -487,6 +533,127 @@ router.post(
|
||||
},
|
||||
);
|
||||
|
||||
router.post(
|
||||
"/refresh-token",
|
||||
async (
|
||||
req: ExpressRequest,
|
||||
res: ExpressResponse,
|
||||
next: NextFunction,
|
||||
): Promise<void> => {
|
||||
try {
|
||||
const refreshToken: string | undefined =
|
||||
CookieUtil.getRefreshTokenFromExpressRequest(req);
|
||||
|
||||
if (!refreshToken) {
|
||||
CookieUtil.removeAllCookies(req, res);
|
||||
return Response.sendErrorResponse(
|
||||
req,
|
||||
res,
|
||||
new NotAuthenticatedException(
|
||||
"Refresh token missing. Please login again.",
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
const session: UserSession | null =
|
||||
await UserSessionService.findActiveSessionByRefreshToken(refreshToken);
|
||||
|
||||
if (!session || !session.id) {
|
||||
CookieUtil.removeAllCookies(req, res);
|
||||
return Response.sendErrorResponse(
|
||||
req,
|
||||
res,
|
||||
new NotAuthenticatedException("Session expired. Please login again."),
|
||||
);
|
||||
}
|
||||
|
||||
if (
|
||||
session.refreshTokenExpiresAt &&
|
||||
OneUptimeDate.hasExpired(session.refreshTokenExpiresAt)
|
||||
) {
|
||||
await UserSessionService.revokeSessionById(session.id, {
|
||||
reason: "Refresh token expired",
|
||||
});
|
||||
CookieUtil.removeAllCookies(req, res);
|
||||
return Response.sendErrorResponse(
|
||||
req,
|
||||
res,
|
||||
new NotAuthenticatedException("Session expired. Please login again."),
|
||||
);
|
||||
}
|
||||
|
||||
if (!session.userId) {
|
||||
await UserSessionService.revokeSessionById(session.id, {
|
||||
reason: "Session missing user",
|
||||
});
|
||||
CookieUtil.removeAllCookies(req, res);
|
||||
return Response.sendErrorResponse(
|
||||
req,
|
||||
res,
|
||||
new NotAuthenticatedException("Session expired. Please login again."),
|
||||
);
|
||||
}
|
||||
|
||||
const user: User | null = await UserService.findOneById({
|
||||
id: session.userId,
|
||||
props: {
|
||||
isRoot: true,
|
||||
},
|
||||
select: {
|
||||
_id: true,
|
||||
email: true,
|
||||
name: true,
|
||||
isMasterAdmin: true,
|
||||
profilePictureId: true,
|
||||
timezone: true,
|
||||
enableTwoFactorAuth: true,
|
||||
},
|
||||
});
|
||||
|
||||
if (!user) {
|
||||
await UserSessionService.revokeSessionById(session.id, {
|
||||
reason: "User not found",
|
||||
});
|
||||
CookieUtil.removeAllCookies(req, res);
|
||||
return Response.sendErrorResponse(
|
||||
req,
|
||||
res,
|
||||
new NotAuthenticatedException("Account no longer exists."),
|
||||
);
|
||||
}
|
||||
|
||||
const additionalInfo: JSONObject = (session.additionalInfo ||
|
||||
{}) as JSONObject;
|
||||
const isGlobalLogin: boolean =
|
||||
typeof additionalInfo["isGlobalLogin"] === "boolean"
|
||||
? (additionalInfo["isGlobalLogin"] as boolean)
|
||||
: true;
|
||||
|
||||
const renewedSession: SessionMetadata =
|
||||
await UserSessionService.renewSessionWithNewRefreshToken({
|
||||
session,
|
||||
ipAddress: getClientIp(req),
|
||||
userAgent: headerValueToString(req.headers["user-agent"]),
|
||||
...extractDeviceInfo(req),
|
||||
});
|
||||
|
||||
CookieUtil.setUserCookie({
|
||||
expressResponse: res,
|
||||
user,
|
||||
isGlobalLogin,
|
||||
sessionId: renewedSession.session.id!,
|
||||
refreshToken: renewedSession.refreshToken,
|
||||
refreshTokenExpiresAt: renewedSession.refreshTokenExpiresAt,
|
||||
accessTokenExpiresInSeconds: ACCESS_TOKEN_EXPIRY_SECONDS,
|
||||
});
|
||||
|
||||
return Response.sendEmptySuccessResponse(req, res);
|
||||
} catch (err) {
|
||||
return next(err);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
router.post(
|
||||
"/logout",
|
||||
async (
|
||||
@@ -495,6 +662,15 @@ router.post(
|
||||
next: NextFunction,
|
||||
): Promise<void> => {
|
||||
try {
|
||||
const refreshToken: string | undefined =
|
||||
CookieUtil.getRefreshTokenFromExpressRequest(req);
|
||||
|
||||
if (refreshToken) {
|
||||
await UserSessionService.revokeSessionByRefreshToken(refreshToken, {
|
||||
reason: "User logout",
|
||||
});
|
||||
}
|
||||
|
||||
CookieUtil.removeAllCookies(req, res);
|
||||
|
||||
return Response.sendEmptySuccessResponse(req, res);
|
||||
@@ -788,8 +964,9 @@ const login: LoginFunction = async (options: {
|
||||
if (alreadySavedUser.password.toString() === user.password!.toString()) {
|
||||
logger.info("User logged in: " + alreadySavedUser.email?.toString());
|
||||
|
||||
CookieUtil.setUserCookie({
|
||||
expressResponse: res,
|
||||
await finalizeUserLogin({
|
||||
req,
|
||||
res,
|
||||
user: alreadySavedUser,
|
||||
isGlobalLogin: true,
|
||||
});
|
||||
|
||||
@@ -834,41 +834,53 @@ router.post(
|
||||
projectId: projectId,
|
||||
name: displayName,
|
||||
},
|
||||
select: { _id: true },
|
||||
select: {
|
||||
_id: true,
|
||||
name: true,
|
||||
createdAt: true,
|
||||
updatedAt: true,
|
||||
projectId: true,
|
||||
},
|
||||
props: { isRoot: true },
|
||||
});
|
||||
|
||||
let targetTeam: Team;
|
||||
let createdNewTeam: boolean = false;
|
||||
|
||||
if (existingTeam) {
|
||||
logger.debug(
|
||||
`SCIM Create group - team already exists with id: ${existingTeam.id}`,
|
||||
`SCIM Create group - team already exists with id: ${existingTeam.id}, reusing existing team`,
|
||||
);
|
||||
throw new BadRequestException("Group with this name already exists");
|
||||
targetTeam = existingTeam;
|
||||
} else {
|
||||
// Create new team
|
||||
logger.debug(`SCIM Create group - creating new team: ${displayName}`);
|
||||
const team: Team = new Team();
|
||||
team.projectId = projectId;
|
||||
team.name = displayName;
|
||||
team.isTeamEditable = true; // Allow editing SCIM-created teams
|
||||
team.isTeamDeleteable = true; // Allow deleting SCIM-created teams
|
||||
team.shouldHaveAtLeastOneMember = false; // SCIM groups can be empty
|
||||
|
||||
const createdTeam: Team = await TeamService.create({
|
||||
data: team,
|
||||
props: { isRoot: true },
|
||||
});
|
||||
|
||||
logger.debug(
|
||||
`SCIM Create group - created team with id: ${createdTeam.id}`,
|
||||
);
|
||||
|
||||
targetTeam = createdTeam;
|
||||
createdNewTeam = true;
|
||||
}
|
||||
|
||||
// Create new team
|
||||
logger.debug(`SCIM Create group - creating new team: ${displayName}`);
|
||||
const team: Team = new Team();
|
||||
team.projectId = projectId;
|
||||
team.name = displayName;
|
||||
team.isTeamEditable = true; // Allow editing SCIM-created teams
|
||||
team.isTeamDeleteable = true; // Allow deleting SCIM-created teams
|
||||
team.shouldHaveAtLeastOneMember = false; // SCIM groups can be empty
|
||||
|
||||
const createdTeam: Team = await TeamService.create({
|
||||
data: team,
|
||||
props: { isRoot: true },
|
||||
});
|
||||
|
||||
logger.debug(
|
||||
`SCIM Create group - created team with id: ${createdTeam.id}`,
|
||||
);
|
||||
|
||||
// Handle initial members if provided
|
||||
// Handle members if provided. Adds any new members and leaves existing ones intact.
|
||||
const members: Array<SCIMMember> =
|
||||
(scimGroup["members"] as Array<SCIMMember>) || [];
|
||||
if (members.length > 0) {
|
||||
logger.debug(
|
||||
`SCIM Create group - adding ${members.length} initial members`,
|
||||
`SCIM Create group - ensuring ${members.length} members are part of team ${targetTeam.id}`,
|
||||
);
|
||||
for (const member of members) {
|
||||
const userId: string = member["value"] as string;
|
||||
@@ -887,18 +899,18 @@ router.post(
|
||||
query: {
|
||||
projectId: projectId,
|
||||
userId: new ObjectID(userId),
|
||||
teamId: createdTeam.id!,
|
||||
teamId: targetTeam.id!,
|
||||
},
|
||||
select: { _id: true },
|
||||
props: { isRoot: true },
|
||||
});
|
||||
|
||||
if (!existingMember) {
|
||||
// Add user to the new team
|
||||
// Add user to the team
|
||||
const newTeamMember: TeamMember = new TeamMember();
|
||||
newTeamMember.projectId = projectId;
|
||||
newTeamMember.userId = new ObjectID(userId);
|
||||
newTeamMember.teamId = createdTeam.id!;
|
||||
newTeamMember.teamId = targetTeam.id!;
|
||||
newTeamMember.hasAcceptedInvitation = true;
|
||||
newTeamMember.invitationAcceptedAt =
|
||||
OneUptimeDate.getCurrentDate();
|
||||
@@ -910,7 +922,7 @@ router.post(
|
||||
},
|
||||
});
|
||||
logger.debug(
|
||||
`SCIM Create group - added user ${userId} to team`,
|
||||
`SCIM Create group - added user ${userId} to team ${targetTeam.id}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -918,18 +930,39 @@ router.post(
|
||||
}
|
||||
}
|
||||
|
||||
const createdGroup: JSONObject = await formatTeamForSCIM(
|
||||
createdTeam,
|
||||
const teamForResponse: Team | null = await TeamService.findOneById({
|
||||
id: targetTeam.id!,
|
||||
select: {
|
||||
_id: true,
|
||||
name: true,
|
||||
createdAt: true,
|
||||
updatedAt: true,
|
||||
projectId: true,
|
||||
},
|
||||
props: { isRoot: true },
|
||||
});
|
||||
|
||||
if (!teamForResponse) {
|
||||
throw new NotFoundException("Failed to retrieve group");
|
||||
}
|
||||
|
||||
const groupResponse: JSONObject = await formatTeamForSCIM(
|
||||
teamForResponse,
|
||||
req.params["projectScimId"]!,
|
||||
true,
|
||||
);
|
||||
|
||||
logger.debug(
|
||||
`SCIM Create group - returning created group with id: ${createdTeam.id}`,
|
||||
`SCIM Create group - returning group with id: ${teamForResponse.id}`,
|
||||
);
|
||||
|
||||
res.status(201);
|
||||
return Response.sendJsonObjectResponse(req, res, createdGroup);
|
||||
if (createdNewTeam) {
|
||||
res.status(201);
|
||||
} else {
|
||||
res.status(200);
|
||||
}
|
||||
|
||||
return Response.sendJsonObjectResponse(req, res, groupResponse);
|
||||
} catch (err) {
|
||||
logger.error(err);
|
||||
return next(err);
|
||||
@@ -995,10 +1028,6 @@ router.put(
|
||||
);
|
||||
}
|
||||
|
||||
if (!team.isTeamEditable) {
|
||||
throw new BadRequestException("This group cannot be updated");
|
||||
}
|
||||
|
||||
// Update team name if provided
|
||||
const displayName: string = scimGroup["displayName"] as string;
|
||||
if (displayName && displayName !== team.name) {
|
||||
@@ -1249,10 +1278,6 @@ router.patch(
|
||||
);
|
||||
}
|
||||
|
||||
if (!team.isTeamEditable) {
|
||||
throw new BadRequestException("This group cannot be updated");
|
||||
}
|
||||
|
||||
// Handle SCIM patch operations
|
||||
const operations: JSONObject[] =
|
||||
(scimPatch["Operations"] as JSONObject[]) || [];
|
||||
|
||||
@@ -20,6 +20,9 @@ import AccessTokenService from "Common/Server/Services/AccessTokenService";
|
||||
import ProjectSSOService from "Common/Server/Services/ProjectSsoService";
|
||||
import TeamMemberService from "Common/Server/Services/TeamMemberService";
|
||||
import UserService from "Common/Server/Services/UserService";
|
||||
import UserSessionService, {
|
||||
SessionMetadata,
|
||||
} from "Common/Server/Services/UserSessionService";
|
||||
import QueryHelper from "Common/Server/Types/Database/QueryHelper";
|
||||
import Select from "Common/Server/Types/Database/Select";
|
||||
import CookieUtil from "Common/Server/Utils/Cookie";
|
||||
@@ -28,6 +31,9 @@ import Express, {
|
||||
ExpressResponse,
|
||||
ExpressRouter,
|
||||
NextFunction,
|
||||
extractDeviceInfo,
|
||||
getClientIp,
|
||||
headerValueToString,
|
||||
} from "Common/Server/Utils/Express";
|
||||
import logger from "Common/Server/Utils/Logger";
|
||||
import Response from "Common/Server/Utils/Response";
|
||||
@@ -40,6 +46,8 @@ import Name from "Common/Types/Name";
|
||||
|
||||
const router: ExpressRouter = Express.getRouter();
|
||||
|
||||
const ACCESS_TOKEN_EXPIRY_SECONDS: number = 15 * 60;
|
||||
|
||||
/*
|
||||
* This route is used to get the SSO config for the user.
|
||||
* when the user logs in from OneUptime and not from the IDP.
|
||||
@@ -539,15 +547,31 @@ const loginUserWithSso: LoginUserWithSsoFunction = async (
|
||||
expressResponse: res,
|
||||
});
|
||||
|
||||
// Refresh Permissions for this user here.
|
||||
await AccessTokenService.refreshUserAllPermissions(alreadySavedUser.id!);
|
||||
|
||||
const sessionMetadata: SessionMetadata =
|
||||
await UserSessionService.createSession({
|
||||
userId: alreadySavedUser.id!,
|
||||
isGlobalLogin: false,
|
||||
ipAddress: getClientIp(req),
|
||||
userAgent: headerValueToString(req.headers["user-agent"]),
|
||||
...extractDeviceInfo(req),
|
||||
additionalInfo: {
|
||||
projectId: projectId.toString(),
|
||||
},
|
||||
});
|
||||
|
||||
CookieUtil.setUserCookie({
|
||||
expressResponse: res,
|
||||
user: alreadySavedUser,
|
||||
isGlobalLogin: false,
|
||||
sessionId: sessionMetadata.session.id!,
|
||||
refreshToken: sessionMetadata.refreshToken,
|
||||
refreshTokenExpiresAt: sessionMetadata.refreshTokenExpiresAt,
|
||||
accessTokenExpiresInSeconds: ACCESS_TOKEN_EXPIRY_SECONDS,
|
||||
});
|
||||
|
||||
// Refresh Permissions for this user here.
|
||||
await AccessTokenService.refreshUserAllPermissions(alreadySavedUser.id!);
|
||||
|
||||
const host: Hostname = await DatabaseConfig.getHost();
|
||||
const httpProtocol: Protocol = await DatabaseConfig.getHttpProtocol();
|
||||
|
||||
|
||||
@@ -1,35 +1,98 @@
|
||||
import BaseModel from "Common/Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel";
|
||||
import { FileRoute } from "Common/ServiceRoute";
|
||||
import { StatusPageApiRoute } from "Common/ServiceRoute";
|
||||
import Hostname from "Common/Types/API/Hostname";
|
||||
import Protocol from "Common/Types/API/Protocol";
|
||||
import URL from "Common/Types/API/URL";
|
||||
import OneUptimeDate from "Common/Types/Date";
|
||||
import EmailTemplateType from "Common/Types/Email/EmailTemplateType";
|
||||
import BadDataException from "Common/Types/Exception/BadDataException";
|
||||
import NotAuthenticatedException from "Common/Types/Exception/NotAuthenticatedException";
|
||||
import { JSONObject } from "Common/Types/JSON";
|
||||
import JSONFunctions from "Common/Types/JSONFunctions";
|
||||
import ObjectID from "Common/Types/ObjectID";
|
||||
import PositiveNumber from "Common/Types/PositiveNumber";
|
||||
import DatabaseConfig from "Common/Server/DatabaseConfig";
|
||||
import { EncryptionSecret } from "Common/Server/EnvironmentConfig";
|
||||
import MailService from "Common/Server/Services/MailService";
|
||||
import StatusPagePrivateUserService from "Common/Server/Services/StatusPagePrivateUserService";
|
||||
import StatusPageService from "Common/Server/Services/StatusPageService";
|
||||
import StatusPagePrivateUserSessionService, {
|
||||
SessionMetadata as StatusPageSessionMetadata,
|
||||
} from "Common/Server/Services/StatusPagePrivateUserSessionService";
|
||||
import CookieUtil from "Common/Server/Utils/Cookie";
|
||||
import Express, {
|
||||
ExpressRequest,
|
||||
ExpressResponse,
|
||||
ExpressRouter,
|
||||
NextFunction,
|
||||
extractDeviceInfo,
|
||||
getClientIp,
|
||||
headerValueToString,
|
||||
} from "Common/Server/Utils/Express";
|
||||
import JSONWebToken from "Common/Server/Utils/JsonWebToken";
|
||||
import logger from "Common/Server/Utils/Logger";
|
||||
import Response from "Common/Server/Utils/Response";
|
||||
import StatusPage from "Common/Models/DatabaseModels/StatusPage";
|
||||
import StatusPagePrivateUser from "Common/Models/DatabaseModels/StatusPagePrivateUser";
|
||||
import StatusPagePrivateUserSession from "Common/Models/DatabaseModels/StatusPagePrivateUserSession";
|
||||
|
||||
const router: ExpressRouter = Express.getRouter();
|
||||
|
||||
const ACCESS_TOKEN_EXPIRY_SECONDS: number = 15 * 60;
|
||||
|
||||
type FinalizeStatusPageLoginInput = {
|
||||
req: ExpressRequest;
|
||||
res: ExpressResponse;
|
||||
user: StatusPagePrivateUser;
|
||||
};
|
||||
|
||||
const finalizeStatusPageLogin: (data: FinalizeStatusPageLoginInput) => Promise<{
|
||||
sessionMetadata: StatusPageSessionMetadata;
|
||||
accessToken: string;
|
||||
}> = async (
|
||||
data: FinalizeStatusPageLoginInput,
|
||||
): Promise<{
|
||||
sessionMetadata: StatusPageSessionMetadata;
|
||||
accessToken: string;
|
||||
}> => {
|
||||
const { req, res, user } = data;
|
||||
|
||||
if (!user.projectId) {
|
||||
throw new BadDataException(
|
||||
"Status page user is missing associated projectId.",
|
||||
);
|
||||
}
|
||||
|
||||
if (!user.statusPageId) {
|
||||
throw new BadDataException(
|
||||
"Status page user is missing associated statusPageId.",
|
||||
);
|
||||
}
|
||||
|
||||
const sessionMetadata: StatusPageSessionMetadata =
|
||||
await StatusPagePrivateUserSessionService.createSession({
|
||||
projectId: user.projectId,
|
||||
statusPageId: user.statusPageId,
|
||||
statusPagePrivateUserId: user.id!,
|
||||
ipAddress: getClientIp(req),
|
||||
userAgent: headerValueToString(req.headers["user-agent"]),
|
||||
...extractDeviceInfo(req),
|
||||
});
|
||||
|
||||
const accessToken: string = CookieUtil.setStatusPagePrivateUserCookie({
|
||||
expressResponse: res,
|
||||
user,
|
||||
statusPageId: user.statusPageId,
|
||||
sessionId: sessionMetadata.session.id!,
|
||||
refreshToken: sessionMetadata.refreshToken,
|
||||
refreshTokenExpiresAt: sessionMetadata.refreshTokenExpiresAt,
|
||||
accessTokenExpiresInSeconds: ACCESS_TOKEN_EXPIRY_SECONDS,
|
||||
});
|
||||
|
||||
return {
|
||||
sessionMetadata,
|
||||
accessToken,
|
||||
};
|
||||
};
|
||||
|
||||
router.post(
|
||||
"/logout/:statuspageid",
|
||||
async (
|
||||
@@ -46,7 +109,20 @@ router.post(
|
||||
req.params["statuspageid"].toString(),
|
||||
);
|
||||
|
||||
CookieUtil.removeCookie(res, CookieUtil.getUserTokenKey(statusPageId)); // remove the cookie.
|
||||
const refreshToken: string | undefined =
|
||||
CookieUtil.getRefreshTokenFromExpressRequest(req, statusPageId);
|
||||
|
||||
if (refreshToken) {
|
||||
await StatusPagePrivateUserSessionService.revokeSessionByRefreshToken(
|
||||
refreshToken,
|
||||
{
|
||||
reason: "User logged out",
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
CookieUtil.removeCookie(res, CookieUtil.getUserTokenKey(statusPageId));
|
||||
CookieUtil.removeCookie(res, CookieUtil.getRefreshTokenKey(statusPageId));
|
||||
|
||||
return Response.sendEmptySuccessResponse(req, res);
|
||||
} catch (err) {
|
||||
@@ -55,6 +131,198 @@ router.post(
|
||||
},
|
||||
);
|
||||
|
||||
router.post(
|
||||
"/refresh-token/:statuspageid",
|
||||
async (
|
||||
req: ExpressRequest,
|
||||
res: ExpressResponse,
|
||||
next: NextFunction,
|
||||
): Promise<void> => {
|
||||
try {
|
||||
const statusPageIdParam: string | undefined = req.params["statuspageid"];
|
||||
|
||||
if (!statusPageIdParam) {
|
||||
throw new BadDataException("Status Page ID is required.");
|
||||
}
|
||||
|
||||
const statusPageId: ObjectID = new ObjectID(statusPageIdParam.toString());
|
||||
|
||||
const refreshToken: string | undefined =
|
||||
CookieUtil.getRefreshTokenFromExpressRequest(req, statusPageId);
|
||||
|
||||
if (!refreshToken) {
|
||||
CookieUtil.removeCookie(res, CookieUtil.getUserTokenKey(statusPageId));
|
||||
CookieUtil.removeCookie(
|
||||
res,
|
||||
CookieUtil.getRefreshTokenKey(statusPageId),
|
||||
);
|
||||
|
||||
return Response.sendErrorResponse(
|
||||
req,
|
||||
res,
|
||||
new NotAuthenticatedException(
|
||||
"Refresh token missing. Please login again.",
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
const session: StatusPagePrivateUserSession | null =
|
||||
await StatusPagePrivateUserSessionService.findActiveSessionByRefreshToken(
|
||||
refreshToken,
|
||||
);
|
||||
|
||||
if (!session || !session.id || !session.statusPageId) {
|
||||
CookieUtil.removeCookie(res, CookieUtil.getUserTokenKey(statusPageId));
|
||||
CookieUtil.removeCookie(
|
||||
res,
|
||||
CookieUtil.getRefreshTokenKey(statusPageId),
|
||||
);
|
||||
|
||||
return Response.sendErrorResponse(
|
||||
req,
|
||||
res,
|
||||
new NotAuthenticatedException("Session expired. Please login again."),
|
||||
);
|
||||
}
|
||||
|
||||
if (session.statusPageId.toString() !== statusPageId.toString()) {
|
||||
await StatusPagePrivateUserSessionService.revokeSessionById(
|
||||
session.id,
|
||||
{
|
||||
reason: "Status page mismatch",
|
||||
},
|
||||
);
|
||||
|
||||
CookieUtil.removeCookie(res, CookieUtil.getUserTokenKey(statusPageId));
|
||||
CookieUtil.removeCookie(
|
||||
res,
|
||||
CookieUtil.getRefreshTokenKey(statusPageId),
|
||||
);
|
||||
|
||||
return Response.sendErrorResponse(
|
||||
req,
|
||||
res,
|
||||
new NotAuthenticatedException("Session expired. Please login again."),
|
||||
);
|
||||
}
|
||||
|
||||
if (
|
||||
session.refreshTokenExpiresAt &&
|
||||
OneUptimeDate.hasExpired(session.refreshTokenExpiresAt)
|
||||
) {
|
||||
await StatusPagePrivateUserSessionService.revokeSessionById(
|
||||
session.id,
|
||||
{
|
||||
reason: "Refresh token expired",
|
||||
},
|
||||
);
|
||||
|
||||
CookieUtil.removeCookie(res, CookieUtil.getUserTokenKey(statusPageId));
|
||||
CookieUtil.removeCookie(
|
||||
res,
|
||||
CookieUtil.getRefreshTokenKey(statusPageId),
|
||||
);
|
||||
|
||||
return Response.sendErrorResponse(
|
||||
req,
|
||||
res,
|
||||
new NotAuthenticatedException("Session expired. Please login again."),
|
||||
);
|
||||
}
|
||||
|
||||
if (!session.statusPagePrivateUserId) {
|
||||
await StatusPagePrivateUserSessionService.revokeSessionById(
|
||||
session.id,
|
||||
{
|
||||
reason: "Session missing user",
|
||||
},
|
||||
);
|
||||
|
||||
CookieUtil.removeCookie(res, CookieUtil.getUserTokenKey(statusPageId));
|
||||
CookieUtil.removeCookie(
|
||||
res,
|
||||
CookieUtil.getRefreshTokenKey(statusPageId),
|
||||
);
|
||||
|
||||
return Response.sendErrorResponse(
|
||||
req,
|
||||
res,
|
||||
new NotAuthenticatedException("Session expired. Please login again."),
|
||||
);
|
||||
}
|
||||
|
||||
const user: StatusPagePrivateUser | null =
|
||||
await StatusPagePrivateUserService.findOneById({
|
||||
id: session.statusPagePrivateUserId,
|
||||
props: {
|
||||
isRoot: true,
|
||||
},
|
||||
select: {
|
||||
_id: true,
|
||||
email: true,
|
||||
statusPageId: true,
|
||||
projectId: true,
|
||||
},
|
||||
});
|
||||
|
||||
if (!user) {
|
||||
await StatusPagePrivateUserSessionService.revokeSessionById(
|
||||
session.id,
|
||||
{
|
||||
reason: "User not found",
|
||||
},
|
||||
);
|
||||
|
||||
CookieUtil.removeCookie(res, CookieUtil.getUserTokenKey(statusPageId));
|
||||
CookieUtil.removeCookie(
|
||||
res,
|
||||
CookieUtil.getRefreshTokenKey(statusPageId),
|
||||
);
|
||||
|
||||
return Response.sendErrorResponse(
|
||||
req,
|
||||
res,
|
||||
new NotAuthenticatedException("Account no longer exists."),
|
||||
);
|
||||
}
|
||||
|
||||
const renewedSession: StatusPageSessionMetadata =
|
||||
await StatusPagePrivateUserSessionService.renewSessionWithNewRefreshToken(
|
||||
{
|
||||
session,
|
||||
ipAddress: getClientIp(req),
|
||||
userAgent: headerValueToString(req.headers["user-agent"]),
|
||||
...extractDeviceInfo(req),
|
||||
},
|
||||
);
|
||||
|
||||
const accessToken: string = CookieUtil.setStatusPagePrivateUserCookie({
|
||||
expressResponse: res,
|
||||
user,
|
||||
statusPageId: user.statusPageId!,
|
||||
sessionId: renewedSession.session.id!,
|
||||
refreshToken: renewedSession.refreshToken,
|
||||
refreshTokenExpiresAt: renewedSession.refreshTokenExpiresAt,
|
||||
accessTokenExpiresInSeconds: ACCESS_TOKEN_EXPIRY_SECONDS,
|
||||
});
|
||||
|
||||
return Response.sendEntityResponse(
|
||||
req,
|
||||
res,
|
||||
user,
|
||||
StatusPagePrivateUser,
|
||||
{
|
||||
miscData: {
|
||||
token: accessToken,
|
||||
},
|
||||
},
|
||||
);
|
||||
} catch (err) {
|
||||
return next(err);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
router.post(
|
||||
"/forgot-password",
|
||||
async (
|
||||
@@ -146,6 +414,8 @@ router.post(
|
||||
|
||||
const host: Hostname = await DatabaseConfig.getHost();
|
||||
const httpProtocol: Protocol = await DatabaseConfig.getHttpProtocol();
|
||||
const statusPageIdString: string | null =
|
||||
statusPage.id?.toString() || statusPage._id?.toString() || null;
|
||||
|
||||
MailService.sendMail(
|
||||
{
|
||||
@@ -154,12 +424,13 @@ router.post(
|
||||
templateType: EmailTemplateType.StatusPageForgotPassword,
|
||||
vars: {
|
||||
statusPageName: statusPageName!,
|
||||
logoUrl: statusPage.logoFileId
|
||||
? new URL(httpProtocol, host)
|
||||
.addRoute(FileRoute)
|
||||
.addRoute("/image/" + statusPage.logoFileId)
|
||||
.toString()
|
||||
: "",
|
||||
logoUrl:
|
||||
statusPage.logoFileId && statusPageIdString
|
||||
? new URL(httpProtocol, host)
|
||||
.addRoute(StatusPageApiRoute)
|
||||
.addRoute(`/logo/${statusPageIdString}`)
|
||||
.toString()
|
||||
: "",
|
||||
homeURL: statusPageURL,
|
||||
tokenVerifyUrl: URL.fromString(statusPageURL)
|
||||
.addRoute("/reset-password/" + token)
|
||||
@@ -288,6 +559,8 @@ router.post(
|
||||
|
||||
const host: Hostname = await DatabaseConfig.getHost();
|
||||
const httpProtocol: Protocol = await DatabaseConfig.getHttpProtocol();
|
||||
const statusPageIdString: string | null =
|
||||
statusPage.id?.toString() || statusPage._id?.toString() || null;
|
||||
|
||||
MailService.sendMail(
|
||||
{
|
||||
@@ -297,12 +570,13 @@ router.post(
|
||||
vars: {
|
||||
homeURL: statusPageURL,
|
||||
statusPageName: statusPageName || "",
|
||||
logoUrl: statusPage.logoFileId
|
||||
? new URL(httpProtocol, host)
|
||||
.addRoute(FileRoute)
|
||||
.addRoute("/image/" + statusPage.logoFileId)
|
||||
.toString()
|
||||
: "",
|
||||
logoUrl:
|
||||
statusPage.logoFileId && statusPageIdString
|
||||
? new URL(httpProtocol, host)
|
||||
.addRoute(StatusPageApiRoute)
|
||||
.addRoute(`/logo/${statusPageIdString}`)
|
||||
.toString()
|
||||
: "",
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -376,6 +650,7 @@ router.post(
|
||||
password: true,
|
||||
email: true,
|
||||
statusPageId: true,
|
||||
projectId: true,
|
||||
},
|
||||
props: {
|
||||
isRoot: true,
|
||||
@@ -383,31 +658,38 @@ router.post(
|
||||
});
|
||||
|
||||
if (alreadySavedUser) {
|
||||
const token: string = JSONWebToken.sign({
|
||||
data: alreadySavedUser,
|
||||
expiresInSeconds: OneUptimeDate.getSecondsInDays(
|
||||
new PositiveNumber(30),
|
||||
),
|
||||
const { accessToken } = await finalizeStatusPageLogin({
|
||||
req,
|
||||
res,
|
||||
user: alreadySavedUser,
|
||||
});
|
||||
|
||||
CookieUtil.setCookie(
|
||||
res,
|
||||
CookieUtil.getUserTokenKey(alreadySavedUser.statusPageId!),
|
||||
token,
|
||||
{
|
||||
httpOnly: true,
|
||||
maxAge: OneUptimeDate.getMillisecondsInDays(new PositiveNumber(30)),
|
||||
},
|
||||
);
|
||||
const sanitizedUser: StatusPagePrivateUser | null =
|
||||
await StatusPagePrivateUserService.findOneById({
|
||||
id: alreadySavedUser.id!,
|
||||
props: {
|
||||
isRoot: true,
|
||||
},
|
||||
select: {
|
||||
_id: true,
|
||||
email: true,
|
||||
statusPageId: true,
|
||||
projectId: true,
|
||||
},
|
||||
});
|
||||
|
||||
if (!sanitizedUser && (alreadySavedUser as any).password) {
|
||||
delete (alreadySavedUser as any).password;
|
||||
}
|
||||
|
||||
return Response.sendEntityResponse(
|
||||
req,
|
||||
res,
|
||||
alreadySavedUser,
|
||||
sanitizedUser || alreadySavedUser,
|
||||
StatusPagePrivateUser,
|
||||
{
|
||||
miscData: {
|
||||
token: token,
|
||||
token: accessToken,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import SSOUtil from "../Utils/SSO";
|
||||
import URL from "Common/Types/API/URL";
|
||||
import OneUptimeDate from "Common/Types/Date";
|
||||
import Email from "Common/Types/Email";
|
||||
import BadRequestException from "Common/Types/Exception/BadRequestException";
|
||||
import Exception from "Common/Types/Exception/Exception";
|
||||
@@ -8,9 +7,11 @@ import ServerException from "Common/Types/Exception/ServerException";
|
||||
import HashedString from "Common/Types/HashedString";
|
||||
import { JSONObject } from "Common/Types/JSON";
|
||||
import ObjectID from "Common/Types/ObjectID";
|
||||
import PositiveNumber from "Common/Types/PositiveNumber";
|
||||
import { Host, HttpProtocol } from "Common/Server/EnvironmentConfig";
|
||||
import StatusPagePrivateUserService from "Common/Server/Services/StatusPagePrivateUserService";
|
||||
import StatusPagePrivateUserSessionService, {
|
||||
SessionMetadata as StatusPageSessionMetadata,
|
||||
} from "Common/Server/Services/StatusPagePrivateUserSessionService";
|
||||
import StatusPageService from "Common/Server/Services/StatusPageService";
|
||||
import StatusPageSsoService from "Common/Server/Services/StatusPageSsoService";
|
||||
import CookieUtil from "Common/Server/Utils/Cookie";
|
||||
@@ -19,8 +20,10 @@ import Express, {
|
||||
ExpressResponse,
|
||||
ExpressRouter,
|
||||
NextFunction,
|
||||
extractDeviceInfo,
|
||||
getClientIp,
|
||||
headerValueToString,
|
||||
} from "Common/Server/Utils/Express";
|
||||
import JSONWebToken from "Common/Server/Utils/JsonWebToken";
|
||||
import logger from "Common/Server/Utils/Logger";
|
||||
import Response from "Common/Server/Utils/Response";
|
||||
import StatusPagePrivateUser from "Common/Models/DatabaseModels/StatusPagePrivateUser";
|
||||
@@ -30,6 +33,8 @@ import xml2js from "xml2js";
|
||||
// Initialize Express router.
|
||||
const router: ExpressRouter = Express.getRouter();
|
||||
|
||||
const ACCESS_TOKEN_EXPIRY_SECONDS: number = 15 * 60;
|
||||
|
||||
// Define a GET route for SSO in a status page context.
|
||||
router.get(
|
||||
"/status-page-sso/:statusPageId/:statusPageSsoId",
|
||||
@@ -285,24 +290,30 @@ router.post(
|
||||
});
|
||||
}
|
||||
|
||||
const token: string = JSONWebToken.sign({
|
||||
data: alreadySavedUser,
|
||||
expiresInSeconds: OneUptimeDate.getSecondsInDays(
|
||||
new PositiveNumber(30),
|
||||
),
|
||||
if (!alreadySavedUser.projectId) {
|
||||
alreadySavedUser.projectId = projectId;
|
||||
}
|
||||
|
||||
const sessionMetadata: StatusPageSessionMetadata =
|
||||
await StatusPagePrivateUserSessionService.createSession({
|
||||
projectId: alreadySavedUser.projectId!,
|
||||
statusPageId: statusPageId,
|
||||
statusPagePrivateUserId: alreadySavedUser.id!,
|
||||
ipAddress: getClientIp(req),
|
||||
userAgent: headerValueToString(req.headers["user-agent"]),
|
||||
...extractDeviceInfo(req),
|
||||
});
|
||||
|
||||
const token: string = CookieUtil.setStatusPagePrivateUserCookie({
|
||||
expressResponse: res,
|
||||
user: alreadySavedUser,
|
||||
statusPageId: statusPageId,
|
||||
sessionId: sessionMetadata.session.id!,
|
||||
refreshToken: sessionMetadata.refreshToken,
|
||||
refreshTokenExpiresAt: sessionMetadata.refreshTokenExpiresAt,
|
||||
accessTokenExpiresInSeconds: ACCESS_TOKEN_EXPIRY_SECONDS,
|
||||
});
|
||||
|
||||
CookieUtil.setCookie(
|
||||
res,
|
||||
CookieUtil.getUserTokenKey(alreadySavedUser.statusPageId!),
|
||||
token,
|
||||
|
||||
{
|
||||
httpOnly: true,
|
||||
maxAge: OneUptimeDate.getMillisecondsInDays(new PositiveNumber(30)),
|
||||
},
|
||||
);
|
||||
|
||||
// get status page URL.
|
||||
const statusPageURL: string =
|
||||
await StatusPageService.getStatusPageFirstURL(statusPageId);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import WhatsAppService from "../Services/WhatsAppService";
|
||||
import BadDataException from "Common/Types/Exception/BadDataException";
|
||||
import { JSONObject } from "Common/Types/JSON";
|
||||
import GlobalConfig from "Common/Models/DatabaseModels/GlobalConfig";
|
||||
import { JSONArray, JSONObject } from "Common/Types/JSON";
|
||||
import ObjectID from "Common/Types/ObjectID";
|
||||
import Phone from "Common/Types/Phone";
|
||||
import WhatsAppMessage from "Common/Types/WhatsApp/WhatsAppMessage";
|
||||
@@ -9,17 +10,214 @@ import {
|
||||
WhatsAppTemplateIds,
|
||||
WhatsAppTemplateLanguage,
|
||||
} from "Common/Types/WhatsApp/WhatsAppTemplates";
|
||||
import WhatsAppStatus from "Common/Types/WhatsAppStatus";
|
||||
import ClusterKeyAuthorization from "Common/Server/Middleware/ClusterKeyAuthorization";
|
||||
import WhatsAppLogService from "Common/Server/Services/WhatsAppLogService";
|
||||
import GlobalConfigService from "Common/Server/Services/GlobalConfigService";
|
||||
import Express, {
|
||||
ExpressRequest,
|
||||
ExpressResponse,
|
||||
ExpressRouter,
|
||||
NextFunction,
|
||||
} from "Common/Server/Utils/Express";
|
||||
import logger from "Common/Server/Utils/Logger";
|
||||
import Response from "Common/Server/Utils/Response";
|
||||
|
||||
const router: ExpressRouter = Express.getRouter();
|
||||
|
||||
const MAX_STATUS_MESSAGE_LENGTH: number = 500;
|
||||
|
||||
export const mapWebhookStatusToWhatsAppStatus: (
|
||||
status?: string,
|
||||
) => WhatsAppStatus = (status?: string): WhatsAppStatus => {
|
||||
switch ((status || "").toLowerCase()) {
|
||||
case "sent":
|
||||
return WhatsAppStatus.Sent;
|
||||
case "delivered":
|
||||
return WhatsAppStatus.Delivered;
|
||||
case "read":
|
||||
return WhatsAppStatus.Read;
|
||||
case "failed":
|
||||
return WhatsAppStatus.Failed;
|
||||
case "deleted":
|
||||
case "removed":
|
||||
return WhatsAppStatus.Deleted;
|
||||
case "warning":
|
||||
return WhatsAppStatus.Warning;
|
||||
case "queued":
|
||||
case "pending":
|
||||
return WhatsAppStatus.Queued;
|
||||
case "error":
|
||||
return WhatsAppStatus.Error;
|
||||
case "success":
|
||||
return WhatsAppStatus.Success;
|
||||
default:
|
||||
return WhatsAppStatus.Unknown;
|
||||
}
|
||||
};
|
||||
|
||||
export const buildStatusMessage: (payload: JSONObject) => string | undefined = (
|
||||
payload: JSONObject,
|
||||
): string | undefined => {
|
||||
const messageParts: Array<string> = [];
|
||||
const rawStatus: string | undefined = payload["status"]
|
||||
? String(payload["status"])
|
||||
: undefined;
|
||||
|
||||
if (rawStatus) {
|
||||
messageParts.push(`Status: ${rawStatus}`);
|
||||
}
|
||||
|
||||
const timestamp: string | undefined = payload["timestamp"]
|
||||
? String(payload["timestamp"])
|
||||
: undefined;
|
||||
|
||||
if (timestamp) {
|
||||
const numericTimestamp: number = Number(timestamp);
|
||||
if (!isNaN(numericTimestamp)) {
|
||||
messageParts.push(
|
||||
`Timestamp: ${new Date(numericTimestamp * 1000).toISOString()}`,
|
||||
);
|
||||
} else {
|
||||
messageParts.push(`Timestamp: ${timestamp}`);
|
||||
}
|
||||
}
|
||||
|
||||
const conversation: JSONObject | undefined =
|
||||
(payload["conversation"] as JSONObject | undefined) || undefined;
|
||||
|
||||
if (conversation) {
|
||||
if (conversation["id"]) {
|
||||
messageParts.push(`Conversation: ${conversation["id"]}`);
|
||||
}
|
||||
|
||||
const origin: JSONObject | undefined =
|
||||
(conversation["origin"] as JSONObject | undefined) || undefined;
|
||||
|
||||
if (origin?.["type"]) {
|
||||
messageParts.push(`Origin: ${origin["type"]}`);
|
||||
}
|
||||
|
||||
if (conversation["expiration_timestamp"]) {
|
||||
const expirationTimestamp: number = Number(
|
||||
conversation["expiration_timestamp"],
|
||||
);
|
||||
|
||||
if (!isNaN(expirationTimestamp)) {
|
||||
messageParts.push(
|
||||
`Conversation expires: ${new Date(expirationTimestamp * 1000).toISOString()}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const pricing: JSONObject | undefined =
|
||||
(payload["pricing"] as JSONObject | undefined) || undefined;
|
||||
|
||||
if (pricing) {
|
||||
const pricingParts: Array<string> = [];
|
||||
|
||||
if (pricing["billable"] !== undefined) {
|
||||
pricingParts.push(`billable=${pricing["billable"]}`);
|
||||
}
|
||||
|
||||
if (pricing["category"]) {
|
||||
pricingParts.push(`category=${pricing["category"]}`);
|
||||
}
|
||||
|
||||
if (pricing["pricing_model"]) {
|
||||
pricingParts.push(`model=${pricing["pricing_model"]}`);
|
||||
}
|
||||
|
||||
if (pricingParts.length > 0) {
|
||||
messageParts.push(`Pricing: ${pricingParts.join(", ")}`);
|
||||
}
|
||||
}
|
||||
|
||||
const errors: JSONArray | undefined =
|
||||
(payload["errors"] as JSONArray | undefined) || undefined;
|
||||
|
||||
if (Array.isArray(errors) && errors.length > 0) {
|
||||
const firstError: JSONObject = errors[0] as JSONObject;
|
||||
const errorParts: Array<string> = [];
|
||||
|
||||
if (firstError["title"]) {
|
||||
errorParts.push(String(firstError["title"]));
|
||||
}
|
||||
|
||||
if (firstError["code"]) {
|
||||
errorParts.push(`code=${firstError["code"]}`);
|
||||
}
|
||||
|
||||
if (firstError["detail"]) {
|
||||
errorParts.push(String(firstError["detail"]));
|
||||
}
|
||||
|
||||
if (errorParts.length > 0) {
|
||||
messageParts.push(`Error: ${errorParts.join(" - ")}`);
|
||||
}
|
||||
}
|
||||
|
||||
if (messageParts.length === 0) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const statusMessage: string = messageParts.join(" | ");
|
||||
|
||||
if (statusMessage.length <= MAX_STATUS_MESSAGE_LENGTH) {
|
||||
return statusMessage;
|
||||
}
|
||||
|
||||
return `${statusMessage.substring(0, MAX_STATUS_MESSAGE_LENGTH - 3)}...`;
|
||||
};
|
||||
|
||||
const updateWhatsAppLogStatus: (
|
||||
statusPayload: JSONObject,
|
||||
) => Promise<void> = async (statusPayload: JSONObject): Promise<void> => {
|
||||
const messageId: string | undefined = statusPayload["id"]
|
||||
? String(statusPayload["id"])
|
||||
: undefined;
|
||||
|
||||
if (!messageId) {
|
||||
logger.warn(
|
||||
`[Meta WhatsApp Webhook] Received status payload without message id. Payload: ${JSON.stringify(statusPayload)}`,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
const rawStatus: string | undefined = statusPayload["status"]
|
||||
? String(statusPayload["status"])
|
||||
: undefined;
|
||||
|
||||
const derivedStatus: WhatsAppStatus =
|
||||
mapWebhookStatusToWhatsAppStatus(rawStatus);
|
||||
|
||||
const statusMessage: string | undefined = buildStatusMessage(statusPayload);
|
||||
|
||||
const updateResult: number = await WhatsAppLogService.updateOneBy({
|
||||
query: {
|
||||
whatsAppMessageId: messageId,
|
||||
},
|
||||
data: {
|
||||
status: derivedStatus,
|
||||
...(statusMessage ? { statusMessage } : {}),
|
||||
},
|
||||
props: {
|
||||
isRoot: true,
|
||||
},
|
||||
});
|
||||
|
||||
if (updateResult === 0) {
|
||||
logger.warn(
|
||||
`[Meta WhatsApp Webhook] No WhatsApp log found for message id ${messageId}. Payload: ${JSON.stringify(statusPayload)}`,
|
||||
);
|
||||
} else {
|
||||
logger.debug(
|
||||
`[Meta WhatsApp Webhook] Updated WhatsApp log for message id ${messageId} with status ${derivedStatus}.`,
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const toTemplateVariables: (
|
||||
rawVariables: JSONObject | undefined,
|
||||
) => Record<string, string> | undefined = (
|
||||
@@ -119,6 +317,128 @@ router.post(
|
||||
},
|
||||
);
|
||||
|
||||
router.get("/webhook", async (req: ExpressRequest, res: ExpressResponse) => {
|
||||
const mode: string | undefined = req.query["hub.mode"]
|
||||
? String(req.query["hub.mode"])
|
||||
: undefined;
|
||||
const verifyToken: string | undefined = req.query["hub.verify_token"]
|
||||
? String(req.query["hub.verify_token"])
|
||||
: undefined;
|
||||
const challenge: string | undefined = req.query["hub.challenge"]
|
||||
? String(req.query["hub.challenge"])
|
||||
: undefined;
|
||||
|
||||
if (mode === "subscribe" && challenge) {
|
||||
const globalConfigTokenResponse: GlobalConfig | null =
|
||||
await GlobalConfigService.findOneBy({
|
||||
query: {
|
||||
_id: ObjectID.getZeroObjectID().toString(),
|
||||
},
|
||||
props: {
|
||||
isRoot: true,
|
||||
},
|
||||
select: {
|
||||
metaWhatsAppWebhookVerifyToken: true,
|
||||
},
|
||||
});
|
||||
|
||||
const configuredVerifyToken: string | undefined =
|
||||
globalConfigTokenResponse?.metaWhatsAppWebhookVerifyToken?.trim() ||
|
||||
undefined;
|
||||
|
||||
if (!configuredVerifyToken) {
|
||||
logger.error(
|
||||
"Meta WhatsApp webhook verify token is not configured. Rejecting verification request.",
|
||||
);
|
||||
res.sendStatus(403);
|
||||
return;
|
||||
}
|
||||
|
||||
if (verifyToken === configuredVerifyToken) {
|
||||
res.status(200).send(challenge);
|
||||
return;
|
||||
}
|
||||
|
||||
logger.warn(
|
||||
"Meta WhatsApp webhook verification failed due to token mismatch.",
|
||||
);
|
||||
res.sendStatus(403);
|
||||
return;
|
||||
}
|
||||
|
||||
res.sendStatus(400);
|
||||
});
|
||||
|
||||
router.post(
|
||||
"/webhook",
|
||||
async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => {
|
||||
try {
|
||||
const body: JSONObject = req.body as JSONObject;
|
||||
|
||||
if (
|
||||
(body["object"] as string | undefined) !== "whatsapp_business_account"
|
||||
) {
|
||||
logger.debug(
|
||||
`[Meta WhatsApp Webhook] Received event for unsupported object: ${JSON.stringify(body)}`,
|
||||
);
|
||||
return Response.sendEmptySuccessResponse(req, res);
|
||||
}
|
||||
|
||||
const entries: JSONArray | undefined = body["entry"] as
|
||||
| JSONArray
|
||||
| undefined;
|
||||
|
||||
if (!Array.isArray(entries)) {
|
||||
logger.warn(
|
||||
`[Meta WhatsApp Webhook] Payload did not include entries array. Payload: ${JSON.stringify(body)}`,
|
||||
);
|
||||
return Response.sendEmptySuccessResponse(req, res);
|
||||
}
|
||||
|
||||
const statusUpdatePromises: Array<Promise<void>> = [];
|
||||
|
||||
for (const entry of entries) {
|
||||
const entryObject: JSONObject = entry as JSONObject;
|
||||
const changes: JSONArray | undefined =
|
||||
(entryObject["changes"] as JSONArray | undefined) || undefined;
|
||||
|
||||
if (!Array.isArray(changes)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (const change of changes) {
|
||||
const changeObject: JSONObject = change as JSONObject;
|
||||
const value: JSONObject | undefined =
|
||||
(changeObject["value"] as JSONObject | undefined) || undefined;
|
||||
|
||||
if (!value) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const statuses: JSONArray | undefined =
|
||||
(value["statuses"] as JSONArray | undefined) || undefined;
|
||||
|
||||
if (Array.isArray(statuses)) {
|
||||
for (const statusItem of statuses) {
|
||||
statusUpdatePromises.push(
|
||||
updateWhatsAppLogStatus(statusItem as JSONObject),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (statusUpdatePromises.length > 0) {
|
||||
await Promise.allSettled(statusUpdatePromises);
|
||||
}
|
||||
|
||||
return Response.sendEmptySuccessResponse(req, res);
|
||||
} catch (err) {
|
||||
return next(err);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
router.post(
|
||||
"/test",
|
||||
async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => {
|
||||
|
||||
@@ -68,8 +68,6 @@ export default class WhatsAppService {
|
||||
);
|
||||
}
|
||||
|
||||
const config: MetaWhatsAppConfig = await getMetaWhatsAppConfig();
|
||||
|
||||
const isSensitiveMessage: boolean = Boolean(options.isSensitive);
|
||||
const messageSummary: string = isSensitiveMessage
|
||||
? SENSITIVE_MESSAGE_PLACEHOLDER
|
||||
@@ -131,6 +129,8 @@ export default class WhatsAppService {
|
||||
whatsAppLog.onCallDutyPolicyScheduleId = options.onCallScheduleId;
|
||||
}
|
||||
|
||||
const config: MetaWhatsAppConfig = await getMetaWhatsAppConfig();
|
||||
|
||||
let messageCost: number = 0;
|
||||
const shouldChargeForMessage: boolean = IsBillingEnabled;
|
||||
|
||||
@@ -417,7 +417,11 @@ export default class WhatsAppService {
|
||||
}
|
||||
}
|
||||
|
||||
whatsAppLog.status = WhatsAppStatus.Success;
|
||||
if (messageId) {
|
||||
whatsAppLog.whatsAppMessageId = messageId;
|
||||
}
|
||||
|
||||
whatsAppLog.status = WhatsAppStatus.Sent;
|
||||
whatsAppLog.statusMessage = messageId
|
||||
? `Message ID: ${messageId}`
|
||||
: "WhatsApp message sent successfully";
|
||||
@@ -470,10 +474,14 @@ export default class WhatsAppService {
|
||||
await UserOnCallLogTimelineService.updateOneById({
|
||||
id: options.userOnCallLogTimelineId,
|
||||
data: {
|
||||
status:
|
||||
whatsAppLog.status === WhatsAppStatus.Success
|
||||
? UserNotificationStatus.Sent
|
||||
: UserNotificationStatus.Error,
|
||||
status: [
|
||||
WhatsAppStatus.Success,
|
||||
WhatsAppStatus.Sent,
|
||||
WhatsAppStatus.Delivered,
|
||||
WhatsAppStatus.Read,
|
||||
].includes(whatsAppLog.status || WhatsAppStatus.Error)
|
||||
? UserNotificationStatus.Sent
|
||||
: UserNotificationStatus.Error,
|
||||
statusMessage: whatsAppLog.statusMessage,
|
||||
},
|
||||
props: {
|
||||
|
||||
@@ -42,8 +42,11 @@
|
||||
{{> InfoBlock info=(concat subscriberEmailNotificationFooterText "") }}
|
||||
|
||||
|
||||
{{> InfoBlock info="You can visit the status page here:"}}
|
||||
{{> InfoBlock info=statusPageUrl}}
|
||||
{{#if detailsUrl}}
|
||||
{{> InfoBlock info=(concat "Find further information here: " detailsUrl)}}
|
||||
{{else}}
|
||||
{{> InfoBlock info=(concat "Find further information here: " statusPageUrl)}}
|
||||
{{/if}}
|
||||
|
||||
{{> UnsubscribeBlock this}}
|
||||
{{> VerticalSpace this}}
|
||||
|
||||
@@ -13,8 +13,11 @@
|
||||
{{> InfoBlock info=(concat subscriberEmailNotificationFooterText "") }}
|
||||
|
||||
|
||||
{{> InfoBlock info="You can visit the status page here:"}}
|
||||
{{> InfoBlock info=statusPageUrl}}
|
||||
{{#if detailsUrl}}
|
||||
{{> InfoBlock info=(concat "Find further information here: " detailsUrl)}}
|
||||
{{else}}
|
||||
{{> InfoBlock info=(concat "Find further information here: " statusPageUrl)}}
|
||||
{{/if}}
|
||||
|
||||
{{> UnsubscribeBlock this}}
|
||||
|
||||
|
||||
@@ -20,8 +20,11 @@
|
||||
{{> InfoBlock info=(concat subscriberEmailNotificationFooterText "") }}
|
||||
|
||||
|
||||
{{> InfoBlock info="You can visit the status page here:"}}
|
||||
{{> InfoBlock info=statusPageUrl}}
|
||||
{{#if detailsUrl}}
|
||||
{{> InfoBlock info=(concat "Find further information here: " detailsUrl)}}
|
||||
{{else}}
|
||||
{{> InfoBlock info=(concat "Find further information here: " statusPageUrl)}}
|
||||
{{/if}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -17,8 +17,11 @@
|
||||
{{> InfoBlock info=(concat subscriberEmailNotificationFooterText "") }}
|
||||
|
||||
|
||||
{{> InfoBlock info="You can visit the status page here:"}}
|
||||
{{> InfoBlock info=statusPageUrl}}
|
||||
{{#if detailsUrl}}
|
||||
{{> InfoBlock info=(concat "Find further information here: " detailsUrl)}}
|
||||
{{else}}
|
||||
{{> InfoBlock info=(concat "Find further information here: " statusPageUrl)}}
|
||||
{{/if}}
|
||||
|
||||
{{> UnsubscribeBlock this}}
|
||||
{{> VerticalSpace this}}
|
||||
|
||||
@@ -14,8 +14,11 @@
|
||||
|
||||
{{> InfoBlock info=(concat subscriberEmailNotificationFooterText "") }}
|
||||
|
||||
{{> InfoBlock info="You can visit the status page here:"}}
|
||||
{{> InfoBlock info=statusPageUrl}}
|
||||
{{#if detailsUrl}}
|
||||
{{> InfoBlock info=(concat "Find further information here: " detailsUrl)}}
|
||||
{{else}}
|
||||
{{> InfoBlock info=(concat "Find further information here: " statusPageUrl)}}
|
||||
{{/if}}
|
||||
|
||||
{{> UnsubscribeBlock this}}
|
||||
{{> VerticalSpace this}}
|
||||
|
||||
@@ -24,8 +24,11 @@
|
||||
{{> InfoBlock info=(concat subscriberEmailNotificationFooterText "") }}
|
||||
|
||||
|
||||
{{> InfoBlock info="You can visit the status page here:"}}
|
||||
{{> InfoBlock info=statusPageUrl}}
|
||||
{{#if detailsUrl}}
|
||||
{{> InfoBlock info=(concat "Find further information here: " detailsUrl)}}
|
||||
{{else}}
|
||||
{{> InfoBlock info=(concat "Find further information here: " statusPageUrl)}}
|
||||
{{/if}}
|
||||
|
||||
{{> UnsubscribeBlock this}}
|
||||
{{> VerticalSpace this}}
|
||||
|
||||
@@ -25,8 +25,11 @@
|
||||
{{> InfoBlock info=(concat subscriberEmailNotificationFooterText "") }}
|
||||
|
||||
|
||||
{{> InfoBlock info="You can visit the status page here:"}}
|
||||
{{> InfoBlock info=statusPageUrl}}
|
||||
{{#if detailsUrl}}
|
||||
{{> InfoBlock info=(concat "Find further information here: " detailsUrl)}}
|
||||
{{else}}
|
||||
{{> InfoBlock info=(concat "Find further information here: " statusPageUrl)}}
|
||||
{{/if}}
|
||||
|
||||
{{> UnsubscribeBlock this}}
|
||||
{{> VerticalSpace this}}
|
||||
|
||||
@@ -20,8 +20,11 @@
|
||||
{{> InfoBlock info=(concat subscriberEmailNotificationFooterText "") }}
|
||||
|
||||
|
||||
{{> InfoBlock info="You can visit the status page here:"}}
|
||||
{{> InfoBlock info=statusPageUrl}}
|
||||
{{#if detailsUrl}}
|
||||
{{> InfoBlock info=(concat "Find further information here: " detailsUrl)}}
|
||||
{{else}}
|
||||
{{> InfoBlock info=(concat "Find further information here: " statusPageUrl)}}
|
||||
{{/if}}
|
||||
|
||||
{{> UnsubscribeBlock this}}
|
||||
{{> VerticalSpace this}}
|
||||
|
||||
566
App/package-lock.json
generated
566
App/package-lock.json
generated
@@ -41,25 +41,26 @@
|
||||
"@elastic/elasticsearch": "^8.12.1",
|
||||
"@monaco-editor/react": "^4.4.6",
|
||||
"@opentelemetry/api": "^1.9.0",
|
||||
"@opentelemetry/api-logs": "^0.52.1",
|
||||
"@opentelemetry/api-logs": "^0.206.0",
|
||||
"@opentelemetry/context-zone": "^1.25.1",
|
||||
"@opentelemetry/exporter-logs-otlp-http": "^0.52.1",
|
||||
"@opentelemetry/exporter-metrics-otlp-proto": "^0.52.1",
|
||||
"@opentelemetry/exporter-trace-otlp-http": "^0.52.1",
|
||||
"@opentelemetry/exporter-trace-otlp-proto": "^0.52.1",
|
||||
"@opentelemetry/exporter-logs-otlp-http": "^0.207.0",
|
||||
"@opentelemetry/exporter-metrics-otlp-proto": "^0.207.0",
|
||||
"@opentelemetry/exporter-trace-otlp-http": "^0.207.0",
|
||||
"@opentelemetry/exporter-trace-otlp-proto": "^0.207.0",
|
||||
"@opentelemetry/id-generator-aws-xray": "^1.2.2",
|
||||
"@opentelemetry/instrumentation": "^0.52.1",
|
||||
"@opentelemetry/instrumentation-fetch": "^0.52.1",
|
||||
"@opentelemetry/instrumentation-xml-http-request": "^0.52.1",
|
||||
"@opentelemetry/instrumentation": "^0.207.0",
|
||||
"@opentelemetry/instrumentation-fetch": "^0.207.0",
|
||||
"@opentelemetry/instrumentation-xml-http-request": "^0.207.0",
|
||||
"@opentelemetry/resources": "^1.25.1",
|
||||
"@opentelemetry/sdk-logs": "^0.52.1",
|
||||
"@opentelemetry/sdk-logs": "^0.207.0",
|
||||
"@opentelemetry/sdk-metrics": "^1.25.1",
|
||||
"@opentelemetry/sdk-node": "^0.52.1",
|
||||
"@opentelemetry/sdk-trace-node": "^1.25.1",
|
||||
"@opentelemetry/sdk-node": "^0.207.0",
|
||||
"@opentelemetry/sdk-trace-web": "^1.25.1",
|
||||
"@opentelemetry/semantic-conventions": "^1.26.0",
|
||||
"@opentelemetry/semantic-conventions": "^1.37.0",
|
||||
"@remixicon/react": "^4.2.0",
|
||||
"@simplewebauthn/server": "^13.2.2",
|
||||
"@tippyjs/react": "^4.2.6",
|
||||
"@types/archiver": "^6.0.3",
|
||||
"@types/crypto-js": "^4.2.2",
|
||||
"@types/qrcode": "^1.5.5",
|
||||
"@types/react-highlight": "^0.12.8",
|
||||
@@ -68,8 +69,10 @@
|
||||
"@types/web-push": "^3.6.4",
|
||||
"acme-client": "^5.3.0",
|
||||
"airtable": "^0.12.2",
|
||||
"axios": "^1.7.2",
|
||||
"bullmq": "^5.3.3",
|
||||
"archiver": "^7.0.1",
|
||||
"axios": "^1.12.0",
|
||||
"botbuilder": "^4.23.3",
|
||||
"bullmq": "^5.61.0",
|
||||
"cookie-parser": "^1.4.7",
|
||||
"cors": "^2.8.5",
|
||||
"cron-parser": "^4.8.1",
|
||||
@@ -90,26 +93,26 @@
|
||||
"moment": "^2.30.1",
|
||||
"moment-timezone": "^0.5.45",
|
||||
"node-cron": "^3.0.3",
|
||||
"nodemailer": "^6.9.10",
|
||||
"nodemailer": "^7.0.7",
|
||||
"otpauth": "^9.3.1",
|
||||
"pg": "^8.7.3",
|
||||
"playwright": "^1.50.0",
|
||||
"posthog-js": "^1.139.6",
|
||||
"pg": "^8.16.3",
|
||||
"playwright": "^1.56.0",
|
||||
"posthog-js": "^1.275.3",
|
||||
"prop-types": "^15.8.1",
|
||||
"qrcode": "^1.5.3",
|
||||
"react": "^18.3.1",
|
||||
"react-beautiful-dnd": "^13.1.1",
|
||||
"react-big-calendar": "^1.13.0",
|
||||
"react-big-calendar": "^1.19.4",
|
||||
"react-color": "^2.19.3",
|
||||
"react-dom": "^18.3.1",
|
||||
"react-dropzone": "^14.2.2",
|
||||
"react-error-boundary": "^4.0.13",
|
||||
"react-highlight": "^0.15.0",
|
||||
"react-markdown": "^8.0.3",
|
||||
"react-router-dom": "^6.24.1",
|
||||
"react-router-dom": "^6.30.1",
|
||||
"react-select": "^5.4.0",
|
||||
"react-spinners": "^0.14.1",
|
||||
"react-syntax-highlighter": "^15.5.0",
|
||||
"react-syntax-highlighter": "^16.0.0",
|
||||
"react-toggle": "^4.1.3",
|
||||
"reactflow": "^11.11.4",
|
||||
"recharts": "^2.12.7",
|
||||
@@ -121,16 +124,16 @@
|
||||
"socket.io": "^4.7.4",
|
||||
"socket.io-client": "^4.7.5",
|
||||
"stripe": "^10.17.0",
|
||||
"tailwind-merge": "^2.5.2",
|
||||
"tailwind-merge": "^2.6.0",
|
||||
"tippy.js": "^6.3.7",
|
||||
"twilio": "^4.22.0",
|
||||
"typeorm": "^0.3.20",
|
||||
"typeorm": "^0.3.26",
|
||||
"typeorm-extension": "^2.2.13",
|
||||
"universal-cookie": "^7.2.1",
|
||||
"use-async-effect": "^2.2.6",
|
||||
"uuid": "^8.3.2",
|
||||
"web-push": "^3.6.7",
|
||||
"zod": "^3.25.30"
|
||||
"zod": "^3.25.76"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@faker-js/faker": "^8.0.2",
|
||||
@@ -253,89 +256,20 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/code-frame": {
|
||||
"version": "7.23.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz",
|
||||
"integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==",
|
||||
"version": "7.27.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz",
|
||||
"integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/highlight": "^7.23.4",
|
||||
"chalk": "^2.4.2"
|
||||
"@babel/helper-validator-identifier": "^7.27.1",
|
||||
"js-tokens": "^4.0.0",
|
||||
"picocolors": "^1.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/code-frame/node_modules/ansi-styles": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
|
||||
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"color-convert": "^1.9.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/code-frame/node_modules/chalk": {
|
||||
"version": "2.4.2",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
|
||||
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"ansi-styles": "^3.2.1",
|
||||
"escape-string-regexp": "^1.0.5",
|
||||
"supports-color": "^5.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/code-frame/node_modules/color-convert": {
|
||||
"version": "1.9.3",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
|
||||
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"color-name": "1.1.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/code-frame/node_modules/color-name": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
|
||||
"integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@babel/code-frame/node_modules/escape-string-regexp": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
|
||||
"integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/code-frame/node_modules/has-flag": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
|
||||
"integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/code-frame/node_modules/supports-color": {
|
||||
"version": "5.5.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
|
||||
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"has-flag": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/compat-data": {
|
||||
"version": "7.23.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.5.tgz",
|
||||
@@ -511,19 +445,21 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/helper-string-parser": {
|
||||
"version": "7.23.4",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz",
|
||||
"integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==",
|
||||
"version": "7.27.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz",
|
||||
"integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/helper-validator-identifier": {
|
||||
"version": "7.22.20",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz",
|
||||
"integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==",
|
||||
"version": "7.28.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz",
|
||||
"integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
@@ -538,109 +474,28 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/helpers": {
|
||||
"version": "7.23.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.6.tgz",
|
||||
"integrity": "sha512-wCfsbN4nBidDRhpDhvcKlzHWCTlgJYUUdSJfzXb2NuBssDSIjc3xcb+znA7l+zYsFljAcGM0aFkN40cR3lXiGA==",
|
||||
"version": "7.28.4",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.4.tgz",
|
||||
"integrity": "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/template": "^7.22.15",
|
||||
"@babel/traverse": "^7.23.6",
|
||||
"@babel/types": "^7.23.6"
|
||||
"@babel/template": "^7.27.2",
|
||||
"@babel/types": "^7.28.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/highlight": {
|
||||
"version": "7.23.4",
|
||||
"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz",
|
||||
"integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/helper-validator-identifier": "^7.22.20",
|
||||
"chalk": "^2.4.2",
|
||||
"js-tokens": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/highlight/node_modules/ansi-styles": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
|
||||
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"color-convert": "^1.9.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/highlight/node_modules/chalk": {
|
||||
"version": "2.4.2",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
|
||||
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"ansi-styles": "^3.2.1",
|
||||
"escape-string-regexp": "^1.0.5",
|
||||
"supports-color": "^5.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/highlight/node_modules/color-convert": {
|
||||
"version": "1.9.3",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
|
||||
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"color-name": "1.1.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/highlight/node_modules/color-name": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
|
||||
"integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@babel/highlight/node_modules/escape-string-regexp": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
|
||||
"integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/highlight/node_modules/has-flag": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
|
||||
"integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/highlight/node_modules/supports-color": {
|
||||
"version": "5.5.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
|
||||
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"has-flag": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/parser": {
|
||||
"version": "7.23.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.6.tgz",
|
||||
"integrity": "sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==",
|
||||
"version": "7.28.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.5.tgz",
|
||||
"integrity": "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/types": "^7.28.5"
|
||||
},
|
||||
"bin": {
|
||||
"parser": "bin/babel-parser.js"
|
||||
},
|
||||
@@ -811,14 +666,15 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/template": {
|
||||
"version": "7.22.15",
|
||||
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz",
|
||||
"integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==",
|
||||
"version": "7.27.2",
|
||||
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz",
|
||||
"integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/code-frame": "^7.22.13",
|
||||
"@babel/parser": "^7.22.15",
|
||||
"@babel/types": "^7.22.15"
|
||||
"@babel/code-frame": "^7.27.1",
|
||||
"@babel/parser": "^7.27.2",
|
||||
"@babel/types": "^7.27.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
@@ -846,14 +702,14 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/types": {
|
||||
"version": "7.23.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.6.tgz",
|
||||
"integrity": "sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg==",
|
||||
"version": "7.28.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.5.tgz",
|
||||
"integrity": "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-string-parser": "^7.23.4",
|
||||
"@babel/helper-validator-identifier": "^7.22.20",
|
||||
"to-fast-properties": "^2.0.0"
|
||||
"@babel/helper-string-parser": "^7.27.1",
|
||||
"@babel/helper-validator-identifier": "^7.28.5"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
@@ -1745,15 +1601,17 @@
|
||||
"node_modules/asynckit": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
||||
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
|
||||
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/axios": {
|
||||
"version": "1.6.2",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.6.2.tgz",
|
||||
"integrity": "sha512-7i24Ri4pmDRfJTR7LDBhsOTtcm+9kjX5WiY1X3wIisx6G9So3pfMkEiU7emUBe46oceVImccTEM3k6C5dbVW8A==",
|
||||
"version": "1.13.1",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.13.1.tgz",
|
||||
"integrity": "sha512-hU4EGxxt+j7TQijx1oYdAjw4xuIp1wRQSsbMFwSthCWeBQur1eF+qJ5iQ5sN3Tw8YRzQNKb8jszgBdMDVqwJcw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"follow-redirects": "^1.15.0",
|
||||
"form-data": "^4.0.0",
|
||||
"follow-redirects": "^1.15.6",
|
||||
"form-data": "^4.0.4",
|
||||
"proxy-from-env": "^1.1.0"
|
||||
}
|
||||
},
|
||||
@@ -1863,21 +1721,23 @@
|
||||
}
|
||||
},
|
||||
"node_modules/brace-expansion": {
|
||||
"version": "1.1.11",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
||||
"version": "1.1.12",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
|
||||
"integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"balanced-match": "^1.0.0",
|
||||
"concat-map": "0.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/braces": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
|
||||
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
|
||||
"integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"fill-range": "^7.0.1"
|
||||
"fill-range": "^7.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
@@ -1948,6 +1808,19 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/call-bind-apply-helpers": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
|
||||
"integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"es-errors": "^1.3.0",
|
||||
"function-bind": "^1.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/callsites": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
|
||||
@@ -2108,6 +1981,7 @@
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
|
||||
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"delayed-stream": "~1.0.0"
|
||||
},
|
||||
@@ -2136,10 +2010,11 @@
|
||||
"integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ=="
|
||||
},
|
||||
"node_modules/cross-spawn": {
|
||||
"version": "7.0.3",
|
||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
|
||||
"integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
|
||||
"version": "7.0.6",
|
||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
|
||||
"integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"path-key": "^3.1.0",
|
||||
"shebang-command": "^2.0.0",
|
||||
@@ -2201,6 +2076,7 @@
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.4.0"
|
||||
}
|
||||
@@ -2231,6 +2107,20 @@
|
||||
"node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/dunder-proto": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
|
||||
"integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"call-bind-apply-helpers": "^1.0.1",
|
||||
"es-errors": "^1.3.0",
|
||||
"gopd": "^1.2.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/ecdsa-sig-formatter": {
|
||||
"version": "1.0.11",
|
||||
"resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
|
||||
@@ -2240,9 +2130,10 @@
|
||||
}
|
||||
},
|
||||
"node_modules/ejs": {
|
||||
"version": "3.1.9",
|
||||
"resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.9.tgz",
|
||||
"integrity": "sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ==",
|
||||
"version": "3.1.10",
|
||||
"resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz",
|
||||
"integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"jake": "^10.8.5"
|
||||
},
|
||||
@@ -2286,6 +2177,51 @@
|
||||
"is-arrayish": "^0.2.1"
|
||||
}
|
||||
},
|
||||
"node_modules/es-define-property": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
|
||||
"integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/es-errors": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
|
||||
"integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/es-object-atoms": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
|
||||
"integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"es-errors": "^1.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/es-set-tostringtag": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
|
||||
"integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"es-errors": "^1.3.0",
|
||||
"get-intrinsic": "^1.2.6",
|
||||
"has-tostringtag": "^1.0.2",
|
||||
"hasown": "^2.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/escalade": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
|
||||
@@ -2389,9 +2325,10 @@
|
||||
}
|
||||
},
|
||||
"node_modules/filelist/node_modules/brace-expansion": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
|
||||
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
|
||||
"integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"balanced-match": "^1.0.0"
|
||||
}
|
||||
@@ -2408,10 +2345,11 @@
|
||||
}
|
||||
},
|
||||
"node_modules/fill-range": {
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
|
||||
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
|
||||
"version": "7.1.1",
|
||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
|
||||
"integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"to-regex-range": "^5.0.1"
|
||||
},
|
||||
@@ -2433,15 +2371,16 @@
|
||||
}
|
||||
},
|
||||
"node_modules/follow-redirects": {
|
||||
"version": "1.15.3",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz",
|
||||
"integrity": "sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==",
|
||||
"version": "1.15.11",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz",
|
||||
"integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
"url": "https://github.com/sponsors/RubenVerborgh"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=4.0"
|
||||
},
|
||||
@@ -2452,12 +2391,15 @@
|
||||
}
|
||||
},
|
||||
"node_modules/form-data": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
|
||||
"integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
|
||||
"version": "4.0.4",
|
||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz",
|
||||
"integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"asynckit": "^0.4.0",
|
||||
"combined-stream": "^1.0.8",
|
||||
"es-set-tostringtag": "^2.1.0",
|
||||
"hasown": "^2.0.2",
|
||||
"mime-types": "^2.1.12"
|
||||
},
|
||||
"engines": {
|
||||
@@ -2511,14 +2453,24 @@
|
||||
}
|
||||
},
|
||||
"node_modules/get-intrinsic": {
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz",
|
||||
"integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==",
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
|
||||
"integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"call-bind-apply-helpers": "^1.0.2",
|
||||
"es-define-property": "^1.0.1",
|
||||
"es-errors": "^1.3.0",
|
||||
"es-object-atoms": "^1.1.1",
|
||||
"function-bind": "^1.1.2",
|
||||
"has-proto": "^1.0.1",
|
||||
"has-symbols": "^1.0.3",
|
||||
"hasown": "^2.0.0"
|
||||
"get-proto": "^1.0.1",
|
||||
"gopd": "^1.2.0",
|
||||
"has-symbols": "^1.1.0",
|
||||
"hasown": "^2.0.2",
|
||||
"math-intrinsics": "^1.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
@@ -2533,6 +2485,19 @@
|
||||
"node": ">=8.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/get-proto": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
|
||||
"integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"dunder-proto": "^1.0.1",
|
||||
"es-object-atoms": "^1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/get-stream": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz",
|
||||
@@ -2587,11 +2552,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/gopd": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz",
|
||||
"integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==",
|
||||
"dependencies": {
|
||||
"get-intrinsic": "^1.1.3"
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
|
||||
"integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
@@ -2642,10 +2608,11 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/has-proto": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz",
|
||||
"integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==",
|
||||
"node_modules/has-symbols": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
|
||||
"integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
@@ -2653,10 +2620,14 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/has-symbols": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
|
||||
"integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
|
||||
"node_modules/has-tostringtag": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
|
||||
"integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"has-symbols": "^1.0.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
@@ -2665,9 +2636,10 @@
|
||||
}
|
||||
},
|
||||
"node_modules/hasown": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz",
|
||||
"integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==",
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
|
||||
"integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"function-bind": "^1.1.2"
|
||||
},
|
||||
@@ -2826,6 +2798,7 @@
|
||||
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
|
||||
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.12.0"
|
||||
}
|
||||
@@ -3523,13 +3496,15 @@
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
|
||||
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/js-yaml": {
|
||||
"version": "3.14.1",
|
||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
|
||||
"integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
|
||||
"version": "3.14.2",
|
||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz",
|
||||
"integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"argparse": "^1.0.7",
|
||||
"esprima": "^4.0.0"
|
||||
@@ -3780,6 +3755,15 @@
|
||||
"tmpl": "1.0.5"
|
||||
}
|
||||
},
|
||||
"node_modules/math-intrinsics": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
|
||||
"integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/merge-stream": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
|
||||
@@ -3787,12 +3771,13 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/micromatch": {
|
||||
"version": "4.0.5",
|
||||
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
|
||||
"integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
|
||||
"version": "4.0.8",
|
||||
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
|
||||
"integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"braces": "^3.0.2",
|
||||
"braces": "^3.0.3",
|
||||
"picomatch": "^2.3.1"
|
||||
},
|
||||
"engines": {
|
||||
@@ -3803,6 +3788,7 @@
|
||||
"version": "1.52.0",
|
||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
|
||||
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
@@ -3811,6 +3797,7 @@
|
||||
"version": "2.1.35",
|
||||
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
|
||||
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"mime-db": "1.52.0"
|
||||
},
|
||||
@@ -3875,9 +3862,10 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/nodemailer": {
|
||||
"version": "6.9.7",
|
||||
"resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.9.7.tgz",
|
||||
"integrity": "sha512-rUtR77ksqex/eZRLmQ21LKVH5nAAsVicAtAYudK7JgwenEDZ0UIQ1adUGqErz7sMkWYxWTTU1aeP2Jga6WQyJw==",
|
||||
"version": "6.10.1",
|
||||
"resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.10.1.tgz",
|
||||
"integrity": "sha512-Z+iLaBGVaSjbIzQ4pX6XV41HrooLsQ10ZWPUehGmuantvzWoDVBnmsdUcOIDM1t+yPor5pDhVlDESgOMEGxhHA==",
|
||||
"license": "MIT-0",
|
||||
"engines": {
|
||||
"node": ">=6.0.0"
|
||||
}
|
||||
@@ -4120,10 +4108,11 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/picocolors": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
|
||||
"integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
|
||||
"dev": true
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
|
||||
"integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/picomatch": {
|
||||
"version": "2.3.1",
|
||||
@@ -4627,20 +4616,12 @@
|
||||
"integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/to-fast-properties": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
|
||||
"integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/to-regex-range": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
||||
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"is-number": "^7.0.0"
|
||||
},
|
||||
@@ -4910,9 +4891,10 @@
|
||||
}
|
||||
},
|
||||
"node_modules/xml-crypto": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/xml-crypto/-/xml-crypto-3.2.0.tgz",
|
||||
"integrity": "sha512-qVurBUOQrmvlgmZqIVBqmb06TD2a/PpEUfFPgD7BuBfjmoH4zgkqaWSIJrnymlCvM2GGt9x+XtJFA+ttoAufqg==",
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/xml-crypto/-/xml-crypto-3.2.1.tgz",
|
||||
"integrity": "sha512-0GUNbPtQt+PLMsC5HoZRONX+K6NBJEqpXe/lsvrFj0EqfpGPpVfJKGE7a5jCg8s2+Wkrf/2U1G41kIH+zC9eyQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@xmldom/xmldom": "^0.8.8",
|
||||
"xpath": "0.0.32"
|
||||
|
||||
@@ -18,8 +18,6 @@
|
||||
"dependencies": {
|
||||
"@sendgrid/mail": "^8.1.0",
|
||||
"Common": "file:../Common",
|
||||
|
||||
|
||||
"ejs": "^3.1.9",
|
||||
"handlebars": "^4.7.8",
|
||||
"nodemailer": "^6.9.7",
|
||||
|
||||
@@ -3,6 +3,8 @@ import Route from "../../../Types/API/Route";
|
||||
import AnalyticsTableEngine from "../../../Types/AnalyticsDatabase/AnalyticsTableEngine";
|
||||
import AnalyticsTableColumn from "../../../Types/AnalyticsDatabase/TableColumn";
|
||||
import TableColumnType from "../../../Types/AnalyticsDatabase/TableColumnType";
|
||||
import Projection from "../../../Types/AnalyticsDatabase/Projection";
|
||||
import MaterializedView from "../../../Types/AnalyticsDatabase/MaterializedView";
|
||||
import {
|
||||
ColumnAccessControl,
|
||||
TableAccessControl,
|
||||
@@ -40,6 +42,8 @@ export default class AnalyticsBaseModel extends CommonModel {
|
||||
enableWorkflowOn?: EnableWorkflowOn | undefined;
|
||||
enableRealtimeEventsOn?: EnableRealtimeEventsOn | undefined;
|
||||
partitionKey: string;
|
||||
projections?: Array<Projection> | undefined;
|
||||
materializedViews?: Array<MaterializedView> | undefined;
|
||||
}) {
|
||||
super({
|
||||
tableColumns: data.tableColumns,
|
||||
@@ -140,6 +144,8 @@ export default class AnalyticsBaseModel extends CommonModel {
|
||||
this.crudApiPath = data.crudApiPath;
|
||||
this.enableRealtimeEventsOn = data.enableRealtimeEventsOn;
|
||||
this.partitionKey = data.partitionKey;
|
||||
this.projections = data.projections || [];
|
||||
this.materializedViews = data.materializedViews || [];
|
||||
}
|
||||
|
||||
private _enableWorkflowOn: EnableWorkflowOn | undefined;
|
||||
@@ -250,6 +256,22 @@ export default class AnalyticsBaseModel extends CommonModel {
|
||||
this._crudApiPath = v;
|
||||
}
|
||||
|
||||
private _projections: Array<Projection> = [];
|
||||
public get projections(): Array<Projection> {
|
||||
return this._projections;
|
||||
}
|
||||
public set projections(v: Array<Projection>) {
|
||||
this._projections = v;
|
||||
}
|
||||
|
||||
private _materializedViews: Array<MaterializedView> = [];
|
||||
public get materializedViews(): Array<MaterializedView> {
|
||||
return this._materializedViews;
|
||||
}
|
||||
public set materializedViews(v: Array<MaterializedView>) {
|
||||
this._materializedViews = v;
|
||||
}
|
||||
|
||||
public getTenantColumn(): AnalyticsTableColumn | null {
|
||||
const column: AnalyticsTableColumn | undefined = this.tableColumns.find(
|
||||
(column: AnalyticsTableColumn) => {
|
||||
|
||||
@@ -9,6 +9,332 @@ import { SpanStatus } from "./Span";
|
||||
|
||||
export default class ExceptionInstance extends AnalyticsBaseModel {
|
||||
public constructor() {
|
||||
const projectIdColumn: AnalyticsTableColumn = new AnalyticsTableColumn({
|
||||
key: "projectId",
|
||||
title: "Project ID",
|
||||
description: "ID of project",
|
||||
required: true,
|
||||
type: TableColumnType.ObjectID,
|
||||
isTenantId: true,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryException,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryException,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
});
|
||||
|
||||
const serviceIdColumn: AnalyticsTableColumn = new AnalyticsTableColumn({
|
||||
key: "serviceId",
|
||||
title: "Service ID",
|
||||
description: "ID of the Service which created the log",
|
||||
required: true,
|
||||
type: TableColumnType.ObjectID,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryException,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryException,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
});
|
||||
|
||||
const timeColumn: AnalyticsTableColumn = new AnalyticsTableColumn({
|
||||
key: "time",
|
||||
title: "Time",
|
||||
description: "When was the log created?",
|
||||
required: true,
|
||||
type: TableColumnType.Date,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryException,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryException,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
});
|
||||
|
||||
const timeUnixNanoColumn: AnalyticsTableColumn = new AnalyticsTableColumn({
|
||||
key: "timeUnixNano",
|
||||
title: "Time (in Unix Nano)",
|
||||
description: "When was the log created?",
|
||||
required: true,
|
||||
type: TableColumnType.LongNumber,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryException,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryException,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
});
|
||||
|
||||
const exceptionTypeColumn: AnalyticsTableColumn = new AnalyticsTableColumn({
|
||||
key: "exceptionType",
|
||||
title: "Exception Type",
|
||||
description: "Exception Type", // Examples: java.net.ConnectException; OSError; etc.
|
||||
required: false,
|
||||
type: TableColumnType.Text,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryException,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryException,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
});
|
||||
|
||||
const stackTraceColumn: AnalyticsTableColumn = new AnalyticsTableColumn({
|
||||
key: "stackTrace",
|
||||
title: "Stack Trace",
|
||||
description: "Exception Stack Trace", // Examples: Division by zero; Can't convert 'int' object to str implicitly
|
||||
required: false,
|
||||
type: TableColumnType.Text,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryException,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryException,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
});
|
||||
|
||||
const messageColumn: AnalyticsTableColumn = new AnalyticsTableColumn({
|
||||
key: "message",
|
||||
title: "Exception Message",
|
||||
description: "Exception Message", // Examples: Division by zero; Can't convert 'int' object to str implicitly
|
||||
required: false,
|
||||
type: TableColumnType.Text,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryException,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryException,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
});
|
||||
|
||||
const spanStatusCodeColumn: AnalyticsTableColumn = new AnalyticsTableColumn(
|
||||
{
|
||||
key: "spanStatusCode",
|
||||
title: "Span Status Code",
|
||||
description: "Span Status Code",
|
||||
required: false,
|
||||
type: TableColumnType.Number,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryException,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryException,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
const escapedColumn: AnalyticsTableColumn = new AnalyticsTableColumn({
|
||||
key: "escaped",
|
||||
title: "Exception Escaped",
|
||||
description: "Exception Escaped", // SHOULD be set to true if the exception event is recorded at a point where it is known that the exception is escaping the scope of the span.
|
||||
required: false,
|
||||
type: TableColumnType.Boolean,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryException,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryException,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
});
|
||||
|
||||
const traceIdColumn: AnalyticsTableColumn = new AnalyticsTableColumn({
|
||||
key: "traceId",
|
||||
title: "Trace ID",
|
||||
description: "ID of the trace",
|
||||
required: false,
|
||||
type: TableColumnType.Text,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryException,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryException,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
});
|
||||
|
||||
const spanIdColumn: AnalyticsTableColumn = new AnalyticsTableColumn({
|
||||
key: "spanId",
|
||||
title: "Span ID",
|
||||
description: "ID of the span",
|
||||
required: false,
|
||||
type: TableColumnType.Text,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryException,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryException,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
});
|
||||
|
||||
const fingerprintColumn: AnalyticsTableColumn = new AnalyticsTableColumn({
|
||||
key: "fingerprint",
|
||||
title: "Fingerprint",
|
||||
description: "Fingerprint of the exception",
|
||||
required: true,
|
||||
type: TableColumnType.Text,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryException,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryException,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
});
|
||||
|
||||
const spanNameColumn: AnalyticsTableColumn = new AnalyticsTableColumn({
|
||||
key: "spanName",
|
||||
title: "Span Name",
|
||||
description: "Name of the span",
|
||||
required: false,
|
||||
type: TableColumnType.Text,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceTraces,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceTraces,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
});
|
||||
|
||||
const attributesColumn: AnalyticsTableColumn = new AnalyticsTableColumn({
|
||||
key: "attributes",
|
||||
title: "Attributes",
|
||||
description: "Attributes",
|
||||
required: true,
|
||||
defaultValue: {},
|
||||
type: TableColumnType.JSON,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryException,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryException,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
});
|
||||
|
||||
super({
|
||||
tableName: "ExceptionItem",
|
||||
tableEngine: AnalyticsTableEngine.MergeTree,
|
||||
@@ -45,330 +371,22 @@ export default class ExceptionInstance extends AnalyticsBaseModel {
|
||||
},
|
||||
crudApiPath: new Route("/exceptions"),
|
||||
tableColumns: [
|
||||
new AnalyticsTableColumn({
|
||||
key: "projectId",
|
||||
title: "Project ID",
|
||||
description: "ID of project",
|
||||
required: true,
|
||||
type: TableColumnType.ObjectID,
|
||||
isTenantId: true,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryException,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryException,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
}),
|
||||
|
||||
new AnalyticsTableColumn({
|
||||
key: "serviceId",
|
||||
title: "Service ID",
|
||||
description: "ID of the Service which created the log",
|
||||
required: true,
|
||||
type: TableColumnType.ObjectID,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryException,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryException,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
}),
|
||||
|
||||
new AnalyticsTableColumn({
|
||||
key: "time",
|
||||
title: "Time",
|
||||
description: "When was the log created?",
|
||||
required: true,
|
||||
type: TableColumnType.Date,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryException,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryException,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
}),
|
||||
|
||||
new AnalyticsTableColumn({
|
||||
key: "timeUnixNano",
|
||||
title: "Time (in Unix Nano)",
|
||||
description: "When was the log created?",
|
||||
required: true,
|
||||
type: TableColumnType.LongNumber,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryException,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryException,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
}),
|
||||
|
||||
new AnalyticsTableColumn({
|
||||
key: "exceptionType",
|
||||
title: "Exception Type",
|
||||
description: "Exception Type", // Examples: java.net.ConnectException; OSError; etc.
|
||||
required: false,
|
||||
type: TableColumnType.Text,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryException,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryException,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
}),
|
||||
|
||||
new AnalyticsTableColumn({
|
||||
key: "stackTrace",
|
||||
title: "Stack Trace",
|
||||
description: "Exception Stack Trace", // Examples: Division by zero; Can't convert 'int' object to str implicitly
|
||||
required: false,
|
||||
type: TableColumnType.Text,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryException,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryException,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
}),
|
||||
|
||||
new AnalyticsTableColumn({
|
||||
key: "message",
|
||||
title: "Exception Message",
|
||||
description: "Exception Message", // Examples: Division by zero; Can't convert 'int' object to str implicitly
|
||||
required: false,
|
||||
type: TableColumnType.Text,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryException,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryException,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
}),
|
||||
|
||||
new AnalyticsTableColumn({
|
||||
key: "spanStatusCode",
|
||||
title: "Span Status Code",
|
||||
description: "Span Status Code",
|
||||
required: false,
|
||||
type: TableColumnType.Number,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryException,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryException,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
}),
|
||||
|
||||
new AnalyticsTableColumn({
|
||||
key: "escaped",
|
||||
title: "Exception Escaped",
|
||||
description: "Exception Escaped", // SHOULD be set to true if the exception event is recorded at a point where it is known that the exception is escaping the scope of the span.
|
||||
required: false,
|
||||
type: TableColumnType.Boolean,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryException,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryException,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
}),
|
||||
|
||||
new AnalyticsTableColumn({
|
||||
key: "traceId",
|
||||
title: "Trace ID",
|
||||
description: "ID of the trace",
|
||||
required: false,
|
||||
type: TableColumnType.Text,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryException,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryException,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
}),
|
||||
|
||||
new AnalyticsTableColumn({
|
||||
key: "spanId",
|
||||
title: "Span ID",
|
||||
description: "ID of the span",
|
||||
required: false,
|
||||
type: TableColumnType.Text,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryException,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryException,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
}),
|
||||
|
||||
new AnalyticsTableColumn({
|
||||
key: "fingerprint",
|
||||
title: "Fingerprint",
|
||||
description: "Fingerprint of the exception",
|
||||
required: true,
|
||||
type: TableColumnType.Text,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryException,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryException,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
}),
|
||||
|
||||
new AnalyticsTableColumn({
|
||||
key: "spanName",
|
||||
title: "Span Name",
|
||||
description: "Name of the span",
|
||||
required: false,
|
||||
type: TableColumnType.Text,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceTraces,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceTraces,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
}),
|
||||
|
||||
new AnalyticsTableColumn({
|
||||
key: "attributes",
|
||||
title: "Attributes",
|
||||
description: "Attributes",
|
||||
required: true,
|
||||
defaultValue: {},
|
||||
type: TableColumnType.JSON,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryException,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryException,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
}),
|
||||
projectIdColumn,
|
||||
serviceIdColumn,
|
||||
timeColumn,
|
||||
timeUnixNanoColumn,
|
||||
exceptionTypeColumn,
|
||||
stackTraceColumn,
|
||||
messageColumn,
|
||||
spanStatusCodeColumn,
|
||||
escapedColumn,
|
||||
traceIdColumn,
|
||||
spanIdColumn,
|
||||
fingerprintColumn,
|
||||
spanNameColumn,
|
||||
attributesColumn,
|
||||
],
|
||||
projections: [],
|
||||
sortKeys: ["projectId", "time", "serviceId", "fingerprint"],
|
||||
primaryKeys: ["projectId", "time", "serviceId", "fingerprint"],
|
||||
partitionKey: "sipHash64(projectId) % 16",
|
||||
|
||||
@@ -2,7 +2,6 @@ import AnalyticsBaseModel from "./AnalyticsBaseModel/AnalyticsBaseModel";
|
||||
import Log from "./Log";
|
||||
import Metric from "./Metric";
|
||||
import Span from "./Span";
|
||||
import TelemetryAttribute from "./TelemetryAttribute";
|
||||
import ExceptionInstance from "./ExceptionInstance";
|
||||
import MonitorLog from "./MonitorLog";
|
||||
|
||||
@@ -10,7 +9,6 @@ const AnalyticsModels: Array<{ new (): AnalyticsBaseModel }> = [
|
||||
Log,
|
||||
Span,
|
||||
Metric,
|
||||
TelemetryAttribute,
|
||||
ExceptionInstance,
|
||||
MonitorLog,
|
||||
];
|
||||
|
||||
@@ -10,6 +10,264 @@ import LogSeverity from "../../Types/Log/LogSeverity";
|
||||
|
||||
export default class Log extends AnalyticsBaseModel {
|
||||
public constructor() {
|
||||
const projectIdColumn: AnalyticsTableColumn = new AnalyticsTableColumn({
|
||||
key: "projectId",
|
||||
title: "Project ID",
|
||||
description: "ID of project",
|
||||
required: true,
|
||||
type: TableColumnType.ObjectID,
|
||||
isTenantId: true,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceLog,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceLog,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
});
|
||||
|
||||
const serviceIdColumn: AnalyticsTableColumn = new AnalyticsTableColumn({
|
||||
key: "serviceId",
|
||||
title: "Service ID",
|
||||
description: "ID of the Service which created the log",
|
||||
required: true,
|
||||
type: TableColumnType.ObjectID,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceLog,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceLog,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
});
|
||||
|
||||
const timeColumn: AnalyticsTableColumn = new AnalyticsTableColumn({
|
||||
key: "time",
|
||||
title: "Time",
|
||||
description: "When was the log created?",
|
||||
required: true,
|
||||
type: TableColumnType.Date,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceLog,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceLog,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
});
|
||||
|
||||
const timeUnixNanoColumn: AnalyticsTableColumn = new AnalyticsTableColumn({
|
||||
key: "timeUnixNano",
|
||||
title: "Time (in Unix Nano)",
|
||||
description: "When was the log created?",
|
||||
required: true,
|
||||
type: TableColumnType.LongNumber,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceLog,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceLog,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
});
|
||||
|
||||
const severityTextColumn: AnalyticsTableColumn = new AnalyticsTableColumn({
|
||||
key: "severityText",
|
||||
title: "Severity Text",
|
||||
description: "Log Severity Text",
|
||||
required: true,
|
||||
type: TableColumnType.Text,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceLog,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceLog,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
});
|
||||
|
||||
const severityNumberColumn: AnalyticsTableColumn = new AnalyticsTableColumn(
|
||||
{
|
||||
key: "severityNumber",
|
||||
title: "Severity Number",
|
||||
description: "Log Severity Number",
|
||||
required: true,
|
||||
type: TableColumnType.Number,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceLog,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceLog,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
const attributesColumn: AnalyticsTableColumn = new AnalyticsTableColumn({
|
||||
key: "attributes",
|
||||
title: "Attributes",
|
||||
description: "Attributes",
|
||||
required: true,
|
||||
defaultValue: {},
|
||||
type: TableColumnType.JSON,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceLog,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceLog,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
});
|
||||
|
||||
const attributeKeysColumn: AnalyticsTableColumn = new AnalyticsTableColumn({
|
||||
key: "attributeKeys",
|
||||
title: "Attribute Keys",
|
||||
description: "Attribute keys extracted from attributes",
|
||||
required: true,
|
||||
defaultValue: [],
|
||||
type: TableColumnType.ArrayText,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceLog,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceLog,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
});
|
||||
|
||||
const traceIdColumn: AnalyticsTableColumn = new AnalyticsTableColumn({
|
||||
key: "traceId",
|
||||
title: "Trace ID",
|
||||
description: "ID of the trace",
|
||||
required: false,
|
||||
type: TableColumnType.Text,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceLog,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceLog,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
});
|
||||
|
||||
const spanIdColumn: AnalyticsTableColumn = new AnalyticsTableColumn({
|
||||
key: "spanId",
|
||||
title: "Span ID",
|
||||
description: "ID of the span",
|
||||
required: false,
|
||||
type: TableColumnType.Text,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceLog,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceLog,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
});
|
||||
|
||||
const bodyColumn: AnalyticsTableColumn = new AnalyticsTableColumn({
|
||||
key: "body",
|
||||
title: "Log Body",
|
||||
description: "Body of the Log",
|
||||
required: false,
|
||||
type: TableColumnType.Text,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceLog,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceLog,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
});
|
||||
|
||||
super({
|
||||
tableName: "LogItem",
|
||||
tableEngine: AnalyticsTableEngine.MergeTree,
|
||||
@@ -43,238 +301,19 @@ export default class Log extends AnalyticsBaseModel {
|
||||
pluralName: "Logs",
|
||||
crudApiPath: new Route("/logs"),
|
||||
tableColumns: [
|
||||
new AnalyticsTableColumn({
|
||||
key: "projectId",
|
||||
title: "Project ID",
|
||||
description: "ID of project",
|
||||
required: true,
|
||||
type: TableColumnType.ObjectID,
|
||||
isTenantId: true,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceLog,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceLog,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
}),
|
||||
|
||||
new AnalyticsTableColumn({
|
||||
key: "serviceId",
|
||||
title: "Service ID",
|
||||
description: "ID of the Service which created the log",
|
||||
required: true,
|
||||
type: TableColumnType.ObjectID,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceLog,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceLog,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
}),
|
||||
|
||||
new AnalyticsTableColumn({
|
||||
key: "time",
|
||||
title: "Time",
|
||||
description: "When was the log created?",
|
||||
required: true,
|
||||
type: TableColumnType.Date,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceLog,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceLog,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
}),
|
||||
|
||||
new AnalyticsTableColumn({
|
||||
key: "timeUnixNano",
|
||||
title: "Time (in Unix Nano)",
|
||||
description: "When was the log created?",
|
||||
required: true,
|
||||
type: TableColumnType.LongNumber,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceLog,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceLog,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
}),
|
||||
|
||||
new AnalyticsTableColumn({
|
||||
key: "severityText",
|
||||
title: "Severity Text",
|
||||
description: "Log Severity Text",
|
||||
required: true,
|
||||
type: TableColumnType.Text,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceLog,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceLog,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
}),
|
||||
|
||||
new AnalyticsTableColumn({
|
||||
key: "severityNumber",
|
||||
title: "Severity Number",
|
||||
description: "Log Severity Number",
|
||||
required: true,
|
||||
type: TableColumnType.Number,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceLog,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceLog,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
}),
|
||||
|
||||
new AnalyticsTableColumn({
|
||||
key: "attributes",
|
||||
title: "Attributes",
|
||||
description: "Attributes",
|
||||
required: true,
|
||||
defaultValue: {},
|
||||
type: TableColumnType.JSON,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceLog,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceLog,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
}),
|
||||
|
||||
new AnalyticsTableColumn({
|
||||
key: "traceId",
|
||||
title: "Trace ID",
|
||||
description: "ID of the trace",
|
||||
required: false,
|
||||
type: TableColumnType.Text,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceLog,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceLog,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
}),
|
||||
|
||||
new AnalyticsTableColumn({
|
||||
key: "spanId",
|
||||
title: "Span ID",
|
||||
description: "ID of the span",
|
||||
required: false,
|
||||
type: TableColumnType.Text,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceLog,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceLog,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
}),
|
||||
|
||||
new AnalyticsTableColumn({
|
||||
key: "body",
|
||||
title: "Log Body",
|
||||
description: "Body of the Log",
|
||||
required: false,
|
||||
type: TableColumnType.Text,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceLog,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceLog,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
}),
|
||||
projectIdColumn,
|
||||
serviceIdColumn,
|
||||
timeColumn,
|
||||
timeUnixNanoColumn,
|
||||
severityTextColumn,
|
||||
severityNumberColumn,
|
||||
attributesColumn,
|
||||
attributeKeysColumn,
|
||||
traceIdColumn,
|
||||
spanIdColumn,
|
||||
bodyColumn,
|
||||
],
|
||||
projections: [],
|
||||
sortKeys: ["projectId", "time", "serviceId"],
|
||||
primaryKeys: ["projectId", "time", "serviceId"],
|
||||
partitionKey: "sipHash64(projectId) % 16",
|
||||
@@ -345,6 +384,14 @@ export default class Log extends AnalyticsBaseModel {
|
||||
this.setColumnValue("attributes", v);
|
||||
}
|
||||
|
||||
public get attributeKeys(): Array<string> | undefined {
|
||||
return this.getColumnValue("attributeKeys") as Array<string> | undefined;
|
||||
}
|
||||
|
||||
public set attributeKeys(v: Array<string> | undefined) {
|
||||
this.setColumnValue("attributeKeys", v);
|
||||
}
|
||||
|
||||
public get traceId(): string | undefined {
|
||||
return this.getColumnValue("traceId") as string | undefined;
|
||||
}
|
||||
|
||||
@@ -28,6 +28,481 @@ export enum ServiceType {
|
||||
|
||||
export default class Metric extends AnalyticsBaseModel {
|
||||
public constructor() {
|
||||
const projectIdColumn: AnalyticsTableColumn = new AnalyticsTableColumn({
|
||||
key: "projectId",
|
||||
title: "Project ID",
|
||||
description: "ID of project",
|
||||
required: true,
|
||||
type: TableColumnType.ObjectID,
|
||||
isTenantId: true,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceLog,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceLog,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
});
|
||||
|
||||
// this can also be the monitor id or the telemetry service id.
|
||||
const serviceIdColumn: AnalyticsTableColumn = new AnalyticsTableColumn({
|
||||
key: "serviceId",
|
||||
title: "Service ID",
|
||||
description: "ID of the Service which created the Metric",
|
||||
required: true,
|
||||
type: TableColumnType.ObjectID,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceLog,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceLog,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
});
|
||||
|
||||
// this can also be the monitor id or the telemetry service id.
|
||||
const serviceTypeColumn: AnalyticsTableColumn = new AnalyticsTableColumn({
|
||||
key: "serviceType",
|
||||
title: "Service Type",
|
||||
description: "Type of the service that this telemetry belongs to",
|
||||
required: false,
|
||||
type: TableColumnType.Text,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceLog,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceLog,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
});
|
||||
|
||||
// add name and description
|
||||
const nameColumn: AnalyticsTableColumn = new AnalyticsTableColumn({
|
||||
key: "name",
|
||||
title: "Name",
|
||||
description: "Name of the Metric",
|
||||
required: true,
|
||||
type: TableColumnType.Text,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceLog,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceLog,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
});
|
||||
|
||||
const aggregationTemporalityColumn: AnalyticsTableColumn =
|
||||
new AnalyticsTableColumn({
|
||||
key: "aggregationTemporality",
|
||||
title: "Aggregation Temporality",
|
||||
description: "Aggregation Temporality of this Metric",
|
||||
required: false,
|
||||
type: TableColumnType.Text,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceLog,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceLog,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
});
|
||||
|
||||
const metricPointTypeColumn: AnalyticsTableColumn =
|
||||
new AnalyticsTableColumn({
|
||||
key: "metricPointType",
|
||||
title: "Metric Point Type",
|
||||
description: "Metric Point Type of this Metric",
|
||||
required: false,
|
||||
type: TableColumnType.Text,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceLog,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceLog,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
});
|
||||
|
||||
// this is end time.
|
||||
const timeColumn: AnalyticsTableColumn = new AnalyticsTableColumn({
|
||||
key: "time",
|
||||
title: "Time",
|
||||
description: "When did the Metric happen?",
|
||||
required: true,
|
||||
type: TableColumnType.Date,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceLog,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceLog,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
});
|
||||
|
||||
const startTimeColumn: AnalyticsTableColumn = new AnalyticsTableColumn({
|
||||
key: "startTime",
|
||||
title: "Start Time",
|
||||
description: "When did the Metric happen?",
|
||||
required: false,
|
||||
type: TableColumnType.Date,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceLog,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceLog,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
});
|
||||
|
||||
// end time.
|
||||
const timeUnixNanoColumn: AnalyticsTableColumn = new AnalyticsTableColumn({
|
||||
key: "timeUnixNano",
|
||||
title: "Time (in Unix Nano)",
|
||||
description: "When did the Metric happen?",
|
||||
required: true,
|
||||
type: TableColumnType.LongNumber,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceLog,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceLog,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
});
|
||||
|
||||
const startTimeUnixNanoColumn: AnalyticsTableColumn =
|
||||
new AnalyticsTableColumn({
|
||||
key: "startTimeUnixNano",
|
||||
title: "Start Time (in Unix Nano)",
|
||||
description: "When did the Metric happen?",
|
||||
required: false,
|
||||
type: TableColumnType.LongNumber,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceLog,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceLog,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
});
|
||||
|
||||
const attributesColumn: AnalyticsTableColumn = new AnalyticsTableColumn({
|
||||
key: "attributes",
|
||||
title: "Attributes",
|
||||
description: "Attributes",
|
||||
required: true,
|
||||
type: TableColumnType.JSON,
|
||||
defaultValue: {},
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceLog,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceLog,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
});
|
||||
|
||||
const attributeKeysColumn: AnalyticsTableColumn = new AnalyticsTableColumn({
|
||||
key: "attributeKeys",
|
||||
title: "Attribute Keys",
|
||||
description: "Attribute keys extracted from attributes",
|
||||
required: true,
|
||||
defaultValue: [],
|
||||
type: TableColumnType.ArrayText,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceLog,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceLog,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
});
|
||||
|
||||
const isMonotonicColumn: AnalyticsTableColumn = new AnalyticsTableColumn({
|
||||
key: "isMonotonic",
|
||||
title: "Is Monotonic",
|
||||
description: "Is Monotonic",
|
||||
required: false,
|
||||
type: TableColumnType.Boolean,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceLog,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceLog,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
});
|
||||
|
||||
const countColumn: AnalyticsTableColumn = new AnalyticsTableColumn({
|
||||
key: "count",
|
||||
title: "Count",
|
||||
description: "Count",
|
||||
required: false,
|
||||
type: TableColumnType.Number,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceLog,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceLog,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
});
|
||||
|
||||
const sumColumn: AnalyticsTableColumn = new AnalyticsTableColumn({
|
||||
key: "sum",
|
||||
title: "Sum",
|
||||
description: "Sum",
|
||||
required: false,
|
||||
type: TableColumnType.Decimal,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceLog,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceLog,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
});
|
||||
|
||||
const valueColumn: AnalyticsTableColumn = new AnalyticsTableColumn({
|
||||
key: "value",
|
||||
title: "Value",
|
||||
description: "Value",
|
||||
required: false,
|
||||
type: TableColumnType.Decimal,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceLog,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceLog,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
});
|
||||
|
||||
const minColumn: AnalyticsTableColumn = new AnalyticsTableColumn({
|
||||
key: "min",
|
||||
title: "Min",
|
||||
description: "Min",
|
||||
required: false,
|
||||
type: TableColumnType.Decimal,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceLog,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceLog,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
});
|
||||
|
||||
const maxColumn: AnalyticsTableColumn = new AnalyticsTableColumn({
|
||||
key: "max",
|
||||
title: "Max",
|
||||
description: "Max",
|
||||
required: false,
|
||||
type: TableColumnType.Decimal,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceLog,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceLog,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
});
|
||||
|
||||
const bucketCountsColumn: AnalyticsTableColumn = new AnalyticsTableColumn({
|
||||
key: "bucketCounts",
|
||||
title: "Bucket Counts",
|
||||
description: "Bucket Counts",
|
||||
required: true,
|
||||
defaultValue: [],
|
||||
type: TableColumnType.ArrayNumber,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceLog,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceLog,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
});
|
||||
|
||||
const explicitBoundsColumn: AnalyticsTableColumn = new AnalyticsTableColumn(
|
||||
{
|
||||
key: "explicitBounds",
|
||||
title: "Explicit Bonds",
|
||||
description: "Explicit Bonds",
|
||||
required: true,
|
||||
defaultValue: [],
|
||||
type: TableColumnType.ArrayNumber,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceLog,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceLog,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
super({
|
||||
tableName: "MetricItem",
|
||||
tableEngine: AnalyticsTableEngine.MergeTree,
|
||||
@@ -61,453 +536,28 @@ export default class Metric extends AnalyticsBaseModel {
|
||||
],
|
||||
},
|
||||
tableColumns: [
|
||||
new AnalyticsTableColumn({
|
||||
key: "projectId",
|
||||
title: "Project ID",
|
||||
description: "ID of project",
|
||||
required: true,
|
||||
type: TableColumnType.ObjectID,
|
||||
isTenantId: true,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceLog,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceLog,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
}),
|
||||
|
||||
// this can also be the monitor id or the telemetry service id.
|
||||
new AnalyticsTableColumn({
|
||||
key: "serviceId",
|
||||
title: "Service ID",
|
||||
description: "ID of the Service which created the Metric",
|
||||
required: true,
|
||||
type: TableColumnType.ObjectID,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceLog,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceLog,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
}),
|
||||
|
||||
// this can also be the monitor id or the telemetry service id.
|
||||
new AnalyticsTableColumn({
|
||||
key: "serviceType",
|
||||
title: "Service Type",
|
||||
description: "Type of the service that this telemetry belongs to",
|
||||
required: false,
|
||||
type: TableColumnType.Text,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceLog,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceLog,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
}),
|
||||
|
||||
// add name and description
|
||||
|
||||
new AnalyticsTableColumn({
|
||||
key: "name",
|
||||
title: "Name",
|
||||
description: "Name of the Metric",
|
||||
required: true,
|
||||
type: TableColumnType.Text,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceLog,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceLog,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
}),
|
||||
|
||||
new AnalyticsTableColumn({
|
||||
key: "aggregationTemporality",
|
||||
title: "Aggregation Temporality",
|
||||
description: "Aggregation Temporality of this Metric",
|
||||
required: false,
|
||||
type: TableColumnType.Text,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceLog,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceLog,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
}),
|
||||
|
||||
new AnalyticsTableColumn({
|
||||
key: "metricPointType",
|
||||
title: "Metric Point Type",
|
||||
description: "Metric Point Type of this Metric",
|
||||
required: false,
|
||||
type: TableColumnType.Text,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceLog,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceLog,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
}),
|
||||
|
||||
// this is end time.
|
||||
new AnalyticsTableColumn({
|
||||
key: "time",
|
||||
title: "Time",
|
||||
description: "When did the Metric happen?",
|
||||
required: true,
|
||||
type: TableColumnType.Date,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceLog,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceLog,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
}),
|
||||
|
||||
new AnalyticsTableColumn({
|
||||
key: "startTime",
|
||||
title: "Start Time",
|
||||
description: "When did the Metric happen?",
|
||||
required: false,
|
||||
type: TableColumnType.Date,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceLog,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceLog,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
}),
|
||||
|
||||
// end time.
|
||||
new AnalyticsTableColumn({
|
||||
key: "timeUnixNano",
|
||||
title: "Time (in Unix Nano)",
|
||||
description: "When did the Metric happen?",
|
||||
required: true,
|
||||
type: TableColumnType.LongNumber,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceLog,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceLog,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
}),
|
||||
|
||||
new AnalyticsTableColumn({
|
||||
key: "startTimeUnixNano",
|
||||
title: "Start Time (in Unix Nano)",
|
||||
description: "When did the Metric happen?",
|
||||
required: false,
|
||||
type: TableColumnType.LongNumber,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceLog,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceLog,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
}),
|
||||
|
||||
new AnalyticsTableColumn({
|
||||
key: "attributes",
|
||||
title: "Attributes",
|
||||
description: "Attributes",
|
||||
required: true,
|
||||
type: TableColumnType.JSON,
|
||||
defaultValue: {},
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceLog,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceLog,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
}),
|
||||
|
||||
new AnalyticsTableColumn({
|
||||
key: "isMonotonic",
|
||||
title: "Is Monotonic",
|
||||
description: "Is Monotonic",
|
||||
required: false,
|
||||
type: TableColumnType.Boolean,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceLog,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceLog,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
}),
|
||||
|
||||
new AnalyticsTableColumn({
|
||||
key: "count",
|
||||
title: "Count",
|
||||
description: "Count",
|
||||
required: false,
|
||||
type: TableColumnType.Number,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceLog,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceLog,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
}),
|
||||
|
||||
new AnalyticsTableColumn({
|
||||
key: "sum",
|
||||
title: "Sum",
|
||||
description: "Sum",
|
||||
required: false,
|
||||
type: TableColumnType.Decimal,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceLog,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceLog,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
}),
|
||||
|
||||
new AnalyticsTableColumn({
|
||||
key: "value",
|
||||
title: "Value",
|
||||
description: "Value",
|
||||
required: false,
|
||||
type: TableColumnType.Decimal,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceLog,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceLog,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
}),
|
||||
|
||||
new AnalyticsTableColumn({
|
||||
key: "min",
|
||||
title: "Min",
|
||||
description: "Min",
|
||||
required: false,
|
||||
type: TableColumnType.Decimal,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceLog,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceLog,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
}),
|
||||
|
||||
new AnalyticsTableColumn({
|
||||
key: "max",
|
||||
title: "Max",
|
||||
description: "Max",
|
||||
required: false,
|
||||
type: TableColumnType.Decimal,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceLog,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceLog,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
}),
|
||||
|
||||
new AnalyticsTableColumn({
|
||||
key: "bucketCounts",
|
||||
title: "Bucket Counts",
|
||||
description: "Bucket Counts",
|
||||
required: true,
|
||||
defaultValue: [],
|
||||
type: TableColumnType.ArrayNumber,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceLog,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceLog,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
}),
|
||||
|
||||
new AnalyticsTableColumn({
|
||||
key: "explicitBounds",
|
||||
title: "Explicit Bonds",
|
||||
description: "Explicit Bonds",
|
||||
required: true,
|
||||
defaultValue: [],
|
||||
type: TableColumnType.ArrayNumber,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceLog,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceLog,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
}),
|
||||
projectIdColumn,
|
||||
serviceIdColumn,
|
||||
serviceTypeColumn,
|
||||
nameColumn,
|
||||
aggregationTemporalityColumn,
|
||||
metricPointTypeColumn,
|
||||
timeColumn,
|
||||
startTimeColumn,
|
||||
timeUnixNanoColumn,
|
||||
startTimeUnixNanoColumn,
|
||||
attributesColumn,
|
||||
attributeKeysColumn,
|
||||
isMonotonicColumn,
|
||||
countColumn,
|
||||
sumColumn,
|
||||
valueColumn,
|
||||
minColumn,
|
||||
maxColumn,
|
||||
bucketCountsColumn,
|
||||
explicitBoundsColumn,
|
||||
],
|
||||
projections: [],
|
||||
sortKeys: ["projectId", "time", "serviceId"],
|
||||
primaryKeys: ["projectId", "time", "serviceId"],
|
||||
partitionKey: "sipHash64(projectId) % 16",
|
||||
@@ -590,6 +640,14 @@ export default class Metric extends AnalyticsBaseModel {
|
||||
this.setColumnValue("attributes", v);
|
||||
}
|
||||
|
||||
public get attributeKeys(): Array<string> | undefined {
|
||||
return this.getColumnValue("attributeKeys") as Array<string> | undefined;
|
||||
}
|
||||
|
||||
public set attributeKeys(v: Array<string> | undefined) {
|
||||
this.setColumnValue("attributeKeys", v);
|
||||
}
|
||||
|
||||
public get startTime(): Date | undefined {
|
||||
return this.getColumnValue("startTime") as Date | undefined;
|
||||
}
|
||||
|
||||
@@ -9,6 +9,100 @@ import Permission from "../../Types/Permission";
|
||||
|
||||
export default class MonitorLog extends AnalyticsBaseModel {
|
||||
public constructor() {
|
||||
const projectIdColumn: AnalyticsTableColumn = new AnalyticsTableColumn({
|
||||
key: "projectId",
|
||||
title: "Project ID",
|
||||
description: "ID of project",
|
||||
required: true,
|
||||
type: TableColumnType.ObjectID,
|
||||
isTenantId: true,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadProjectMonitor,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateProjectMonitor,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
});
|
||||
|
||||
const monitorIdColumn: AnalyticsTableColumn = new AnalyticsTableColumn({
|
||||
key: "monitorId",
|
||||
title: "Monitor ID",
|
||||
description: "ID of the monitor which this logs belongs to",
|
||||
required: true,
|
||||
type: TableColumnType.ObjectID,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadProjectMonitor,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateProjectMonitor,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
});
|
||||
|
||||
const timeColumn: AnalyticsTableColumn = new AnalyticsTableColumn({
|
||||
key: "time",
|
||||
title: "Time",
|
||||
description: "When was the log created?",
|
||||
required: true,
|
||||
type: TableColumnType.Date,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadProjectMonitor,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateProjectMonitor,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
});
|
||||
|
||||
const logBodyColumn: AnalyticsTableColumn = new AnalyticsTableColumn({
|
||||
key: "logBody",
|
||||
title: "Log Body",
|
||||
description: "The body of the log",
|
||||
required: true,
|
||||
defaultValue: {},
|
||||
type: TableColumnType.JSON,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadProjectMonitor,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateProjectMonitor,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
});
|
||||
|
||||
super({
|
||||
tableName: "MonitorLog",
|
||||
tableEngine: AnalyticsTableEngine.MergeTree,
|
||||
@@ -42,100 +136,12 @@ export default class MonitorLog extends AnalyticsBaseModel {
|
||||
pluralName: "Monitor Logs",
|
||||
crudApiPath: new Route("/monitor-log"),
|
||||
tableColumns: [
|
||||
new AnalyticsTableColumn({
|
||||
key: "projectId",
|
||||
title: "Project ID",
|
||||
description: "ID of project",
|
||||
required: true,
|
||||
type: TableColumnType.ObjectID,
|
||||
isTenantId: true,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadProjectMonitor,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateProjectMonitor,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
}),
|
||||
|
||||
new AnalyticsTableColumn({
|
||||
key: "monitorId",
|
||||
title: "Monitor ID",
|
||||
description: "ID of the monitor which this logs belongs to",
|
||||
required: true,
|
||||
type: TableColumnType.ObjectID,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadProjectMonitor,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateProjectMonitor,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
}),
|
||||
|
||||
new AnalyticsTableColumn({
|
||||
key: "time",
|
||||
title: "Time",
|
||||
description: "When was the log created?",
|
||||
required: true,
|
||||
type: TableColumnType.Date,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadProjectMonitor,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateProjectMonitor,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
}),
|
||||
|
||||
new AnalyticsTableColumn({
|
||||
key: "logBody",
|
||||
title: "Log Body",
|
||||
description: "The body of the log",
|
||||
required: true,
|
||||
defaultValue: {},
|
||||
type: TableColumnType.JSON,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadProjectMonitor,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateProjectMonitor,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
}),
|
||||
projectIdColumn,
|
||||
monitorIdColumn,
|
||||
timeColumn,
|
||||
logBodyColumn,
|
||||
],
|
||||
projections: [],
|
||||
sortKeys: ["projectId", "time", "monitorId"],
|
||||
primaryKeys: ["projectId", "time", "monitorId"],
|
||||
partitionKey: "sipHash64(projectId) % 16",
|
||||
|
||||
@@ -41,6 +41,451 @@ export interface SpanLink {
|
||||
|
||||
export default class Span extends AnalyticsBaseModel {
|
||||
public constructor() {
|
||||
const projectIdColumn: AnalyticsTableColumn = new AnalyticsTableColumn({
|
||||
key: "projectId",
|
||||
title: "Project ID",
|
||||
description: "ID of project",
|
||||
required: true,
|
||||
type: TableColumnType.ObjectID,
|
||||
isTenantId: true,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceTraces,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceTraces,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
});
|
||||
|
||||
const serviceIdColumn: AnalyticsTableColumn = new AnalyticsTableColumn({
|
||||
key: "serviceId",
|
||||
title: "Service ID",
|
||||
description: "ID of the Service which created the log",
|
||||
required: true,
|
||||
type: TableColumnType.ObjectID,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceTraces,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceTraces,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
});
|
||||
|
||||
const startTimeColumn: AnalyticsTableColumn = new AnalyticsTableColumn({
|
||||
key: "startTime",
|
||||
title: "Start Time",
|
||||
description: "When did the span start?",
|
||||
required: true,
|
||||
type: TableColumnType.Date,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceTraces,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceTraces,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
});
|
||||
|
||||
const endTimeColumn: AnalyticsTableColumn = new AnalyticsTableColumn({
|
||||
key: "endTime",
|
||||
title: "End Time",
|
||||
description: "When did the span end?",
|
||||
required: true,
|
||||
type: TableColumnType.Date,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceTraces,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceTraces,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
});
|
||||
|
||||
const startTimeUnixNanoColumn: AnalyticsTableColumn =
|
||||
new AnalyticsTableColumn({
|
||||
key: "startTimeUnixNano",
|
||||
title: "Start Time in Unix Nano",
|
||||
description: "When did the span start?",
|
||||
required: true,
|
||||
type: TableColumnType.LongNumber,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceTraces,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceTraces,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
});
|
||||
|
||||
const durationUnixNanoColumn: AnalyticsTableColumn =
|
||||
new AnalyticsTableColumn({
|
||||
key: "durationUnixNano",
|
||||
title: "Duration in Unix Nano",
|
||||
description: "How long did the span last?",
|
||||
required: true,
|
||||
type: TableColumnType.LongNumber,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceTraces,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceTraces,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
});
|
||||
|
||||
const endTimeUnixNanoColumn: AnalyticsTableColumn =
|
||||
new AnalyticsTableColumn({
|
||||
key: "endTimeUnixNano",
|
||||
title: "End Time",
|
||||
description: "When did the span end?",
|
||||
required: true,
|
||||
type: TableColumnType.LongNumber,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceTraces,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceTraces,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
});
|
||||
|
||||
const traceIdColumn: AnalyticsTableColumn = new AnalyticsTableColumn({
|
||||
key: "traceId",
|
||||
title: "Trace ID",
|
||||
description: "ID of the trace",
|
||||
required: true,
|
||||
type: TableColumnType.Text,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceTraces,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceTraces,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
});
|
||||
|
||||
const spanIdColumn: AnalyticsTableColumn = new AnalyticsTableColumn({
|
||||
key: "spanId",
|
||||
title: "Span ID",
|
||||
description: "ID of the span",
|
||||
required: true,
|
||||
type: TableColumnType.Text,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceTraces,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceTraces,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
});
|
||||
|
||||
const parentSpanIdColumn: AnalyticsTableColumn = new AnalyticsTableColumn({
|
||||
key: "parentSpanId",
|
||||
title: "Parent Span ID",
|
||||
description: "ID of the parent span",
|
||||
required: false,
|
||||
type: TableColumnType.Text,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceTraces,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceTraces,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
});
|
||||
|
||||
const traceStateColumn: AnalyticsTableColumn = new AnalyticsTableColumn({
|
||||
key: "traceState",
|
||||
title: "Trace State",
|
||||
description: "Trace State",
|
||||
required: false,
|
||||
type: TableColumnType.Text,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceTraces,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceTraces,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
});
|
||||
|
||||
const attributesColumn: AnalyticsTableColumn = new AnalyticsTableColumn({
|
||||
key: "attributes",
|
||||
title: "Attributes",
|
||||
description: "Attributes",
|
||||
required: true,
|
||||
defaultValue: {},
|
||||
type: TableColumnType.JSON,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceTraces,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceTraces,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
});
|
||||
|
||||
const attributeKeysColumn: AnalyticsTableColumn = new AnalyticsTableColumn({
|
||||
key: "attributeKeys",
|
||||
title: "Attribute Keys",
|
||||
description: "Attribute keys extracted from attributes",
|
||||
required: true,
|
||||
defaultValue: [],
|
||||
type: TableColumnType.ArrayText,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceTraces,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceTraces,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
});
|
||||
|
||||
const eventsColumn: AnalyticsTableColumn = new AnalyticsTableColumn({
|
||||
key: "events",
|
||||
title: "Events",
|
||||
description: "Span Events",
|
||||
required: true,
|
||||
defaultValue: [],
|
||||
type: TableColumnType.JSONArray,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceTraces,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceTraces,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
});
|
||||
|
||||
const linksColumn: AnalyticsTableColumn = new AnalyticsTableColumn({
|
||||
key: "links",
|
||||
title: "Links",
|
||||
description: "Span Links",
|
||||
required: true,
|
||||
defaultValue: {},
|
||||
type: TableColumnType.JSON,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceTraces,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceTraces,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
});
|
||||
|
||||
const statusCodeColumn: AnalyticsTableColumn = new AnalyticsTableColumn({
|
||||
key: "statusCode",
|
||||
title: "Status Code",
|
||||
description: "Status Code",
|
||||
required: false,
|
||||
type: TableColumnType.Number,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceTraces,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceTraces,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
});
|
||||
|
||||
const statusMessageColumn: AnalyticsTableColumn = new AnalyticsTableColumn({
|
||||
key: "statusMessage",
|
||||
title: "Status Message",
|
||||
description: "Status Message",
|
||||
required: false,
|
||||
type: TableColumnType.Text,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceTraces,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceTraces,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
});
|
||||
|
||||
const nameColumn: AnalyticsTableColumn = new AnalyticsTableColumn({
|
||||
key: "name",
|
||||
title: "Name",
|
||||
description: "Name of the span",
|
||||
required: false,
|
||||
type: TableColumnType.Text,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceTraces,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceTraces,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
});
|
||||
|
||||
const kindColumn: AnalyticsTableColumn = new AnalyticsTableColumn({
|
||||
key: "kind",
|
||||
title: "Kind",
|
||||
description: "Kind of the span",
|
||||
required: false,
|
||||
type: TableColumnType.Text,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceTraces,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceTraces,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
});
|
||||
|
||||
super({
|
||||
tableName: "SpanItem",
|
||||
tableEngine: AnalyticsTableEngine.MergeTree,
|
||||
@@ -74,424 +519,27 @@ export default class Span extends AnalyticsBaseModel {
|
||||
],
|
||||
},
|
||||
tableColumns: [
|
||||
new AnalyticsTableColumn({
|
||||
key: "projectId",
|
||||
title: "Project ID",
|
||||
description: "ID of project",
|
||||
required: true,
|
||||
type: TableColumnType.ObjectID,
|
||||
isTenantId: true,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceTraces,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceTraces,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
}),
|
||||
|
||||
new AnalyticsTableColumn({
|
||||
key: "serviceId",
|
||||
title: "Service ID",
|
||||
description: "ID of the Service which created the log",
|
||||
required: true,
|
||||
type: TableColumnType.ObjectID,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceTraces,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceTraces,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
}),
|
||||
|
||||
new AnalyticsTableColumn({
|
||||
key: "startTime",
|
||||
title: "Start Time",
|
||||
description: "When did the span start?",
|
||||
required: true,
|
||||
type: TableColumnType.Date,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceTraces,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceTraces,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
}),
|
||||
|
||||
new AnalyticsTableColumn({
|
||||
key: "endTime",
|
||||
title: "End Time",
|
||||
description: "When did the span end?",
|
||||
required: true,
|
||||
type: TableColumnType.Date,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceTraces,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceTraces,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
}),
|
||||
|
||||
new AnalyticsTableColumn({
|
||||
key: "startTimeUnixNano",
|
||||
title: "Start Time in Unix Nano",
|
||||
description: "When did the span start?",
|
||||
required: true,
|
||||
type: TableColumnType.LongNumber,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceTraces,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceTraces,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
}),
|
||||
|
||||
new AnalyticsTableColumn({
|
||||
key: "durationUnixNano",
|
||||
title: "Duration in Unix Nano",
|
||||
description: "How long did the span last?",
|
||||
required: true,
|
||||
type: TableColumnType.LongNumber,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceTraces,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceTraces,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
}),
|
||||
|
||||
new AnalyticsTableColumn({
|
||||
key: "endTimeUnixNano",
|
||||
title: "End Time",
|
||||
description: "When did the span end?",
|
||||
required: true,
|
||||
type: TableColumnType.LongNumber,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceTraces,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceTraces,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
}),
|
||||
|
||||
new AnalyticsTableColumn({
|
||||
key: "traceId",
|
||||
title: "Trace ID",
|
||||
description: "ID of the trace",
|
||||
required: true,
|
||||
type: TableColumnType.Text,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceTraces,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceTraces,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
}),
|
||||
|
||||
new AnalyticsTableColumn({
|
||||
key: "spanId",
|
||||
title: "Span ID",
|
||||
description: "ID of the span",
|
||||
required: true,
|
||||
type: TableColumnType.Text,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceTraces,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceTraces,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
}),
|
||||
|
||||
new AnalyticsTableColumn({
|
||||
key: "parentSpanId",
|
||||
title: "Parent Span ID",
|
||||
description: "ID of the parent span",
|
||||
required: false,
|
||||
type: TableColumnType.Text,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceTraces,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceTraces,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
}),
|
||||
|
||||
new AnalyticsTableColumn({
|
||||
key: "traceState",
|
||||
title: "Trace State",
|
||||
description: "Trace State",
|
||||
required: false,
|
||||
type: TableColumnType.Text,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceTraces,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceTraces,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
}),
|
||||
|
||||
new AnalyticsTableColumn({
|
||||
key: "attributes",
|
||||
title: "Attributes",
|
||||
description: "Attributes",
|
||||
required: true,
|
||||
defaultValue: {},
|
||||
type: TableColumnType.JSON,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceTraces,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceTraces,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
}),
|
||||
|
||||
new AnalyticsTableColumn({
|
||||
key: "events",
|
||||
title: "Events",
|
||||
description: "Span Events",
|
||||
required: true,
|
||||
defaultValue: [],
|
||||
type: TableColumnType.JSONArray,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceTraces,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceTraces,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
}),
|
||||
|
||||
new AnalyticsTableColumn({
|
||||
key: "links",
|
||||
title: "Links",
|
||||
description: "Span Links",
|
||||
required: true,
|
||||
defaultValue: {},
|
||||
type: TableColumnType.JSON,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceTraces,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceTraces,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
}),
|
||||
|
||||
new AnalyticsTableColumn({
|
||||
key: "statusCode",
|
||||
title: "Status Code",
|
||||
description: "Status Code",
|
||||
required: false,
|
||||
type: TableColumnType.Number,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceTraces,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceTraces,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
}),
|
||||
|
||||
new AnalyticsTableColumn({
|
||||
key: "statusMessage",
|
||||
title: "Status Message",
|
||||
description: "Status Message",
|
||||
required: false,
|
||||
type: TableColumnType.Text,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceTraces,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceTraces,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
}),
|
||||
|
||||
new AnalyticsTableColumn({
|
||||
key: "name",
|
||||
title: "Name",
|
||||
description: "Name of the span",
|
||||
required: false,
|
||||
type: TableColumnType.Text,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceTraces,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceTraces,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
}),
|
||||
|
||||
new AnalyticsTableColumn({
|
||||
key: "kind",
|
||||
title: "Kind",
|
||||
description: "Kind of the span",
|
||||
required: false,
|
||||
type: TableColumnType.Text,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceTraces,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceTraces,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
}),
|
||||
projectIdColumn,
|
||||
serviceIdColumn,
|
||||
startTimeColumn,
|
||||
endTimeColumn,
|
||||
startTimeUnixNanoColumn,
|
||||
durationUnixNanoColumn,
|
||||
endTimeUnixNanoColumn,
|
||||
traceIdColumn,
|
||||
spanIdColumn,
|
||||
parentSpanIdColumn,
|
||||
traceStateColumn,
|
||||
attributesColumn,
|
||||
attributeKeysColumn,
|
||||
eventsColumn,
|
||||
linksColumn,
|
||||
statusCodeColumn,
|
||||
statusMessageColumn,
|
||||
nameColumn,
|
||||
kindColumn,
|
||||
],
|
||||
projections: [],
|
||||
sortKeys: ["projectId", "startTime", "serviceId", "traceId"],
|
||||
primaryKeys: ["projectId", "startTime", "serviceId", "traceId"],
|
||||
partitionKey: "sipHash64(projectId) % 16",
|
||||
@@ -610,6 +658,14 @@ export default class Span extends AnalyticsBaseModel {
|
||||
this.setColumnValue("attributes", v);
|
||||
}
|
||||
|
||||
public get attributeKeys(): Array<string> | undefined {
|
||||
return this.getColumnValue("attributeKeys") as Array<string> | undefined;
|
||||
}
|
||||
|
||||
public set attributeKeys(v: Array<string> | undefined) {
|
||||
this.setColumnValue("attributeKeys", v);
|
||||
}
|
||||
|
||||
public get events(): Array<SpanEvent> | undefined {
|
||||
return this.getColumnValue("events") as Array<SpanEvent> | undefined;
|
||||
}
|
||||
|
||||
@@ -1,164 +0,0 @@
|
||||
import AnalyticsBaseModel from "./AnalyticsBaseModel/AnalyticsBaseModel";
|
||||
import Route from "../../Types/API/Route";
|
||||
import AnalyticsTableEngine from "../../Types/AnalyticsDatabase/AnalyticsTableEngine";
|
||||
import AnalyticsTableColumn from "../../Types/AnalyticsDatabase/TableColumn";
|
||||
import TableColumnType from "../../Types/AnalyticsDatabase/TableColumnType";
|
||||
import TelemetryType from "../../Types/Telemetry/TelemetryType";
|
||||
import ObjectID from "../../Types/ObjectID";
|
||||
import Permission from "../../Types/Permission";
|
||||
|
||||
export default class TelemetryAttribute extends AnalyticsBaseModel {
|
||||
public constructor() {
|
||||
super({
|
||||
tableName: "TelemetryAttribute",
|
||||
tableEngine: AnalyticsTableEngine.MergeTree,
|
||||
singularName: "Telemetry Attribute",
|
||||
pluralName: "Telemetry Attributes",
|
||||
crudApiPath: new Route("/telemetry-attributes"),
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceTraces,
|
||||
Permission.ReadTelemetryServiceLog,
|
||||
Permission.ReadTelemetryServiceMetrics,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateTelemetryServiceTraces,
|
||||
Permission.CreateTelemetryServiceLog,
|
||||
Permission.CreateTelemetryServiceMetrics,
|
||||
],
|
||||
update: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.EditTelemetryServiceTraces,
|
||||
Permission.EditTelemetryServiceLog,
|
||||
Permission.EditTelemetryServiceMetrics,
|
||||
],
|
||||
delete: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.DeleteTelemetryServiceTraces,
|
||||
Permission.DeleteTelemetryServiceLog,
|
||||
Permission.DeleteTelemetryServiceMetrics,
|
||||
],
|
||||
},
|
||||
tableColumns: [
|
||||
new AnalyticsTableColumn({
|
||||
key: "projectId",
|
||||
title: "Project ID",
|
||||
description: "ID of project",
|
||||
required: true,
|
||||
type: TableColumnType.ObjectID,
|
||||
isTenantId: true,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceTraces,
|
||||
Permission.ReadTelemetryServiceLog,
|
||||
Permission.ReadTelemetryServiceMetrics,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.EditTelemetryServiceTraces,
|
||||
Permission.EditTelemetryServiceLog,
|
||||
Permission.EditTelemetryServiceMetrics,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
}),
|
||||
|
||||
new AnalyticsTableColumn({
|
||||
key: "telemetryType",
|
||||
title: "Telemetry Type",
|
||||
description: "Type of telemetry",
|
||||
required: true,
|
||||
type: TableColumnType.Text,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceTraces,
|
||||
Permission.ReadTelemetryServiceLog,
|
||||
Permission.ReadTelemetryServiceMetrics,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.EditTelemetryServiceTraces,
|
||||
Permission.EditTelemetryServiceLog,
|
||||
Permission.EditTelemetryServiceMetrics,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
}),
|
||||
|
||||
new AnalyticsTableColumn({
|
||||
key: "attributes",
|
||||
title: "Attributes",
|
||||
description: "Attributes",
|
||||
required: true,
|
||||
type: TableColumnType.JSONArray,
|
||||
accessControl: {
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadTelemetryServiceTraces,
|
||||
Permission.ReadTelemetryServiceLog,
|
||||
Permission.ReadTelemetryServiceMetrics,
|
||||
],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.EditTelemetryServiceTraces,
|
||||
Permission.EditTelemetryServiceLog,
|
||||
Permission.EditTelemetryServiceMetrics,
|
||||
],
|
||||
update: [],
|
||||
},
|
||||
}),
|
||||
],
|
||||
sortKeys: ["projectId", "telemetryType"],
|
||||
primaryKeys: ["projectId", "telemetryType"],
|
||||
partitionKey: "sipHash64(projectId) % 16",
|
||||
});
|
||||
}
|
||||
|
||||
public get projectId(): ObjectID | undefined {
|
||||
return this.getColumnValue("projectId") as ObjectID | undefined;
|
||||
}
|
||||
|
||||
public set projectId(v: ObjectID | undefined) {
|
||||
this.setColumnValue("projectId", v);
|
||||
}
|
||||
|
||||
public get telemetryType(): TelemetryType | undefined {
|
||||
return this.getColumnValue("telemetryType") as TelemetryType | undefined;
|
||||
}
|
||||
|
||||
public set telemetryType(v: TelemetryType | undefined) {
|
||||
this.setColumnValue("telemetryType", v);
|
||||
}
|
||||
|
||||
public get attributes(): Array<string> | undefined {
|
||||
return this.getColumnValue("attributes") as Array<string> | undefined;
|
||||
}
|
||||
|
||||
public set attributes(v: Array<string> | undefined) {
|
||||
this.setColumnValue("attributes", v);
|
||||
}
|
||||
}
|
||||
@@ -4,11 +4,13 @@ import ColumnAccessControl from "../../Types/Database/AccessControl/ColumnAccess
|
||||
import TableAccessControl from "../../Types/Database/AccessControl/TableAccessControl";
|
||||
import ColumnLength from "../../Types/Database/ColumnLength";
|
||||
import ColumnType from "../../Types/Database/ColumnType";
|
||||
import CrudApiEndpoint from "../../Types/Database/CrudApiEndpoint";
|
||||
import TableColumn from "../../Types/Database/TableColumn";
|
||||
import TableColumnType from "../../Types/Database/TableColumnType";
|
||||
import TableMetadata from "../../Types/Database/TableMetadata";
|
||||
import IconProp from "../../Types/Icon/IconProp";
|
||||
import ObjectID from "../../Types/ObjectID";
|
||||
import Route from "../../Types/API/Route";
|
||||
import { Column, Entity, Index, JoinColumn, ManyToOne } from "typeorm";
|
||||
|
||||
@TableAccessControl({
|
||||
@@ -24,6 +26,7 @@ import { Column, Entity, Index, JoinColumn, ManyToOne } from "typeorm";
|
||||
icon: IconProp.Lock,
|
||||
tableDescription: "HTTP Challege for Lets Encrypt Certificates",
|
||||
})
|
||||
@CrudApiEndpoint(new Route("/acme-challenge"))
|
||||
@Entity({
|
||||
name: "AcmeChallenge",
|
||||
})
|
||||
|
||||
@@ -10,6 +10,7 @@ import ColumnType from "../../Types/Database/ColumnType";
|
||||
import CrudApiEndpoint from "../../Types/Database/CrudApiEndpoint";
|
||||
import EnableDocumentation from "../../Types/Database/EnableDocumentation";
|
||||
import EnableWorkflow from "../../Types/Database/EnableWorkflow";
|
||||
import ColorField from "../../Types/Database/ColorField";
|
||||
import TableColumn from "../../Types/Database/TableColumn";
|
||||
import TableColumnType from "../../Types/Database/TableColumnType";
|
||||
import TableMetadata from "../../Types/Database/TableMetadata";
|
||||
@@ -418,6 +419,7 @@ export default class AlertFeed extends BaseModel {
|
||||
],
|
||||
update: [],
|
||||
})
|
||||
@ColorField()
|
||||
@TableColumn({
|
||||
type: TableColumnType.Color,
|
||||
required: true,
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import Alert from "./Alert";
|
||||
import Project from "./Project";
|
||||
import User from "./User";
|
||||
import File from "./File";
|
||||
import BaseModel from "./DatabaseBaseModel/DatabaseBaseModel";
|
||||
import Route from "../../Types/API/Route";
|
||||
import ColumnAccessControl from "../../Types/Database/AccessControl/ColumnAccessControl";
|
||||
@@ -17,7 +18,15 @@ import TenantColumn from "../../Types/Database/TenantColumn";
|
||||
import IconProp from "../../Types/Icon/IconProp";
|
||||
import ObjectID from "../../Types/ObjectID";
|
||||
import Permission from "../../Types/Permission";
|
||||
import { Column, Entity, Index, JoinColumn, ManyToOne } from "typeorm";
|
||||
import {
|
||||
Column,
|
||||
Entity,
|
||||
Index,
|
||||
JoinColumn,
|
||||
JoinTable,
|
||||
ManyToMany,
|
||||
ManyToOne,
|
||||
} from "typeorm";
|
||||
|
||||
@EnableDocumentation()
|
||||
@CanAccessIfCanReadOn("alert")
|
||||
@@ -340,6 +349,54 @@ export default class AlertInternalNote extends BaseModel {
|
||||
})
|
||||
public note?: string = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateAlertInternalNote,
|
||||
],
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadAlertInternalNote,
|
||||
],
|
||||
update: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.EditAlertInternalNote,
|
||||
],
|
||||
})
|
||||
@TableColumn({
|
||||
type: TableColumnType.EntityArray,
|
||||
modelType: File,
|
||||
title: "Attachments",
|
||||
description: "Files attached to this note",
|
||||
required: false,
|
||||
})
|
||||
@ManyToMany(
|
||||
() => {
|
||||
return File;
|
||||
},
|
||||
{
|
||||
eager: false,
|
||||
},
|
||||
)
|
||||
@JoinTable({
|
||||
name: "AlertInternalNoteFile",
|
||||
joinColumn: {
|
||||
name: "alertInternalNoteId",
|
||||
referencedColumnName: "_id",
|
||||
},
|
||||
inverseJoinColumn: {
|
||||
name: "fileId",
|
||||
referencedColumnName: "_id",
|
||||
},
|
||||
})
|
||||
public attachments?: Array<File> = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [],
|
||||
read: [
|
||||
|
||||
@@ -12,6 +12,7 @@ import ColumnType from "../../Types/Database/ColumnType";
|
||||
import CrudApiEndpoint from "../../Types/Database/CrudApiEndpoint";
|
||||
import EnableDocumentation from "../../Types/Database/EnableDocumentation";
|
||||
import EnableWorkflow from "../../Types/Database/EnableWorkflow";
|
||||
import ColorField from "../../Types/Database/ColorField";
|
||||
import SlugifyColumn from "../../Types/Database/SlugifyColumn";
|
||||
import TableColumn from "../../Types/Database/TableColumn";
|
||||
import TableColumnType from "../../Types/Database/TableColumnType";
|
||||
@@ -378,6 +379,7 @@ export default class AlertSeverity extends BaseModel {
|
||||
Permission.EditAlertSeverity,
|
||||
],
|
||||
})
|
||||
@ColorField()
|
||||
@TableColumn({
|
||||
title: "Color",
|
||||
required: true,
|
||||
|
||||
@@ -12,6 +12,7 @@ import ColumnType from "../../Types/Database/ColumnType";
|
||||
import CrudApiEndpoint from "../../Types/Database/CrudApiEndpoint";
|
||||
import EnableDocumentation from "../../Types/Database/EnableDocumentation";
|
||||
import EnableWorkflow from "../../Types/Database/EnableWorkflow";
|
||||
import ColorField from "../../Types/Database/ColorField";
|
||||
import SlugifyColumn from "../../Types/Database/SlugifyColumn";
|
||||
import TableColumn from "../../Types/Database/TableColumn";
|
||||
import TableColumnType from "../../Types/Database/TableColumnType";
|
||||
@@ -356,6 +357,7 @@ export default class AlertState extends BaseModel {
|
||||
Permission.EditAlertState,
|
||||
],
|
||||
})
|
||||
@ColorField()
|
||||
@TableColumn({
|
||||
title: "Color",
|
||||
required: true,
|
||||
|
||||
@@ -15,6 +15,7 @@ import TableColumn, {
|
||||
getTableColumns,
|
||||
} from "../../../Types/Database/TableColumn";
|
||||
import TableColumnType from "../../../Types/Database/TableColumnType";
|
||||
import { getFirstColorFieldColumn } from "../../../Types/Database/ColorField";
|
||||
import Dictionary from "../../../Types/Dictionary";
|
||||
import Email from "../../../Types/Email";
|
||||
import BadDataException from "../../../Types/Exception/BadDataException";
|
||||
@@ -57,6 +58,7 @@ export default class DatabaseBaseModel extends BaseEntity {
|
||||
type: TableColumnType.ObjectID,
|
||||
description: "ID of this object",
|
||||
computed: true,
|
||||
canReadOnRelationQuery: true,
|
||||
})
|
||||
@PrimaryGeneratedColumn("uuid")
|
||||
public _id?: string = undefined;
|
||||
@@ -123,7 +125,6 @@ export default class DatabaseBaseModel extends BaseEntity {
|
||||
public isMasterAdminApiDocs!: boolean;
|
||||
|
||||
public currentUserCanAccessColumnBy!: string | null;
|
||||
public labelsColumn!: string | null;
|
||||
public slugifyColumn!: string | null;
|
||||
public saveSlugToColumn!: string | null;
|
||||
public singularName!: string | null;
|
||||
@@ -204,6 +205,10 @@ export default class DatabaseBaseModel extends BaseEntity {
|
||||
return new Columns(Object.keys(getTableColumns(this)));
|
||||
}
|
||||
|
||||
public getFirstColorColumn(): string | null {
|
||||
return getFirstColorFieldColumn(this);
|
||||
}
|
||||
|
||||
public canQueryMultiTenant(): boolean {
|
||||
return Boolean(this.isMultiTenantRequestAllowed);
|
||||
}
|
||||
@@ -345,10 +350,6 @@ export default class DatabaseBaseModel extends BaseEntity {
|
||||
return this.currentUserCanAccessColumnBy;
|
||||
}
|
||||
|
||||
public getLabelsColumn(): string | null {
|
||||
return this.labelsColumn;
|
||||
}
|
||||
|
||||
public get id(): ObjectID | null {
|
||||
return this._id ? new ObjectID(this._id) : null;
|
||||
}
|
||||
|
||||
@@ -301,7 +301,12 @@ export default class Domain extends BaseModel {
|
||||
public deletedByUserId?: ObjectID = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [],
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateProjectDomain,
|
||||
],
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
|
||||
104
Common/Models/DatabaseModels/EnterpriseLicense.ts
Normal file
104
Common/Models/DatabaseModels/EnterpriseLicense.ts
Normal file
@@ -0,0 +1,104 @@
|
||||
import BaseModel from "./DatabaseBaseModel/DatabaseBaseModel";
|
||||
import Route from "../../Types/API/Route";
|
||||
import ColumnAccessControl from "../../Types/Database/AccessControl/ColumnAccessControl";
|
||||
import TableAccessControl from "../../Types/Database/AccessControl/TableAccessControl";
|
||||
import ColumnLength from "../../Types/Database/ColumnLength";
|
||||
import ColumnType from "../../Types/Database/ColumnType";
|
||||
import CrudApiEndpoint from "../../Types/Database/CrudApiEndpoint";
|
||||
import TableColumn from "../../Types/Database/TableColumn";
|
||||
import TableColumnType from "../../Types/Database/TableColumnType";
|
||||
import TableMetadata from "../../Types/Database/TableMetadata";
|
||||
import IconProp from "../../Types/Icon/IconProp";
|
||||
import { Column, Entity, Index } from "typeorm";
|
||||
|
||||
@TableAccessControl({
|
||||
create: [],
|
||||
read: [],
|
||||
update: [],
|
||||
delete: [],
|
||||
})
|
||||
@CrudApiEndpoint(new Route("/enterprise-license"))
|
||||
@TableMetadata({
|
||||
tableName: "EnterpriseLicense",
|
||||
singularName: "Enterprise License",
|
||||
pluralName: "Enterprise Licenses",
|
||||
icon: IconProp.Lock,
|
||||
tableDescription: "Enterprise license keys issued by OneUptime.",
|
||||
})
|
||||
@Entity({
|
||||
name: "EnterpriseLicense",
|
||||
})
|
||||
export default class EnterpriseLicense extends BaseModel {
|
||||
@ColumnAccessControl({
|
||||
create: [],
|
||||
read: [],
|
||||
update: [],
|
||||
})
|
||||
@TableColumn({
|
||||
required: true,
|
||||
type: TableColumnType.ShortText,
|
||||
title: "Company Name",
|
||||
description: "Company name associated with this license.",
|
||||
})
|
||||
@Column({
|
||||
nullable: false,
|
||||
type: ColumnType.ShortText,
|
||||
length: ColumnLength.ShortText,
|
||||
})
|
||||
public companyName?: string = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [],
|
||||
read: [],
|
||||
update: [],
|
||||
})
|
||||
@TableColumn({
|
||||
required: true,
|
||||
type: TableColumnType.ShortText,
|
||||
title: "License Key",
|
||||
description: "Enterprise license key.",
|
||||
unique: true,
|
||||
})
|
||||
@Index({ unique: true })
|
||||
@Column({
|
||||
nullable: false,
|
||||
type: ColumnType.ShortText,
|
||||
length: ColumnLength.ShortText,
|
||||
unique: true,
|
||||
})
|
||||
public licenseKey?: string = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [],
|
||||
read: [],
|
||||
update: [],
|
||||
})
|
||||
@TableColumn({
|
||||
required: true,
|
||||
type: TableColumnType.Date,
|
||||
title: "Expires At",
|
||||
description: "Expiration date of this license.",
|
||||
})
|
||||
@Column({
|
||||
nullable: false,
|
||||
type: ColumnType.Date,
|
||||
})
|
||||
public expiresAt?: Date = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [],
|
||||
read: [],
|
||||
update: [],
|
||||
})
|
||||
@TableColumn({
|
||||
required: false,
|
||||
type: TableColumnType.Number,
|
||||
title: "Annual Contract Value",
|
||||
description: "Annual contract value (in USD) for this license.",
|
||||
})
|
||||
@Column({
|
||||
nullable: true,
|
||||
type: ColumnType.Number,
|
||||
})
|
||||
public annualContractValue?: number = undefined;
|
||||
}
|
||||
@@ -22,7 +22,7 @@ import { Entity } from "typeorm";
|
||||
@CrudApiEndpoint(new Route("/file"))
|
||||
@TableAccessControl({
|
||||
create: [Permission.CurrentUser, Permission.AuthenticatedRequest],
|
||||
read: [Permission.CurrentUser, Permission.AuthenticatedRequest],
|
||||
read: [],
|
||||
delete: [],
|
||||
update: [],
|
||||
})
|
||||
|
||||
@@ -352,6 +352,25 @@ export default class GlobalConfig extends GlobalConfigModel {
|
||||
})
|
||||
public metaWhatsAppAppSecret?: string = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [],
|
||||
read: [],
|
||||
update: [],
|
||||
})
|
||||
@TableColumn({
|
||||
type: TableColumnType.ShortText,
|
||||
title: "Meta WhatsApp Webhook Verify Token",
|
||||
description:
|
||||
"Verify token configured in Meta to validate webhook subscriptions.",
|
||||
})
|
||||
@Column({
|
||||
type: ColumnType.ShortText,
|
||||
length: ColumnLength.ShortText,
|
||||
nullable: true,
|
||||
unique: true,
|
||||
})
|
||||
public metaWhatsAppWebhookVerifyToken?: string = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [],
|
||||
read: [],
|
||||
@@ -478,4 +497,75 @@ export default class GlobalConfig extends GlobalConfigModel {
|
||||
transformer: Email.getDatabaseTransformer(),
|
||||
})
|
||||
public adminNotificationEmail?: Email = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [],
|
||||
read: [],
|
||||
update: [],
|
||||
})
|
||||
@TableColumn({
|
||||
type: TableColumnType.ShortText,
|
||||
title: "Enterprise Company Name",
|
||||
description:
|
||||
"Company name associated with the validated enterprise license.",
|
||||
})
|
||||
@Column({
|
||||
type: ColumnType.ShortText,
|
||||
length: ColumnLength.ShortText,
|
||||
nullable: true,
|
||||
unique: true,
|
||||
})
|
||||
public enterpriseCompanyName?: string = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [],
|
||||
read: [],
|
||||
update: [],
|
||||
})
|
||||
@TableColumn({
|
||||
type: TableColumnType.ShortText,
|
||||
title: "Enterprise License Key",
|
||||
description: "Enterprise license key stored after successful validation.",
|
||||
})
|
||||
@Column({
|
||||
type: ColumnType.ShortText,
|
||||
length: ColumnLength.ShortText,
|
||||
nullable: true,
|
||||
unique: true,
|
||||
})
|
||||
public enterpriseLicenseKey?: string = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [],
|
||||
read: [],
|
||||
update: [],
|
||||
})
|
||||
@TableColumn({
|
||||
type: TableColumnType.Date,
|
||||
title: "Enterprise License Expires At",
|
||||
description: "Expiration date of the validated enterprise license.",
|
||||
})
|
||||
@Column({
|
||||
type: ColumnType.Date,
|
||||
nullable: true,
|
||||
unique: true,
|
||||
})
|
||||
public enterpriseLicenseExpiresAt?: Date = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [],
|
||||
read: [],
|
||||
update: [],
|
||||
})
|
||||
@TableColumn({
|
||||
type: TableColumnType.VeryLongText,
|
||||
title: "Enterprise License Token",
|
||||
description: "Signed JWT returned from license validation.",
|
||||
})
|
||||
@Column({
|
||||
type: ColumnType.VeryLongText,
|
||||
nullable: true,
|
||||
unique: true,
|
||||
})
|
||||
public enterpriseLicenseToken?: string = undefined;
|
||||
}
|
||||
|
||||
@@ -926,6 +926,39 @@ export default class Incident extends BaseModel {
|
||||
})
|
||||
public rootCause?: string = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateProjectIncident,
|
||||
],
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadProjectIncident,
|
||||
],
|
||||
update: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.EditProjectIncident,
|
||||
],
|
||||
})
|
||||
@TableColumn({
|
||||
type: TableColumnType.Markdown,
|
||||
required: false,
|
||||
isDefaultValueColumn: false,
|
||||
title: "Postmortem Note",
|
||||
description: "Document the postmortem summary for this incident.",
|
||||
})
|
||||
@Column({
|
||||
type: ColumnType.Markdown,
|
||||
nullable: true,
|
||||
})
|
||||
public postmortemNote?: string = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [],
|
||||
read: [
|
||||
|
||||
@@ -33,6 +33,7 @@ export enum IncidentFeedEventType {
|
||||
IncidentUpdated = "IncidentUpdated",
|
||||
RootCause = "RootCause",
|
||||
RemediationNotes = "RemediationNotes",
|
||||
PostmortemNote = "PostmortemNote",
|
||||
OwnerUserRemoved = "OwnerUserRemoved",
|
||||
OwnerTeamRemoved = "OwnerTeamRemoved",
|
||||
OnCallPolicy = "OnCallPolicy",
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import Incident from "./Incident";
|
||||
import Project from "./Project";
|
||||
import User from "./User";
|
||||
import File from "./File";
|
||||
import BaseModel from "./DatabaseBaseModel/DatabaseBaseModel";
|
||||
import Route from "../../Types/API/Route";
|
||||
import ColumnAccessControl from "../../Types/Database/AccessControl/ColumnAccessControl";
|
||||
@@ -17,7 +18,15 @@ import TenantColumn from "../../Types/Database/TenantColumn";
|
||||
import IconProp from "../../Types/Icon/IconProp";
|
||||
import ObjectID from "../../Types/ObjectID";
|
||||
import Permission from "../../Types/Permission";
|
||||
import { Column, Entity, Index, JoinColumn, ManyToOne } from "typeorm";
|
||||
import {
|
||||
Column,
|
||||
Entity,
|
||||
Index,
|
||||
JoinColumn,
|
||||
JoinTable,
|
||||
ManyToMany,
|
||||
ManyToOne,
|
||||
} from "typeorm";
|
||||
|
||||
@EnableDocumentation()
|
||||
@CanAccessIfCanReadOn("incident")
|
||||
@@ -340,6 +349,54 @@ export default class IncidentInternalNote extends BaseModel {
|
||||
})
|
||||
public note?: string = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateIncidentInternalNote,
|
||||
],
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadIncidentInternalNote,
|
||||
],
|
||||
update: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.EditIncidentInternalNote,
|
||||
],
|
||||
})
|
||||
@TableColumn({
|
||||
type: TableColumnType.EntityArray,
|
||||
modelType: File,
|
||||
title: "Attachments",
|
||||
description: "Files attached to this note",
|
||||
required: false,
|
||||
})
|
||||
@ManyToMany(
|
||||
() => {
|
||||
return File;
|
||||
},
|
||||
{
|
||||
eager: false,
|
||||
},
|
||||
)
|
||||
@JoinTable({
|
||||
name: "IncidentInternalNoteFile",
|
||||
joinColumn: {
|
||||
name: "incidentInternalNoteId",
|
||||
referencedColumnName: "_id",
|
||||
},
|
||||
inverseJoinColumn: {
|
||||
name: "fileId",
|
||||
referencedColumnName: "_id",
|
||||
},
|
||||
})
|
||||
public attachments?: Array<File> = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [],
|
||||
read: [
|
||||
|
||||
353
Common/Models/DatabaseModels/IncidentPostmortemTemplate.ts
Normal file
353
Common/Models/DatabaseModels/IncidentPostmortemTemplate.ts
Normal file
@@ -0,0 +1,353 @@
|
||||
import Project from "./Project";
|
||||
import User from "./User";
|
||||
import BaseModel from "./DatabaseBaseModel/DatabaseBaseModel";
|
||||
import Route from "../../Types/API/Route";
|
||||
import ColumnAccessControl from "../../Types/Database/AccessControl/ColumnAccessControl";
|
||||
import TableAccessControl from "../../Types/Database/AccessControl/TableAccessControl";
|
||||
import ColumnLength from "../../Types/Database/ColumnLength";
|
||||
import ColumnType from "../../Types/Database/ColumnType";
|
||||
import CrudApiEndpoint from "../../Types/Database/CrudApiEndpoint";
|
||||
import EnableDocumentation from "../../Types/Database/EnableDocumentation";
|
||||
import EnableWorkflow from "../../Types/Database/EnableWorkflow";
|
||||
import TableColumn from "../../Types/Database/TableColumn";
|
||||
import TableColumnType from "../../Types/Database/TableColumnType";
|
||||
import TableMetadata from "../../Types/Database/TableMetadata";
|
||||
import TenantColumn from "../../Types/Database/TenantColumn";
|
||||
import IconProp from "../../Types/Icon/IconProp";
|
||||
import ObjectID from "../../Types/ObjectID";
|
||||
import Permission from "../../Types/Permission";
|
||||
import { Column, Entity, Index, JoinColumn, ManyToOne } from "typeorm";
|
||||
import TableBillingAccessControl from "../../Types/Database/AccessControl/TableBillingAccessControl";
|
||||
import { PlanType } from "../../Types/Billing/SubscriptionPlan";
|
||||
|
||||
@TableBillingAccessControl({
|
||||
create: PlanType.Growth,
|
||||
read: PlanType.Growth,
|
||||
update: PlanType.Growth,
|
||||
delete: PlanType.Growth,
|
||||
})
|
||||
@EnableDocumentation()
|
||||
@TenantColumn("projectId")
|
||||
@TableAccessControl({
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateIncidentNoteTemplate,
|
||||
],
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadIncidentNoteTemplate,
|
||||
],
|
||||
delete: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.DeleteIncidentNoteTemplate,
|
||||
],
|
||||
update: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.EditIncidentNoteTemplate,
|
||||
],
|
||||
})
|
||||
@CrudApiEndpoint(new Route("/incident-postmortem-template"))
|
||||
@Entity({
|
||||
name: "IncidentPostmortemTemplate",
|
||||
})
|
||||
@EnableWorkflow({
|
||||
create: true,
|
||||
delete: true,
|
||||
update: true,
|
||||
read: true,
|
||||
})
|
||||
@TableMetadata({
|
||||
tableName: "IncidentPostmortemTemplate",
|
||||
singularName: "Incident Postmortem Template",
|
||||
pluralName: "Incident Postmortem Templates",
|
||||
icon: IconProp.Book,
|
||||
tableDescription: "Manage postmortem templates for your incidents",
|
||||
})
|
||||
export default class IncidentPostmortemTemplate extends BaseModel {
|
||||
@ColumnAccessControl({
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateIncidentNoteTemplate,
|
||||
],
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadIncidentNoteTemplate,
|
||||
],
|
||||
update: [],
|
||||
})
|
||||
@TableColumn({
|
||||
manyToOneRelationColumn: "projectId",
|
||||
type: TableColumnType.Entity,
|
||||
modelType: Project,
|
||||
title: "Project",
|
||||
description: "Relation to Project Resource in which this object belongs",
|
||||
})
|
||||
@ManyToOne(
|
||||
() => {
|
||||
return Project;
|
||||
},
|
||||
{
|
||||
eager: false,
|
||||
nullable: true,
|
||||
onDelete: "CASCADE",
|
||||
orphanedRowAction: "nullify",
|
||||
},
|
||||
)
|
||||
@JoinColumn({ name: "projectId" })
|
||||
public project?: Project = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateIncidentNoteTemplate,
|
||||
],
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadIncidentNoteTemplate,
|
||||
],
|
||||
update: [],
|
||||
})
|
||||
@Index()
|
||||
@TableColumn({
|
||||
type: TableColumnType.ObjectID,
|
||||
required: true,
|
||||
canReadOnRelationQuery: true,
|
||||
title: "Project ID",
|
||||
description: "ID of your OneUptime Project in which this object belongs",
|
||||
})
|
||||
@Column({
|
||||
type: ColumnType.ObjectID,
|
||||
nullable: false,
|
||||
transformer: ObjectID.getDatabaseTransformer(),
|
||||
})
|
||||
public projectId?: ObjectID = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateIncidentNoteTemplate,
|
||||
],
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadIncidentNoteTemplate,
|
||||
],
|
||||
update: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.EditIncidentNoteTemplate,
|
||||
],
|
||||
})
|
||||
@Index()
|
||||
@TableColumn({
|
||||
type: TableColumnType.Markdown,
|
||||
title: "Postmortem Note",
|
||||
description:
|
||||
"Markdown template used when documenting an incident postmortem.",
|
||||
})
|
||||
@Column({
|
||||
type: ColumnType.Markdown,
|
||||
nullable: false,
|
||||
unique: false,
|
||||
})
|
||||
public postmortemNote?: string = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateIncidentNoteTemplate,
|
||||
],
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadIncidentNoteTemplate,
|
||||
],
|
||||
update: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.EditIncidentNoteTemplate,
|
||||
],
|
||||
})
|
||||
@TableColumn({
|
||||
required: true,
|
||||
type: TableColumnType.ShortText,
|
||||
canReadOnRelationQuery: true,
|
||||
title: "Name",
|
||||
description: "Name of the Postmortem Template",
|
||||
})
|
||||
@Column({
|
||||
nullable: false,
|
||||
type: ColumnType.ShortText,
|
||||
length: ColumnLength.ShortText,
|
||||
})
|
||||
public templateName?: string = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateIncidentNoteTemplate,
|
||||
],
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadIncidentNoteTemplate,
|
||||
],
|
||||
update: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.EditIncidentNoteTemplate,
|
||||
],
|
||||
})
|
||||
@TableColumn({
|
||||
required: true,
|
||||
type: TableColumnType.LongText,
|
||||
canReadOnRelationQuery: true,
|
||||
title: "Template Description",
|
||||
description: "Description of the Postmortem Template",
|
||||
})
|
||||
@Column({
|
||||
nullable: false,
|
||||
type: ColumnType.LongText,
|
||||
length: ColumnLength.LongText,
|
||||
})
|
||||
public templateDescription?: string = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateIncidentNoteTemplate,
|
||||
],
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadIncidentNoteTemplate,
|
||||
],
|
||||
update: [],
|
||||
})
|
||||
@TableColumn({
|
||||
manyToOneRelationColumn: "createdByUserId",
|
||||
type: TableColumnType.Entity,
|
||||
modelType: User,
|
||||
title: "Created by User",
|
||||
description:
|
||||
"Relation to User who created this object (if this object was created by a User)",
|
||||
})
|
||||
@ManyToOne(
|
||||
() => {
|
||||
return User;
|
||||
},
|
||||
{
|
||||
eager: false,
|
||||
nullable: true,
|
||||
onDelete: "SET NULL",
|
||||
orphanedRowAction: "nullify",
|
||||
},
|
||||
)
|
||||
@JoinColumn({ name: "createdByUserId" })
|
||||
public createdByUser?: User = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateIncidentNoteTemplate,
|
||||
],
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadIncidentNoteTemplate,
|
||||
],
|
||||
update: [],
|
||||
})
|
||||
@TableColumn({
|
||||
type: TableColumnType.ObjectID,
|
||||
title: "Created by User ID",
|
||||
description:
|
||||
"User ID who created this object (if this object was created by a User)",
|
||||
})
|
||||
@Column({
|
||||
type: ColumnType.ObjectID,
|
||||
nullable: true,
|
||||
transformer: ObjectID.getDatabaseTransformer(),
|
||||
})
|
||||
public createdByUserId?: ObjectID = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [],
|
||||
read: [],
|
||||
update: [],
|
||||
})
|
||||
@TableColumn({
|
||||
manyToOneRelationColumn: "deletedByUserId",
|
||||
type: TableColumnType.Entity,
|
||||
title: "Deleted by User",
|
||||
modelType: User,
|
||||
description:
|
||||
"Relation to User who deleted this object (if this object was deleted by a User)",
|
||||
})
|
||||
@ManyToOne(
|
||||
() => {
|
||||
return User;
|
||||
},
|
||||
{
|
||||
cascade: false,
|
||||
eager: false,
|
||||
nullable: true,
|
||||
onDelete: "SET NULL",
|
||||
orphanedRowAction: "nullify",
|
||||
},
|
||||
)
|
||||
@JoinColumn({ name: "deletedByUserId" })
|
||||
public deletedByUser?: User = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [],
|
||||
read: [],
|
||||
update: [],
|
||||
})
|
||||
@TableColumn({
|
||||
type: TableColumnType.ObjectID,
|
||||
title: "Deleted by User ID",
|
||||
description:
|
||||
"User ID who deleted this object (if this object was deleted by a User)",
|
||||
})
|
||||
@Column({
|
||||
type: ColumnType.ObjectID,
|
||||
nullable: true,
|
||||
transformer: ObjectID.getDatabaseTransformer(),
|
||||
})
|
||||
public deletedByUserId?: ObjectID = undefined;
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
import Incident from "./Incident";
|
||||
import Project from "./Project";
|
||||
import User from "./User";
|
||||
import File from "./File";
|
||||
import BaseModel from "./DatabaseBaseModel/DatabaseBaseModel";
|
||||
import Route from "../../Types/API/Route";
|
||||
import ColumnAccessControl from "../../Types/Database/AccessControl/ColumnAccessControl";
|
||||
@@ -18,7 +19,15 @@ import IconProp from "../../Types/Icon/IconProp";
|
||||
import ObjectID from "../../Types/ObjectID";
|
||||
import Permission from "../../Types/Permission";
|
||||
import StatusPageSubscriberNotificationStatus from "../../Types/StatusPage/StatusPageSubscriberNotificationStatus";
|
||||
import { Column, Entity, Index, JoinColumn, ManyToOne } from "typeorm";
|
||||
import {
|
||||
Column,
|
||||
Entity,
|
||||
Index,
|
||||
JoinColumn,
|
||||
JoinTable,
|
||||
ManyToMany,
|
||||
ManyToOne,
|
||||
} from "typeorm";
|
||||
|
||||
@EnableDocumentation()
|
||||
@CanAccessIfCanReadOn("incident")
|
||||
@@ -341,6 +350,54 @@ export default class IncidentPublicNote extends BaseModel {
|
||||
})
|
||||
public note?: string = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateIncidentPublicNote,
|
||||
],
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadIncidentPublicNote,
|
||||
],
|
||||
update: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.EditIncidentPublicNote,
|
||||
],
|
||||
})
|
||||
@TableColumn({
|
||||
type: TableColumnType.EntityArray,
|
||||
modelType: File,
|
||||
title: "Attachments",
|
||||
description: "Files attached to this note",
|
||||
required: false,
|
||||
})
|
||||
@ManyToMany(
|
||||
() => {
|
||||
return File;
|
||||
},
|
||||
{
|
||||
eager: false,
|
||||
},
|
||||
)
|
||||
@JoinTable({
|
||||
name: "IncidentPublicNoteFile",
|
||||
joinColumn: {
|
||||
name: "incidentPublicNoteId",
|
||||
referencedColumnName: "_id",
|
||||
},
|
||||
inverseJoinColumn: {
|
||||
name: "fileId",
|
||||
referencedColumnName: "_id",
|
||||
},
|
||||
})
|
||||
public attachments?: Array<File> = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
|
||||
@@ -12,6 +12,7 @@ import ColumnType from "../../Types/Database/ColumnType";
|
||||
import CrudApiEndpoint from "../../Types/Database/CrudApiEndpoint";
|
||||
import EnableDocumentation from "../../Types/Database/EnableDocumentation";
|
||||
import EnableWorkflow from "../../Types/Database/EnableWorkflow";
|
||||
import ColorField from "../../Types/Database/ColorField";
|
||||
import SlugifyColumn from "../../Types/Database/SlugifyColumn";
|
||||
import TableColumn from "../../Types/Database/TableColumn";
|
||||
import TableColumnType from "../../Types/Database/TableColumnType";
|
||||
@@ -378,6 +379,7 @@ export default class IncidentSeverity extends BaseModel {
|
||||
Permission.EditIncidentSeverity,
|
||||
],
|
||||
})
|
||||
@ColorField()
|
||||
@TableColumn({
|
||||
title: "Color",
|
||||
required: true,
|
||||
|
||||
@@ -12,6 +12,7 @@ import ColumnType from "../../Types/Database/ColumnType";
|
||||
import CrudApiEndpoint from "../../Types/Database/CrudApiEndpoint";
|
||||
import EnableDocumentation from "../../Types/Database/EnableDocumentation";
|
||||
import EnableWorkflow from "../../Types/Database/EnableWorkflow";
|
||||
import ColorField from "../../Types/Database/ColorField";
|
||||
import SlugifyColumn from "../../Types/Database/SlugifyColumn";
|
||||
import TableColumn from "../../Types/Database/TableColumn";
|
||||
import TableColumnType from "../../Types/Database/TableColumnType";
|
||||
@@ -380,6 +381,7 @@ export default class IncidentState extends BaseModel {
|
||||
Permission.EditIncidentState,
|
||||
],
|
||||
})
|
||||
@ColorField()
|
||||
@TableColumn({
|
||||
title: "Color",
|
||||
required: true,
|
||||
|
||||
@@ -24,6 +24,7 @@ import IncidentFeed from "./IncidentFeed";
|
||||
import IncidentCustomField from "./IncidentCustomField";
|
||||
import IncidentInternalNote from "./IncidentInternalNote";
|
||||
import IncidentNoteTemplate from "./IncidentNoteTemplate";
|
||||
import IncidentPostmortemTemplate from "./IncidentPostmortemTemplate";
|
||||
import IncidentOwnerTeam from "./IncidentOwnerTeam";
|
||||
import IncidentOwnerUser from "./IncidentOwnerUser";
|
||||
import IncidentPublicNote from "./IncidentPublicNote";
|
||||
@@ -80,6 +81,7 @@ import ProjectSmtpConfig from "./ProjectSmtpConfig";
|
||||
//SSO
|
||||
import ProjectSSO from "./ProjectSso";
|
||||
import PromoCode from "./PromoCode";
|
||||
import EnterpriseLicense from "./EnterpriseLicense";
|
||||
import Reseller from "./Reseller";
|
||||
import ResellerPlan from "./ResellerPlan";
|
||||
// ScheduledMaintenances
|
||||
@@ -116,6 +118,7 @@ import StatusPageHistoryChartBarColorRule from "./StatusPageHistoryChartBarColor
|
||||
import StatusPageOwnerTeam from "./StatusPageOwnerTeam";
|
||||
import StatusPageOwnerUser from "./StatusPageOwnerUser";
|
||||
import StatusPagePrivateUser from "./StatusPagePrivateUser";
|
||||
import StatusPagePrivateUserSession from "./StatusPagePrivateUserSession";
|
||||
import StatusPageResource from "./StatusPageResource";
|
||||
import StatusPageSCIM from "./StatusPageSCIM";
|
||||
import StatusPageSSO from "./StatusPageSso";
|
||||
@@ -128,6 +131,7 @@ import TeamComplianceSetting from "./TeamComplianceSetting";
|
||||
import TelemetryService from "./TelemetryService";
|
||||
import UsageBilling from "./TelemetryUsageBilling";
|
||||
import User from "./User";
|
||||
import UserSession from "./UserSession";
|
||||
import UserCall from "./UserCall";
|
||||
// Notification Methods
|
||||
import UserEmail from "./UserEmail";
|
||||
@@ -235,6 +239,7 @@ const AllModelTypes: Array<{
|
||||
IncidentOwnerUser,
|
||||
IncidentSeverity,
|
||||
IncidentNoteTemplate,
|
||||
IncidentPostmortemTemplate,
|
||||
|
||||
AlertState,
|
||||
Alert,
|
||||
@@ -263,6 +268,7 @@ const AllModelTypes: Array<{
|
||||
StatusPageFooterLink,
|
||||
StatusPageHeaderLink,
|
||||
StatusPagePrivateUser,
|
||||
StatusPagePrivateUserSession,
|
||||
StatusPageHistoryChartBarColorRule,
|
||||
|
||||
ScheduledMaintenanceState,
|
||||
@@ -329,6 +335,7 @@ const AllModelTypes: Array<{
|
||||
ResellerPlan,
|
||||
|
||||
PromoCode,
|
||||
EnterpriseLicense,
|
||||
|
||||
GlobalConfig,
|
||||
|
||||
@@ -371,6 +378,7 @@ const AllModelTypes: Array<{
|
||||
ProbeOwnerTeam,
|
||||
ProbeOwnerUser,
|
||||
|
||||
UserSession,
|
||||
UserTotpAuth,
|
||||
UserWebAuthn,
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ import ColumnType from "../../Types/Database/ColumnType";
|
||||
import CrudApiEndpoint from "../../Types/Database/CrudApiEndpoint";
|
||||
import EnableDocumentation from "../../Types/Database/EnableDocumentation";
|
||||
import EnableWorkflow from "../../Types/Database/EnableWorkflow";
|
||||
import ColorField from "../../Types/Database/ColorField";
|
||||
import SlugifyColumn from "../../Types/Database/SlugifyColumn";
|
||||
import TableColumn from "../../Types/Database/TableColumn";
|
||||
import TableColumnType from "../../Types/Database/TableColumnType";
|
||||
@@ -365,6 +366,7 @@ export default class Label extends AccessControlModel {
|
||||
Permission.EditProjectLabel,
|
||||
],
|
||||
})
|
||||
@ColorField()
|
||||
@TableColumn({
|
||||
title: "Color",
|
||||
required: true,
|
||||
|
||||
@@ -12,6 +12,7 @@ import ColumnType from "../../Types/Database/ColumnType";
|
||||
import CrudApiEndpoint from "../../Types/Database/CrudApiEndpoint";
|
||||
import EnableDocumentation from "../../Types/Database/EnableDocumentation";
|
||||
import EnableWorkflow from "../../Types/Database/EnableWorkflow";
|
||||
import ColorField from "../../Types/Database/ColorField";
|
||||
import SlugifyColumn from "../../Types/Database/SlugifyColumn";
|
||||
import TableColumn from "../../Types/Database/TableColumn";
|
||||
import TableColumnType from "../../Types/Database/TableColumnType";
|
||||
@@ -379,6 +380,7 @@ export default class MonitorStatus extends BaseModel {
|
||||
Permission.EditProjectMonitorStatus,
|
||||
],
|
||||
})
|
||||
@ColorField()
|
||||
@TableColumn({
|
||||
title: "Color",
|
||||
required: true,
|
||||
|
||||
@@ -134,7 +134,7 @@ export default class Project extends TenantModel {
|
||||
Permission.UnAuthorizedSsoUser,
|
||||
Permission.ProjectUser,
|
||||
],
|
||||
update: [Permission.ProjectOwner],
|
||||
update: [Permission.ProjectOwner, Permission.ManageProjectBilling],
|
||||
})
|
||||
@TableColumn({ type: TableColumnType.ShortText })
|
||||
@Column({
|
||||
@@ -704,8 +704,8 @@ export default class Project extends TenantModel {
|
||||
type: TableColumnType.Number,
|
||||
isDefaultValueColumn: true,
|
||||
required: true,
|
||||
title: "SMS or Call Current Balance",
|
||||
description: "Balance in USD for SMS or Call",
|
||||
title: "SMS, Call, and WhatsApp Current Balance",
|
||||
description: "Balance in USD for SMS, Call, and WhatsApp",
|
||||
defaultValue: 0,
|
||||
})
|
||||
@Column({
|
||||
@@ -732,7 +732,7 @@ export default class Project extends TenantModel {
|
||||
isDefaultValueColumn: true,
|
||||
required: true,
|
||||
title: "Auto Recharge Amount",
|
||||
description: "Auto recharge amount in USD for SMS or Call",
|
||||
description: "Auto recharge amount in USD for SMS, Call, and WhatsApp",
|
||||
defaultValue: 20,
|
||||
})
|
||||
@Column({
|
||||
@@ -760,7 +760,7 @@ export default class Project extends TenantModel {
|
||||
required: true,
|
||||
title: "Auto Recharge when current balance falls to",
|
||||
description:
|
||||
"Auto recharge is triggered when current balance falls to this amount in USD for SMS or Call",
|
||||
"Auto recharge is triggered when current balance falls to this amount in USD for SMS, Call, and WhatsApp",
|
||||
defaultValue: 10,
|
||||
})
|
||||
@Column({
|
||||
@@ -868,8 +868,9 @@ export default class Project extends TenantModel {
|
||||
required: true,
|
||||
isDefaultValueColumn: true,
|
||||
type: TableColumnType.Boolean,
|
||||
title: "Enable auto recharge SMS or Call balance",
|
||||
description: "Enable auto recharge SMS or Call balance for this project.",
|
||||
title: "Enable auto recharge for SMS, Call, and WhatsApp balance",
|
||||
description:
|
||||
"Enable auto recharge for SMS, Call, and WhatsApp balance for this project.",
|
||||
defaultValue: false,
|
||||
})
|
||||
@Column({
|
||||
@@ -889,8 +890,9 @@ export default class Project extends TenantModel {
|
||||
isDefaultValueColumn: true,
|
||||
hideColumnInDocumentation: true,
|
||||
type: TableColumnType.Boolean,
|
||||
title: "Low Call and SMS Balance Notification Sent to Owners",
|
||||
description: "Low Call and SMS Balance Notification Sent to Owners",
|
||||
title: "Low SMS, Call, and WhatsApp Balance Notification Sent to Owners",
|
||||
description:
|
||||
"Low SMS, Call, and WhatsApp Balance Notification Sent to Owners",
|
||||
defaultValue: false,
|
||||
})
|
||||
@Column({
|
||||
@@ -910,9 +912,10 @@ export default class Project extends TenantModel {
|
||||
isDefaultValueColumn: true,
|
||||
type: TableColumnType.Boolean,
|
||||
hideColumnInDocumentation: true,
|
||||
title: "Failed Call and SMS Balance Charge Notification Sent to Owners",
|
||||
title:
|
||||
"Failed SMS, Call, and WhatsApp Balance Charge Notification Sent to Owners",
|
||||
description:
|
||||
"Failed Call and SMS Balance Charge Notification Sent to Owners",
|
||||
"Failed SMS, Call, and WhatsApp Balance Charge Notification Sent to Owners",
|
||||
defaultValue: false,
|
||||
})
|
||||
@Column({
|
||||
@@ -933,8 +936,9 @@ export default class Project extends TenantModel {
|
||||
isDefaultValueColumn: true,
|
||||
hideColumnInDocumentation: true,
|
||||
type: TableColumnType.Boolean,
|
||||
title: "Not Enabled SMS or Call Notification Sent to Owners",
|
||||
description: "Not Enabled SMS or Call Notification Sent to Owners",
|
||||
title: "Not Enabled SMS, Call, or WhatsApp Notification Sent to Owners",
|
||||
description:
|
||||
"Not Enabled SMS, Call, or WhatsApp Notification Sent to Owners",
|
||||
defaultValue: false,
|
||||
})
|
||||
@Column({
|
||||
|
||||
@@ -10,6 +10,7 @@ import ColumnType from "../../Types/Database/ColumnType";
|
||||
import CrudApiEndpoint from "../../Types/Database/CrudApiEndpoint";
|
||||
import EnableDocumentation from "../../Types/Database/EnableDocumentation";
|
||||
import EnableWorkflow from "../../Types/Database/EnableWorkflow";
|
||||
import ColorField from "../../Types/Database/ColorField";
|
||||
import TableColumn from "../../Types/Database/TableColumn";
|
||||
import TableColumnType from "../../Types/Database/TableColumnType";
|
||||
import TableMetadata from "../../Types/Database/TableMetadata";
|
||||
@@ -422,6 +423,7 @@ export default class ScheduledMaintenanceFeed extends BaseModel {
|
||||
],
|
||||
update: [],
|
||||
})
|
||||
@ColorField()
|
||||
@TableColumn({
|
||||
type: TableColumnType.Color,
|
||||
required: true,
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import Project from "./Project";
|
||||
import ScheduledMaintenance from "./ScheduledMaintenance";
|
||||
import User from "./User";
|
||||
import File from "./File";
|
||||
import BaseModel from "./DatabaseBaseModel/DatabaseBaseModel";
|
||||
import Route from "../../Types/API/Route";
|
||||
import ColumnAccessControl from "../../Types/Database/AccessControl/ColumnAccessControl";
|
||||
@@ -16,7 +17,15 @@ import TenantColumn from "../../Types/Database/TenantColumn";
|
||||
import IconProp from "../../Types/Icon/IconProp";
|
||||
import ObjectID from "../../Types/ObjectID";
|
||||
import Permission from "../../Types/Permission";
|
||||
import { Column, Entity, Index, JoinColumn, ManyToOne } from "typeorm";
|
||||
import {
|
||||
Column,
|
||||
Entity,
|
||||
Index,
|
||||
JoinColumn,
|
||||
JoinTable,
|
||||
ManyToMany,
|
||||
ManyToOne,
|
||||
} from "typeorm";
|
||||
|
||||
@CanAccessIfCanReadOn("scheduledMaintenance")
|
||||
@TenantColumn("projectId")
|
||||
@@ -340,6 +349,54 @@ export default class ScheduledMaintenanceInternalNote extends BaseModel {
|
||||
})
|
||||
public note?: string = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateScheduledMaintenanceInternalNote,
|
||||
],
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadScheduledMaintenanceInternalNote,
|
||||
],
|
||||
update: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.EditScheduledMaintenanceInternalNote,
|
||||
],
|
||||
})
|
||||
@TableColumn({
|
||||
type: TableColumnType.EntityArray,
|
||||
modelType: File,
|
||||
title: "Attachments",
|
||||
description: "Files attached to this note",
|
||||
required: false,
|
||||
})
|
||||
@ManyToMany(
|
||||
() => {
|
||||
return File;
|
||||
},
|
||||
{
|
||||
eager: false,
|
||||
},
|
||||
)
|
||||
@JoinTable({
|
||||
name: "ScheduledMaintenanceInternalNoteFile",
|
||||
joinColumn: {
|
||||
name: "scheduledMaintenanceInternalNoteId",
|
||||
referencedColumnName: "_id",
|
||||
},
|
||||
inverseJoinColumn: {
|
||||
name: "fileId",
|
||||
referencedColumnName: "_id",
|
||||
},
|
||||
})
|
||||
public attachments?: Array<File> = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [],
|
||||
read: [
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import Project from "./Project";
|
||||
import ScheduledMaintenance from "./ScheduledMaintenance";
|
||||
import User from "./User";
|
||||
import File from "./File";
|
||||
import BaseModel from "./DatabaseBaseModel/DatabaseBaseModel";
|
||||
import Route from "../../Types/API/Route";
|
||||
import ColumnAccessControl from "../../Types/Database/AccessControl/ColumnAccessControl";
|
||||
@@ -18,7 +19,15 @@ import IconProp from "../../Types/Icon/IconProp";
|
||||
import ObjectID from "../../Types/ObjectID";
|
||||
import Permission from "../../Types/Permission";
|
||||
import StatusPageSubscriberNotificationStatus from "../../Types/StatusPage/StatusPageSubscriberNotificationStatus";
|
||||
import { Column, Entity, Index, JoinColumn, ManyToOne } from "typeorm";
|
||||
import {
|
||||
Column,
|
||||
Entity,
|
||||
Index,
|
||||
JoinColumn,
|
||||
JoinTable,
|
||||
ManyToMany,
|
||||
ManyToOne,
|
||||
} from "typeorm";
|
||||
|
||||
@EnableDocumentation()
|
||||
@CanAccessIfCanReadOn("scheduledMaintenance")
|
||||
@@ -342,6 +351,54 @@ export default class ScheduledMaintenancePublicNote extends BaseModel {
|
||||
})
|
||||
public note?: string = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateScheduledMaintenancePublicNote,
|
||||
],
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadScheduledMaintenancePublicNote,
|
||||
],
|
||||
update: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.EditScheduledMaintenancePublicNote,
|
||||
],
|
||||
})
|
||||
@TableColumn({
|
||||
type: TableColumnType.EntityArray,
|
||||
modelType: File,
|
||||
title: "Attachments",
|
||||
description: "Files attached to this note",
|
||||
required: false,
|
||||
})
|
||||
@ManyToMany(
|
||||
() => {
|
||||
return File;
|
||||
},
|
||||
{
|
||||
eager: false,
|
||||
},
|
||||
)
|
||||
@JoinTable({
|
||||
name: "ScheduledMaintenancePublicNoteFile",
|
||||
joinColumn: {
|
||||
name: "scheduledMaintenancePublicNoteId",
|
||||
referencedColumnName: "_id",
|
||||
},
|
||||
inverseJoinColumn: {
|
||||
name: "fileId",
|
||||
referencedColumnName: "_id",
|
||||
},
|
||||
})
|
||||
public attachments?: Array<File> = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
|
||||
@@ -12,6 +12,7 @@ import ColumnType from "../../Types/Database/ColumnType";
|
||||
import CrudApiEndpoint from "../../Types/Database/CrudApiEndpoint";
|
||||
import EnableDocumentation from "../../Types/Database/EnableDocumentation";
|
||||
import EnableWorkflow from "../../Types/Database/EnableWorkflow";
|
||||
import ColorField from "../../Types/Database/ColorField";
|
||||
import SlugifyColumn from "../../Types/Database/SlugifyColumn";
|
||||
import TableColumn from "../../Types/Database/TableColumn";
|
||||
import TableColumnType from "../../Types/Database/TableColumnType";
|
||||
@@ -380,6 +381,7 @@ export default class ScheduledMaintenanceState extends BaseModel {
|
||||
Permission.EditScheduledMaintenanceState,
|
||||
],
|
||||
})
|
||||
@ColorField()
|
||||
@TableColumn({
|
||||
title: "Color",
|
||||
required: true,
|
||||
|
||||
@@ -14,6 +14,7 @@ import ColumnType from "../../Types/Database/ColumnType";
|
||||
import CrudApiEndpoint from "../../Types/Database/CrudApiEndpoint";
|
||||
import EnableDocumentation from "../../Types/Database/EnableDocumentation";
|
||||
import EnableWorkflow from "../../Types/Database/EnableWorkflow";
|
||||
import ColorField from "../../Types/Database/ColorField";
|
||||
import SlugifyColumn from "../../Types/Database/SlugifyColumn";
|
||||
import TableColumn from "../../Types/Database/TableColumn";
|
||||
import TableColumnType from "../../Types/Database/TableColumnType";
|
||||
@@ -448,6 +449,7 @@ export default class ServiceCatalog extends BaseModel {
|
||||
Permission.EditServiceCatalog,
|
||||
],
|
||||
})
|
||||
@ColorField()
|
||||
@TableColumn({
|
||||
type: TableColumnType.Color,
|
||||
title: "Service Color",
|
||||
|
||||
@@ -2331,4 +2331,84 @@ export default class StatusPage extends BaseModel {
|
||||
create: PlanType.Free,
|
||||
})
|
||||
public ipWhitelist?: string = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateProjectStatusPage,
|
||||
],
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadProjectStatusPage,
|
||||
],
|
||||
update: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.EditProjectStatusPage,
|
||||
],
|
||||
})
|
||||
@TableColumn({
|
||||
isDefaultValueColumn: true,
|
||||
type: TableColumnType.Boolean,
|
||||
title: "Enable Embedded Overall Status Badge",
|
||||
description:
|
||||
"Enable embedded overall status badge that can be displayed on external websites?",
|
||||
defaultValue: false,
|
||||
})
|
||||
@Column({
|
||||
type: ColumnType.Boolean,
|
||||
default: false,
|
||||
nullable: false,
|
||||
})
|
||||
@ColumnBillingAccessControl({
|
||||
read: PlanType.Free,
|
||||
update: PlanType.Growth,
|
||||
create: PlanType.Free,
|
||||
})
|
||||
public enableEmbeddedOverallStatus?: boolean = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateProjectStatusPage,
|
||||
],
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadProjectStatusPage,
|
||||
],
|
||||
update: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.EditProjectStatusPage,
|
||||
],
|
||||
})
|
||||
@Index()
|
||||
@TableColumn({
|
||||
type: TableColumnType.ShortText,
|
||||
required: false,
|
||||
title: "Embedded Overall Status Token",
|
||||
description:
|
||||
"Security token required to access the embedded overall status badge. This token must be provided in the URL.",
|
||||
})
|
||||
@Column({
|
||||
type: ColumnType.ShortText,
|
||||
length: ColumnLength.ShortText,
|
||||
nullable: true,
|
||||
})
|
||||
@ColumnBillingAccessControl({
|
||||
read: PlanType.Free,
|
||||
update: PlanType.Growth,
|
||||
create: PlanType.Free,
|
||||
})
|
||||
public embeddedOverallStatusToken?: string = undefined;
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ import Monitor from "./Monitor";
|
||||
import Project from "./Project";
|
||||
import StatusPage from "./StatusPage";
|
||||
import User from "./User";
|
||||
import File from "./File";
|
||||
import BaseModel from "./DatabaseBaseModel/DatabaseBaseModel";
|
||||
import Route from "../../Types/API/Route";
|
||||
import { PlanType } from "../../Types/Billing/SubscriptionPlan";
|
||||
@@ -375,6 +376,54 @@ export default class StatusPageAnnouncement extends BaseModel {
|
||||
})
|
||||
public description?: string = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.CreateStatusPageAnnouncement,
|
||||
],
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadStatusPageAnnouncement,
|
||||
],
|
||||
update: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.EditStatusPageAnnouncement,
|
||||
],
|
||||
})
|
||||
@TableColumn({
|
||||
type: TableColumnType.EntityArray,
|
||||
modelType: File,
|
||||
title: "Attachments",
|
||||
description: "Files attached to this announcement",
|
||||
required: false,
|
||||
})
|
||||
@ManyToMany(
|
||||
() => {
|
||||
return File;
|
||||
},
|
||||
{
|
||||
eager: false,
|
||||
},
|
||||
)
|
||||
@JoinTable({
|
||||
name: "StatusPageAnnouncementFile",
|
||||
joinColumn: {
|
||||
name: "statusPageAnnouncementId",
|
||||
referencedColumnName: "_id",
|
||||
},
|
||||
inverseJoinColumn: {
|
||||
name: "fileId",
|
||||
referencedColumnName: "_id",
|
||||
},
|
||||
})
|
||||
public attachments?: Array<File> = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
|
||||
413
Common/Models/DatabaseModels/StatusPagePrivateUserSession.ts
Normal file
413
Common/Models/DatabaseModels/StatusPagePrivateUserSession.ts
Normal file
@@ -0,0 +1,413 @@
|
||||
import BaseModel from "./DatabaseBaseModel/DatabaseBaseModel";
|
||||
import Project from "./Project";
|
||||
import StatusPage from "./StatusPage";
|
||||
import StatusPagePrivateUser from "./StatusPagePrivateUser";
|
||||
import Route from "../../Types/API/Route";
|
||||
import { PlanType } from "../../Types/Billing/SubscriptionPlan";
|
||||
import AllowAccessIfSubscriptionIsUnpaid from "../../Types/Database/AccessControl/AllowAccessIfSubscriptionIsUnpaid";
|
||||
import ColumnAccessControl from "../../Types/Database/AccessControl/ColumnAccessControl";
|
||||
import TableAccessControl from "../../Types/Database/AccessControl/TableAccessControl";
|
||||
import TableBillingAccessControl from "../../Types/Database/AccessControl/TableBillingAccessControl";
|
||||
import CanAccessIfCanReadOn from "../../Types/Database/CanAccessIfCanReadOn";
|
||||
import ColumnLength from "../../Types/Database/ColumnLength";
|
||||
import ColumnType from "../../Types/Database/ColumnType";
|
||||
import CrudApiEndpoint from "../../Types/Database/CrudApiEndpoint";
|
||||
import TableColumn from "../../Types/Database/TableColumn";
|
||||
import TableColumnType from "../../Types/Database/TableColumnType";
|
||||
import TableMetadata from "../../Types/Database/TableMetadata";
|
||||
import TenantColumn from "../../Types/Database/TenantColumn";
|
||||
import HashedString from "../../Types/HashedString";
|
||||
import IconProp from "../../Types/Icon/IconProp";
|
||||
import { JSONObject } from "../../Types/JSON";
|
||||
import ObjectID from "../../Types/ObjectID";
|
||||
import { Column, Entity, Index, JoinColumn, ManyToOne } from "typeorm";
|
||||
|
||||
@AllowAccessIfSubscriptionIsUnpaid()
|
||||
@TableBillingAccessControl({
|
||||
create: PlanType.Growth,
|
||||
read: PlanType.Growth,
|
||||
update: PlanType.Growth,
|
||||
delete: PlanType.Growth,
|
||||
})
|
||||
@CanAccessIfCanReadOn("statusPage")
|
||||
@TenantColumn("projectId")
|
||||
@TableAccessControl({
|
||||
create: [],
|
||||
read: [],
|
||||
delete: [],
|
||||
update: [],
|
||||
})
|
||||
@CrudApiEndpoint(new Route("/status-page-private-user-session"))
|
||||
@Entity({
|
||||
name: "StatusPagePrivateUserSession",
|
||||
})
|
||||
@TableMetadata({
|
||||
tableName: "StatusPagePrivateUserSession",
|
||||
singularName: "Status Page Private User Session",
|
||||
pluralName: "Status Page Private User Sessions",
|
||||
icon: IconProp.Lock,
|
||||
tableDescription:
|
||||
"Stores status page private user sessions, refresh tokens, and device metadata for secure access control.",
|
||||
})
|
||||
export default class StatusPagePrivateUserSession extends BaseModel {
|
||||
@ColumnAccessControl({
|
||||
create: [],
|
||||
read: [],
|
||||
update: [],
|
||||
})
|
||||
@TableColumn({
|
||||
manyToOneRelationColumn: "projectId",
|
||||
type: TableColumnType.Entity,
|
||||
modelType: Project,
|
||||
title: "Project",
|
||||
description: "Project that owns this private status page session.",
|
||||
})
|
||||
@ManyToOne(
|
||||
() => {
|
||||
return Project;
|
||||
},
|
||||
{
|
||||
eager: false,
|
||||
nullable: true,
|
||||
onDelete: "CASCADE",
|
||||
orphanedRowAction: "nullify",
|
||||
},
|
||||
)
|
||||
@JoinColumn({ name: "projectId" })
|
||||
public project?: Project = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [],
|
||||
read: [],
|
||||
update: [],
|
||||
})
|
||||
@Index()
|
||||
@TableColumn({
|
||||
type: TableColumnType.ObjectID,
|
||||
title: "Project ID",
|
||||
description: "Project identifier for this session.",
|
||||
required: true,
|
||||
canReadOnRelationQuery: true,
|
||||
})
|
||||
@Column({
|
||||
type: ColumnType.ObjectID,
|
||||
nullable: false,
|
||||
transformer: ObjectID.getDatabaseTransformer(),
|
||||
})
|
||||
public projectId?: ObjectID = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [],
|
||||
read: [],
|
||||
update: [],
|
||||
})
|
||||
@TableColumn({
|
||||
manyToOneRelationColumn: "statusPageId",
|
||||
type: TableColumnType.Entity,
|
||||
modelType: StatusPage,
|
||||
title: "Status Page",
|
||||
description: "Status page associated with this session.",
|
||||
})
|
||||
@ManyToOne(
|
||||
() => {
|
||||
return StatusPage;
|
||||
},
|
||||
{
|
||||
eager: false,
|
||||
nullable: true,
|
||||
onDelete: "CASCADE",
|
||||
orphanedRowAction: "nullify",
|
||||
},
|
||||
)
|
||||
@JoinColumn({ name: "statusPageId" })
|
||||
public statusPage?: StatusPage = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [],
|
||||
read: [],
|
||||
update: [],
|
||||
})
|
||||
@Index()
|
||||
@TableColumn({
|
||||
type: TableColumnType.ObjectID,
|
||||
title: "Status Page ID",
|
||||
description: "Identifier for the status page.",
|
||||
required: true,
|
||||
})
|
||||
@Column({
|
||||
type: ColumnType.ObjectID,
|
||||
nullable: false,
|
||||
transformer: ObjectID.getDatabaseTransformer(),
|
||||
})
|
||||
public statusPageId?: ObjectID = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [],
|
||||
read: [],
|
||||
update: [],
|
||||
})
|
||||
@TableColumn({
|
||||
manyToOneRelationColumn: "statusPagePrivateUserId",
|
||||
type: TableColumnType.Entity,
|
||||
modelType: StatusPagePrivateUser,
|
||||
title: "Status Page Private User",
|
||||
description: "Private user record associated with this session.",
|
||||
})
|
||||
@ManyToOne(
|
||||
() => {
|
||||
return StatusPagePrivateUser;
|
||||
},
|
||||
{
|
||||
eager: false,
|
||||
nullable: false,
|
||||
onDelete: "CASCADE",
|
||||
orphanedRowAction: "delete",
|
||||
},
|
||||
)
|
||||
@JoinColumn({ name: "statusPagePrivateUserId" })
|
||||
public statusPagePrivateUser?: StatusPagePrivateUser = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [],
|
||||
read: [],
|
||||
update: [],
|
||||
})
|
||||
@Index()
|
||||
@TableColumn({
|
||||
type: TableColumnType.ObjectID,
|
||||
title: "Status Page Private User ID",
|
||||
description: "Identifier for the status page private user.",
|
||||
required: true,
|
||||
canReadOnRelationQuery: true,
|
||||
})
|
||||
@Column({
|
||||
type: ColumnType.ObjectID,
|
||||
nullable: false,
|
||||
transformer: ObjectID.getDatabaseTransformer(),
|
||||
})
|
||||
public statusPagePrivateUserId?: ObjectID = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [],
|
||||
read: [],
|
||||
update: [],
|
||||
})
|
||||
@Index({ unique: true })
|
||||
@TableColumn({
|
||||
type: TableColumnType.HashedString,
|
||||
title: "Refresh Token",
|
||||
description: "Hashed refresh token for the private user session.",
|
||||
required: true,
|
||||
hideColumnInDocumentation: true,
|
||||
})
|
||||
@Column({
|
||||
type: ColumnType.HashedString,
|
||||
length: ColumnLength.HashedString,
|
||||
nullable: false,
|
||||
unique: true,
|
||||
transformer: HashedString.getDatabaseTransformer(),
|
||||
})
|
||||
public refreshToken?: HashedString = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [],
|
||||
read: [],
|
||||
update: [],
|
||||
})
|
||||
@TableColumn({
|
||||
type: TableColumnType.Date,
|
||||
title: "Refresh Token Expires At",
|
||||
description: "Expiration timestamp for the refresh token.",
|
||||
required: true,
|
||||
})
|
||||
@Column({
|
||||
type: ColumnType.Date,
|
||||
nullable: false,
|
||||
})
|
||||
public refreshTokenExpiresAt?: Date = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [],
|
||||
read: [],
|
||||
update: [],
|
||||
})
|
||||
@TableColumn({
|
||||
type: TableColumnType.Date,
|
||||
title: "Last Active At",
|
||||
description: "Last time this session was active.",
|
||||
})
|
||||
@Column({
|
||||
type: ColumnType.Date,
|
||||
nullable: true,
|
||||
})
|
||||
public lastActiveAt?: Date = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [],
|
||||
read: [],
|
||||
update: [],
|
||||
})
|
||||
@TableColumn({
|
||||
type: TableColumnType.ShortText,
|
||||
title: "Device Name",
|
||||
description: "Friendly name for the device used to access the status page.",
|
||||
})
|
||||
@Column({
|
||||
type: ColumnType.ShortText,
|
||||
length: ColumnLength.ShortText,
|
||||
nullable: true,
|
||||
})
|
||||
public deviceName?: string = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [],
|
||||
read: [],
|
||||
update: [],
|
||||
})
|
||||
@TableColumn({
|
||||
type: TableColumnType.ShortText,
|
||||
title: "Device Type",
|
||||
description: "Type of device (desktop, mobile, etc).",
|
||||
})
|
||||
@Column({
|
||||
type: ColumnType.ShortText,
|
||||
length: ColumnLength.ShortText,
|
||||
nullable: true,
|
||||
})
|
||||
public deviceType?: string = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [],
|
||||
read: [],
|
||||
update: [],
|
||||
})
|
||||
@TableColumn({
|
||||
type: TableColumnType.ShortText,
|
||||
title: "Device OS",
|
||||
description: "Operating system reported for this session.",
|
||||
})
|
||||
@Column({
|
||||
type: ColumnType.ShortText,
|
||||
length: ColumnLength.ShortText,
|
||||
nullable: true,
|
||||
})
|
||||
public deviceOS?: string = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [],
|
||||
read: [],
|
||||
update: [],
|
||||
})
|
||||
@TableColumn({
|
||||
type: TableColumnType.ShortText,
|
||||
title: "Browser",
|
||||
description: "Browser or client application used for the session.",
|
||||
})
|
||||
@Column({
|
||||
type: ColumnType.ShortText,
|
||||
length: ColumnLength.ShortText,
|
||||
nullable: true,
|
||||
})
|
||||
public deviceBrowser?: string = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [],
|
||||
read: [],
|
||||
update: [],
|
||||
})
|
||||
@TableColumn({
|
||||
type: TableColumnType.ShortText,
|
||||
title: "IP Address",
|
||||
description: "IP address recorded for this session.",
|
||||
})
|
||||
@Column({
|
||||
type: ColumnType.ShortText,
|
||||
length: ColumnLength.ShortText,
|
||||
nullable: true,
|
||||
})
|
||||
public ipAddress?: string = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [],
|
||||
read: [],
|
||||
update: [],
|
||||
})
|
||||
@TableColumn({
|
||||
type: TableColumnType.VeryLongText,
|
||||
title: "User Agent",
|
||||
description: "User agent string supplied by the client.",
|
||||
})
|
||||
@Column({
|
||||
type: ColumnType.VeryLongText,
|
||||
nullable: true,
|
||||
})
|
||||
public userAgent?: string = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [],
|
||||
read: [],
|
||||
update: [],
|
||||
})
|
||||
@TableColumn({
|
||||
type: TableColumnType.Boolean,
|
||||
title: "Is Revoked",
|
||||
description: "Indicates if the session has been revoked.",
|
||||
isDefaultValueColumn: true,
|
||||
defaultValue: false,
|
||||
})
|
||||
@Column({
|
||||
type: ColumnType.Boolean,
|
||||
nullable: false,
|
||||
default: false,
|
||||
})
|
||||
public isRevoked?: boolean = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [],
|
||||
read: [],
|
||||
update: [],
|
||||
})
|
||||
@TableColumn({
|
||||
type: TableColumnType.Date,
|
||||
title: "Revoked At",
|
||||
description: "Timestamp when the session was revoked, if applicable.",
|
||||
})
|
||||
@Column({
|
||||
type: ColumnType.Date,
|
||||
nullable: true,
|
||||
})
|
||||
public revokedAt?: Date = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [],
|
||||
read: [],
|
||||
update: [],
|
||||
})
|
||||
@TableColumn({
|
||||
type: TableColumnType.ShortText,
|
||||
title: "Revoked Reason",
|
||||
description: "Reason provided for revoking this session.",
|
||||
})
|
||||
@Column({
|
||||
type: ColumnType.ShortText,
|
||||
length: ColumnLength.ShortText,
|
||||
nullable: true,
|
||||
})
|
||||
public revokedReason?: string = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [],
|
||||
read: [],
|
||||
update: [],
|
||||
})
|
||||
@TableColumn({
|
||||
type: TableColumnType.JSON,
|
||||
title: "Additional Info",
|
||||
description: "Flexible JSON payload for storing structured metadata.",
|
||||
})
|
||||
@Column({
|
||||
type: ColumnType.JSON,
|
||||
nullable: true,
|
||||
})
|
||||
public additionalInfo?: JSONObject = undefined;
|
||||
}
|
||||
@@ -8,7 +8,6 @@ import ColumnLength from "../../Types/Database/ColumnLength";
|
||||
import ColumnType from "../../Types/Database/ColumnType";
|
||||
import CrudApiEndpoint from "../../Types/Database/CrudApiEndpoint";
|
||||
import EnableDocumentation from "../../Types/Database/EnableDocumentation";
|
||||
import EnableWorkflow from "../../Types/Database/EnableWorkflow";
|
||||
import TableColumn from "../../Types/Database/TableColumn";
|
||||
import TableColumnType from "../../Types/Database/TableColumnType";
|
||||
import TableMetadata from "../../Types/Database/TableMetadata";
|
||||
@@ -45,12 +44,6 @@ import TelemetryService from "./TelemetryService";
|
||||
Permission.EditTelemetryException,
|
||||
],
|
||||
})
|
||||
@EnableWorkflow({
|
||||
create: true,
|
||||
delete: true,
|
||||
update: true,
|
||||
read: true,
|
||||
})
|
||||
@CrudApiEndpoint(new Route("/telemetry-exception-status"))
|
||||
@TableMetadata({
|
||||
tableName: "TelemetryException",
|
||||
|
||||
@@ -12,6 +12,7 @@ import ColumnType from "../../Types/Database/ColumnType";
|
||||
import CrudApiEndpoint from "../../Types/Database/CrudApiEndpoint";
|
||||
import EnableDocumentation from "../../Types/Database/EnableDocumentation";
|
||||
import EnableWorkflow from "../../Types/Database/EnableWorkflow";
|
||||
import ColorField from "../../Types/Database/ColorField";
|
||||
import SlugifyColumn from "../../Types/Database/SlugifyColumn";
|
||||
import TableColumn from "../../Types/Database/TableColumn";
|
||||
import TableColumnType from "../../Types/Database/TableColumnType";
|
||||
@@ -505,6 +506,7 @@ export default class TelemetryService extends BaseModel {
|
||||
Permission.EditTelemetryService,
|
||||
],
|
||||
})
|
||||
@ColorField()
|
||||
@TableColumn({
|
||||
type: TableColumnType.Color,
|
||||
title: "Service Color",
|
||||
|
||||
@@ -39,7 +39,7 @@ export const DEFAULT_RETENTION_IN_DAYS: number = 15;
|
||||
pluralName: "Telemetry Usage Billings",
|
||||
icon: IconProp.Billing,
|
||||
tableDescription:
|
||||
"Stores historical usage billing data for your telemetry data like Logs, Metrics, and Traces.",
|
||||
"Stores historical usage billing data for your telemetry data like Logs, Metrics, Traces, and Exceptions.",
|
||||
})
|
||||
@Entity({
|
||||
name: "TelemetryUsageBilling",
|
||||
|
||||
@@ -300,21 +300,6 @@ class User extends UserModel {
|
||||
})
|
||||
public twoFactorAuthEnabled?: boolean = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [],
|
||||
read: [],
|
||||
|
||||
update: [],
|
||||
})
|
||||
@TableColumn({ type: TableColumnType.ShortText })
|
||||
@Column({
|
||||
type: ColumnType.ShortText,
|
||||
length: ColumnLength.ShortText,
|
||||
nullable: true,
|
||||
unique: false,
|
||||
})
|
||||
public jwtRefreshToken?: string = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [],
|
||||
read: [],
|
||||
|
||||
318
Common/Models/DatabaseModels/UserSession.ts
Normal file
318
Common/Models/DatabaseModels/UserSession.ts
Normal file
@@ -0,0 +1,318 @@
|
||||
import BaseModel from "./DatabaseBaseModel/DatabaseBaseModel";
|
||||
import User from "./User";
|
||||
import Route from "../../Types/API/Route";
|
||||
import AllowAccessIfSubscriptionIsUnpaid from "../../Types/Database/AccessControl/AllowAccessIfSubscriptionIsUnpaid";
|
||||
import ColumnAccessControl from "../../Types/Database/AccessControl/ColumnAccessControl";
|
||||
import TableAccessControl from "../../Types/Database/AccessControl/TableAccessControl";
|
||||
import ColumnLength from "../../Types/Database/ColumnLength";
|
||||
import ColumnType from "../../Types/Database/ColumnType";
|
||||
import CrudApiEndpoint from "../../Types/Database/CrudApiEndpoint";
|
||||
import CurrentUserCanAccessRecordBy from "../../Types/Database/CurrentUserCanAccessRecordBy";
|
||||
import EnableDocumentation from "../../Types/Database/EnableDocumentation";
|
||||
import TableColumn from "../../Types/Database/TableColumn";
|
||||
import TableColumnType from "../../Types/Database/TableColumnType";
|
||||
import TableMetadata from "../../Types/Database/TableMetadata";
|
||||
import HashedString from "../../Types/HashedString";
|
||||
import IconProp from "../../Types/Icon/IconProp";
|
||||
import { JSONObject } from "../../Types/JSON";
|
||||
import ObjectID from "../../Types/ObjectID";
|
||||
import Permission from "../../Types/Permission";
|
||||
import { Column, Entity, Index, JoinColumn, ManyToOne } from "typeorm";
|
||||
|
||||
@EnableDocumentation({
|
||||
isMasterAdminApiDocs: true,
|
||||
})
|
||||
@AllowAccessIfSubscriptionIsUnpaid()
|
||||
@TableAccessControl({
|
||||
create: [Permission.CurrentUser],
|
||||
read: [Permission.CurrentUser],
|
||||
delete: [Permission.CurrentUser],
|
||||
update: [Permission.CurrentUser],
|
||||
})
|
||||
@CrudApiEndpoint(new Route("/user-session"))
|
||||
@Entity({
|
||||
name: "UserSession",
|
||||
})
|
||||
@TableMetadata({
|
||||
tableName: "UserSession",
|
||||
singularName: "User Session",
|
||||
pluralName: "User Sessions",
|
||||
icon: IconProp.Lock,
|
||||
tableDescription:
|
||||
"Active user sessions with refresh tokens and device metadata for enhanced authentication security.",
|
||||
})
|
||||
@CurrentUserCanAccessRecordBy("userId")
|
||||
class UserSession extends BaseModel {
|
||||
@ColumnAccessControl({
|
||||
create: [Permission.CurrentUser],
|
||||
read: [Permission.CurrentUser],
|
||||
update: [],
|
||||
})
|
||||
@TableColumn({
|
||||
manyToOneRelationColumn: "userId",
|
||||
type: TableColumnType.Entity,
|
||||
modelType: User,
|
||||
title: "User",
|
||||
description: "User account this session belongs to.",
|
||||
})
|
||||
@ManyToOne(
|
||||
() => {
|
||||
return User;
|
||||
},
|
||||
{
|
||||
eager: false,
|
||||
nullable: false,
|
||||
onDelete: "CASCADE",
|
||||
orphanedRowAction: "delete",
|
||||
},
|
||||
)
|
||||
@JoinColumn({ name: "userId" })
|
||||
public user?: User = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [Permission.CurrentUser],
|
||||
read: [Permission.CurrentUser],
|
||||
update: [],
|
||||
})
|
||||
@Index()
|
||||
@TableColumn({
|
||||
type: TableColumnType.ObjectID,
|
||||
required: true,
|
||||
title: "User ID",
|
||||
description: "Identifier for the user that owns this session.",
|
||||
canReadOnRelationQuery: true,
|
||||
})
|
||||
@Column({
|
||||
type: ColumnType.ObjectID,
|
||||
nullable: false,
|
||||
transformer: ObjectID.getDatabaseTransformer(),
|
||||
})
|
||||
public userId?: ObjectID = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [],
|
||||
read: [],
|
||||
update: [],
|
||||
})
|
||||
@Index({ unique: true })
|
||||
@TableColumn({
|
||||
type: TableColumnType.HashedString,
|
||||
title: "Refresh Token",
|
||||
description: "Hashed refresh token for this session.",
|
||||
required: true,
|
||||
hideColumnInDocumentation: true,
|
||||
})
|
||||
@Column({
|
||||
type: ColumnType.HashedString,
|
||||
length: ColumnLength.HashedString,
|
||||
nullable: false,
|
||||
unique: true,
|
||||
transformer: HashedString.getDatabaseTransformer(),
|
||||
})
|
||||
public refreshToken?: HashedString = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [],
|
||||
read: [],
|
||||
update: [],
|
||||
})
|
||||
@TableColumn({
|
||||
type: TableColumnType.Date,
|
||||
title: "Refresh Token Expires At",
|
||||
description: "Expiration timestamp for the refresh token.",
|
||||
required: true,
|
||||
})
|
||||
@Column({
|
||||
type: ColumnType.Date,
|
||||
nullable: false,
|
||||
})
|
||||
public refreshTokenExpiresAt?: Date = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [],
|
||||
read: [Permission.CurrentUser],
|
||||
update: [],
|
||||
})
|
||||
@TableColumn({
|
||||
type: TableColumnType.Date,
|
||||
title: "Last Active At",
|
||||
description: "Last time this session was used.",
|
||||
})
|
||||
@Column({
|
||||
type: ColumnType.Date,
|
||||
nullable: true,
|
||||
})
|
||||
public lastActiveAt?: Date = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [],
|
||||
read: [Permission.CurrentUser],
|
||||
update: [],
|
||||
})
|
||||
@TableColumn({
|
||||
type: TableColumnType.ShortText,
|
||||
title: "Device Name",
|
||||
description: "Friendly name for the device used to sign in.",
|
||||
})
|
||||
@Column({
|
||||
type: ColumnType.ShortText,
|
||||
length: ColumnLength.ShortText,
|
||||
nullable: true,
|
||||
})
|
||||
public deviceName?: string = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [],
|
||||
read: [Permission.CurrentUser],
|
||||
update: [],
|
||||
})
|
||||
@TableColumn({
|
||||
type: TableColumnType.ShortText,
|
||||
title: "Device Type",
|
||||
description: "Type of device (e.g., desktop, mobile).",
|
||||
})
|
||||
@Column({
|
||||
type: ColumnType.ShortText,
|
||||
length: ColumnLength.ShortText,
|
||||
nullable: true,
|
||||
})
|
||||
public deviceType?: string = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [],
|
||||
read: [Permission.CurrentUser],
|
||||
update: [],
|
||||
})
|
||||
@TableColumn({
|
||||
type: TableColumnType.ShortText,
|
||||
title: "Device OS",
|
||||
description: "Operating system reported for this session.",
|
||||
})
|
||||
@Column({
|
||||
type: ColumnType.ShortText,
|
||||
length: ColumnLength.ShortText,
|
||||
nullable: true,
|
||||
})
|
||||
public deviceOS?: string = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [],
|
||||
read: [Permission.CurrentUser],
|
||||
update: [],
|
||||
})
|
||||
@TableColumn({
|
||||
type: TableColumnType.ShortText,
|
||||
title: "Browser",
|
||||
description: "Browser or client application used for this session.",
|
||||
})
|
||||
@Column({
|
||||
type: ColumnType.ShortText,
|
||||
length: ColumnLength.ShortText,
|
||||
nullable: true,
|
||||
})
|
||||
public deviceBrowser?: string = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [],
|
||||
read: [Permission.CurrentUser],
|
||||
update: [],
|
||||
})
|
||||
@TableColumn({
|
||||
type: TableColumnType.ShortText,
|
||||
title: "IP Address",
|
||||
description: "IP address observed for this session.",
|
||||
})
|
||||
@Column({
|
||||
type: ColumnType.ShortText,
|
||||
length: ColumnLength.ShortText,
|
||||
nullable: true,
|
||||
})
|
||||
public ipAddress?: string = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [],
|
||||
read: [Permission.CurrentUser],
|
||||
update: [],
|
||||
})
|
||||
@TableColumn({
|
||||
type: TableColumnType.VeryLongText,
|
||||
title: "User Agent",
|
||||
description: "Complete user agent string supplied by the client.",
|
||||
})
|
||||
@Column({
|
||||
type: ColumnType.VeryLongText,
|
||||
nullable: true,
|
||||
})
|
||||
public userAgent?: string = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [],
|
||||
read: [Permission.CurrentUser],
|
||||
update: [],
|
||||
})
|
||||
@TableColumn({
|
||||
type: TableColumnType.Boolean,
|
||||
title: "Is Revoked",
|
||||
description: "Marks whether the session has been explicitly revoked.",
|
||||
isDefaultValueColumn: true,
|
||||
defaultValue: false,
|
||||
})
|
||||
@Column({
|
||||
type: ColumnType.Boolean,
|
||||
nullable: false,
|
||||
default: false,
|
||||
})
|
||||
public isRevoked?: boolean = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [],
|
||||
read: [Permission.CurrentUser],
|
||||
update: [],
|
||||
})
|
||||
@TableColumn({
|
||||
type: TableColumnType.Date,
|
||||
title: "Revoked At",
|
||||
description: "Timestamp when the session was revoked, if applicable.",
|
||||
})
|
||||
@Column({
|
||||
type: ColumnType.Date,
|
||||
nullable: true,
|
||||
})
|
||||
public revokedAt?: Date = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [],
|
||||
read: [Permission.CurrentUser],
|
||||
update: [],
|
||||
})
|
||||
@TableColumn({
|
||||
type: TableColumnType.ShortText,
|
||||
title: "Revoked Reason",
|
||||
description: "Optional reason describing why the session was revoked.",
|
||||
})
|
||||
@Column({
|
||||
type: ColumnType.ShortText,
|
||||
length: ColumnLength.ShortText,
|
||||
nullable: true,
|
||||
})
|
||||
public revokedReason?: string = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [],
|
||||
read: [Permission.CurrentUser],
|
||||
update: [],
|
||||
})
|
||||
@TableColumn({
|
||||
type: TableColumnType.JSON,
|
||||
title: "Additional Info",
|
||||
description:
|
||||
"Flexible JSON payload for storing structured session metadata.",
|
||||
})
|
||||
@Column({
|
||||
type: ColumnType.JSON,
|
||||
nullable: true,
|
||||
})
|
||||
public additionalInfo?: JSONObject = undefined;
|
||||
}
|
||||
|
||||
export default UserSession;
|
||||
@@ -37,7 +37,7 @@ import { Column, Entity, Index, JoinColumn, ManyToOne } from "typeorm";
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadSmsLog,
|
||||
Permission.ReadWhatsAppLog,
|
||||
],
|
||||
delete: [],
|
||||
update: [],
|
||||
@@ -66,7 +66,7 @@ export default class WhatsAppLog extends BaseModel {
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadSmsLog,
|
||||
Permission.ReadWhatsAppLog,
|
||||
],
|
||||
update: [],
|
||||
})
|
||||
@@ -97,7 +97,7 @@ export default class WhatsAppLog extends BaseModel {
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadSmsLog,
|
||||
Permission.ReadWhatsAppLog,
|
||||
],
|
||||
update: [],
|
||||
})
|
||||
@@ -122,7 +122,7 @@ export default class WhatsAppLog extends BaseModel {
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadSmsLog,
|
||||
Permission.ReadWhatsAppLog,
|
||||
],
|
||||
update: [],
|
||||
})
|
||||
@@ -148,7 +148,7 @@ export default class WhatsAppLog extends BaseModel {
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadSmsLog,
|
||||
Permission.ReadWhatsAppLog,
|
||||
],
|
||||
update: [],
|
||||
})
|
||||
@@ -175,7 +175,7 @@ export default class WhatsAppLog extends BaseModel {
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadSmsLog,
|
||||
Permission.ReadWhatsAppLog,
|
||||
],
|
||||
update: [],
|
||||
})
|
||||
@@ -198,7 +198,7 @@ export default class WhatsAppLog extends BaseModel {
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadSmsLog,
|
||||
Permission.ReadWhatsAppLog,
|
||||
],
|
||||
update: [],
|
||||
})
|
||||
@@ -222,7 +222,32 @@ export default class WhatsAppLog extends BaseModel {
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadSmsLog,
|
||||
Permission.ReadWhatsAppLog,
|
||||
],
|
||||
update: [],
|
||||
})
|
||||
@Index()
|
||||
@TableColumn({
|
||||
required: false,
|
||||
type: TableColumnType.ShortText,
|
||||
title: "WhatsApp Message ID",
|
||||
description: "Message ID returned by Meta's API",
|
||||
canReadOnRelationQuery: false,
|
||||
})
|
||||
@Column({
|
||||
nullable: true,
|
||||
type: ColumnType.ShortText,
|
||||
length: ColumnLength.ShortText,
|
||||
})
|
||||
public whatsAppMessageId?: string = undefined;
|
||||
|
||||
@ColumnAccessControl({
|
||||
create: [],
|
||||
read: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadWhatsAppLog,
|
||||
],
|
||||
update: [],
|
||||
})
|
||||
@@ -246,7 +271,7 @@ export default class WhatsAppLog extends BaseModel {
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadSmsLog,
|
||||
Permission.ReadWhatsAppLog,
|
||||
],
|
||||
update: [],
|
||||
})
|
||||
@@ -273,7 +298,7 @@ export default class WhatsAppLog extends BaseModel {
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadSmsLog,
|
||||
Permission.ReadWhatsAppLog,
|
||||
],
|
||||
update: [],
|
||||
})
|
||||
@@ -304,7 +329,7 @@ export default class WhatsAppLog extends BaseModel {
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadSmsLog,
|
||||
Permission.ReadWhatsAppLog,
|
||||
],
|
||||
update: [],
|
||||
})
|
||||
@@ -329,7 +354,7 @@ export default class WhatsAppLog extends BaseModel {
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadSmsLog,
|
||||
Permission.ReadWhatsAppLog,
|
||||
],
|
||||
update: [],
|
||||
})
|
||||
@@ -360,7 +385,7 @@ export default class WhatsAppLog extends BaseModel {
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadSmsLog,
|
||||
Permission.ReadWhatsAppLog,
|
||||
],
|
||||
update: [],
|
||||
})
|
||||
@@ -385,7 +410,7 @@ export default class WhatsAppLog extends BaseModel {
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadSmsLog,
|
||||
Permission.ReadWhatsAppLog,
|
||||
],
|
||||
update: [],
|
||||
})
|
||||
@@ -416,7 +441,7 @@ export default class WhatsAppLog extends BaseModel {
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadSmsLog,
|
||||
Permission.ReadWhatsAppLog,
|
||||
],
|
||||
update: [],
|
||||
})
|
||||
@@ -441,7 +466,7 @@ export default class WhatsAppLog extends BaseModel {
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadSmsLog,
|
||||
Permission.ReadWhatsAppLog,
|
||||
],
|
||||
update: [],
|
||||
})
|
||||
@@ -472,7 +497,7 @@ export default class WhatsAppLog extends BaseModel {
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadSmsLog,
|
||||
Permission.ReadWhatsAppLog,
|
||||
],
|
||||
update: [],
|
||||
})
|
||||
@@ -498,7 +523,7 @@ export default class WhatsAppLog extends BaseModel {
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadSmsLog,
|
||||
Permission.ReadWhatsAppLog,
|
||||
],
|
||||
update: [],
|
||||
})
|
||||
@@ -529,7 +554,7 @@ export default class WhatsAppLog extends BaseModel {
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadSmsLog,
|
||||
Permission.ReadWhatsAppLog,
|
||||
],
|
||||
update: [],
|
||||
})
|
||||
@@ -554,7 +579,7 @@ export default class WhatsAppLog extends BaseModel {
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadSmsLog,
|
||||
Permission.ReadWhatsAppLog,
|
||||
],
|
||||
update: [],
|
||||
})
|
||||
@@ -586,7 +611,7 @@ export default class WhatsAppLog extends BaseModel {
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadSmsLog,
|
||||
Permission.ReadWhatsAppLog,
|
||||
],
|
||||
update: [],
|
||||
})
|
||||
@@ -612,7 +637,7 @@ export default class WhatsAppLog extends BaseModel {
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadSmsLog,
|
||||
Permission.ReadWhatsAppLog,
|
||||
],
|
||||
update: [],
|
||||
})
|
||||
@@ -643,7 +668,7 @@ export default class WhatsAppLog extends BaseModel {
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadSmsLog,
|
||||
Permission.ReadWhatsAppLog,
|
||||
],
|
||||
update: [],
|
||||
})
|
||||
@@ -668,7 +693,7 @@ export default class WhatsAppLog extends BaseModel {
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadSmsLog,
|
||||
Permission.ReadWhatsAppLog,
|
||||
],
|
||||
update: [],
|
||||
})
|
||||
@@ -699,7 +724,7 @@ export default class WhatsAppLog extends BaseModel {
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadSmsLog,
|
||||
Permission.ReadWhatsAppLog,
|
||||
],
|
||||
update: [],
|
||||
})
|
||||
@@ -725,7 +750,7 @@ export default class WhatsAppLog extends BaseModel {
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadSmsLog,
|
||||
Permission.ReadWhatsAppLog,
|
||||
],
|
||||
update: [],
|
||||
})
|
||||
@@ -758,7 +783,7 @@ export default class WhatsAppLog extends BaseModel {
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadSmsLog,
|
||||
Permission.ReadWhatsAppLog,
|
||||
],
|
||||
update: [],
|
||||
})
|
||||
@@ -784,7 +809,7 @@ export default class WhatsAppLog extends BaseModel {
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadSmsLog,
|
||||
Permission.ReadWhatsAppLog,
|
||||
],
|
||||
update: [],
|
||||
})
|
||||
@@ -816,7 +841,7 @@ export default class WhatsAppLog extends BaseModel {
|
||||
Permission.ProjectOwner,
|
||||
Permission.ProjectAdmin,
|
||||
Permission.ProjectMember,
|
||||
Permission.ReadSmsLog,
|
||||
Permission.ReadWhatsAppLog,
|
||||
],
|
||||
update: [],
|
||||
})
|
||||
|
||||
64
Common/Server/API/AcmeChallengeAPI.ts
Normal file
64
Common/Server/API/AcmeChallengeAPI.ts
Normal file
@@ -0,0 +1,64 @@
|
||||
import AcmeChallenge from "../../Models/DatabaseModels/AcmeChallenge";
|
||||
import NotFoundException from "../../Types/Exception/NotFoundException";
|
||||
import AcmeChallengeService, {
|
||||
Service as AcmeChallengeServiceType,
|
||||
} from "../Services/AcmeChallengeService";
|
||||
import Express, {
|
||||
ExpressRequest,
|
||||
ExpressResponse,
|
||||
ExpressRouter,
|
||||
NextFunction,
|
||||
} from "../Utils/Express";
|
||||
import Response from "../Utils/Response";
|
||||
import BaseAPI from "./BaseAPI";
|
||||
|
||||
export default class AcmeChallengeAPI extends BaseAPI<
|
||||
AcmeChallenge,
|
||||
AcmeChallengeServiceType
|
||||
> {
|
||||
private wellKnownRouter: ExpressRouter;
|
||||
|
||||
public constructor() {
|
||||
super(AcmeChallenge, AcmeChallengeService);
|
||||
|
||||
this.wellKnownRouter = Express.getRouter();
|
||||
|
||||
this.wellKnownRouter.get(
|
||||
"/acme-challenge/.well-known/:token",
|
||||
async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => {
|
||||
try {
|
||||
const challenge: AcmeChallenge | null =
|
||||
await AcmeChallengeService.findOneBy({
|
||||
query: {
|
||||
token: req.params["token"] as string,
|
||||
},
|
||||
select: {
|
||||
challenge: true,
|
||||
},
|
||||
props: {
|
||||
isRoot: true,
|
||||
},
|
||||
});
|
||||
|
||||
if (!challenge) {
|
||||
return next(new NotFoundException("Challenge not found"));
|
||||
}
|
||||
|
||||
return Response.sendTextResponse(
|
||||
req,
|
||||
res,
|
||||
challenge.challenge as string,
|
||||
);
|
||||
} catch (err) {
|
||||
return next(err);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
this.router.use("/", this.wellKnownRouter);
|
||||
}
|
||||
|
||||
public getWellKnownRouter(): ExpressRouter {
|
||||
return this.wellKnownRouter;
|
||||
}
|
||||
}
|
||||
96
Common/Server/API/AlertInternalNoteAPI.ts
Normal file
96
Common/Server/API/AlertInternalNoteAPI.ts
Normal file
@@ -0,0 +1,96 @@
|
||||
import AlertInternalNote from "../../Models/DatabaseModels/AlertInternalNote";
|
||||
import File from "../../Models/DatabaseModels/File";
|
||||
import NotFoundException from "../../Types/Exception/NotFoundException";
|
||||
import ObjectID from "../../Types/ObjectID";
|
||||
import AlertInternalNoteService, {
|
||||
Service as AlertInternalNoteServiceType,
|
||||
} from "../Services/AlertInternalNoteService";
|
||||
import Response from "../Utils/Response";
|
||||
import BaseAPI from "./BaseAPI";
|
||||
import UserMiddleware from "../Middleware/UserAuthorization";
|
||||
import CommonAPI from "./CommonAPI";
|
||||
import DatabaseCommonInteractionProps from "../../Types/BaseDatabase/DatabaseCommonInteractionProps";
|
||||
import {
|
||||
ExpressRequest,
|
||||
ExpressResponse,
|
||||
NextFunction,
|
||||
} from "../Utils/Express";
|
||||
|
||||
export default class AlertInternalNoteAPI extends BaseAPI<
|
||||
AlertInternalNote,
|
||||
AlertInternalNoteServiceType
|
||||
> {
|
||||
public constructor() {
|
||||
super(AlertInternalNote, AlertInternalNoteService);
|
||||
|
||||
this.router.get(
|
||||
`${new this.entityType().getCrudApiPath()?.toString()}/attachment/:projectId/:noteId/:fileId`,
|
||||
UserMiddleware.getUserMiddleware,
|
||||
async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => {
|
||||
try {
|
||||
await this.getAttachment(req, res);
|
||||
} catch (err) {
|
||||
next(err);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
private async getAttachment(
|
||||
req: ExpressRequest,
|
||||
res: ExpressResponse,
|
||||
): Promise<void> {
|
||||
const noteIdParam: string | undefined = req.params["noteId"];
|
||||
const fileIdParam: string | undefined = req.params["fileId"];
|
||||
|
||||
if (!noteIdParam || !fileIdParam) {
|
||||
throw new NotFoundException("Attachment not found");
|
||||
}
|
||||
|
||||
let noteId: ObjectID;
|
||||
let fileId: ObjectID;
|
||||
|
||||
try {
|
||||
noteId = new ObjectID(noteIdParam);
|
||||
fileId = new ObjectID(fileIdParam);
|
||||
} catch {
|
||||
throw new NotFoundException("Attachment not found");
|
||||
}
|
||||
|
||||
const props: DatabaseCommonInteractionProps =
|
||||
await CommonAPI.getDatabaseCommonInteractionProps(req);
|
||||
|
||||
const note: AlertInternalNote | null = await this.service.findOneBy({
|
||||
query: {
|
||||
_id: noteId,
|
||||
},
|
||||
select: {
|
||||
attachments: {
|
||||
_id: true,
|
||||
file: true,
|
||||
fileType: true,
|
||||
name: true,
|
||||
},
|
||||
},
|
||||
props,
|
||||
});
|
||||
|
||||
const attachment: File | undefined = note?.attachments?.find(
|
||||
(file: File) => {
|
||||
const attachmentId: string | null = file._id
|
||||
? file._id.toString()
|
||||
: file.id
|
||||
? file.id.toString()
|
||||
: null;
|
||||
return attachmentId === fileId.toString();
|
||||
},
|
||||
);
|
||||
|
||||
if (!attachment || !attachment.file) {
|
||||
throw new NotFoundException("Attachment not found");
|
||||
}
|
||||
|
||||
Response.setNoCacheHeaders(res);
|
||||
return Response.sendFileResponse(req, res, attachment);
|
||||
}
|
||||
}
|
||||
102
Common/Server/API/EnterpriseLicenseAPI.ts
Normal file
102
Common/Server/API/EnterpriseLicenseAPI.ts
Normal file
@@ -0,0 +1,102 @@
|
||||
import EnterpriseLicense from "../../Models/DatabaseModels/EnterpriseLicense";
|
||||
import BadDataException from "../../Types/Exception/BadDataException";
|
||||
import { JSONObject } from "../../Types/JSON";
|
||||
import EnterpriseLicenseService, {
|
||||
Service as EnterpriseLicenseServiceType,
|
||||
} from "../Services/EnterpriseLicenseService";
|
||||
import UserMiddleware from "../Middleware/UserAuthorization";
|
||||
import JSONWebToken from "../Utils/JsonWebToken";
|
||||
import Response from "../Utils/Response";
|
||||
import {
|
||||
ExpressRequest,
|
||||
ExpressResponse,
|
||||
NextFunction,
|
||||
} from "../Utils/Express";
|
||||
import BaseAPI from "./BaseAPI";
|
||||
// import { Host } from "../EnvironmentConfig";
|
||||
|
||||
export default class EnterpriseLicenseAPI extends BaseAPI<
|
||||
EnterpriseLicense,
|
||||
EnterpriseLicenseServiceType
|
||||
> {
|
||||
public constructor() {
|
||||
super(EnterpriseLicense, EnterpriseLicenseService);
|
||||
|
||||
this.router.post(
|
||||
`${new this.entityType().getCrudApiPath()?.toString()}/validate`,
|
||||
UserMiddleware.getUserMiddleware,
|
||||
async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => {
|
||||
try {
|
||||
const licenseKey: string | undefined = req.body["licenseKey"];
|
||||
|
||||
if (!licenseKey) {
|
||||
throw new BadDataException("License key is required");
|
||||
}
|
||||
|
||||
//const serverHost: string = Host.toString();
|
||||
|
||||
/*
|
||||
* if (!serverHost.includes("oneuptime.com")) {
|
||||
* throw new BadDataException(
|
||||
* "Enterprise license validation is only available on oneuptime.com",
|
||||
* );
|
||||
* }
|
||||
*/
|
||||
|
||||
const license: EnterpriseLicense | null =
|
||||
await EnterpriseLicenseService.findOneBy({
|
||||
query: {
|
||||
licenseKey: licenseKey,
|
||||
},
|
||||
select: {
|
||||
companyName: true,
|
||||
expiresAt: true,
|
||||
licenseKey: true,
|
||||
},
|
||||
props: {
|
||||
isRoot: true,
|
||||
},
|
||||
});
|
||||
|
||||
if (!license) {
|
||||
throw new BadDataException("License key is invalid");
|
||||
}
|
||||
|
||||
if (!license.expiresAt) {
|
||||
throw new BadDataException("License expiration is not set");
|
||||
}
|
||||
|
||||
const now: number = Date.now();
|
||||
const expiresAtMs: number = license.expiresAt.getTime();
|
||||
const secondsUntilExpiry: number = Math.floor(
|
||||
(expiresAtMs - now) / 1000,
|
||||
);
|
||||
|
||||
if (secondsUntilExpiry <= 0) {
|
||||
throw new BadDataException("License key has expired");
|
||||
}
|
||||
|
||||
const payload: JSONObject = {
|
||||
companyName: license.companyName || "",
|
||||
expiresAt: license.expiresAt.toISOString(),
|
||||
licenseKey: license.licenseKey || "",
|
||||
};
|
||||
|
||||
const token: string = JSONWebToken.signJsonPayload(
|
||||
payload,
|
||||
Math.max(secondsUntilExpiry, 1),
|
||||
);
|
||||
|
||||
return Response.sendJsonObjectResponse(req, res, {
|
||||
companyName: payload["companyName"] as string,
|
||||
expiresAt: payload["expiresAt"] as string,
|
||||
licenseKey: payload["licenseKey"] as string,
|
||||
token,
|
||||
});
|
||||
} catch (err) {
|
||||
next(err);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,15 @@ import {
|
||||
import Response from "../Utils/Response";
|
||||
import BaseAPI from "./BaseAPI";
|
||||
import GlobalConfig from "../../Models/DatabaseModels/GlobalConfig";
|
||||
import ObjectID from "../../Types/ObjectID";
|
||||
import { JSONObject } from "../../Types/JSON";
|
||||
import BadDataException from "../../Types/Exception/BadDataException";
|
||||
import API from "../../Utils/API";
|
||||
import HTTPErrorResponse from "../../Types/API/HTTPErrorResponse";
|
||||
import HTTPResponse from "../../Types/API/HTTPResponse";
|
||||
import PartialEntity from "../../Types/Database/PartialEntity";
|
||||
import { EnterpriseLicenseValidationUrl } from "../EnvironmentConfig";
|
||||
import UserMiddleware from "../Middleware/UserAuthorization";
|
||||
|
||||
export default class GlobalConfigAPI extends BaseAPI<
|
||||
GlobalConfig,
|
||||
@@ -45,5 +54,164 @@ export default class GlobalConfigAPI extends BaseAPI<
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
this.router.get(
|
||||
`${new this.entityType().getCrudApiPath()?.toString()}/license`,
|
||||
async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => {
|
||||
try {
|
||||
const config: GlobalConfig | null =
|
||||
await GlobalConfigService.findOneById({
|
||||
id: ObjectID.getZeroObjectID(),
|
||||
select: {
|
||||
enterpriseCompanyName: true,
|
||||
enterpriseLicenseExpiresAt: true,
|
||||
enterpriseLicenseKey: true,
|
||||
enterpriseLicenseToken: true,
|
||||
},
|
||||
props: {
|
||||
isRoot: true,
|
||||
},
|
||||
});
|
||||
|
||||
const responseBody: JSONObject = {
|
||||
companyName: config?.enterpriseCompanyName || null,
|
||||
expiresAt: config?.enterpriseLicenseExpiresAt
|
||||
? config.enterpriseLicenseExpiresAt.toISOString()
|
||||
: null,
|
||||
licenseKey: config?.enterpriseLicenseKey || null,
|
||||
token: config?.enterpriseLicenseToken || null,
|
||||
};
|
||||
|
||||
return Response.sendJsonObjectResponse(req, res, responseBody);
|
||||
} catch (err) {
|
||||
next(err);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
this.router.post(
|
||||
`${new this.entityType().getCrudApiPath()?.toString()}/license`,
|
||||
UserMiddleware.getUserMiddleware,
|
||||
async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => {
|
||||
try {
|
||||
const licenseKey: string =
|
||||
(req.body["licenseKey"] as string | undefined)?.trim() || "";
|
||||
|
||||
if (!licenseKey) {
|
||||
throw new BadDataException("License key is required");
|
||||
}
|
||||
|
||||
const validationResponse:
|
||||
| HTTPResponse<JSONObject>
|
||||
| HTTPErrorResponse = await API.post<JSONObject>({
|
||||
url: EnterpriseLicenseValidationUrl,
|
||||
data: {
|
||||
licenseKey,
|
||||
},
|
||||
});
|
||||
|
||||
if (!validationResponse.isSuccess()) {
|
||||
const errorMessage: string =
|
||||
validationResponse instanceof HTTPErrorResponse
|
||||
? validationResponse.message ||
|
||||
"Failed to validate license key."
|
||||
: "Failed to validate license key.";
|
||||
throw new BadDataException(errorMessage);
|
||||
}
|
||||
|
||||
const payload: JSONObject = validationResponse.data as JSONObject;
|
||||
|
||||
const companyNameRaw: string =
|
||||
(payload["companyName"] as string | undefined)?.trim() || "";
|
||||
const expiresAtRaw: string =
|
||||
(payload["expiresAt"] as string | undefined) || "";
|
||||
const licenseKeyRaw: string =
|
||||
(payload["licenseKey"] as string | undefined)?.trim() || licenseKey;
|
||||
const licenseToken: string =
|
||||
(payload["token"] as string | undefined) || "";
|
||||
|
||||
let licenseExpiry: Date | undefined = undefined;
|
||||
if (expiresAtRaw) {
|
||||
const parsedDate: Date = new Date(expiresAtRaw);
|
||||
|
||||
if (Number.isNaN(parsedDate.getTime())) {
|
||||
throw new BadDataException(
|
||||
"License expiration returned from server is invalid.",
|
||||
);
|
||||
}
|
||||
|
||||
licenseExpiry = parsedDate;
|
||||
}
|
||||
|
||||
const updatePayload: PartialEntity<GlobalConfig> = {
|
||||
enterpriseCompanyName: companyNameRaw || null,
|
||||
enterpriseLicenseKey: licenseKeyRaw || null,
|
||||
enterpriseLicenseExpiresAt: licenseExpiry || null,
|
||||
enterpriseLicenseToken: licenseToken || null,
|
||||
};
|
||||
|
||||
const globalConfigId: ObjectID = ObjectID.getZeroObjectID();
|
||||
|
||||
const existingConfig: GlobalConfig | null =
|
||||
await GlobalConfigService.findOneById({
|
||||
id: globalConfigId,
|
||||
select: {
|
||||
_id: true,
|
||||
},
|
||||
props: {
|
||||
isRoot: true,
|
||||
ignoreHooks: true,
|
||||
},
|
||||
});
|
||||
|
||||
if (existingConfig) {
|
||||
await GlobalConfigService.updateOneById({
|
||||
id: globalConfigId,
|
||||
data: updatePayload,
|
||||
props: {
|
||||
isRoot: true,
|
||||
ignoreHooks: true,
|
||||
},
|
||||
});
|
||||
} else {
|
||||
const newConfig: GlobalConfig = new GlobalConfig();
|
||||
newConfig.id = globalConfigId;
|
||||
|
||||
if (companyNameRaw) {
|
||||
newConfig.enterpriseCompanyName = companyNameRaw;
|
||||
}
|
||||
|
||||
if (licenseKeyRaw) {
|
||||
newConfig.enterpriseLicenseKey = licenseKeyRaw;
|
||||
}
|
||||
|
||||
if (licenseToken) {
|
||||
newConfig.enterpriseLicenseToken = licenseToken;
|
||||
}
|
||||
|
||||
if (licenseExpiry) {
|
||||
newConfig.enterpriseLicenseExpiresAt = licenseExpiry;
|
||||
}
|
||||
|
||||
await GlobalConfigService.create({
|
||||
data: newConfig,
|
||||
props: {
|
||||
isRoot: true,
|
||||
ignoreHooks: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
return Response.sendJsonObjectResponse(req, res, {
|
||||
companyName: companyNameRaw || null,
|
||||
expiresAt: licenseExpiry ? licenseExpiry.toISOString() : null,
|
||||
licenseKey: licenseKeyRaw || null,
|
||||
token: licenseToken || null,
|
||||
});
|
||||
} catch (err) {
|
||||
next(err);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
96
Common/Server/API/IncidentInternalNoteAPI.ts
Normal file
96
Common/Server/API/IncidentInternalNoteAPI.ts
Normal file
@@ -0,0 +1,96 @@
|
||||
import IncidentInternalNote from "../../Models/DatabaseModels/IncidentInternalNote";
|
||||
import File from "../../Models/DatabaseModels/File";
|
||||
import NotFoundException from "../../Types/Exception/NotFoundException";
|
||||
import ObjectID from "../../Types/ObjectID";
|
||||
import IncidentInternalNoteService, {
|
||||
Service as IncidentInternalNoteServiceType,
|
||||
} from "../Services/IncidentInternalNoteService";
|
||||
import Response from "../Utils/Response";
|
||||
import BaseAPI from "./BaseAPI";
|
||||
import UserMiddleware from "../Middleware/UserAuthorization";
|
||||
import CommonAPI from "./CommonAPI";
|
||||
import DatabaseCommonInteractionProps from "../../Types/BaseDatabase/DatabaseCommonInteractionProps";
|
||||
import {
|
||||
ExpressRequest,
|
||||
ExpressResponse,
|
||||
NextFunction,
|
||||
} from "../Utils/Express";
|
||||
|
||||
export default class IncidentInternalNoteAPI extends BaseAPI<
|
||||
IncidentInternalNote,
|
||||
IncidentInternalNoteServiceType
|
||||
> {
|
||||
public constructor() {
|
||||
super(IncidentInternalNote, IncidentInternalNoteService);
|
||||
|
||||
this.router.get(
|
||||
`${new this.entityType().getCrudApiPath()?.toString()}/attachment/:projectId/:noteId/:fileId`,
|
||||
UserMiddleware.getUserMiddleware,
|
||||
async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => {
|
||||
try {
|
||||
await this.getAttachment(req, res);
|
||||
} catch (err) {
|
||||
next(err);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
private async getAttachment(
|
||||
req: ExpressRequest,
|
||||
res: ExpressResponse,
|
||||
): Promise<void> {
|
||||
const noteIdParam: string | undefined = req.params["noteId"];
|
||||
const fileIdParam: string | undefined = req.params["fileId"];
|
||||
|
||||
if (!noteIdParam || !fileIdParam) {
|
||||
throw new NotFoundException("Attachment not found");
|
||||
}
|
||||
|
||||
let noteId: ObjectID;
|
||||
let fileId: ObjectID;
|
||||
|
||||
try {
|
||||
noteId = new ObjectID(noteIdParam);
|
||||
fileId = new ObjectID(fileIdParam);
|
||||
} catch {
|
||||
throw new NotFoundException("Attachment not found");
|
||||
}
|
||||
|
||||
const props: DatabaseCommonInteractionProps =
|
||||
await CommonAPI.getDatabaseCommonInteractionProps(req);
|
||||
|
||||
const note: IncidentInternalNote | null = await this.service.findOneBy({
|
||||
query: {
|
||||
_id: noteId,
|
||||
},
|
||||
select: {
|
||||
attachments: {
|
||||
_id: true,
|
||||
file: true,
|
||||
fileType: true,
|
||||
name: true,
|
||||
},
|
||||
},
|
||||
props,
|
||||
});
|
||||
|
||||
const attachment: File | undefined = note?.attachments?.find(
|
||||
(file: File) => {
|
||||
const attachmentId: string | null = file._id
|
||||
? file._id.toString()
|
||||
: file.id
|
||||
? file.id.toString()
|
||||
: null;
|
||||
return attachmentId === fileId.toString();
|
||||
},
|
||||
);
|
||||
|
||||
if (!attachment || !attachment.file) {
|
||||
throw new NotFoundException("Attachment not found");
|
||||
}
|
||||
|
||||
Response.setNoCacheHeaders(res);
|
||||
return Response.sendFileResponse(req, res, attachment);
|
||||
}
|
||||
}
|
||||
96
Common/Server/API/IncidentPublicNoteAPI.ts
Normal file
96
Common/Server/API/IncidentPublicNoteAPI.ts
Normal file
@@ -0,0 +1,96 @@
|
||||
import IncidentPublicNote from "../../Models/DatabaseModels/IncidentPublicNote";
|
||||
import File from "../../Models/DatabaseModels/File";
|
||||
import NotFoundException from "../../Types/Exception/NotFoundException";
|
||||
import ObjectID from "../../Types/ObjectID";
|
||||
import IncidentPublicNoteService, {
|
||||
Service as IncidentPublicNoteServiceType,
|
||||
} from "../Services/IncidentPublicNoteService";
|
||||
import Response from "../Utils/Response";
|
||||
import BaseAPI from "./BaseAPI";
|
||||
import UserMiddleware from "../Middleware/UserAuthorization";
|
||||
import {
|
||||
ExpressRequest,
|
||||
ExpressResponse,
|
||||
NextFunction,
|
||||
} from "../Utils/Express";
|
||||
import CommonAPI from "./CommonAPI";
|
||||
import DatabaseCommonInteractionProps from "../../Types/BaseDatabase/DatabaseCommonInteractionProps";
|
||||
|
||||
export default class IncidentPublicNoteAPI extends BaseAPI<
|
||||
IncidentPublicNote,
|
||||
IncidentPublicNoteServiceType
|
||||
> {
|
||||
public constructor() {
|
||||
super(IncidentPublicNote, IncidentPublicNoteService);
|
||||
|
||||
this.router.get(
|
||||
`${new this.entityType().getCrudApiPath()?.toString()}/attachment/:projectId/:noteId/:fileId`,
|
||||
UserMiddleware.getUserMiddleware,
|
||||
async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => {
|
||||
try {
|
||||
await this.getAttachment(req, res);
|
||||
} catch (err) {
|
||||
next(err);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
private async getAttachment(
|
||||
req: ExpressRequest,
|
||||
res: ExpressResponse,
|
||||
): Promise<void> {
|
||||
const noteIdParam: string | undefined = req.params["noteId"];
|
||||
const fileIdParam: string | undefined = req.params["fileId"];
|
||||
|
||||
if (!noteIdParam || !fileIdParam) {
|
||||
throw new NotFoundException("Attachment not found");
|
||||
}
|
||||
|
||||
let noteId: ObjectID;
|
||||
let fileId: ObjectID;
|
||||
|
||||
try {
|
||||
noteId = new ObjectID(noteIdParam);
|
||||
fileId = new ObjectID(fileIdParam);
|
||||
} catch {
|
||||
throw new NotFoundException("Attachment not found");
|
||||
}
|
||||
|
||||
const props: DatabaseCommonInteractionProps =
|
||||
await CommonAPI.getDatabaseCommonInteractionProps(req);
|
||||
|
||||
const note: IncidentPublicNote | null = await this.service.findOneBy({
|
||||
query: {
|
||||
_id: noteId,
|
||||
},
|
||||
select: {
|
||||
attachments: {
|
||||
_id: true,
|
||||
file: true,
|
||||
fileType: true,
|
||||
name: true,
|
||||
},
|
||||
},
|
||||
props,
|
||||
});
|
||||
|
||||
const attachment: File | undefined = note?.attachments?.find(
|
||||
(file: File) => {
|
||||
const attachmentId: string | null = file._id
|
||||
? file._id.toString()
|
||||
: file.id
|
||||
? file.id.toString()
|
||||
: null;
|
||||
return attachmentId === fileId.toString();
|
||||
},
|
||||
);
|
||||
|
||||
if (!attachment || !attachment.file) {
|
||||
throw new NotFoundException("Attachment not found");
|
||||
}
|
||||
|
||||
Response.setNoCacheHeaders(res);
|
||||
return Response.sendFileResponse(req, res, attachment);
|
||||
}
|
||||
}
|
||||
@@ -58,7 +58,7 @@ export default class MicrosoftTeamsAPI {
|
||||
"https://developer.microsoft.com/json-schemas/teams/v1.23/MicrosoftTeams.schema.json",
|
||||
manifestVersion: "1.23",
|
||||
version: AppVersion.toLowerCase().includes("unknown")
|
||||
? "1.3.0"
|
||||
? "1.5.0"
|
||||
: AppVersion,
|
||||
id: MicrosoftTeamsAppClientId,
|
||||
developer: {
|
||||
@@ -75,12 +75,13 @@ export default class MicrosoftTeamsAPI {
|
||||
},
|
||||
description: {
|
||||
short: "Complete open-source monitoring and observability platform. ",
|
||||
full: `OneUptime is a comprehensive solution for monitoring and managing your online services. Whether you need to check the availability of your website, dashboard, API, or any other online resource, OneUptime can alert your team when downtime happens and keep your customers informed with a status page. OneUptime also helps you handle incidents, set up on-call rotations, run tests, secure your services, analyze logs, track performance, and debug errors.
|
||||
full: `<p>OneUptime is a comprehensive solution for monitoring and managing your online services. Whether you need to check the availability of your website, dashboard, API, or any other online resource, OneUptime can alert your team when downtime happens and keep your customers informed with a status page. OneUptime also helps you handle incidents, set up on-call rotations, run tests, secure your services, analyze logs, track performance, and debug errors.</p>
|
||||
|
||||
In order to use the app, you need to have an active account with OneUptime at https://oneuptime.com. Please send an email to support@oneupitme.com if you need more details.
|
||||
<p>In order to use the app, you need to have an active account with <a href="https://oneuptime.com" target="_blank">OneUptime</a>. Please send an email to <a href="mailto:support@oneuptime.com">support@oneuptime.com</a> if you need more details.</p>
|
||||
|
||||
Create a new OneUptime Account: If you wish to sign up for a new account, you can do so at https://oneuptime.com and click on Sign up.
|
||||
Help and Support: You can reach out to help and support here: https://oneuptime.com/support or contact support@oneuptime.com
|
||||
<p><strong>Create a new OneUptime Account:</strong> If you wish to sign up for a new account, you can do so by visiting <a href="https://oneuptime.com" target="_blank">OneUptime Sign Up</a>.</p>
|
||||
|
||||
<p><strong>Help and Support:</strong> You can reach out to help and support via <a href="https://oneuptime.com/support" target="_blank">Support Page</a> or contact <a href="mailto:support@oneuptime.com">support@oneuptime.com</a>.</p>
|
||||
`,
|
||||
},
|
||||
// Default to size-specific names; route will adjust if fallbacks are used
|
||||
@@ -622,9 +623,8 @@ Help and Support: You can reach out to help and support here: https://oneuptime.
|
||||
projectId: new ObjectID(projectId),
|
||||
workspaceType: WorkspaceType.MicrosoftTeams,
|
||||
});
|
||||
const existingTenant: string | undefined = (
|
||||
existingAuth?.miscData as any
|
||||
)?.tenantId;
|
||||
const existingTenant: string | undefined =
|
||||
existingAuth?.workspaceProjectId;
|
||||
if (existingTenant) {
|
||||
tenantForConsent = existingTenant;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user