@cryptotaxi247 / CoPilot / commits / 588735ee

Darktrace (#270)

* darktrace auth keys * darktrace markdown * markdown cleanup * provision darktrace initial * dashboard template * feat: Add Darktrace dashboard support The code changes include adding support for the Darktrace dashboard in the Grafana connector. This allows users to provision and use the Darktrace summary dashboard. The changes involve adding the DarktraceDashboard enum and updating the DashboardProvisionRequest model to include the Darktrace dashboard. Recent user commits: - dashboard template - provision darktrace initial - markdown cleanup - darktrace markdown - darktrace auth keys - precommit fixes Recent repository commits: - Refactor artifact recommendation error handling - Docker compose nuclei (#262) * feat: Add Darktrace integration to scheduler * feat: Update Darktrace dashboard title The code changes include updating the title of the Darktrace dashboard in the Grafana connector. This commit modifies the "title" property in the Darktrace summary.json file to display "DARKTRACE EVENTS AND ALERTS" as the new title. Note: This commit is related to the recent user commit "feat: Add Darktrace integration to scheduler" and the recent repository commit "feat: Add Darktrace dashboard support". * feat: Update Darktrace integration service name The code changes involve updating the integration service name in the `invoke_darktrace.py` file. The previous integration service name "DUO" has been changed to "Darktrace" to accurately reflect the integration. * update: dependencies * add: darktrace provision * precommit fixes --------- Co-authored-by: Davide Di Modica <webmaster.ddm@gmail.com>

taylor_socfortress committed Jul 10, 2024 at 07:11 UTC 588735ee7dfed800fe5db498aa7638a9b8c70095
21 files changed +3051 -696
.vscode/settings.json
+1
@@ -11,6 +11,7 @@
11 "commonmark",
12 "creationdate",
13 "Crowdstrike",
14 + "darktrace",
15 "datejs",
16 "datetimesec",
17 "DFIR",
backend/app/connectors/grafana/dashboards/Darktrace/summary.json new
+1658
@@ -0,0 +1,1658 @@
1 +{
2 + "annotations": {
3 + "list": [
4 + {
5 + "builtIn": 1,
6 + "datasource": {
7 + "type": "grafana",
8 + "uid": "-- Grafana --"
9 + },
10 + "enable": true,
11 + "hide": true,
12 + "iconColor": "rgba(0, 211, 255, 1)",
13 + "name": "Annotations & Alerts",
14 + "type": "dashboard"
15 + }
16 + ]
17 + },
18 + "description": "DARKTRACE - SUMMARY",
19 + "editable": false,
20 + "fiscalYearStartMonth": 0,
21 + "graphTooltip": 0,
22 + "id": null,
23 + "links": [],
24 + "liveNow": false,
25 + "panels": [
26 + {
27 + "datasource": {
28 + "type": "grafana-opensearch-datasource",
29 + "uid": "replace_datasource_uid"
30 + },
31 + "fieldConfig": {
32 + "defaults": {
33 + "mappings": [
34 + {
35 + "options": {
36 + "match": "null",
37 + "result": {
38 + "text": "N/A"
39 + }
40 + },
41 + "type": "special"
42 + }
43 + ],
44 + "thresholds": {
45 + "mode": "absolute",
46 + "steps": [
47 + {
48 + "color": "orange",
49 + "value": null
50 + }
51 + ]
52 + },
53 + "unit": "locale",
54 + "unitScale": true
55 + },
56 + "overrides": []
57 + },
58 + "gridPos": {
59 + "h": 7,
60 + "w": 4,
61 + "x": 0,
62 + "y": 0
63 + },
64 + "id": 1,
65 + "links": [],
66 + "options": {
67 + "colorMode": "value",
68 + "graphMode": "area",
69 + "justifyMode": "auto",
70 + "orientation": "horizontal",
71 + "reduceOptions": {
72 + "calcs": ["sum"],
73 + "fields": "",
74 + "values": false
75 + },
76 + "showPercentChange": false,
77 + "text": {},
78 + "textMode": "auto",
79 + "wideLayout": true
80 + },
81 + "pluginVersion": "10.3.3",
82 + "targets": [
83 + {
84 + "bucketAggs": [
85 + {
86 + "field": "timestamp",
87 + "id": "2",
88 + "settings": {
89 + "interval": "auto",
90 + "min_doc_count": 0,
91 + "trimEdges": 0
92 + },
93 + "type": "date_histogram"
94 + }
95 + ],
96 + "datasource": {
97 + "type": "grafana-opensearch-datasource",
98 + "uid": "replace_datasource_uid"
99 + },
100 + "metrics": [
101 + {
102 + "field": "select field",
103 + "id": "1",
104 + "type": "count"
105 + }
106 + ],
107 + "query": "model_now_actions_alert:true AND source:$source",
108 + "refId": "A",
109 + "timeField": "timestamp"
110 + }
111 + ],
112 + "title": "ALERTS",
113 + "type": "stat"
114 + },
115 + {
116 + "datasource": {
117 + "type": "grafana-opensearch-datasource",
118 + "uid": "replace_datasource_uid"
119 + },
120 + "fieldConfig": {
121 + "defaults": {
122 + "mappings": [
123 + {
124 + "options": {
125 + "match": "null",
126 + "result": {
127 + "text": "N/A"
128 + }
129 + },
130 + "type": "special"
131 + }
132 + ],
133 + "thresholds": {
134 + "mode": "absolute",
135 + "steps": [
136 + {
137 + "color": "blue",
138 + "value": null
139 + }
140 + ]
141 + },
142 + "unit": "none",
143 + "unitScale": true
144 + },
145 + "overrides": []
146 + },
147 + "gridPos": {
148 + "h": 7,
149 + "w": 4,
150 + "x": 4,
151 + "y": 0
152 + },
153 + "id": 2,
154 + "links": [],
155 + "maxDataPoints": 100,
156 + "options": {
157 + "colorMode": "value",
158 + "graphMode": "none",
159 + "justifyMode": "auto",
160 + "orientation": "horizontal",
161 + "reduceOptions": {
162 + "calcs": ["max"],
163 + "fields": "",
164 + "values": false
165 + },
166 + "showPercentChange": false,
167 + "text": {},
168 + "textMode": "auto",
169 + "wideLayout": true
170 + },
171 + "pluginVersion": "10.3.3",
172 + "targets": [
173 + {
174 + "bucketAggs": [
175 + {
176 + "$$hashKey": "object:235",
177 + "field": "timestamp",
178 + "id": "2",
179 + "settings": {
180 + "interval": "365d",
181 + "min_doc_count": 0,
182 + "trimEdges": 0
183 + },
184 + "type": "date_histogram"
185 + }
186 + ],
187 + "datasource": {
188 + "type": "grafana-opensearch-datasource",
189 + "uid": "replace_datasource_uid"
190 + },
191 + "metrics": [
192 + {
193 + "$$hashKey": "object:233",
194 + "field": "source",
195 + "id": "1",
196 + "meta": {},
197 + "settings": {},
198 + "type": "cardinality"
199 + }
200 + ],
201 + "query": "source:$source",
202 + "refId": "A",
203 + "timeField": "timestamp"
204 + }
205 + ],
206 + "title": "SENSORS",
207 + "type": "stat"
208 + },
209 + {
210 + "datasource": {
211 + "type": "grafana-opensearch-datasource",
212 + "uid": "replace_datasource_uid"
213 + },
214 + "fieldConfig": {
215 + "defaults": {
216 + "color": {
217 + "mode": "thresholds"
218 + },
219 + "custom": {
220 + "align": "auto",
221 + "cellOptions": {
222 + "type": "auto"
223 + },
224 + "inspect": false
225 + },
226 + "mappings": [],
227 + "thresholds": {
228 + "mode": "absolute",
229 + "steps": [
230 + {
231 + "color": "dark-orange",
232 + "value": null
233 + }
234 + ]
235 + },
236 + "unitScale": true
237 + },
238 + "overrides": [
239 + {
240 + "matcher": {
241 + "id": "byName",
242 + "options": "Time"
243 + },
244 + "properties": [
245 + {
246 + "id": "displayName",
247 + "value": "Time"
248 + },
249 + {
250 + "id": "unit",
251 + "value": "time: YYYY-MM-DD HH:mm:ss"
252 + },
253 + {
254 + "id": "custom.align"
255 + }
256 + ]
257 + },
258 + {
259 + "matcher": {
260 + "id": "byName",
261 + "options": "Count"
262 + },
263 + "properties": [
264 + {
265 + "id": "displayName",
266 + "value": "EVENTS"
267 + },
268 + {
269 + "id": "unit",
270 + "value": "short"
271 + },
272 + {
273 + "id": "decimals",
274 + "value": -1
275 + },
276 + {
277 + "id": "custom.cellOptions",
278 + "value": {
279 + "mode": "gradient",
280 + "type": "color-background"
281 + }
282 + },
283 + {
284 + "id": "custom.align"
285 + },
286 + {
287 + "id": "thresholds",
288 + "value": {
289 + "mode": "absolute",
290 + "steps": [
291 + {
292 + "color": "dark-orange",
293 + "value": null
294 + }
295 + ]
296 + }
297 + }
298 + ]
299 + },
300 + {
301 + "matcher": {
302 + "id": "byName",
303 + "options": "agent_name"
304 + },
305 + "properties": [
306 + {
307 + "id": "displayName",
308 + "value": "AGENT"
309 + },
310 + {
311 + "id": "custom.cellOptions",
312 + "value": {
313 + "mode": "gradient",
314 + "type": "color-background"
315 + }
316 + },
317 + {
318 + "id": "custom.align"
319 + },
320 + {
321 + "id": "links",
322 + "value": [
323 + {
324 + "targetBlank": true,
325 + "title": "VIEW EVENTS",
326 + "url": "https://grafana.company.local/explore?left=%5B%22now-1h%22,%22now%22,%22DARKTRECE%22,%7B%22refId%22:%22A%22,%22query%22:%22agent_name:${__value.text}%22,%22alias%22:%22%22,%22metrics%22:%5B%7B%22id%22:%221%22,%22type%22:%22logs%22,%22settings%22:%7B%22limit%22:%22500%22%7D%7D%5D,%22bucketAggs%22:%5B%5D,%22timeField%22:%22timestamp%22%7D%5D"
327 + }
328 + ]
329 + }
330 + ]
331 + },
332 + {
333 + "matcher": {
334 + "id": "byName",
335 + "options": "Count"
336 + },
337 + "properties": [
338 + {
339 + "id": "displayName",
340 + "value": "ALERTS"
341 + },
342 + {
343 + "id": "unit",
344 + "value": "short"
345 + },
346 + {
347 + "id": "decimals",
348 + "value": 0
349 + },
350 + {
351 + "id": "custom.align"
352 + }
353 + ]
354 + }
355 + ]
356 + },
357 + "gridPos": {
358 + "h": 7,
359 + "w": 7,
360 + "x": 8,
361 + "y": 0
362 + },
363 + "id": 3,
364 + "options": {
365 + "cellHeight": "sm",
366 + "footer": {
367 + "countRows": false,
368 + "fields": "",
369 + "reducer": ["sum"],
370 + "show": false
371 + },
372 + "showHeader": true
373 + },
374 + "pluginVersion": "10.3.3",
375 + "targets": [
376 + {
377 + "bucketAggs": [
378 + {
379 + "fake": true,
380 + "field": "source",
381 + "id": "4",
382 + "settings": {
383 + "min_doc_count": 1,
384 + "order": "desc",
385 + "orderBy": "_term",
386 + "size": "0"
387 + },
388 + "type": "terms"
389 + }
390 + ],
391 + "datasource": {
392 + "type": "grafana-opensearch-datasource",
393 + "uid": "replace_datasource_uid"
394 + },
395 + "metrics": [
396 + {
397 + "field": "select field",
398 + "id": "1",
399 + "type": "count"
400 + }
401 + ],
402 + "query": "model_now_actions_alert:true AND source:$source",
403 + "refId": "A",
404 + "timeField": "timestamp"
405 + }
406 + ],
407 + "title": "ALERTS BY SENSOR",
408 + "transformations": [
409 + {
410 + "id": "organize",
411 + "options": {
412 + "excludeByName": {},
413 + "includeByName": {},
414 + "indexByName": {},
415 + "renameByName": {
416 + "source": "Sensor"
417 + }
418 + }
419 + }
420 + ],
421 + "type": "table"
422 + },
423 + {
424 + "datasource": {
425 + "type": "grafana-opensearch-datasource",
426 + "uid": "replace_datasource_uid"
427 + },
428 + "fieldConfig": {
429 + "defaults": {
430 + "color": {
431 + "mode": "thresholds"
432 + },
433 + "custom": {
434 + "align": "auto",
435 + "cellOptions": {
436 + "type": "auto"
437 + },
438 + "inspect": false
439 + },
440 + "mappings": [],
441 + "thresholds": {
442 + "mode": "absolute",
443 + "steps": [
444 + {
445 + "color": "dark-orange",
446 + "value": null
447 + }
448 + ]
449 + },
450 + "unitScale": true
451 + },
452 + "overrides": [
453 + {
454 + "matcher": {
455 + "id": "byName",
456 + "options": "Time"
457 + },
458 + "properties": [
459 + {
460 + "id": "displayName",
461 + "value": "Time"
462 + },
463 + {
464 + "id": "unit",
465 + "value": "time: YYYY-MM-DD HH:mm:ss"
466 + },
467 + {
468 + "id": "custom.align"
469 + }
470 + ]
471 + },
472 + {
473 + "matcher": {
474 + "id": "byName",
475 + "options": "Count"
476 + },
477 + "properties": [
478 + {
479 + "id": "displayName",
480 + "value": "EVENTS"
481 + },
482 + {
483 + "id": "unit",
484 + "value": "short"
485 + },
486 + {
487 + "id": "decimals",
488 + "value": -1
489 + },
490 + {
491 + "id": "custom.cellOptions",
492 + "value": {
493 + "type": "color-background"
494 + }
495 + },
496 + {
497 + "id": "custom.align"
498 + },
499 + {
500 + "id": "thresholds",
501 + "value": {
502 + "mode": "absolute",
503 + "steps": [
504 + {
505 + "color": "dark-orange",
506 + "value": null
507 + }
508 + ]
509 + }
510 + }
511 + ]
512 + },
513 + {
514 + "matcher": {
515 + "id": "byName",
516 + "options": "rule_groups"
517 + },
518 + "properties": [
519 + {
520 + "id": "displayName",
521 + "value": "ALERTS BY TYPE"
522 + },
523 + {
524 + "id": "unit",
525 + "value": "short"
526 + },
527 + {
528 + "id": "decimals",
529 + "value": -1
530 + },
531 + {
532 + "id": "custom.cellOptions",
533 + "value": {
534 + "type": "color-background"
535 + }
536 + },
537 + {
538 + "id": "custom.align"
539 + }
540 + ]
541 + },
542 + {
543 + "matcher": {
544 + "id": "byName",
545 + "options": "model_now_name"
546 + },
547 + "properties": [
548 + {
549 + "id": "custom.width",
550 + "value": 768
551 + }
552 + ]
553 + }
554 + ]
555 + },
556 + "gridPos": {
557 + "h": 7,
558 + "w": 9,
559 + "x": 15,
560 + "y": 0
561 + },
562 + "id": 4,
563 + "options": {
564 + "cellHeight": "sm",
565 + "footer": {
566 + "countRows": false,
567 + "fields": "",
568 + "reducer": ["sum"],
569 + "show": false
570 + },
571 + "showHeader": true,
572 + "sortBy": []
573 + },
574 + "pluginVersion": "10.3.3",
575 + "targets": [
576 + {
577 + "bucketAggs": [
578 + {
579 + "fake": true,
580 + "field": "model_now_name",
581 + "id": "4",
582 + "settings": {
583 + "min_doc_count": 1,
584 + "order": "desc",
585 + "orderBy": "_term",
586 + "size": "0"
587 + },
588 + "type": "terms"
589 + }
590 + ],
591 + "datasource": {
592 + "type": "grafana-opensearch-datasource",
593 + "uid": "replace_datasource_uid"
594 + },
595 + "metrics": [
596 + {
597 + "field": "select field",
598 + "id": "1",
599 + "type": "count"
600 + }
601 + ],
602 + "query": "model_now_actions_alert:true AND source:$source",
603 + "refId": "A",
604 + "timeField": "timestamp"
605 + }
606 + ],
607 + "title": "ALERTS BY CATEGORY",
608 + "transformations": [
609 + {
610 + "id": "organize",
611 + "options": {
612 + "excludeByName": {},
613 + "includeByName": {},
614 + "indexByName": {},
615 + "renameByName": {
616 + "model_now_name": "Name"
617 + }
618 + }
619 + }
620 + ],
621 + "type": "table"
622 + },
623 + {
624 + "datasource": {
625 + "type": "grafana-opensearch-datasource",
626 + "uid": "replace_datasource_uid"
627 + },
628 + "fieldConfig": {
629 + "defaults": {
630 + "mappings": [
631 + {
632 + "options": {
633 + "match": "null",
634 + "result": {
635 + "text": "N/A"
636 + }
637 + },
638 + "type": "special"
639 + }
640 + ],
641 + "thresholds": {
642 + "mode": "absolute",
643 + "steps": [
644 + {
645 + "color": "blue",
646 + "value": null
647 + }
648 + ]
649 + },
650 + "unit": "locale",
651 + "unitScale": true
652 + },
653 + "overrides": []
654 + },
655 + "gridPos": {
656 + "h": 9,
657 + "w": 4,
658 + "x": 0,
659 + "y": 7
660 + },
661 + "id": 8,
662 + "links": [],
663 + "options": {
664 + "colorMode": "value",
665 + "graphMode": "area",
666 + "justifyMode": "auto",
667 + "orientation": "horizontal",
668 + "reduceOptions": {
669 + "calcs": ["sum"],
670 + "fields": "",
671 + "values": false
672 + },
673 + "showPercentChange": false,
674 + "text": {},
675 + "textMode": "auto",
676 + "wideLayout": true
677 + },
678 + "pluginVersion": "10.3.3",
679 + "targets": [
680 + {
681 + "bucketAggs": [
682 + {
683 + "field": "timestamp",
684 + "id": "2",
685 + "settings": {
686 + "interval": "auto",
687 + "min_doc_count": "1",
688 + "trimEdges": 0
689 + },
690 + "type": "date_histogram"
691 + }
692 + ],
693 + "datasource": {
694 + "type": "grafana-opensearch-datasource",
695 + "uid": "replace_datasource_uid"
696 + },
697 + "metrics": [
698 + {
699 + "field": "device_hostname",
700 + "id": "1",
701 + "type": "cardinality"
702 + }
703 + ],
704 + "query": "source:$source",
705 + "refId": "A",
706 + "timeField": "timestamp"
707 + }
708 + ],
709 + "title": "DEVICES - TOTAL",
710 + "type": "stat"
711 + },
712 + {
713 + "datasource": {
714 + "type": "grafana-opensearch-datasource",
715 + "uid": "replace_datasource_uid"
716 + },
717 + "fieldConfig": {
718 + "defaults": {
719 + "color": {
720 + "mode": "thresholds"
721 + },
722 + "custom": {
723 + "align": "auto",
724 + "cellOptions": {
725 + "type": "auto"
726 + },
727 + "inspect": false
728 + },
729 + "mappings": [],
730 + "thresholds": {
731 + "mode": "absolute",
732 + "steps": [
733 + {
734 + "color": "dark-orange",
735 + "value": null
736 + }
737 + ]
738 + },
739 + "unitScale": true
740 + },
741 + "overrides": [
742 + {
743 + "matcher": {
744 + "id": "byName",
745 + "options": "Time"
746 + },
747 + "properties": [
748 + {
749 + "id": "displayName",
750 + "value": "Time"
751 + },
752 + {
753 + "id": "unit",
754 + "value": "time: YYYY-MM-DD HH:mm:ss"
755 + },
756 + {
757 + "id": "custom.align"
758 + }
759 + ]
760 + },
761 + {
762 + "matcher": {
763 + "id": "byName",
764 + "options": "Count"
765 + },
766 + "properties": [
767 + {
768 + "id": "displayName",
769 + "value": "EVENTS"
770 + },
771 + {
772 + "id": "unit",
773 + "value": "short"
774 + },
775 + {
776 + "id": "decimals",
777 + "value": -1
778 + },
779 + {
780 + "id": "custom.cellOptions",
781 + "value": {
782 + "type": "color-background"
783 + }
784 + },
785 + {
786 + "id": "custom.align"
787 + },
788 + {
789 + "id": "thresholds",
790 + "value": {
791 + "mode": "absolute",
792 + "steps": [
793 + {
794 + "color": "dark-orange",
795 + "value": null
796 + }
797 + ]
798 + }
799 + }
800 + ]
801 + },
802 + {
803 + "matcher": {
804 + "id": "byName",
805 + "options": "rule_groups"
806 + },
807 + "properties": [
808 + {
809 + "id": "displayName",
810 + "value": "ALERTS BY TYPE"
811 + },
812 + {
813 + "id": "unit",
814 + "value": "short"
815 + },
816 + {
817 + "id": "decimals",
818 + "value": -1
819 + },
820 + {
821 + "id": "custom.cellOptions",
822 + "value": {
823 + "type": "color-background"
824 + }
825 + },
826 + {
827 + "id": "custom.align"
828 + }
829 + ]
830 + },
831 + {
832 + "matcher": {
833 + "id": "byName",
834 + "options": "model_now_name"
835 + },
836 + "properties": [
837 + {
838 + "id": "custom.width",
839 + "value": 768
840 + }
841 + ]
842 + }
843 + ]
844 + },
845 + "gridPos": {
846 + "h": 9,
847 + "w": 11,
848 + "x": 4,
849 + "y": 7
850 + },
851 + "id": 9,
852 + "options": {
853 + "cellHeight": "sm",
854 + "footer": {
855 + "countRows": false,
856 + "fields": "",
857 + "reducer": ["sum"],
858 + "show": false
859 + },
860 + "showHeader": true,
861 + "sortBy": []
862 + },
863 + "pluginVersion": "10.3.3",
864 + "targets": [
865 + {
866 + "bucketAggs": [
867 + {
868 + "fake": true,
869 + "field": "device_hostname",
870 + "id": "4",
871 + "settings": {
872 + "min_doc_count": 1,
873 + "order": "desc",
874 + "orderBy": "_term",
875 + "size": "0"
876 + },
877 + "type": "terms"
878 + }
879 + ],
880 + "datasource": {
881 + "type": "grafana-opensearch-datasource",
882 + "uid": "replace_datasource_uid"
883 + },
884 + "metrics": [
885 + {
886 + "field": "select field",
887 + "id": "1",
888 + "type": "count"
889 + }
890 + ],
891 + "query": "source:$source",
892 + "refId": "A",
893 + "timeField": "timestamp"
894 + }
895 + ],
896 + "title": "EVENTS BY DEVICE",
897 + "transformations": [
898 + {
899 + "id": "organize",
900 + "options": {
901 + "excludeByName": {},
902 + "includeByName": {},
903 + "indexByName": {},
904 + "renameByName": {
905 + "device_hostname": "Device",
906 + "model_now_name": "Name"
907 + }
908 + }
909 + }
910 + ],
911 + "type": "table"
912 + },
913 + {
914 + "datasource": {
915 + "type": "grafana-opensearch-datasource",
916 + "uid": "replace_datasource_uid"
917 + },
918 + "fieldConfig": {
919 + "defaults": {
920 + "color": {
921 + "mode": "palette-classic"
922 + },
923 + "custom": {
924 + "hideFrom": {
925 + "legend": false,
926 + "tooltip": false,
927 + "viz": false
928 + }
929 + },
930 + "decimals": 0,
931 + "mappings": [],
932 + "unit": "short",
933 + "unitScale": true
934 + },
935 + "overrides": [
936 + {
937 + "matcher": {
938 + "id": "byName",
939 + "options": "1"
940 + },
941 + "properties": [
942 + {
943 + "id": "color",
944 + "value": {
945 + "fixedColor": "#C8F2C2",
946 + "mode": "fixed"
947 + }
948 + }
949 + ]
950 + },
951 + {
952 + "matcher": {
953 + "id": "byName",
954 + "options": "2"
955 + },
956 + "properties": [
957 + {
958 + "id": "color",
959 + "value": {
960 + "fixedColor": "#96D98D",
961 + "mode": "fixed"
962 + }
963 + }
964 + ]
965 + },
966 + {
967 + "matcher": {
968 + "id": "byName",
969 + "options": "3"
970 + },
971 + "properties": [
972 + {
973 + "id": "color",
974 + "value": {
975 + "fixedColor": "#56A64B",
976 + "mode": "fixed"
977 + }
978 + }
979 + ]
980 + },
981 + {
982 + "matcher": {
983 + "id": "byName",
984 + "options": "4"
985 + },
986 + "properties": [
987 + {
988 + "id": "color",
989 + "value": {
990 + "fixedColor": "#37872D",
991 + "mode": "fixed"
992 + }
993 + }
994 + ]
995 + },
996 + {
997 + "matcher": {
998 + "id": "byName",
999 + "options": "5"
1000 + },
1001 + "properties": [
1002 + {
1003 + "id": "color",
1004 + "value": {
1005 + "fixedColor": "#FFF899",
1006 + "mode": "fixed"
1007 + }
1008 + }
1009 + ]
1010 + },
1011 + {
1012 + "matcher": {
1013 + "id": "byName",
1014 + "options": "7"
1015 + },
1016 + "properties": [
1017 + {
1018 + "id": "color",
1019 + "value": {
1020 + "fixedColor": "#F2CC0C",
1021 + "mode": "fixed"
1022 + }
1023 + }
1024 + ]
1025 + },
1026 + {
1027 + "matcher": {
1028 + "id": "byName",
1029 + "options": "9"
1030 + },
1031 + "properties": [
1032 + {
1033 + "id": "color",
1034 + "value": {
1035 + "fixedColor": "#FF9830",
1036 + "mode": "fixed"
1037 + }
1038 + }
1039 + ]
1040 + },
1041 + {
1042 + "matcher": {
1043 + "id": "byName",
1044 + "options": "10"
1045 + },
1046 + "properties": [
1047 + {
1048 + "id": "color",
1049 + "value": {
1050 + "fixedColor": "#FF9830",
1051 + "mode": "fixed"
1052 + }
1053 + }
1054 + ]
1055 + },
1056 + {
1057 + "matcher": {
1058 + "id": "byName",
1059 + "options": "12"
1060 + },
1061 + "properties": [
1062 + {
1063 + "id": "color",
1064 + "value": {
1065 + "fixedColor": "#F2495C",
1066 + "mode": "fixed"
1067 + }
1068 + }
1069 + ]
1070 + },
1071 + {
1072 + "matcher": {
1073 + "id": "byName",
1074 + "options": "13"
1075 + },
1076 + "properties": [
1077 + {
1078 + "id": "color",
1079 + "value": {
1080 + "fixedColor": "#FF7383",
1081 + "mode": "fixed"
1082 + }
1083 + }
1084 + ]
1085 + }
1086 + ]
1087 + },
1088 + "gridPos": {
1089 + "h": 9,
1090 + "w": 9,
1091 + "x": 15,
1092 + "y": 7
1093 + },
1094 + "id": 10,
1095 + "links": [],
1096 + "maxDataPoints": 3,
1097 + "options": {
1098 + "displayLabels": [],
1099 + "legend": {
1100 + "calcs": [],
1101 + "displayMode": "table",
1102 + "placement": "right",
1103 + "showLegend": true,
1104 + "values": ["value", "percent"]
1105 + },
1106 + "pieType": "donut",
1107 + "reduceOptions": {
1108 + "calcs": ["sum"],
1109 + "fields": "",
1110 + "values": false
1111 + },
1112 + "text": {},
1113 + "tooltip": {
1114 + "mode": "single",
1115 + "sort": "none"
1116 + }
1117 + },
1118 + "targets": [
1119 + {
1120 + "bucketAggs": [
1121 + {
1122 + "$$hashKey": "object:235",
1123 + "fake": true,
1124 + "field": "device_os",
1125 + "id": "3",
1126 + "settings": {
1127 + "min_doc_count": 1,
1128 + "order": "desc",
1129 + "orderBy": "_count",
1130 + "size": "10"
1131 + },
1132 + "type": "terms"
1133 + },
1134 + {
1135 + "$$hashKey": "object:236",
1136 + "field": "timestamp",
1137 + "id": "2",
1138 + "settings": {
1139 + "interval": "auto",
1140 + "min_doc_count": 0,
1141 + "trimEdges": 0
1142 + },
1143 + "type": "date_histogram"
1144 + }
1145 + ],
1146 + "datasource": {
1147 + "type": "grafana-opensearch-datasource",
1148 + "uid": "replace_datasource_uid"
1149 + },
1150 + "metrics": [
1151 + {
1152 + "$$hashKey": "object:233",
1153 + "field": "select field",
1154 + "id": "1",
1155 + "meta": {},
1156 + "settings": {},
1157 + "type": "count"
1158 + }
1159 + ],
1160 + "query": "source:$source",
1161 + "refId": "A",
1162 + "timeField": "timestamp"
1163 + }
1164 + ],
1165 + "title": "DEVICES BY OS",
1166 + "type": "piechart"
1167 + },
1168 + {
1169 + "datasource": {
1170 + "type": "grafana-opensearch-datasource",
1171 + "uid": "replace_datasource_uid"
1172 + },
1173 + "fieldConfig": {
1174 + "defaults": {
1175 + "mappings": [
1176 + {
1177 + "options": {
1178 + "match": "null",
1179 + "result": {
1180 + "text": "N/A"
1181 + }
1182 + },
1183 + "type": "special"
1184 + }
1185 + ],
1186 + "thresholds": {
1187 + "mode": "absolute",
1188 + "steps": [
1189 + {
1190 + "color": "blue",
1191 + "value": null
1192 + }
1193 + ]
1194 + },
1195 + "unit": "locale",
1196 + "unitScale": true
1197 + },
1198 + "overrides": []
1199 + },
1200 + "gridPos": {
1201 + "h": 9,
1202 + "w": 4,
1203 + "x": 0,
1204 + "y": 16
1205 + },
1206 + "id": 5,
1207 + "links": [],
1208 + "options": {
1209 + "colorMode": "value",
1210 + "graphMode": "area",
1211 + "justifyMode": "auto",
1212 + "orientation": "horizontal",
1213 + "reduceOptions": {
1214 + "calcs": ["sum"],
1215 + "fields": "",
1216 + "values": false
1217 + },
1218 + "showPercentChange": false,
1219 + "text": {},
1220 + "textMode": "auto",
1221 + "wideLayout": true
1222 + },
1223 + "pluginVersion": "10.3.3",
1224 + "targets": [
1225 + {
1226 + "bucketAggs": [
1227 + {
1228 + "field": "timestamp",
1229 + "id": "2",
1230 + "settings": {
1231 + "interval": "auto",
1232 + "min_doc_count": 0,
1233 + "trimEdges": 0
1234 + },
1235 + "type": "date_histogram"
1236 + }
1237 + ],
1238 + "datasource": {
1239 + "type": "grafana-opensearch-datasource",
1240 + "uid": "replace_datasource_uid"
1241 + },
1242 + "metrics": [
1243 + {
1244 + "field": "select field",
1245 + "id": "1",
1246 + "type": "count"
1247 + }
1248 + ],
1249 + "query": "source:$source",
1250 + "refId": "A",
1251 + "timeField": "timestamp"
1252 + }
1253 + ],
1254 + "title": "EVENTS - TOTAL",
1255 + "type": "stat"
1256 + },
1257 + {
1258 + "datasource": {
1259 + "type": "grafana-opensearch-datasource",
1260 + "uid": "replace_datasource_uid"
1261 + },
1262 + "fieldConfig": {
1263 + "defaults": {
1264 + "color": {
1265 + "mode": "palette-classic"
1266 + },
1267 + "custom": {
1268 + "axisBorderShow": false,
1269 + "axisCenteredZero": false,
1270 + "axisColorMode": "text",
1271 + "axisLabel": "",
1272 + "axisPlacement": "auto",
1273 + "barAlignment": 0,
1274 + "drawStyle": "bars",
1275 + "fillOpacity": 0,
1276 + "gradientMode": "none",
1277 + "hideFrom": {
1278 + "legend": false,
1279 + "tooltip": false,
1280 + "viz": false
1281 + },
1282 + "insertNulls": false,
1283 + "lineInterpolation": "linear",
1284 + "lineWidth": 1,
1285 + "pointSize": 5,
1286 + "scaleDistribution": {
1287 + "type": "linear"
1288 + },
1289 + "showPoints": "auto",
1290 + "spanNulls": false,
1291 + "stacking": {
1292 + "group": "A",
1293 + "mode": "normal"
1294 + },
1295 + "thresholdsStyle": {
1296 + "mode": "off"
1297 + }
1298 + },
1299 + "mappings": [],
1300 + "thresholds": {
1301 + "mode": "absolute",
1302 + "steps": [
1303 + {
1304 + "color": "green",
1305 + "value": null
1306 + },
1307 + {
1308 + "color": "red",
1309 + "value": 80
1310 + }
1311 + ]
1312 + },
1313 + "unitScale": true
1314 + },
1315 + "overrides": []
1316 + },
1317 + "gridPos": {
1318 + "h": 9,
1319 + "w": 20,
1320 + "x": 4,
1321 + "y": 16
1322 + },
1323 + "id": 6,
1324 + "options": {
1325 + "legend": {
1326 + "calcs": [],
1327 + "displayMode": "table",
1328 + "placement": "right",
1329 + "showLegend": true
1330 + },
1331 + "tooltip": {
1332 + "mode": "single",
1333 + "sort": "none"
1334 + }
1335 + },
1336 + "targets": [
1337 + {
1338 + "alias": "",
1339 + "bucketAggs": [
1340 + {
1341 + "field": "source",
1342 + "id": "3",
1343 + "settings": {
1344 + "min_doc_count": "1",
1345 + "order": "desc",
1346 + "orderBy": "_term",
1347 + "size": "10"
1348 + },
1349 + "type": "terms"
1350 + },
1351 + {
1352 + "field": "timestamp",
1353 + "id": "2",
1354 + "settings": {
1355 + "interval": "5m"
1356 + },
1357 + "type": "date_histogram"
1358 + }
1359 + ],
1360 + "datasource": {
1361 + "type": "grafana-opensearch-datasource",
1362 + "uid": "replace_datasource_uid"
1363 + },
1364 + "metrics": [
1365 + {
1366 + "id": "1",
1367 + "type": "count"
1368 + }
1369 + ],
1370 + "query": "source:$source",
1371 + "refId": "A",
1372 + "timeField": "timestamp"
1373 + }
1374 + ],
1375 + "title": "EVENTS BY SENSOR - HISTOGRAM",
1376 + "transparent": true,
1377 + "type": "timeseries"
1378 + },
1379 + {
1380 + "datasource": {
1381 + "type": "grafana-opensearch-datasource",
1382 + "uid": "replace_datasource_uid"
1383 + },
1384 + "fieldConfig": {
1385 + "defaults": {
1386 + "color": {
1387 + "mode": "thresholds"
1388 + },
1389 + "custom": {
1390 + "align": "auto",
1391 + "cellOptions": {
1392 + "type": "auto"
1393 + },
1394 + "filterable": true,
1395 + "inspect": false
1396 + },
1397 + "mappings": [],
1398 + "thresholds": {
1399 + "mode": "absolute",
1400 + "steps": [
1401 + {
1402 + "color": "green",
1403 + "value": null
1404 + },
1405 + {
1406 + "color": "red",
1407 + "value": 80
1408 + }
1409 + ]
1410 + },
1411 + "unitScale": true
1412 + },
1413 + "overrides": [
1414 + {
1415 + "matcher": {
1416 + "id": "byName",
1417 + "options": "DATE/TIME"
1418 + },
1419 + "properties": [
1420 + {
1421 + "id": "custom.width",
1422 + "value": 196
1423 + }
1424 + ]
1425 + },
1426 + {
1427 + "matcher": {
1428 + "id": "byName",
1429 + "options": "SENSOR"
1430 + },
1431 + "properties": [
1432 + {
1433 + "id": "custom.width",
1434 + "value": 203
1435 + }
1436 + ]
1437 + },
1438 + {
1439 + "matcher": {
1440 + "id": "byName",
1441 + "options": "ALERT"
1442 + },
1443 + "properties": [
1444 + {
1445 + "id": "custom.width",
1446 + "value": 120
1447 + }
1448 + ]
1449 + },
1450 + {
1451 + "matcher": {
1452 + "id": "byName",
1453 + "options": "CATEGORY"
1454 + },
1455 + "properties": [
1456 + {
1457 + "id": "custom.width",
1458 + "value": 162
1459 + }
1460 + ]
1461 + },
1462 + {
1463 + "matcher": {
1464 + "id": "byName",
1465 + "options": "DESCRIPTION"
1466 + },
1467 + "properties": [
1468 + {
1469 + "id": "custom.width",
1470 + "value": 749
1471 + }
1472 + ]
1473 + },
1474 + {
1475 + "matcher": {
1476 + "id": "byName",
1477 + "options": "NAME"
1478 + },
1479 + "properties": [
1480 + {
1481 + "id": "custom.width",
1482 + "value": 508
1483 + }
1484 + ]
1485 + },
1486 + {
1487 + "matcher": {
1488 + "id": "byName",
1489 + "options": "EVENT ID"
1490 + },
1491 + "properties": [
1492 + {
1493 + "id": "links",
1494 + "value": [
1495 + {
1496 + "targetBlank": true,
1497 + "title": "EVENT DETAILS",
1498 + "url": "https://grafana.company.local/explore?left=%7B%22datasource%22:%22DARKTRACE%22,%22queries%22:%5B%7B%22refId%22:%22A%22,%22query%22:%22_id:${__value.text}%22,%22alias%22:%22%22,%22metrics%22:%5B%7B%22id%22:%221%22,%22type%22:%22logs%22,%22settings%22:%7B%22limit%22:%22500%22%7D%7D%5D,%22bucketAggs%22:%5B%5D,%22timeField%22:%22timestamp%22%7D%5D,%22range%22:%7B%22from%22:%22now-6h%22,%22to%22:%22now%22%7D%7D"
1499 + }
1500 + ]
1501 + }
1502 + ]
1503 + }
1504 + ]
1505 + },
1506 + "gridPos": {
1507 + "h": 17,
1508 + "w": 24,
1509 + "x": 0,
1510 + "y": 25
1511 + },
1512 + "id": 7,
1513 + "options": {
1514 + "cellHeight": "sm",
1515 + "footer": {
1516 + "countRows": false,
1517 + "enablePagination": true,
1518 + "fields": "",
1519 + "reducer": ["sum"],
1520 + "show": false
1521 + },
1522 + "showHeader": true,
1523 + "sortBy": []
1524 + },
1525 + "pluginVersion": "10.3.3",
1526 + "targets": [
1527 + {
1528 + "alias": "",
1529 + "bucketAggs": [],
1530 + "datasource": {
1531 + "type": "grafana-opensearch-datasource",
1532 + "uid": "replace_datasource_uid"
1533 + },
1534 + "format": "table",
1535 + "metrics": [
1536 + {
1537 + "id": "1",
1538 + "settings": {
1539 + "order": "desc",
1540 + "size": "500",
1541 + "useTimeRange": true
1542 + },
1543 + "type": "raw_data"
1544 + }
1545 + ],
1546 + "query": "",
1547 + "queryType": "lucene",
1548 + "refId": "A",
1549 + "timeField": "timestamp"
1550 + }
1551 + ],
1552 + "title": "EVENTS",
1553 + "transformations": [
1554 + {
1555 + "id": "filterFieldsByName",
1556 + "options": {
1557 + "include": {
1558 + "names": [
1559 + "timestamp",
1560 + "_id",
1561 + "model_now_actions_alert",
1562 + "model_now_category",
1563 + "model_now_description",
1564 + "model_now_mitre_techniques",
1565 + "model_now_name",
1566 + "source",
1567 + "model_now_mitre_tactics"
1568 + ]
1569 + }
1570 + }
1571 + },
1572 + {
1573 + "id": "organize",
1574 + "options": {
1575 + "excludeByName": {},
1576 + "includeByName": {},
1577 + "indexByName": {
1578 + "_id": 1,
1579 + "model_now_actions_alert": 3,
1580 + "model_now_category": 4,
1581 + "model_now_description": 6,
1582 + "model_now_mitre_tactics": 7,
1583 + "model_now_mitre_techniques": 8,
1584 + "model_now_name": 5,
1585 + "source": 2,
1586 + "timestamp": 0
1587 + },
1588 + "renameByName": {
1589 + "_id": "EVENT ID",
1590 + "model_now_actions_alert": "ALERT",
1591 + "model_now_category": "CATEGORY",
1592 + "model_now_description": "DESCRIPTION",
1593 + "model_now_mitre_tactics": "MITRE TACTICS",
1594 + "model_now_mitre_techniques": "MITRE TECHNIQUES",
1595 + "model_now_name": "NAME",
1596 + "source": "SENSOR",
1597 + "timestamp": "DATE/TIME"
1598 + }
1599 + }
1600 + }
1601 + ],
1602 + "transparent": true,
1603 + "type": "table"
1604 + }
1605 + ],
1606 + "refresh": "",
1607 + "schemaVersion": 39,
1608 + "tags": ["DARKTRACE"],
1609 + "templating": {
1610 + "list": [
1611 + {
1612 + "datasource": {
1613 + "type": "grafana-opensearch-datasource",
1614 + "uid": "replace_datasource_uid"
1615 + },
1616 + "filters": [],
1617 + "hide": 0,
1618 + "label": "Filters",
1619 + "name": "Filters",
1620 + "skipUrlSync": false,
1621 + "type": "adhoc"
1622 + },
1623 + {
1624 + "current": {
1625 + "selected": true,
1626 + "text": "All",
1627 + "value": "$__all"
1628 + },
1629 + "datasource": {
1630 + "type": "grafana-opensearch-datasource",
1631 + "uid": "replace_datasource_uid"
1632 + },
1633 + "definition": "{ \"find\": \"terms\", \"field\": \"source\", \"query\": \"*\"}",
1634 + "hide": 0,
1635 + "includeAll": true,
1636 + "label": "Source",
1637 + "multi": false,
1638 + "name": "source",
1639 + "options": [],
1640 + "query": "{ \"find\": \"terms\", \"field\": \"source\", \"query\": \"*\"}",
1641 + "refresh": 1,
1642 + "regex": "",
1643 + "skipUrlSync": false,
1644 + "sort": 0,
1645 + "type": "query"
1646 + }
1647 + ]
1648 + },
1649 + "time": {
1650 + "from": "now-24h",
1651 + "to": "now"
1652 + },
1653 + "timepicker": {},
1654 + "timezone": "",
1655 + "title": "DARKTRACE EVENTS AND ALERTS",
1656 + "version": 11,
1657 + "weekStart": ""
1658 +}
backend/app/connectors/grafana/schema/dashboards.py
+5
@@ -102,6 +102,10 @@ class DuoDashboard(Enum):
102 DUO_AUTH = ("Duo", "duo_auth.json")
103
104
105 +class DarktraceDashboard(Enum):
106 + DARKTRACE_SUMMARY = ("Darktrace", "summary.json")
107 +
108 +
109 class DashboardProvisionRequest(BaseModel):
110 dashboards: List[str] = Field(
111 ...,
@@ -134,6 +138,7 @@ class DashboardProvisionRequest(BaseModel):
138 + list(FortinetDashboard)
139 + list(CrowdstrikeDashboard)
140 + list(DuoDashboard)
141 + + list(DarktraceDashboard)
142 }
143 if e not in valid_dashboards:
144 raise ValueError(f'Dashboard identifier "{e}" is not recognized.')
backend/app/connectors/grafana/services/dashboards.py
+2
@@ -6,6 +6,7 @@ from loguru import logger
6
7 from app.connectors.grafana.schema.dashboards import CarbonBlackDashboard
8 from app.connectors.grafana.schema.dashboards import CrowdstrikeDashboard
9 +from app.connectors.grafana.schema.dashboards import DarktraceDashboard
10 from app.connectors.grafana.schema.dashboards import DashboardProvisionRequest
11 from app.connectors.grafana.schema.dashboards import DuoDashboard
12 from app.connectors.grafana.schema.dashboards import FortinetDashboard
@@ -183,6 +184,7 @@ async def provision_dashboards(
184 + list(FortinetDashboard)
185 + list(CrowdstrikeDashboard)
186 + list(DuoDashboard)
187 + + list(DarktraceDashboard)
188 }
189
190 for dashboard_name in dashboard_request.dashboards:
backend/app/db/db_populate.py
+5
@@ -274,6 +274,7 @@ def get_available_integrations_list():
274 ("CarbonBlack", "Integrate CarbonBlack with SOCFortress."),
275 ("Crowdstrike", "Integrate Crowdstrike with SOCFortress."),
276 ("DUO", "Integrate DUO with SOCFortress."),
277 + ("Darktrace", "Integrate Darktrace with SOCFortress."),
278 # ... Add more available integrations as needed ...
279 ]
280
@@ -389,6 +390,10 @@ async def get_available_integrations_auth_keys_list(session: AsyncSession):
390 ("DUO", "API_HOSTNAME"),
391 ("DUO", "INTEGRATION_KEY"),
392 ("DUO", "SECRET_KEY"),
393 + ("Darktrace", "PUBLIC_TOKEN"),
394 + ("Darktrace", "PRIVATE_TOKEN"),
395 + ("Darktrace", "HOST"),
396 + ("Darktrace", "PORT"),
397 # ... Add more available integrations auth keys as needed ...
398 ]
399 logger.info("Getting available integrations auth keys.")
backend/app/integrations/darktrace/routes/provision.py new
+51
@@ -0,0 +1,51 @@
1 +from fastapi import APIRouter
2 +from fastapi import Depends
3 +from sqlalchemy.ext.asyncio import AsyncSession
4 +
5 +from app.db.db_session import get_db
6 +from app.integrations.darktrace.schema.provision import ProvisionDarktraceRequest
7 +from app.integrations.darktrace.schema.provision import ProvisionDarktraceResponse
8 +from app.integrations.darktrace.services.provision import provision_darktrace
9 +from app.integrations.utils.utils import get_customer_integration_response
10 +from app.schedulers.models.scheduler import CreateSchedulerRequest
11 +from app.schedulers.scheduler import add_scheduler_jobs
12 +
13 +integration_darktrace_provision_router = APIRouter()
14 +
15 +
16 +@integration_darktrace_provision_router.post(
17 + "/provision",
18 + response_model=ProvisionDarktraceResponse,
19 + description="Provision a Darktrace integration.",
20 +)
21 +async def provision_darktrace_route(
22 + provision_darktrace_request: ProvisionDarktraceRequest,
23 + session: AsyncSession = Depends(get_db),
24 +) -> ProvisionDarktraceResponse:
25 + """
26 + Provisions a darktrace integration.
27 +
28 + Args:
29 + provision_darktrace_request (ProvisionDarktraceRequest): The request object containing the necessary data for provisioning.
30 + session (AsyncSession, optional): The database session. Defaults to Depends(get_db).
31 +
32 + Returns:
33 + ProvisionDarktraceResponse: The response object indicating the success or failure of the provisioning process.
34 + """
35 + # Check if the customer integration settings are available and can be provisioned
36 + await get_customer_integration_response(
37 + provision_darktrace_request.customer_code,
38 + session,
39 + )
40 + await provision_darktrace(provision_darktrace_request, session)
41 + await add_scheduler_jobs(
42 + CreateSchedulerRequest(
43 + function_name="invoke_darktrace_integration_collect",
44 + time_interval=provision_darktrace_request.time_interval,
45 + job_id="invoke_darktrace_integration_collect",
46 + ),
47 + )
48 + return ProvisionDarktraceResponse(
49 + success=True,
50 + message="Darktrace integration provisioned successfully.",
51 + )
backend/app/integrations/darktrace/schema/provision.py new
+87
@@ -0,0 +1,87 @@
1 +from typing import Any
2 +from typing import Dict
3 +from typing import List
4 +from typing import Optional
5 +
6 +from pydantic import BaseModel
7 +from pydantic import Field
8 +from pydantic import root_validator
9 +
10 +
11 +class ProvisionDarktraceRequest(BaseModel):
12 + customer_code: str = Field(
13 + ...,
14 + description="The customer code.",
15 + examples=["00002"],
16 + )
17 + time_interval: int = Field(
18 + 15,
19 + description="The time interval for the scheduler.",
20 + examples=[15],
21 + )
22 + integration_name: str = Field(
23 + "Darktrace",
24 + description="The integration name.",
25 + examples=["Darktrace"],
26 + )
27 +
28 + # ensure the `integration_name` is always set to "Mimecast"
29 + @root_validator(pre=True)
30 + def set_integration_name(cls, values: Dict[str, Any]) -> Dict[str, Any]:
31 + values["integration_name"] = "Darktrace"
32 + return values
33 +
34 +
35 +class ProvisionDarktraceResponse(BaseModel):
36 + success: bool
37 + message: str
38 +
39 +
40 +# ! STREAMS ! #
41 +class StreamRule(BaseModel):
42 + field: str
43 + type: int
44 + inverted: bool
45 + value: str
46 +
47 +
48 +class DarktraceEventStream(BaseModel):
49 + title: str = Field(..., description="Title of the stream")
50 + description: str = Field(..., description="Description of the stream")
51 + index_set_id: str = Field(..., description="ID of the associated index set")
52 + rules: List[StreamRule] = Field(..., description="List of rules for the stream")
53 + matching_type: str = Field(..., description="Matching type for the rules")
54 + remove_matches_from_default_stream: bool = Field(
55 + ...,
56 + description="Whether to remove matches from the default stream",
57 + )
58 + content_pack: Optional[str] = Field(
59 + None,
60 + description="Associated content pack, if any",
61 + )
62 +
63 + class Config:
64 + schema_extra = {
65 + "example": {
66 + "title": "Darktrace SIEM EVENTS - Example Company",
67 + "description": "Darktrace SIEM EVENTS - Example Company",
68 + "index_set_id": "12345",
69 + "rules": [
70 + {
71 + "field": "customer_code",
72 + "type": 1,
73 + "inverted": False,
74 + "value": "ExampleCode",
75 + },
76 + {
77 + "field": "integration",
78 + "type": 1,
79 + "inverted": False,
80 + "value": "darktrace",
81 + },
82 + ],
83 + "matching_type": "AND",
84 + "remove_matches_from_default_stream": True,
85 + "content_pack": None,
86 + },
87 + }
backend/app/integrations/darktrace/services/provision.py new
+397
@@ -0,0 +1,397 @@
1 +import json
2 +from datetime import datetime
3 +
4 +from loguru import logger
5 +from sqlalchemy import and_
6 +from sqlalchemy import update
7 +from sqlalchemy.ext.asyncio import AsyncSession
8 +
9 +from app.connectors.grafana.schema.dashboards import DarktraceDashboard
10 +from app.connectors.grafana.schema.dashboards import DashboardProvisionRequest
11 +from app.connectors.grafana.services.dashboards import provision_dashboards
12 +from app.connectors.grafana.utils.universal import create_grafana_client
13 +from app.connectors.graylog.services.management import start_stream
14 +from app.connectors.graylog.utils.universal import send_post_request
15 +from app.connectors.wazuh_indexer.services.monitoring import (
16 + output_shard_number_to_be_set_based_on_nodes,
17 +)
18 +from app.customer_provisioning.schema.grafana import GrafanaDatasource
19 +from app.customer_provisioning.schema.grafana import GrafanaDataSourceCreationResponse
20 +from app.customer_provisioning.schema.graylog import GraylogIndexSetCreationResponse
21 +from app.customer_provisioning.schema.graylog import StreamCreationResponse
22 +from app.customer_provisioning.schema.graylog import TimeBasedIndexSet
23 +from app.customer_provisioning.services.grafana import create_grafana_folder
24 +from app.customer_provisioning.services.grafana import get_opensearch_version
25 +from app.customers.routes.customers import get_customer
26 +from app.customers.routes.customers import get_customer_meta
27 +from app.integrations.darktrace.schema.provision import DarktraceEventStream
28 +from app.integrations.darktrace.schema.provision import ProvisionDarktraceRequest
29 +from app.integrations.darktrace.schema.provision import ProvisionDarktraceResponse
30 +from app.integrations.models.customer_integration_settings import CustomerIntegrations
31 +from app.integrations.routes import create_integration_meta
32 +from app.integrations.schema import CustomerIntegrationsMetaSchema
33 +from app.utils import get_connector_attribute
34 +
35 +
36 +################## ! GRAYLOG ! ##################
37 +async def build_index_set_config(
38 + customer_code: str,
39 + session: AsyncSession,
40 +) -> TimeBasedIndexSet:
41 + """
42 + Build the configuration for a time-based index set.
43 +
44 + Args:
45 + request (ProvisionNewCustomer): The request object containing customer information.
46 +
47 + Returns:
48 + TimeBasedIndexSet: The configured time-based index set.
49 + """
50 + return TimeBasedIndexSet(
51 + title=f"{(await get_customer(customer_code, session)).customer.customer_name} - DARKTRACE",
52 + description=f"{customer_code} - DARKTRACE",
53 + index_prefix=f"darktrace-{customer_code.lower()}-",
54 + rotation_strategy_class="org.graylog2.indexer.rotation.strategies.TimeBasedRotationStrategy",
55 + rotation_strategy={
56 + "type": "org.graylog2.indexer.rotation.strategies.TimeBasedRotationStrategyConfig",
57 + "rotation_period": "P1D",
58 + "rotate_empty_index_set": False,
59 + "max_rotation_period": None,
60 + },
61 + retention_strategy_class="org.graylog2.indexer.retention.strategies.DeletionRetentionStrategy",
62 + retention_strategy={
63 + "type": "org.graylog2.indexer.retention.strategies.DeletionRetentionStrategyConfig",
64 + "max_number_of_indices": 30,
65 + },
66 + creation_date=datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%S.%fZ"),
67 + index_analyzer="standard",
68 + shards=await output_shard_number_to_be_set_based_on_nodes(),
69 + replicas=0,
70 + index_optimization_max_num_segments=1,
71 + index_optimization_disabled=False,
72 + writable=True,
73 + field_type_refresh_interval=5000,
74 + )
75 +
76 +
77 +# Function to send the POST request and handle the response
78 +async def send_index_set_creation_request(
79 + index_set: TimeBasedIndexSet,
80 +) -> GraylogIndexSetCreationResponse:
81 + """
82 + Sends a request to create an index set in Graylog.
83 +
84 + Args:
85 + index_set (TimeBasedIndexSet): The index set to be created.
86 +
87 + Returns:
88 + GraylogIndexSetCreationResponse: The response from Graylog after creating the index set.
89 + """
90 + json_index_set = json.dumps(index_set.dict())
91 + logger.info(f"json_index_set set: {json_index_set}")
92 + response_json = await send_post_request(
93 + endpoint="/api/system/indices/index_sets",
94 + data=index_set.dict(),
95 + )
96 + return GraylogIndexSetCreationResponse(**response_json)
97 +
98 +
99 +async def create_index_set(
100 + customer_code: str,
101 + session: AsyncSession,
102 +) -> GraylogIndexSetCreationResponse:
103 + """
104 + Creates an index set for a new customer.
105 +
106 + Args:
107 + request (ProvisionNewCustomer): The request object containing the customer information.
108 +
109 + Returns:
110 + GraylogIndexSetCreationResponse: The response object containing the result of the index set creation.
111 + """
112 + logger.info(f"Creating index set for customer {customer_code}")
113 + index_set_config = await build_index_set_config(customer_code, session)
114 + return await send_index_set_creation_request(index_set_config)
115 +
116 +
117 +# ! Event STREAMS ! #
118 +# Function to create event stream configuration
119 +async def build_event_stream_config(
120 + customer_code: str,
121 + index_set_id: str,
122 + session: AsyncSession,
123 +) -> DarktraceEventStream:
124 + """
125 + Builds the configuration for the Darktrace event stream.
126 +
127 + Args:
128 + customer_code (str): The customer code.
129 + index_set_id (str): The index set ID.
130 + session (AsyncSession): The async session.
131 +
132 + Returns:
133 + DarktraceEventStream: The configured Darktrace event stream.
134 + """
135 + return DarktraceEventStream(
136 + title=f"{(await get_customer(customer_code, session)).customer.customer_name} - DARKTRACE",
137 + description=f"{(await get_customer(customer_code, session)).customer.customer_name} - DARKTRACE",
138 + index_set_id=index_set_id,
139 + rules=[
140 + {
141 + "field": "integration",
142 + "type": 1,
143 + "inverted": False,
144 + "value": "darktrace",
145 + },
146 + {
147 + "field": "customer_code",
148 + "type": 1,
149 + "inverted": False,
150 + "value": f"{customer_code}",
151 + },
152 + ],
153 + matching_type="AND",
154 + remove_matches_from_default_stream=True,
155 + content_pack=None,
156 + )
157 +
158 +
159 +async def send_event_stream_creation_request(
160 + event_stream: DarktraceEventStream,
161 +) -> StreamCreationResponse:
162 + """
163 + Sends a request to create an event stream.
164 +
165 + Args:
166 + event_stream (SapSiemEventStream): The event stream to be created.
167 +
168 + Returns:
169 + StreamCreationResponse: The response containing the created event stream.
170 + """
171 + json_event_stream = json.dumps(event_stream.dict())
172 + logger.info(f"json_event_stream set: {json_event_stream}")
173 + response_json = await send_post_request(
174 + endpoint="/api/streams",
175 + data=event_stream.dict(),
176 + )
177 + return StreamCreationResponse(**response_json)
178 +
179 +
180 +async def create_event_stream(
181 + customer_code: str,
182 + index_set_id: str,
183 + session: AsyncSession,
184 +) -> StreamCreationResponse:
185 + """
186 + Creates an event stream for a customer.
187 +
188 + Args:
189 + request (ProvisionNewCustomer): The request object containing customer information.
190 + index_set_id (str): The ID of the index set.
191 +
192 + Returns:
193 + The result of the event stream creation request.
194 + """
195 + event_stream_config = await build_event_stream_config(
196 + customer_code,
197 + index_set_id,
198 + session,
199 + )
200 + return await send_event_stream_creation_request(event_stream_config)
201 +
202 +
203 +#### ! GRAFANA ! ####
204 +async def create_grafana_datasource(
205 + customer_code: str,
206 + session: AsyncSession,
207 +) -> GrafanaDataSourceCreationResponse:
208 + """
209 + Creates a Grafana datasource for the specified customer.
210 +
211 + Args:
212 + customer_code (str): The customer code.
213 + session (AsyncSession): The async session.
214 +
215 + Returns:
216 + GrafanaDataSourceCreationResponse: The response containing the created datasource details.
217 + """
218 + logger.info("Creating Grafana datasource")
219 + grafana_client = await create_grafana_client("Grafana")
220 + # Switch to the newly created organization
221 + grafana_client.user.switch_actual_user_organisation(
222 + (await get_customer_meta(customer_code, session)).customer_meta.customer_meta_grafana_org_id,
223 + )
224 + datasource_payload = GrafanaDatasource(
225 + name="DARKTRACE",
226 + type="grafana-opensearch-datasource",
227 + typeName="OpenSearch",
228 + access="proxy",
229 + url=await get_connector_attribute(
230 + connector_id=1,
231 + column_name="connector_url",
232 + session=session,
233 + ),
234 + database=f"darktrace-{customer_code}*",
235 + basicAuth=True,
236 + basicAuthUser=await get_connector_attribute(
237 + connector_id=1,
238 + column_name="connector_username",
239 + session=session,
240 + ),
241 + secureJsonData={
242 + "basicAuthPassword": await get_connector_attribute(
243 + connector_id=1,
244 + column_name="connector_password",
245 + session=session,
246 + ),
247 + },
248 + isDefault=False,
249 + jsonData={
250 + "database": f"darktrace-{customer_code}*",
251 + "flavor": "opensearch",
252 + "includeFrozen": False,
253 + "logLevelField": "severity",
254 + "logMessageField": "summary",
255 + "maxConcurrentShardRequests": 5,
256 + "pplEnabled": True,
257 + "timeField": "timestamp",
258 + "tlsSkipVerify": True,
259 + "version": await get_opensearch_version(),
260 + },
261 + readOnly=True,
262 + )
263 + results = grafana_client.datasource.create_datasource(
264 + datasource=datasource_payload.dict(),
265 + )
266 + return GrafanaDataSourceCreationResponse(**results)
267 +
268 +
269 +async def provision_darktrace(
270 + provision_darktrace_request: ProvisionDarktraceRequest,
271 + session: AsyncSession,
272 +) -> ProvisionDarktraceResponse:
273 + logger.info(
274 + f"Provisioning Darktrace integration for customer {provision_darktrace_request.customer_code}.",
275 + )
276 +
277 + # Create Index Set
278 + index_set_id = (
279 + await create_index_set(
280 + customer_code=provision_darktrace_request.customer_code,
281 + session=session,
282 + )
283 + ).data.id
284 + logger.info(f"Index set: {index_set_id}")
285 + # Create event stream
286 + stream_id = (
287 + await create_event_stream(
288 + provision_darktrace_request.customer_code,
289 + index_set_id,
290 + session,
291 + )
292 + ).data.stream_id
293 + # Start stream
294 + await start_stream(stream_id=stream_id)
295 +
296 + # Grafana Deployment
297 + darktrace_datasource_uid = (
298 + await create_grafana_datasource(
299 + customer_code=provision_darktrace_request.customer_code,
300 + session=session,
301 + )
302 + ).datasource.uid
303 + grafana_darktrace_folder_id = (
304 + await create_grafana_folder(
305 + organization_id=(
306 + await get_customer_meta(
307 + provision_darktrace_request.customer_code,
308 + session,
309 + )
310 + ).customer_meta.customer_meta_grafana_org_id,
311 + folder_title="DARKTRACE",
312 + )
313 + ).id
314 + await provision_dashboards(
315 + DashboardProvisionRequest(
316 + dashboards=[dashboard.name for dashboard in DarktraceDashboard],
317 + organizationId=(
318 + await get_customer_meta(
319 + provision_darktrace_request.customer_code,
320 + session,
321 + )
322 + ).customer_meta.customer_meta_grafana_org_id,
323 + folderId=grafana_darktrace_folder_id,
324 + datasourceUid=darktrace_datasource_uid,
325 + ),
326 + )
327 + await create_integration_meta_entry(
328 + CustomerIntegrationsMetaSchema(
329 + customer_code=provision_darktrace_request.customer_code,
330 + integration_name="Darktrace",
331 + graylog_input_id=None,
332 + graylog_index_id=index_set_id,
333 + graylog_stream_id=stream_id,
334 + grafana_org_id=(
335 + await get_customer_meta(
336 + provision_darktrace_request.customer_code,
337 + session,
338 + )
339 + ).customer_meta.customer_meta_grafana_org_id,
340 + grafana_dashboard_folder_id=grafana_darktrace_folder_id,
341 + ),
342 + session,
343 + )
344 + await update_customer_integration_table(
345 + provision_darktrace_request.customer_code,
346 + session,
347 + )
348 +
349 + return ProvisionDarktraceResponse(
350 + success=True,
351 + message="Darktrace integration provisioned successfully.",
352 + )
353 +
354 +
355 +############## ! WRITE TO DB ! ##############
356 +async def create_integration_meta_entry(
357 + customer_integration_meta: CustomerIntegrationsMetaSchema,
358 + session: AsyncSession,
359 +) -> None:
360 + """
361 + Creates an entry for the customer integration meta in the database.
362 +
363 + Args:
364 + customer_integration_meta (CustomerIntegrationsMetaSchema): The customer integration meta object.
365 + session (AsyncSession): The async session object for database operations.
366 + """
367 + await create_integration_meta(customer_integration_meta, session)
368 + logger.info(
369 + f"Integration meta entry created for customer {customer_integration_meta.customer_code}.",
370 + )
371 +
372 +
373 +async def update_customer_integration_table(
374 + customer_code: str,
375 + session: AsyncSession,
376 +) -> None:
377 + """
378 + Updates the `customer_integrations` table to set the `deployed` column to True where the `customer_code`
379 + matches the given customer code and the `integration_service_name` is "Darktrace".
380 +
381 + Args:
382 + customer_code (str): The customer code.
383 + session (AsyncSession): The async session object for making HTTP requests.
384 + """
385 + await session.execute(
386 + update(CustomerIntegrations)
387 + .where(
388 + and_(
389 + CustomerIntegrations.customer_code == customer_code,
390 + CustomerIntegrations.integration_service_name == "Darktrace",
391 + ),
392 + )
393 + .values(deployed=True),
394 + )
395 + await session.commit()
396 +
397 + return None
backend/app/integrations/markdown/darktrace.md new
+48
@@ -0,0 +1,48 @@
1 +# Darktrace Integration
2 +
3 +The Darktrace integration allows you to monitor Alert Logs. Darktrace is a network solution for detecting and investigating emerging cyber-threats that evade traditional security tools. It is powered by Enterprise Immune System technology, which uses machine learning and mathematics to monitor behaviors and detect anomalies in your organization’s network.
4 +
5 +For example, you could use the data from this integration to know which model is breached and analyse model breaches, and also know about system health, changes in monitored traffic, and any errors experienced by Darktrace Security Modules or probe instances.
6 +
7 +# Data Streams
8 +
9 +The Darktrace integration collects logs for three types of events:
10 +
11 +## AI Analyst Alert
12 +
13 +Generated by AI that investigates, analyzes, and reports threats within the Darktrace environment. It reviews all Model Breaches and creates events for behaviors of interest to cyber analysts.
14 +
15 +## Model Breach Alert
16 +
17 +Triggered when a model breach occurs. Models define conditions that alert the system to anomalous behavior, malicious activity, or compliance issues.
18 +
19 +## System Status Alert
20 +
21 +Informs operators of system health, traffic changes, and errors. Includes host details, event severity, and useful investigation links. Notifications are sent for active and resolved events.
22 +
23 +## Acquiring the API Token Pair
24 +
25 +An API token pair is required for each Master instance.
26 +
27 +### Per-user Token
28 +
29 +API tokens can only be created by local users with granted API access permissions.
30 +
31 +1. Navigate to the Permissions Admin page (Main Menu - Admin) on the Threat Visualizer.
32 +2. Locate the user and enable "API Access".
33 +3. Log in as the user intended for API access, navigate to Account Settings, and generate new API tokens.
34 +4. Record the Public and Private tokens securely.
35 +
36 +### Global Token
37 +
38 +Requires access to the System Config page and appropriate permissions.
39 +
40 +1. Navigate to the System Config page on the Threat Visualizer.
41 +2. Select "Settings" and generate new API tokens.
42 +3. Record the Public and Private tokens securely.
43 +
44 +## Token Usage
45 +
46 +Both tokens are required to generate the DT-API Signature, which must be included with every API request.
47 +
48 +For more details, refer to the Darktrace Threat Visualizer API Guide.
backend/app/integrations/modules/routes/darktrace.py new
+91
@@ -0,0 +1,91 @@
1 +from fastapi import APIRouter
2 +from fastapi import Depends
3 +from loguru import logger
4 +from sqlalchemy.ext.asyncio import AsyncSession
5 +
6 +from app.db.db_session import get_db
7 +from app.integrations.modules.schema.darktrace import CollectDarktrace
8 +from app.integrations.modules.schema.darktrace import DarktraceAuthKeys
9 +from app.integrations.modules.schema.darktrace import InvokeDarktraceRequest
10 +from app.integrations.modules.schema.darktrace import InvokeDarktraceResponse
11 +from app.integrations.modules.services.darktrace import post_to_copilot_darktrace_module
12 +from app.integrations.routes import find_customer_integration
13 +from app.integrations.utils.utils import extract_auth_keys
14 +from app.integrations.utils.utils import get_customer_integration_response
15 +from app.utils import get_connector_attribute
16 +
17 +module_darktrace_router = APIRouter()
18 +
19 +
20 +async def get_darktrace_auth_keys(customer_integration) -> DarktraceAuthKeys:
21 + """
22 + Extract the Darktrace authentication keys from the CustomerIntegration.
23 +
24 + Args:
25 + customer_integration (CustomerIntegration): The CustomerIntegration containing the
26 + Darktrace authentication keys.
27 +
28 + Returns:
29 + DarktraceAuthKeys: The extracted Darktrace authentication keys.
30 + """
31 + darktrace_auth_keys = extract_auth_keys(
32 + customer_integration,
33 + service_name="Darktrace",
34 + )
35 +
36 + return DarktraceAuthKeys(**darktrace_auth_keys)
37 +
38 +
39 +async def get_collect_darktrace_data(darktrace_request, session, auth_keys):
40 + return CollectDarktrace(
41 + integration="darktrace",
42 + customer_code=darktrace_request.customer_code,
43 + graylog_host=await get_connector_attribute(
44 + connector_id=14,
45 + column_name="connector_url",
46 + session=session,
47 + ),
48 + graylog_port=await get_connector_attribute(
49 + connector_id=14,
50 + column_name="connector_extra_data",
51 + session=session,
52 + ),
53 + public_token=auth_keys.PUBLIC_TOKEN,
54 + private_token=auth_keys.PRIVATE_TOKEN,
55 + darktrace_host=auth_keys.HOST,
56 + darktrace_port=auth_keys.PORT,
57 + timeframe="15m",
58 + )
59 +
60 +
61 +@module_darktrace_router.post(
62 + "",
63 + response_model=InvokeDarktraceResponse,
64 + description="Invoke the Darktrace module.",
65 +)
66 +async def collect_darktrace_route(darktrace_request: InvokeDarktraceRequest, session: AsyncSession = Depends(get_db)):
67 + """Pull down Darktrace Events."""
68 + logger.info(f"Invoke Darktrace Request: {darktrace_request}")
69 + try:
70 + customer_integration_response = await get_customer_integration_response(
71 + darktrace_request.customer_code,
72 + session,
73 + )
74 +
75 + customer_integration = await find_customer_integration(
76 + darktrace_request.customer_code,
77 + darktrace_request.integration_name,
78 + customer_integration_response,
79 + )
80 +
81 + auth_keys = await get_darktrace_auth_keys(customer_integration)
82 +
83 + collect_darktrace_data = await get_collect_darktrace_data(darktrace_request, session, auth_keys)
84 +
85 + await post_to_copilot_darktrace_module(data=collect_darktrace_data)
86 +
87 + except Exception as e:
88 + logger.error(f"Error during DB session: {str(e)}")
89 + return InvokeDarktraceResponse(success=False, message=str(e))
90 +
91 + return InvokeDarktraceResponse(success=True, message="Darktrace Events collected successfully.")
backend/app/integrations/modules/schema/darktrace.py new
+83
@@ -0,0 +1,83 @@
1 +from fastapi import HTTPException
2 +from pydantic import BaseModel
3 +from pydantic import Field
4 +from pydantic import validator
5 +
6 +
7 +class InvokeDarktraceRequest(BaseModel):
8 + customer_code: str = Field(
9 + ...,
10 + description="The customer code.",
11 + examples=["00002"],
12 + )
13 + integration_name: str = Field(
14 + "Darktrace",
15 + description="The integration name.",
16 + examples=["Darktrace"],
17 + )
18 +
19 +
20 +class DarktraceAuthKeys(BaseModel):
21 + PUBLIC_TOKEN: str = Field(
22 + ...,
23 + description="The API key.",
24 + examples=["123456"],
25 + )
26 + PRIVATE_TOKEN: str = Field(
27 + ...,
28 + description="The integration key.",
29 + examples=["123456"],
30 + )
31 + HOST: str = Field(
32 + ...,
33 + description="The secret key.",
34 + examples=["123456"],
35 + )
36 + PORT: str = Field(
37 + ...,
38 + description="The secret key.",
39 + examples=["123456"],
40 + )
41 +
42 +
43 +class InvokeDarktraceResponse(BaseModel):
44 + success: bool = Field(
45 + ...,
46 + description="The success status.",
47 + examples=[True],
48 + )
49 + message: str = Field(
50 + ...,
51 + description="The message.",
52 + examples=["Darktrace Events collected successfully."],
53 + )
54 +
55 +
56 +class CollectDarktrace(BaseModel):
57 + integration: str = Field(..., example="darktrace")
58 + customer_code: str = Field(..., example="socfortress")
59 + graylog_host: str = Field(..., example="127.0.0.1")
60 + graylog_port: str = Field(..., example=12201)
61 + public_token: str = Field(..., example="public_token")
62 + private_token: str = Field(..., example="private_token")
63 + darktrace_host: str = Field(..., example="https://darktrace.local")
64 + darktrace_port: str = Field(..., example=2026)
65 + timeframe: str = Field(..., example="15m")
66 +
67 + @validator("integration")
68 + def check_integration(cls, v):
69 + if v != "darktrace":
70 + raise HTTPException(
71 + status_code=400,
72 + detail="Invalid integration. Only 'darktrace' is supported.",
73 + )
74 + return v
75 +
76 + @validator("timeframe")
77 + def validate_range(cls, v):
78 + if not v.endswith(("m", "h", "d")):
79 + raise HTTPException(
80 + status_code=400,
81 + detail="Invalid range. Use 'm' for minutes, 'h' for hours, or 'd' for days.",
82 + )
83 + return v
backend/app/integrations/modules/services/darktrace.py new
+21
@@ -0,0 +1,21 @@
1 +import httpx
2 +from loguru import logger
3 +
4 +from app.integrations.modules.schema.darktrace import CollectDarktrace
5 +
6 +
7 +async def post_to_copilot_darktrace_module(data: CollectDarktrace):
8 + """
9 + Send a POST request to the copilot-darktrace-module Docker container.
10 +
11 + Args:
12 + data (CollectDarktrace): The data to send to the copilot-darktrace-module Docker container.
13 + """
14 + logger.info(f"Sending POST request to http://copilot-darktrace-module/all_logs with data: {data.dict()}")
15 + async with httpx.AsyncClient() as client:
16 + await client.post(
17 + "http://copilot-darktrace-module/all_logs",
18 + json=data.dict(),
19 + timeout=120,
20 + )
21 + return None
backend/app/routers/darktrace.py new
+15
@@ -0,0 +1,15 @@
1 +from fastapi import APIRouter
2 +
3 +from app.integrations.darktrace.routes.provision import (
4 + integration_darktrace_provision_router,
5 +)
6 +
7 +# Instantiate the APIRouter
8 +router = APIRouter()
9 +
10 +# Include the Duo Provision APIRouter
11 +router.include_router(
12 + integration_darktrace_provision_router,
13 + prefix="/darktrace",
14 + tags=["darktrace"],
15 +)
backend/app/schedulers/scheduler.py
+4
@@ -17,6 +17,9 @@ from app.schedulers.services.agent_sync import agent_sync
17 from app.schedulers.services.invoke_carbonblack import (
18 invoke_carbonblack_integration_collect,
19 )
20 +from app.schedulers.services.invoke_darktrace import (
21 + invoke_darktrace_integration_collect,
22 +)
23 from app.schedulers.services.invoke_duo import invoke_duo_integration_collect
24 from app.schedulers.services.invoke_huntress import invoke_huntress_integration_collect
25 from app.schedulers.services.invoke_mimecast import invoke_mimecast_integration
@@ -211,6 +214,7 @@ def get_function_by_name(function_name: str):
214 "invoke_sap_siem_integration_successful_login_after_multiple_failed_logins": invoke_sap_siem_integration_successful_login_after_multiple_failed_logins,
215 "invoke_huntress_integration_collection": invoke_huntress_integration_collect,
216 "invoke_duo_integration_collect": invoke_duo_integration_collect,
217 + "invoke_darktrace_integration_collect": invoke_darktrace_integration_collect,
218 "invoke_carbonblack_integration_collection": invoke_carbonblack_integration_collect,
219 # Add other function mappings here
220 }
backend/app/schedulers/services/invoke_darktrace.py new
+52
@@ -0,0 +1,52 @@
1 +from datetime import datetime
2 +
3 +from dotenv import load_dotenv
4 +from loguru import logger
5 +from sqlalchemy import select
6 +
7 +from app.db.db_session import get_db_session
8 +from app.db.db_session import get_sync_db_session
9 +from app.integrations.models.customer_integration_settings import CustomerIntegrations
10 +from app.integrations.modules.routes.darktrace import collect_darktrace_route
11 +from app.integrations.modules.schema.darktrace import InvokeDarktraceRequest
12 +from app.integrations.modules.schema.darktrace import InvokeDarktraceResponse
13 +from app.schedulers.models.scheduler import JobMetadata
14 +
15 +load_dotenv()
16 +
17 +
18 +async def invoke_darktrace_integration_collect() -> InvokeDarktraceResponse:
19 + """
20 + Invokes the Darktrace integration collection.
21 + """
22 + logger.info("Invoking Darktrace integration collection.")
23 + customer_codes = []
24 + async with get_db_session() as session:
25 + stmt = select(CustomerIntegrations).where(
26 + CustomerIntegrations.integration_service_name == "Darktrace",
27 + )
28 + result = await session.execute(stmt)
29 + customer_codes = [row.customer_code for row in result.scalars()]
30 + logger.info(f"customer_codes: {customer_codes}")
31 + for customer_code in customer_codes:
32 + await collect_darktrace_route(
33 + InvokeDarktraceRequest(
34 + customer_code=customer_code,
35 + integration_name="Darktrace",
36 + ),
37 + session,
38 + )
39 + # Close the session
40 + await session.close()
41 + with get_sync_db_session() as session:
42 + # Synchronous ORM operations
43 + job_metadata = session.query(JobMetadata).filter_by(job_id="invoke_darktrace_integration_collect").one_or_none()
44 + if job_metadata:
45 + job_metadata.last_success = datetime.utcnow()
46 + session.add(job_metadata)
47 + session.commit()
48 + else:
49 + # Handle the case where job_metadata does not exist
50 + print("JobMetadata for 'invoke_darktrace_integration_collect' not found.")
51 +
52 + return InvokeDarktraceResponse(success=True, message="Darktrace integration invoked.")
backend/copilot.py
+2
@@ -39,6 +39,7 @@ from app.routers import cortex
39 from app.routers import crowdstrike
40 from app.routers import customer_provisioning
41 from app.routers import customers
42 +from app.routers import darktrace
43 from app.routers import dfir_iris
44 from app.routers import dnstwist
45 from app.routers import duo
@@ -148,6 +149,7 @@ api_router.include_router(crowdstrike.router)
149 api_router.include_router(scoutsuite.router)
150 api_router.include_router(nuclei.router)
151 api_router.include_router(duo.router)
152 +api_router.include_router(darktrace.router)
153
154 # Include the APIRouter in the FastAPI app
155 app.include_router(api_router)
frontend/package-lock.json
+461 -549
@@ -14,10 +14,10 @@
14 "@fontsource/lexend": "^5.0.20",
15 "@fontsource/public-sans": "^5.0.18",
16 "@popperjs/core": "^2.11.8",
17 - "@shikijs/markdown-it": "^1.9.1",
17 + "@shikijs/markdown-it": "^1.10.3",
18 "@vueuse/components": "^10.11.0",
19 "@vueuse/core": "^10.11.0",
20 - "apexcharts": "^3.49.2",
20 + "apexcharts": "^3.50.0",
21 "bytes": "^3.1.2",
22 "colord": "^2.9.3",
23 "crypto-js": "^4.2.0",
@@ -26,7 +26,7 @@
26 "echarts": "^5.5.1",
27 "file-saver": "^2.0.5",
28 "html-entities": "^2.5.2",
29 - "jose": "^5.6.2",
29 + "jose": "^5.6.3",
30 "js-md5": "^0.8.3",
31 "lodash": "^4.17.21",
32 "mitt": "^3.0.1",
@@ -35,7 +35,7 @@
35 "pinia": "^2.1.7",
36 "pinia-plugin-persistedstate": "^3.2.1",
37 "secure-ls": "^2.0.0",
38 - "shiki": "^1.9.1",
38 + "shiki": "^1.10.3",
39 "validator": "^13.12.0",
40 "vue": "^3.4.31",
41 "vue-advanced-cropper": "^2.8.9",
@@ -57,7 +57,7 @@
57 "@types/inquirer": "^9.0.7",
58 "@types/jsdom": "^21.1.7",
59 "@types/lodash": "^4.17.6",
60 - "@types/node": "^20.14.9",
60 + "@types/node": "^20.14.10",
61 "@types/validator": "^13.12.0",
62 "@vitejs/plugin-vue": "^5.0.5",
63 "@vitejs/plugin-vue-jsx": "^4.0.0",
@@ -66,39 +66,39 @@
66 "@vue/test-utils": "^2.4.6",
67 "@vue/tsconfig": "^0.5.1",
68 "autoprefixer": "^10.4.19",
69 - "cypress": "^13.12.0",
70 - "eslint": "^9.5.0",
69 + "cypress": "^13.13.0",
70 + "eslint": "^9.6.0",
71 "eslint-plugin-cypress": "^3.3.0",
72 - "eslint-plugin-vue": "^9.26.0",
72 + "eslint-plugin-vue": "^9.27.0",
73 "flourite": "^1.3.0",
74 "fs-extra": "^11.2.0",
75 - "globals": "^15.6.0",
75 + "globals": "^15.8.0",
76 "jsdom": "^24.1.0",
77 "json5": "^2.2.3",
78 - "npm-run-all2": "^6.2.0",
78 + "npm-run-all2": "^6.2.2",
79 "picocolors": "^1.0.1",
80 - "postcss": "^8.4.38",
80 + "postcss": "^8.4.39",
81 "prettier": "^3.3.2",
82 "sass": "^1.77.6",
83 "start-server-and-test": "^2.0.4",
84 "tailwind-config-viewer": "^2.0.4",
85 "tailwindcss": "^3.4.4",
86 - "taze": "^0.13.9",
87 - "type-fest": "^4.20.1",
86 + "taze": "^0.14.2",
87 + "type-fest": "^4.21.0",
88 "unplugin-vue-components": "^0.27.2",
89 - "vite": "^5.3.2",
89 + "vite": "^5.3.3",
90 "vite-bundle-analyzer": "^0.10.3",
91 "vite-bundle-visualizer": "^1.2.1",
92 - "vite-plugin-vue-devtools": "^7.3.4",
92 + "vite-plugin-vue-devtools": "^7.3.5",
93 "vite-svg-loader": "^5.1.0",
94 - "vitest": "^1.6.0",
95 - "vue-tsc": "^2.0.22"
94 + "vitest": "^2.0.1",
95 + "vue-tsc": "^2.0.26"
96 },
97 "engines": {
98 "node": ">=18.0.0"
99 },
100 "optionalDependencies": {
101 - "@rollup/rollup-linux-x64-gnu": "^4.18.0"
101 + "@rollup/rollup-linux-x64-gnu": "^4.18.1"
102 }
103 },
104 "node_modules/@ajoelp/json-to-formdata": {
@@ -1209,13 +1209,13 @@
1209 }
1210 },
1211 "node_modules/@eslint/config-array": {
1212 - "version": "0.16.0",
1213 - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.16.0.tgz",
1214 - "integrity": "sha512-/jmuSd74i4Czf1XXn7wGRWZCuyaUZ330NH1Bek0Pplatt4Sy1S5haN21SCLLdbeKslQ+S0wEJ+++v5YibSi+Lg==",
1212 + "version": "0.17.0",
1213 + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.17.0.tgz",
1214 + "integrity": "sha512-A68TBu6/1mHHuc5YJL0U0VVeGNiklLAL6rRmhTCP2B5XjWLMnrX+HkO+IAXyHvks5cyyY1jjK5ITPQ1HGS2EVA==",
1215 "dependencies": {
1216 "@eslint/object-schema": "^2.1.4",
1217 "debug": "^4.3.1",
1218 - "minimatch": "^3.0.5"
1218 + "minimatch": "^3.1.2"
1219 },
1220 "engines": {
1221 "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -1839,9 +1839,9 @@
1839 }
1840 },
1841 "node_modules/@rollup/rollup-android-arm-eabi": {
1842 - "version": "4.18.0",
1843 - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.18.0.tgz",
1844 - "integrity": "sha512-Tya6xypR10giZV1XzxmH5wr25VcZSncG0pZIjfePT0OVBvqNEurzValetGNarVrGiq66EBVAFn15iYX4w6FKgQ==",
1842 + "version": "4.18.1",
1843 + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.18.1.tgz",
1844 + "integrity": "sha512-lncuC4aHicncmbORnx+dUaAgzee9cm/PbIqgWz1PpXuwc+sa1Ct83tnqUDy/GFKleLiN7ZIeytM6KJ4cAn1SxA==",
1845 "cpu": [
1846 "arm"
1847 ],
@@ -1852,9 +1852,9 @@
1852 ]
1853 },
1854 "node_modules/@rollup/rollup-android-arm64": {
1855 - "version": "4.18.0",
1856 - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.18.0.tgz",
1857 - "integrity": "sha512-avCea0RAP03lTsDhEyfy+hpfr85KfyTctMADqHVhLAF3MlIkq83CP8UfAHUssgXTYd+6er6PaAhx/QGv4L1EiA==",
1855 + "version": "4.18.1",
1856 + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.18.1.tgz",
1857 + "integrity": "sha512-F/tkdw0WSs4ojqz5Ovrw5r9odqzFjb5LIgHdHZG65dFI1lWTWRVy32KDJLKRISHgJvqUeUhdIvy43fX41znyDg==",
1858 "cpu": [
1859 "arm64"
1860 ],
@@ -1865,9 +1865,9 @@
1865 ]
1866 },
1867 "node_modules/@rollup/rollup-darwin-arm64": {
1868 - "version": "4.18.0",
1869 - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.18.0.tgz",
1870 - "integrity": "sha512-IWfdwU7KDSm07Ty0PuA/W2JYoZ4iTj3TUQjkVsO/6U+4I1jN5lcR71ZEvRh52sDOERdnNhhHU57UITXz5jC1/w==",
1868 + "version": "4.18.1",
1869 + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.18.1.tgz",
1870 + "integrity": "sha512-vk+ma8iC1ebje/ahpxpnrfVQJibTMyHdWpOGZ3JpQ7Mgn/3QNHmPq7YwjZbIE7km73dH5M1e6MRRsnEBW7v5CQ==",
1871 "cpu": [
1872 "arm64"
1873 ],
@@ -1878,9 +1878,9 @@
1878 ]
1879 },
1880 "node_modules/@rollup/rollup-darwin-x64": {
1881 - "version": "4.18.0",
1882 - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.18.0.tgz",
1883 - "integrity": "sha512-n2LMsUz7Ynu7DoQrSQkBf8iNrjOGyPLrdSg802vk6XT3FtsgX6JbE8IHRvposskFm9SNxzkLYGSq9QdpLYpRNA==",
1881 + "version": "4.18.1",
1882 + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.18.1.tgz",
1883 + "integrity": "sha512-IgpzXKauRe1Tafcej9STjSSuG0Ghu/xGYH+qG6JwsAUxXrnkvNHcq/NL6nz1+jzvWAnQkuAJ4uIwGB48K9OCGA==",
1884 "cpu": [
1885 "x64"
1886 ],
@@ -1891,9 +1891,9 @@
1891 ]
1892 },
1893 "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
1894 - "version": "4.18.0",
1895 - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.18.0.tgz",
1896 - "integrity": "sha512-C/zbRYRXFjWvz9Z4haRxcTdnkPt1BtCkz+7RtBSuNmKzMzp3ZxdM28Mpccn6pt28/UWUCTXa+b0Mx1k3g6NOMA==",
1894 + "version": "4.18.1",
1895 + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.18.1.tgz",
1896 + "integrity": "sha512-P9bSiAUnSSM7EmyRK+e5wgpqai86QOSv8BwvkGjLwYuOpaeomiZWifEos517CwbG+aZl1T4clSE1YqqH2JRs+g==",
1897 "cpu": [
1898 "arm"
1899 ],
@@ -1904,9 +1904,9 @@
1904 ]
1905 },
1906 "node_modules/@rollup/rollup-linux-arm-musleabihf": {
1907 - "version": "4.18.0",
1908 - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.18.0.tgz",
1909 - "integrity": "sha512-l3m9ewPgjQSXrUMHg93vt0hYCGnrMOcUpTz6FLtbwljo2HluS4zTXFy2571YQbisTnfTKPZ01u/ukJdQTLGh9A==",
1907 + "version": "4.18.1",
1908 + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.18.1.tgz",
1909 + "integrity": "sha512-5RnjpACoxtS+aWOI1dURKno11d7krfpGDEn19jI8BuWmSBbUC4ytIADfROM1FZrFhQPSoP+KEa3NlEScznBTyQ==",
1910 "cpu": [
1911 "arm"
1912 ],
@@ -1917,9 +1917,9 @@
1917 ]
1918 },
1919 "node_modules/@rollup/rollup-linux-arm64-gnu": {
1920 - "version": "4.18.0",
1921 - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.18.0.tgz",
1922 - "integrity": "sha512-rJ5D47d8WD7J+7STKdCUAgmQk49xuFrRi9pZkWoRD1UeSMakbcepWXPF8ycChBoAqs1pb2wzvbY6Q33WmN2ftw==",
1920 + "version": "4.18.1",
1921 + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.18.1.tgz",
1922 + "integrity": "sha512-8mwmGD668m8WaGbthrEYZ9CBmPug2QPGWxhJxh/vCgBjro5o96gL04WLlg5BA233OCWLqERy4YUzX3bJGXaJgQ==",
1923 "cpu": [
1924 "arm64"
1925 ],
@@ -1930,9 +1930,9 @@
1930 ]
1931 },
1932 "node_modules/@rollup/rollup-linux-arm64-musl": {
1933 - "version": "4.18.0",
1934 - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.18.0.tgz",
1935 - "integrity": "sha512-be6Yx37b24ZwxQ+wOQXXLZqpq4jTckJhtGlWGZs68TgdKXJgw54lUUoFYrg6Zs/kjzAQwEwYbp8JxZVzZLRepQ==",
1933 + "version": "4.18.1",
1934 + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.18.1.tgz",
1935 + "integrity": "sha512-dJX9u4r4bqInMGOAQoGYdwDP8lQiisWb9et+T84l2WXk41yEej8v2iGKodmdKimT8cTAYt0jFb+UEBxnPkbXEQ==",
1936 "cpu": [
1937 "arm64"
1938 ],
@@ -1943,9 +1943,9 @@
1943 ]
1944 },
1945 "node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
1946 - "version": "4.18.0",
1947 - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.18.0.tgz",
1948 - "integrity": "sha512-hNVMQK+qrA9Todu9+wqrXOHxFiD5YmdEi3paj6vP02Kx1hjd2LLYR2eaN7DsEshg09+9uzWi2W18MJDlG0cxJA==",
1946 + "version": "4.18.1",
1947 + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.18.1.tgz",
1948 + "integrity": "sha512-V72cXdTl4EI0x6FNmho4D502sy7ed+LuVW6Ym8aI6DRQ9hQZdp5sj0a2usYOlqvFBNKQnLQGwmYnujo2HvjCxQ==",
1949 "cpu": [
1950 "ppc64"
1951 ],
@@ -1956,9 +1956,9 @@
1956 ]
1957 },
1958 "node_modules/@rollup/rollup-linux-riscv64-gnu": {
1959 - "version": "4.18.0",
1960 - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.18.0.tgz",
1961 - "integrity": "sha512-ROCM7i+m1NfdrsmvwSzoxp9HFtmKGHEqu5NNDiZWQtXLA8S5HBCkVvKAxJ8U+CVctHwV2Gb5VUaK7UAkzhDjlg==",
1959 + "version": "4.18.1",
1960 + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.18.1.tgz",
1961 + "integrity": "sha512-f+pJih7sxoKmbjghrM2RkWo2WHUW8UbfxIQiWo5yeCaCM0TveMEuAzKJte4QskBp1TIinpnRcxkquY+4WuY/tg==",
1962 "cpu": [
1963 "riscv64"
1964 ],
@@ -1969,9 +1969,9 @@
1969 ]
1970 },
1971 "node_modules/@rollup/rollup-linux-s390x-gnu": {
1972 - "version": "4.18.0",
1973 - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.18.0.tgz",
1974 - "integrity": "sha512-0UyyRHyDN42QL+NbqevXIIUnKA47A+45WyasO+y2bGJ1mhQrfrtXUpTxCOrfxCR4esV3/RLYyucGVPiUsO8xjg==",
1972 + "version": "4.18.1",
1973 + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.18.1.tgz",
1974 + "integrity": "sha512-qb1hMMT3Fr/Qz1OKovCuUM11MUNLUuHeBC2DPPAWUYYUAOFWaxInaTwTQmc7Fl5La7DShTEpmYwgdt2hG+4TEg==",
1975 "cpu": [
1976 "s390x"
1977 ],
@@ -1982,9 +1982,9 @@
1982 ]
1983 },
1984 "node_modules/@rollup/rollup-linux-x64-gnu": {
1985 - "version": "4.18.0",
1986 - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.18.0.tgz",
1987 - "integrity": "sha512-xuglR2rBVHA5UsI8h8UbX4VJ470PtGCf5Vpswh7p2ukaqBGFTnsfzxUBetoWBWymHMxbIG0Cmx7Y9qDZzr648w==",
1985 + "version": "4.18.1",
1986 + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.18.1.tgz",
1987 + "integrity": "sha512-7O5u/p6oKUFYjRbZkL2FLbwsyoJAjyeXHCU3O4ndvzg2OFO2GinFPSJFGbiwFDaCFc+k7gs9CF243PwdPQFh5g==",
1988 "cpu": [
1989 "x64"
1990 ],
@@ -1994,9 +1994,9 @@
1994 ]
1995 },
1996 "node_modules/@rollup/rollup-linux-x64-musl": {
1997 - "version": "4.18.0",
1998 - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.18.0.tgz",
1999 - "integrity": "sha512-LKaqQL9osY/ir2geuLVvRRs+utWUNilzdE90TpyoX0eNqPzWjRm14oMEE+YLve4k/NAqCdPkGYDaDF5Sw+xBfg==",
1997 + "version": "4.18.1",
1998 + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.18.1.tgz",
1999 + "integrity": "sha512-pDLkYITdYrH/9Cv/Vlj8HppDuLMDUBmgsM0+N+xLtFd18aXgM9Nyqupb/Uw+HeidhfYg2lD6CXvz6CjoVOaKjQ==",
2000 "cpu": [
2001 "x64"
2002 ],
@@ -2007,9 +2007,9 @@
2007 ]
2008 },
2009 "node_modules/@rollup/rollup-win32-arm64-msvc": {
2010 - "version": "4.18.0",
2011 - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.18.0.tgz",
2012 - "integrity": "sha512-7J6TkZQFGo9qBKH0pk2cEVSRhJbL6MtfWxth7Y5YmZs57Pi+4x6c2dStAUvaQkHQLnEQv1jzBUW43GvZW8OFqA==",
2010 + "version": "4.18.1",
2011 + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.18.1.tgz",
2012 + "integrity": "sha512-W2ZNI323O/8pJdBGil1oCauuCzmVd9lDmWBBqxYZcOqWD6aWqJtVBQ1dFrF4dYpZPks6F+xCZHfzG5hYlSHZ6g==",
2013 "cpu": [
2014 "arm64"
2015 ],
@@ -2020,9 +2020,9 @@
2020 ]
2021 },
2022 "node_modules/@rollup/rollup-win32-ia32-msvc": {
2023 - "version": "4.18.0",
2024 - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.18.0.tgz",
2025 - "integrity": "sha512-Txjh+IxBPbkUB9+SXZMpv+b/vnTEtFyfWZgJ6iyCmt2tdx0OF5WhFowLmnh8ENGNpfUlUZkdI//4IEmhwPieNg==",
2023 + "version": "4.18.1",
2024 + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.18.1.tgz",
2025 + "integrity": "sha512-ELfEX1/+eGZYMaCIbK4jqLxO1gyTSOIlZr6pbC4SRYFaSIDVKOnZNMdoZ+ON0mrFDp4+H5MhwNC1H/AhE3zQLg==",
2026 "cpu": [
2027 "ia32"
2028 ],
@@ -2033,9 +2033,9 @@
2033 ]
2034 },
2035 "node_modules/@rollup/rollup-win32-x64-msvc": {
2036 - "version": "4.18.0",
2037 - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.18.0.tgz",
2038 - "integrity": "sha512-UOo5FdvOL0+eIVTgS4tIdbW+TtnBLWg1YBCcU2KWM7nuNwRz9bksDX1bekJJCpu25N1DVWaCwnT39dVQxzqS8g==",
2036 + "version": "4.18.1",
2037 + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.18.1.tgz",
2038 + "integrity": "sha512-yjk2MAkQmoaPYCSu35RLJ62+dz358nE83VfTePJRp8CG7aMg25mEJYpXFiD+NcevhX8LxD5OP5tktPXnXN7GDw==",
2039 "cpu": [
2040 "x64"
2041 ],
@@ -2046,26 +2046,29 @@
2046 ]
2047 },
2048 "node_modules/@shikijs/core": {
2049 - "version": "1.9.1",
2050 - "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-1.9.1.tgz",
2051 - "integrity": "sha512-EmUful2MQtY8KgCF1OkBtOuMcvaZEvmdubhW0UHCGXi21O9dRLeADVCj+k6ZS+de7Mz9d2qixOXJ+GLhcK3pXg=="
2049 + "version": "1.10.3",
2050 + "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-1.10.3.tgz",
2051 + "integrity": "sha512-D45PMaBaeDHxww+EkcDQtDAtzv00Gcsp72ukBtaLSmqRvh0WgGMq3Al0rl1QQBZfuneO75NXMIzEZGFitThWbg==",
2052 + "dependencies": {
2053 + "@types/hast": "^3.0.4"
2054 + }
2055 },
2056 "node_modules/@shikijs/markdown-it": {
2054 - "version": "1.9.1",
2055 - "resolved": "https://registry.npmjs.org/@shikijs/markdown-it/-/markdown-it-1.9.1.tgz",
2056 - "integrity": "sha512-0f5Lfwx+e6t6lQPZAX2BZxlhzN6aBhB83FfgmC2yegx4Id7YGCsi3/aaipDZT2nityqiNEY+Mmdg2Fr4++EJWg==",
2057 + "version": "1.10.3",
2058 + "resolved": "https://registry.npmjs.org/@shikijs/markdown-it/-/markdown-it-1.10.3.tgz",
2059 + "integrity": "sha512-QH0SbMx+pnUNr6/CWrq3SbfT3myZ0uJGFTsp5+7mlzPbX+73FjRO9K03A7gmv+LutqSiDQCOfkeixSuP7a4sug==",
2060 "dependencies": {
2058 - "@shikijs/transformers": "1.9.1",
2061 + "@shikijs/transformers": "1.10.3",
2062 "markdown-it": "^14.1.0",
2060 - "shiki": "1.9.1"
2063 + "shiki": "1.10.3"
2064 }
2065 },
2066 "node_modules/@shikijs/transformers": {
2064 - "version": "1.9.1",
2065 - "resolved": "https://registry.npmjs.org/@shikijs/transformers/-/transformers-1.9.1.tgz",
2066 - "integrity": "sha512-wPrGTpBURQ95IKPIhPQE3bGsANpPPtea1+aVHZp0aYtgxfL5UM3QbJ5rNdCuhcyjz/JNp5ZvSItOr+ayJxebJQ==",
2067 + "version": "1.10.3",
2068 + "resolved": "https://registry.npmjs.org/@shikijs/transformers/-/transformers-1.10.3.tgz",
2069 + "integrity": "sha512-MNjsyye2WHVdxfZUSr5frS97sLGe6G1T+1P41QjyBFJehZphMcr4aBlRLmq6OSPBslYe9byQPVvt/LJCOfxw8Q==",
2070 "dependencies": {
2068 - "shiki": "1.9.1"
2071 + "shiki": "1.10.3"
2072 }
2073 },
2074 "node_modules/@sideway/address": {
@@ -2138,6 +2141,14 @@
2141 "@types/node": "*"
2142 }
2143 },
2144 + "node_modules/@types/hast": {
2145 + "version": "3.0.4",
2146 + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz",
2147 + "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==",
2148 + "dependencies": {
2149 + "@types/unist": "*"
2150 + }
2151 + },
2152 "node_modules/@types/inquirer": {
2153 "version": "9.0.7",
2154 "resolved": "https://registry.npmjs.org/@types/inquirer/-/inquirer-9.0.7.tgz",
@@ -2192,9 +2203,9 @@
2203 }
2204 },
2205 "node_modules/@types/node": {
2195 - "version": "20.14.9",
2196 - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.9.tgz",
2197 - "integrity": "sha512-06OCtnTXtWOZBJlRApleWndH4JsRVs1pDCc8dLSQp+7PpUpX3ePdHyeNSFTeSe7FtKyQkrlPvHwJOW3SLd8Oyg==",
2206 + "version": "20.14.10",
2207 + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.10.tgz",
2208 + "integrity": "sha512-MdiXf+nDuMvY0gJKxyfZ7/6UFsETO7mGKF54MVD/ekJS6HdFtpZFBgrh6Pseu64XTb2MLyFPlbW6hj8HYRQNOQ==",
2209 "dev": true,
2210 "dependencies": {
2211 "undici-types": "~5.26.4"
@@ -2232,6 +2243,11 @@
2243 "integrity": "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==",
2244 "dev": true
2245 },
2246 + "node_modules/@types/unist": {
2247 + "version": "3.0.2",
2248 + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz",
2249 + "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ=="
2250 + },
2251 "node_modules/@types/validator": {
2252 "version": "13.12.0",
2253 "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.12.0.tgz",
@@ -2254,16 +2270,16 @@
2270 }
2271 },
2272 "node_modules/@typescript-eslint/eslint-plugin": {
2257 - "version": "7.14.1",
2258 - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.14.1.tgz",
2259 - "integrity": "sha512-aAJd6bIf2vvQRjUG3ZkNXkmBpN+J7Wd0mfQiiVCJMu9Z5GcZZdcc0j8XwN/BM97Fl7e3SkTXODSk4VehUv7CGw==",
2273 + "version": "7.16.0",
2274 + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.16.0.tgz",
2275 + "integrity": "sha512-py1miT6iQpJcs1BiJjm54AMzeuMPBSPuKPlnT8HlfudbcS5rYeX5jajpLf3mrdRh9dA/Ec2FVUY0ifeVNDIhZw==",
2276 "dev": true,
2277 "dependencies": {
2278 "@eslint-community/regexpp": "^4.10.0",
2263 - "@typescript-eslint/scope-manager": "7.14.1",
2264 - "@typescript-eslint/type-utils": "7.14.1",
2265 - "@typescript-eslint/utils": "7.14.1",
2266 - "@typescript-eslint/visitor-keys": "7.14.1",
2279 + "@typescript-eslint/scope-manager": "7.16.0",
2280 + "@typescript-eslint/type-utils": "7.16.0",
2281 + "@typescript-eslint/utils": "7.16.0",
2282 + "@typescript-eslint/visitor-keys": "7.16.0",
2283 "graphemer": "^1.4.0",
2284 "ignore": "^5.3.1",
2285 "natural-compare": "^1.4.0",
@@ -2287,13 +2303,13 @@
2303 }
2304 },
2305 "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager": {
2290 - "version": "7.14.1",
2291 - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.14.1.tgz",
2292 - "integrity": "sha512-gPrFSsoYcsffYXTOZ+hT7fyJr95rdVe4kGVX1ps/dJ+DfmlnjFN/GcMxXcVkeHDKqsq6uAcVaQaIi3cFffmAbA==",
2306 + "version": "7.16.0",
2307 + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.16.0.tgz",
2308 + "integrity": "sha512-8gVv3kW6n01Q6TrI1cmTZ9YMFi3ucDT7i7aI5lEikk2ebk1AEjrwX8MDTdaX5D7fPXMBLvnsaa0IFTAu+jcfOw==",
2309 "dev": true,
2310 "dependencies": {
2295 - "@typescript-eslint/types": "7.14.1",
2296 - "@typescript-eslint/visitor-keys": "7.14.1"
2311 + "@typescript-eslint/types": "7.16.0",
2312 + "@typescript-eslint/visitor-keys": "7.16.0"
2313 },
2314 "engines": {
2315 "node": "^18.18.0 || >=20.0.0"
@@ -2304,9 +2320,9 @@
2320 }
2321 },
2322 "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types": {
2307 - "version": "7.14.1",
2308 - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.14.1.tgz",
2309 - "integrity": "sha512-mL7zNEOQybo5R3AavY+Am7KLv8BorIv7HCYS5rKoNZKQD9tsfGUpO4KdAn3sSUvTiS4PQkr2+K0KJbxj8H9NDg==",
2323 + "version": "7.16.0",
2324 + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.16.0.tgz",
2325 + "integrity": "sha512-fecuH15Y+TzlUutvUl9Cc2XJxqdLr7+93SQIbcZfd4XRGGKoxyljK27b+kxKamjRkU7FYC6RrbSCg0ALcZn/xw==",
2326 "dev": true,
2327 "engines": {
2328 "node": "^18.18.0 || >=20.0.0"
@@ -2317,13 +2333,13 @@
2333 }
2334 },
2335 "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/typescript-estree": {
2320 - "version": "7.14.1",
2321 - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.14.1.tgz",
2322 - "integrity": "sha512-k5d0VuxViE2ulIO6FbxxSZaxqDVUyMbXcidC8rHvii0I56XZPv8cq+EhMns+d/EVIL41sMXqRbK3D10Oza1bbA==",
2336 + "version": "7.16.0",
2337 + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.16.0.tgz",
2338 + "integrity": "sha512-a5NTvk51ZndFuOLCh5OaJBELYc2O3Zqxfl3Js78VFE1zE46J2AaVuW+rEbVkQznjkmlzWsUI15BG5tQMixzZLw==",
2339 "dev": true,
2340 "dependencies": {
2325 - "@typescript-eslint/types": "7.14.1",
2326 - "@typescript-eslint/visitor-keys": "7.14.1",
2341 + "@typescript-eslint/types": "7.16.0",
2342 + "@typescript-eslint/visitor-keys": "7.16.0",
2343 "debug": "^4.3.4",
2344 "globby": "^11.1.0",
2345 "is-glob": "^4.0.3",
@@ -2345,15 +2361,15 @@
2361 }
2362 },
2363 "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/utils": {
2348 - "version": "7.14.1",
2349 - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.14.1.tgz",
2350 - "integrity": "sha512-CMmVVELns3nak3cpJhZosDkm63n+DwBlDX8g0k4QUa9BMnF+lH2lr3d130M1Zt1xxmB3LLk3NV7KQCq86ZBBhQ==",
2364 + "version": "7.16.0",
2365 + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.16.0.tgz",
2366 + "integrity": "sha512-PqP4kP3hb4r7Jav+NiRCntlVzhxBNWq6ZQ+zQwII1y/G/1gdIPeYDCKr2+dH6049yJQsWZiHU6RlwvIFBXXGNA==",
2367 "dev": true,
2368 "dependencies": {
2369 "@eslint-community/eslint-utils": "^4.4.0",
2354 - "@typescript-eslint/scope-manager": "7.14.1",
2355 - "@typescript-eslint/types": "7.14.1",
2356 - "@typescript-eslint/typescript-estree": "7.14.1"
2370 + "@typescript-eslint/scope-manager": "7.16.0",
2371 + "@typescript-eslint/types": "7.16.0",
2372 + "@typescript-eslint/typescript-estree": "7.16.0"
2373 },
2374 "engines": {
2375 "node": "^18.18.0 || >=20.0.0"
@@ -2367,12 +2383,12 @@
2383 }
2384 },
2385 "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": {
2370 - "version": "7.14.1",
2371 - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.14.1.tgz",
2372 - "integrity": "sha512-Crb+F75U1JAEtBeQGxSKwI60hZmmzaqA3z9sYsVm8X7W5cwLEm5bRe0/uXS6+MR/y8CVpKSR/ontIAIEPFcEkA==",
2386 + "version": "7.16.0",
2387 + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.16.0.tgz",
2388 + "integrity": "sha512-rMo01uPy9C7XxG7AFsxa8zLnWXTF8N3PYclekWSrurvhwiw1eW88mrKiAYe6s53AUY57nTRz8dJsuuXdkAhzCg==",
2389 "dev": true,
2390 "dependencies": {
2375 - "@typescript-eslint/types": "7.14.1",
2391 + "@typescript-eslint/types": "7.16.0",
2392 "eslint-visitor-keys": "^3.4.3"
2393 },
2394 "engines": {
@@ -2399,15 +2415,15 @@
2415 }
2416 },
2417 "node_modules/@typescript-eslint/parser": {
2402 - "version": "7.14.1",
2403 - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.14.1.tgz",
2404 - "integrity": "sha512-8lKUOebNLcR0D7RvlcloOacTOWzOqemWEWkKSVpMZVF/XVcwjPR+3MD08QzbW9TCGJ+DwIc6zUSGZ9vd8cO1IA==",
2418 + "version": "7.16.0",
2419 + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.16.0.tgz",
2420 + "integrity": "sha512-ar9E+k7CU8rWi2e5ErzQiC93KKEFAXA2Kky0scAlPcxYblLt8+XZuHUZwlyfXILyQa95P6lQg+eZgh/dDs3+Vw==",
2421 "dev": true,
2422 "dependencies": {
2407 - "@typescript-eslint/scope-manager": "7.14.1",
2408 - "@typescript-eslint/types": "7.14.1",
2409 - "@typescript-eslint/typescript-estree": "7.14.1",
2410 - "@typescript-eslint/visitor-keys": "7.14.1",
2423 + "@typescript-eslint/scope-manager": "7.16.0",
2424 + "@typescript-eslint/types": "7.16.0",
2425 + "@typescript-eslint/typescript-estree": "7.16.0",
2426 + "@typescript-eslint/visitor-keys": "7.16.0",
2427 "debug": "^4.3.4"
2428 },
2429 "engines": {
@@ -2427,13 +2443,13 @@
2443 }
2444 },
2445 "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": {
2430 - "version": "7.14.1",
2431 - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.14.1.tgz",
2432 - "integrity": "sha512-gPrFSsoYcsffYXTOZ+hT7fyJr95rdVe4kGVX1ps/dJ+DfmlnjFN/GcMxXcVkeHDKqsq6uAcVaQaIi3cFffmAbA==",
2446 + "version": "7.16.0",
2447 + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.16.0.tgz",
2448 + "integrity": "sha512-8gVv3kW6n01Q6TrI1cmTZ9YMFi3ucDT7i7aI5lEikk2ebk1AEjrwX8MDTdaX5D7fPXMBLvnsaa0IFTAu+jcfOw==",
2449 "dev": true,
2450 "dependencies": {
2435 - "@typescript-eslint/types": "7.14.1",
2436 - "@typescript-eslint/visitor-keys": "7.14.1"
2451 + "@typescript-eslint/types": "7.16.0",
2452 + "@typescript-eslint/visitor-keys": "7.16.0"
2453 },
2454 "engines": {
2455 "node": "^18.18.0 || >=20.0.0"
@@ -2444,9 +2460,9 @@
2460 }
2461 },
2462 "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": {
2447 - "version": "7.14.1",
2448 - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.14.1.tgz",
2449 - "integrity": "sha512-mL7zNEOQybo5R3AavY+Am7KLv8BorIv7HCYS5rKoNZKQD9tsfGUpO4KdAn3sSUvTiS4PQkr2+K0KJbxj8H9NDg==",
2463 + "version": "7.16.0",
2464 + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.16.0.tgz",
2465 + "integrity": "sha512-fecuH15Y+TzlUutvUl9Cc2XJxqdLr7+93SQIbcZfd4XRGGKoxyljK27b+kxKamjRkU7FYC6RrbSCg0ALcZn/xw==",
2466 "dev": true,
2467 "engines": {
2468 "node": "^18.18.0 || >=20.0.0"
@@ -2457,13 +2473,13 @@
2473 }
2474 },
2475 "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": {
2460 - "version": "7.14.1",
2461 - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.14.1.tgz",
2462 - "integrity": "sha512-k5d0VuxViE2ulIO6FbxxSZaxqDVUyMbXcidC8rHvii0I56XZPv8cq+EhMns+d/EVIL41sMXqRbK3D10Oza1bbA==",
2476 + "version": "7.16.0",
2477 + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.16.0.tgz",
2478 + "integrity": "sha512-a5NTvk51ZndFuOLCh5OaJBELYc2O3Zqxfl3Js78VFE1zE46J2AaVuW+rEbVkQznjkmlzWsUI15BG5tQMixzZLw==",
2479 "dev": true,
2480 "dependencies": {
2465 - "@typescript-eslint/types": "7.14.1",
2466 - "@typescript-eslint/visitor-keys": "7.14.1",
2481 + "@typescript-eslint/types": "7.16.0",
2482 + "@typescript-eslint/visitor-keys": "7.16.0",
2483 "debug": "^4.3.4",
2484 "globby": "^11.1.0",
2485 "is-glob": "^4.0.3",
@@ -2485,12 +2501,12 @@
2501 }
2502 },
2503 "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": {
2488 - "version": "7.14.1",
2489 - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.14.1.tgz",
2490 - "integrity": "sha512-Crb+F75U1JAEtBeQGxSKwI60hZmmzaqA3z9sYsVm8X7W5cwLEm5bRe0/uXS6+MR/y8CVpKSR/ontIAIEPFcEkA==",
2504 + "version": "7.16.0",
2505 + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.16.0.tgz",
2506 + "integrity": "sha512-rMo01uPy9C7XxG7AFsxa8zLnWXTF8N3PYclekWSrurvhwiw1eW88mrKiAYe6s53AUY57nTRz8dJsuuXdkAhzCg==",
2507 "dev": true,
2508 "dependencies": {
2493 - "@typescript-eslint/types": "7.14.1",
2509 + "@typescript-eslint/types": "7.16.0",
2510 "eslint-visitor-keys": "^3.4.3"
2511 },
2512 "engines": {
@@ -2533,13 +2549,13 @@
2549 }
2550 },
2551 "node_modules/@typescript-eslint/type-utils": {
2536 - "version": "7.14.1",
2537 - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.14.1.tgz",
2538 - "integrity": "sha512-/MzmgNd3nnbDbOi3LfasXWWe292+iuo+umJ0bCCMCPc1jLO/z2BQmWUUUXvXLbrQey/JgzdF/OV+I5bzEGwJkQ==",
2552 + "version": "7.16.0",
2553 + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.16.0.tgz",
2554 + "integrity": "sha512-j0fuUswUjDHfqV/UdW6mLtOQQseORqfdmoBNDFOqs9rvNVR2e+cmu6zJu/Ku4SDuqiJko6YnhwcL8x45r8Oqxg==",
2555 "dev": true,
2556 "dependencies": {
2541 - "@typescript-eslint/typescript-estree": "7.14.1",
2542 - "@typescript-eslint/utils": "7.14.1",
2557 + "@typescript-eslint/typescript-estree": "7.16.0",
2558 + "@typescript-eslint/utils": "7.16.0",
2559 "debug": "^4.3.4",
2560 "ts-api-utils": "^1.3.0"
2561 },
@@ -2560,13 +2576,13 @@
2576 }
2577 },
2578 "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/scope-manager": {
2563 - "version": "7.14.1",
2564 - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.14.1.tgz",
2565 - "integrity": "sha512-gPrFSsoYcsffYXTOZ+hT7fyJr95rdVe4kGVX1ps/dJ+DfmlnjFN/GcMxXcVkeHDKqsq6uAcVaQaIi3cFffmAbA==",
2579 + "version": "7.16.0",
2580 + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.16.0.tgz",
2581 + "integrity": "sha512-8gVv3kW6n01Q6TrI1cmTZ9YMFi3ucDT7i7aI5lEikk2ebk1AEjrwX8MDTdaX5D7fPXMBLvnsaa0IFTAu+jcfOw==",
2582 "dev": true,
2583 "dependencies": {
2568 - "@typescript-eslint/types": "7.14.1",
2569 - "@typescript-eslint/visitor-keys": "7.14.1"
2584 + "@typescript-eslint/types": "7.16.0",
2585 + "@typescript-eslint/visitor-keys": "7.16.0"
2586 },
2587 "engines": {
2588 "node": "^18.18.0 || >=20.0.0"
@@ -2577,9 +2593,9 @@
2593 }
2594 },
2595 "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": {
2580 - "version": "7.14.1",
2581 - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.14.1.tgz",
2582 - "integrity": "sha512-mL7zNEOQybo5R3AavY+Am7KLv8BorIv7HCYS5rKoNZKQD9tsfGUpO4KdAn3sSUvTiS4PQkr2+K0KJbxj8H9NDg==",
2596 + "version": "7.16.0",
2597 + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.16.0.tgz",
2598 + "integrity": "sha512-fecuH15Y+TzlUutvUl9Cc2XJxqdLr7+93SQIbcZfd4XRGGKoxyljK27b+kxKamjRkU7FYC6RrbSCg0ALcZn/xw==",
2599 "dev": true,
2600 "engines": {
2601 "node": "^18.18.0 || >=20.0.0"
@@ -2590,13 +2606,13 @@
2606 }
2607 },
2608 "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": {
2593 - "version": "7.14.1",
2594 - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.14.1.tgz",
2595 - "integrity": "sha512-k5d0VuxViE2ulIO6FbxxSZaxqDVUyMbXcidC8rHvii0I56XZPv8cq+EhMns+d/EVIL41sMXqRbK3D10Oza1bbA==",
2609 + "version": "7.16.0",
2610 + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.16.0.tgz",
2611 + "integrity": "sha512-a5NTvk51ZndFuOLCh5OaJBELYc2O3Zqxfl3Js78VFE1zE46J2AaVuW+rEbVkQznjkmlzWsUI15BG5tQMixzZLw==",
2612 "dev": true,
2613 "dependencies": {
2598 - "@typescript-eslint/types": "7.14.1",
2599 - "@typescript-eslint/visitor-keys": "7.14.1",
2614 + "@typescript-eslint/types": "7.16.0",
2615 + "@typescript-eslint/visitor-keys": "7.16.0",
2616 "debug": "^4.3.4",
2617 "globby": "^11.1.0",
2618 "is-glob": "^4.0.3",
@@ -2618,15 +2634,15 @@
2634 }
2635 },
2636 "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/utils": {
2621 - "version": "7.14.1",
2622 - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.14.1.tgz",
2623 - "integrity": "sha512-CMmVVELns3nak3cpJhZosDkm63n+DwBlDX8g0k4QUa9BMnF+lH2lr3d130M1Zt1xxmB3LLk3NV7KQCq86ZBBhQ==",
2637 + "version": "7.16.0",
2638 + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.16.0.tgz",
2639 + "integrity": "sha512-PqP4kP3hb4r7Jav+NiRCntlVzhxBNWq6ZQ+zQwII1y/G/1gdIPeYDCKr2+dH6049yJQsWZiHU6RlwvIFBXXGNA==",
2640 "dev": true,
2641 "dependencies": {
2642 "@eslint-community/eslint-utils": "^4.4.0",
2627 - "@typescript-eslint/scope-manager": "7.14.1",
2628 - "@typescript-eslint/types": "7.14.1",
2629 - "@typescript-eslint/typescript-estree": "7.14.1"
2643 + "@typescript-eslint/scope-manager": "7.16.0",
2644 + "@typescript-eslint/types": "7.16.0",
2645 + "@typescript-eslint/typescript-estree": "7.16.0"
2646 },
2647 "engines": {
2648 "node": "^18.18.0 || >=20.0.0"
@@ -2640,12 +2656,12 @@
2656 }
2657 },
2658 "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys": {
2643 - "version": "7.14.1",
2644 - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.14.1.tgz",
2645 - "integrity": "sha512-Crb+F75U1JAEtBeQGxSKwI60hZmmzaqA3z9sYsVm8X7W5cwLEm5bRe0/uXS6+MR/y8CVpKSR/ontIAIEPFcEkA==",
2659 + "version": "7.16.0",
2660 + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.16.0.tgz",
2661 + "integrity": "sha512-rMo01uPy9C7XxG7AFsxa8zLnWXTF8N3PYclekWSrurvhwiw1eW88mrKiAYe6s53AUY57nTRz8dJsuuXdkAhzCg==",
2662 "dev": true,
2663 "dependencies": {
2648 - "@typescript-eslint/types": "7.14.1",
2664 + "@typescript-eslint/types": "7.16.0",
2665 "eslint-visitor-keys": "^3.4.3"
2666 },
2667 "engines": {
@@ -2837,68 +2853,40 @@
2853 }
2854 },
2855 "node_modules/@vitest/expect": {
2840 - "version": "1.6.0",
2841 - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-1.6.0.tgz",
2842 - "integrity": "sha512-ixEvFVQjycy/oNgHjqsL6AZCDduC+tflRluaHIzKIsdbzkLn2U/iBnVeJwB6HsIjQBdfMR8Z0tRxKUsvFJEeWQ==",
2856 + "version": "2.0.1",
2857 + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-2.0.1.tgz",
2858 + "integrity": "sha512-yw70WL3ZwzbI2O3MOXYP2Shf4vqVkS3q5FckLJ6lhT9VMMtDyWdofD53COZcoeuHwsBymdOZp99r5bOr5g+oeA==",
2859 "dev": true,
2860 "dependencies": {
2845 - "@vitest/spy": "1.6.0",
2846 - "@vitest/utils": "1.6.0",
2847 - "chai": "^4.3.10"
2861 + "@vitest/spy": "2.0.1",
2862 + "@vitest/utils": "2.0.1",
2863 + "chai": "^5.1.1"
2864 },
2865 "funding": {
2866 "url": "https://opencollective.com/vitest"
2867 }
2868 },
2869 "node_modules/@vitest/runner": {
2854 - "version": "1.6.0",
2855 - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-1.6.0.tgz",
2856 - "integrity": "sha512-P4xgwPjwesuBiHisAVz/LSSZtDjOTPYZVmNAnpHHSR6ONrf8eCJOFRvUwdHn30F5M1fxhqtl7QZQUk2dprIXAg==",
2870 + "version": "2.0.1",
2871 + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-2.0.1.tgz",
2872 + "integrity": "sha512-XfcSXOGGxgR2dQ466ZYqf0ZtDLLDx9mZeQcKjQDLQ9y6Cmk2Wl7wxMuhiYK4Fo1VxCtLcFEGW2XpcfMuiD1Maw==",
2873 "dev": true,
2874 "dependencies": {
2859 - "@vitest/utils": "1.6.0",
2860 - "p-limit": "^5.0.0",
2861 - "pathe": "^1.1.1"
2875 + "@vitest/utils": "2.0.1",
2876 + "pathe": "^1.1.2"
2877 },
2878 "funding": {
2879 "url": "https://opencollective.com/vitest"
2880 }
2881 },
2867 - "node_modules/@vitest/runner/node_modules/p-limit": {
2868 - "version": "5.0.0",
2869 - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-5.0.0.tgz",
2870 - "integrity": "sha512-/Eaoq+QyLSiXQ4lyYV23f14mZRQcXnxfHrN0vCai+ak9G0pp9iEQukIIZq5NccEvwRB8PUnZT0KsOoDCINS1qQ==",
2871 - "dev": true,
2872 - "dependencies": {
2873 - "yocto-queue": "^1.0.0"
2874 - },
2875 - "engines": {
2876 - "node": ">=18"
2877 - },
2878 - "funding": {
2879 - "url": "https://github.com/sponsors/sindresorhus"
2880 - }
2881 - },
2882 - "node_modules/@vitest/runner/node_modules/yocto-queue": {
2883 - "version": "1.0.0",
2884 - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz",
2885 - "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==",
2886 - "dev": true,
2887 - "engines": {
2888 - "node": ">=12.20"
2889 - },
2890 - "funding": {
2891 - "url": "https://github.com/sponsors/sindresorhus"
2892 - }
2893 - },
2882 "node_modules/@vitest/snapshot": {
2895 - "version": "1.6.0",
2896 - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-1.6.0.tgz",
2897 - "integrity": "sha512-+Hx43f8Chus+DCmygqqfetcAZrDJwvTj0ymqjQq4CvmpKFSTVteEOBzCusu1x2tt4OJcvBflyHUE0DZSLgEMtQ==",
2883 + "version": "2.0.1",
2884 + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-2.0.1.tgz",
2885 + "integrity": "sha512-rst79a4Q+J5vrvHRapdfK4BdqpMH0eF58jVY1vYeBo/1be+nkyenGI5SCSohmjf6MkCkI20/yo5oG+0R8qrAnA==",
2886 "dev": true,
2887 "dependencies": {
2900 - "magic-string": "^0.30.5",
2901 - "pathe": "^1.1.1",
2888 + "magic-string": "^0.30.10",
2889 + "pathe": "^1.1.2",
2890 "pretty-format": "^29.7.0"
2891 },
2892 "funding": {
@@ -2906,26 +2894,26 @@
2894 }
2895 },
2896 "node_modules/@vitest/spy": {
2909 - "version": "1.6.0",
2910 - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-1.6.0.tgz",
2911 - "integrity": "sha512-leUTap6B/cqi/bQkXUu6bQV5TZPx7pmMBKBQiI0rJA8c3pB56ZsaTbREnF7CJfmvAS4V2cXIBAh/3rVwrrCYgw==",
2897 + "version": "2.0.1",
2898 + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-2.0.1.tgz",
2899 + "integrity": "sha512-NLkdxbSefAtJN56GtCNcB4GiHFb5i9q1uh4V229lrlTZt2fnwsTyjLuWIli1xwK2fQspJJmHXHyWx0Of3KTXWA==",
2900 "dev": true,
2901 "dependencies": {
2914 - "tinyspy": "^2.2.0"
2902 + "tinyspy": "^3.0.0"
2903 },
2904 "funding": {
2905 "url": "https://opencollective.com/vitest"
2906 }
2907 },
2908 "node_modules/@vitest/utils": {
2921 - "version": "1.6.0",
2922 - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-1.6.0.tgz",
2923 - "integrity": "sha512-21cPiuGMoMZwiOHa2i4LXkMkMkCGzA+MVFV70jRwHo95dL4x/ts5GZhML1QWuy7yfp3WzK3lRvZi3JnXTYqrBw==",
2909 + "version": "2.0.1",
2910 + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-2.0.1.tgz",
2911 + "integrity": "sha512-STH+2fHZxlveh1mpU4tKzNgRk7RZJyr6kFGJYCI5vocdfqfPsQrgVC6k7dBWHfin5QNB4TLvRS0Ckly3Dt1uWw==",
2912 "dev": true,
2913 "dependencies": {
2914 "diff-sequences": "^29.6.3",
2915 "estree-walker": "^3.0.3",
2928 - "loupe": "^2.3.7",
2916 + "loupe": "^3.1.1",
2917 "pretty-format": "^29.7.0"
2918 },
2919 "funding": {
@@ -2942,27 +2930,27 @@
2930 }
2931 },
2932 "node_modules/@volar/language-core": {
2945 - "version": "2.3.4",
2946 - "resolved": "https://registry.npmjs.org/@volar/language-core/-/language-core-2.3.4.tgz",
2947 - "integrity": "sha512-wXBhY11qG6pCDAqDnbBRFIDSIwbqkWI7no+lj5+L7IlA7HRIjRP7YQLGzT0LF4lS6eHkMSsclXqy9DwYJasZTQ==",
2933 + "version": "2.4.0-alpha.15",
2934 + "resolved": "https://registry.npmjs.org/@volar/language-core/-/language-core-2.4.0-alpha.15.tgz",
2935 + "integrity": "sha512-mt8z4Fm2WxfQYoQHPcKVjLQV6PgPqyKLbkCVY2cr5RSaamqCHjhKEpsFX66aL4D/7oYguuaUw9Bx03Vt0TpIIA==",
2936 "dev": true,
2937 "dependencies": {
2950 - "@volar/source-map": "2.3.4"
2938 + "@volar/source-map": "2.4.0-alpha.15"
2939 }
2940 },
2941 "node_modules/@volar/source-map": {
2954 - "version": "2.3.4",
2955 - "resolved": "https://registry.npmjs.org/@volar/source-map/-/source-map-2.3.4.tgz",
2956 - "integrity": "sha512-C+t63nwcblqLIVTYXaVi/+gC8NukDaDIQI72J3R7aXGvtgaVB16c+J8Iz7/VfOy7kjYv7lf5GhBny6ACw9fTGQ==",
2942 + "version": "2.4.0-alpha.15",
2943 + "resolved": "https://registry.npmjs.org/@volar/source-map/-/source-map-2.4.0-alpha.15.tgz",
2944 + "integrity": "sha512-8Htngw5TmBY4L3ClDqBGyfLhsB8EmoEXUH1xydyEtEoK0O6NX5ur4Jw8jgvscTlwzizyl/wsN1vn0cQXVbbXYg==",
2945 "dev": true
2946 },
2947 "node_modules/@volar/typescript": {
2960 - "version": "2.3.4",
2961 - "resolved": "https://registry.npmjs.org/@volar/typescript/-/typescript-2.3.4.tgz",
2962 - "integrity": "sha512-acCvt7dZECyKcvO5geNybmrqOsu9u8n5XP1rfiYsOLYGPxvHRav9BVmEdRyZ3vvY6mNyQ1wLL5Hday4IShe17w==",
2948 + "version": "2.4.0-alpha.15",
2949 + "resolved": "https://registry.npmjs.org/@volar/typescript/-/typescript-2.4.0-alpha.15.tgz",
2950 + "integrity": "sha512-U3StRBbDuxV6Woa4hvGS4kz3XcOzrWUKgFdEFN+ba1x3eaYg7+ytau8ul05xgA+UNGLXXsKur7fTUhDFyISk0w==",
2951 "dev": true,
2952 "dependencies": {
2965 - "@volar/language-core": "2.3.4",
2953 + "@volar/language-core": "2.4.0-alpha.15",
2954 "path-browserify": "^1.0.1",
2955 "vscode-uri": "^3.0.8"
2956 }
@@ -3092,13 +3080,13 @@
3080 "integrity": "sha512-0MiMsFma/HqA6g3KLKn+AGpL1kgKhFWszC9U29NfpWK5LE7bjeXxySWJrOJ77hBz+TBrBQ7o4QJqbPbqbs8rJw=="
3081 },
3082 "node_modules/@vue/devtools-core": {
3095 - "version": "7.3.4",
3096 - "resolved": "https://registry.npmjs.org/@vue/devtools-core/-/devtools-core-7.3.4.tgz",
3097 - "integrity": "sha512-HiaskdszC1ajYhZkglBzc4BBb4OHAhYonoOaQMx62ZId++ezpd4n0CbM9SXYp8o1JhxImSdueKgJgtyvhm4vAA==",
3083 + "version": "7.3.5",
3084 + "resolved": "https://registry.npmjs.org/@vue/devtools-core/-/devtools-core-7.3.5.tgz",
3085 + "integrity": "sha512-uSC3IkIp6MtyJYSh5xzY99sgqlAXLq+peE2KKXTi6JeRHOtMngFWFWENXi70IJ1EVGYztiFQoHhI9WZcgKBz8g==",
3086 "dev": true,
3087 "dependencies": {
3100 - "@vue/devtools-kit": "^7.3.4",
3101 - "@vue/devtools-shared": "^7.3.4",
3088 + "@vue/devtools-kit": "^7.3.5",
3089 + "@vue/devtools-shared": "^7.3.5",
3090 "mitt": "^3.0.1",
3091 "nanoid": "^3.3.4",
3092 "pathe": "^1.1.2",
@@ -3109,12 +3097,12 @@
3097 }
3098 },
3099 "node_modules/@vue/devtools-kit": {
3112 - "version": "7.3.4",
3113 - "resolved": "https://registry.npmjs.org/@vue/devtools-kit/-/devtools-kit-7.3.4.tgz",
3114 - "integrity": "sha512-DalQZWaFLRyA4qfKT0WT7e+q2AwvYoTwd0pWqswHqcpviXw+oU6FlSJHMrEACB3lBHjN1KBS9Kh527sWIe1vcg==",
3100 + "version": "7.3.5",
3101 + "resolved": "https://registry.npmjs.org/@vue/devtools-kit/-/devtools-kit-7.3.5.tgz",
3102 + "integrity": "sha512-wwfi10gJ1HMtjzcd8aIOnzBHlIRqsYDgcDyrKvkeyc0Gbcoe7UrkXRVHZUOtcxxoplHA0PwpT6wFg0uUCmi8Ww==",
3103 "dev": true,
3104 "dependencies": {
3117 - "@vue/devtools-shared": "^7.3.4",
3105 + "@vue/devtools-shared": "^7.3.5",
3106 "birpc": "^0.2.17",
3107 "hookable": "^5.5.3",
3108 "mitt": "^3.0.1",
@@ -3124,9 +3112,9 @@
3112 }
3113 },
3114 "node_modules/@vue/devtools-shared": {
3127 - "version": "7.3.4",
3128 - "resolved": "https://registry.npmjs.org/@vue/devtools-shared/-/devtools-shared-7.3.4.tgz",
3129 - "integrity": "sha512-5S5cHh7oWLZdboujnLteR3rT8UGfKHfA34aGLyFRB/B5TqBxmeLW1Rq32xW6TCDEy4isoYsYHGwJVp6DQcpiDA==",
3115 + "version": "7.3.5",
3116 + "resolved": "https://registry.npmjs.org/@vue/devtools-shared/-/devtools-shared-7.3.5.tgz",
3117 + "integrity": "sha512-Rqii3VazmWTi67a86rYopi61n5Ved05EybJCwyrfoO9Ok3MaS/4yRFl706ouoISMlyrASJFEzM0/AiDA6w4f9A==",
3118 "dev": true,
3119 "dependencies": {
3120 "rfdc": "^1.4.1"
@@ -3171,12 +3159,12 @@
3159 }
3160 },
3161 "node_modules/@vue/language-core": {
3174 - "version": "2.0.22",
3175 - "resolved": "https://registry.npmjs.org/@vue/language-core/-/language-core-2.0.22.tgz",
3176 - "integrity": "sha512-dNTAAtEOuMiz7N1s5tKpypnVVCtawxVSF5BukD0ELcYSw+DSbrSlYYSw8GuwvurodCeYFSHsmslE+c2sYDNoiA==",
3162 + "version": "2.0.26",
3163 + "resolved": "https://registry.npmjs.org/@vue/language-core/-/language-core-2.0.26.tgz",
3164 + "integrity": "sha512-/lt6SfQ3O1yDAhPsnLv9iSUgXd1dMHqUm/t3RctfqjuwQf1LnftZ414X3UBn6aXT4MiwXWtbNJ4Z0NZWwDWgJQ==",
3165 "dev": true,
3166 "dependencies": {
3179 - "@volar/language-core": "~2.3.1",
3167 + "@volar/language-core": "~2.4.0-alpha.15",
3168 "@vue/compiler-dom": "^3.4.0",
3169 "@vue/shared": "^3.4.0",
3170 "computeds": "^0.0.1",
@@ -3401,9 +3389,9 @@
3389 }
3390 },
3391 "node_modules/acorn": {
3404 - "version": "8.12.0",
3405 - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.0.tgz",
3406 - "integrity": "sha512-RTvkC4w+KNXrM39/lWCUaG0IbRkWdCv7W/IOW9oU6SawyxulvkQy5HQPVTKxEjczcUvapcrw3cFx/60VN/NRNw==",
3392 + "version": "8.12.1",
3393 + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz",
3394 + "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==",
3395 "bin": {
3396 "acorn": "bin/acorn"
3397 },
@@ -3419,18 +3407,6 @@
3407 "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
3408 }
3409 },
3422 - "node_modules/acorn-walk": {
3423 - "version": "8.3.3",
3424 - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.3.tgz",
3425 - "integrity": "sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==",
3426 - "dev": true,
3427 - "dependencies": {
3428 - "acorn": "^8.11.0"
3429 - },
3430 - "engines": {
3431 - "node": ">=0.4.0"
3432 - }
3433 - },
3410 "node_modules/agent-base": {
3411 "version": "7.1.1",
3412 "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz",
@@ -3547,9 +3523,9 @@
3523 }
3524 },
3525 "node_modules/apexcharts": {
3550 - "version": "3.49.2",
3551 - "resolved": "https://registry.npmjs.org/apexcharts/-/apexcharts-3.49.2.tgz",
3552 - "integrity": "sha512-vBB8KgwfD9rSObA7s4kY2rU6DeaN67gTR3JN7r32ztgKVf8lKkdFQ6iUhk6oIHrV7W8PoHhr5EwKymn0z5Fz6A==",
3526 + "version": "3.50.0",
3527 + "resolved": "https://registry.npmjs.org/apexcharts/-/apexcharts-3.50.0.tgz",
3528 + "integrity": "sha512-LJT1PNAm+NoIU3aogL2P+ViC0y/Cjik54FdzzGV54UNnGQLBoLe5ok3fxsJDTgyez45BGYT8gqNpYKqhdfy5sg==",
3529 "dependencies": {
3530 "@yr/monotone-cubic-spline": "^1.0.3",
3531 "svg.draggable.js": "^2.2.2",
@@ -3618,12 +3594,12 @@
3594 }
3595 },
3596 "node_modules/assertion-error": {
3621 - "version": "1.1.0",
3622 - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz",
3623 - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==",
3597 + "version": "2.0.1",
3598 + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz",
3599 + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==",
3600 "dev": true,
3601 "engines": {
3626 - "node": "*"
3602 + "node": ">=12"
3603 }
3604 },
3605 "node_modules/astral-regex": {
@@ -4024,9 +4000,9 @@
4000 }
4001 },
4002 "node_modules/caniuse-lite": {
4027 - "version": "1.0.30001638",
4028 - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001638.tgz",
4029 - "integrity": "sha512-5SuJUJ7cZnhPpeLHaH0c/HPAnAHZvS6ElWyHK9GSIbVOQABLzowiI2pjmpvZ1WEbkyz46iFd4UXlOHR5SqgfMQ==",
4003 + "version": "1.0.30001640",
4004 + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001640.tgz",
4005 + "integrity": "sha512-lA4VMpW0PSUrFnkmVuEKBUovSWKhj7puyCg8StBChgu298N1AtuF1sKWEvfDuimSEDbhlb/KqPKC3fs1HbuQUA==",
4006 "dev": true,
4007 "funding": [
4008 {
@@ -4050,21 +4026,19 @@
4026 "dev": true
4027 },
4028 "node_modules/chai": {
4053 - "version": "4.4.1",
4054 - "resolved": "https://registry.npmjs.org/chai/-/chai-4.4.1.tgz",
4055 - "integrity": "sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==",
4029 + "version": "5.1.1",
4030 + "resolved": "https://registry.npmjs.org/chai/-/chai-5.1.1.tgz",
4031 + "integrity": "sha512-pT1ZgP8rPNqUgieVaEY+ryQr6Q4HXNg8Ei9UnLUrjN4IA7dvQC5JB+/kxVcPNDHyBcc/26CXPkbNzq3qwrOEKA==",
4032 "dev": true,
4033 "dependencies": {
4058 - "assertion-error": "^1.1.0",
4059 - "check-error": "^1.0.3",
4060 - "deep-eql": "^4.1.3",
4061 - "get-func-name": "^2.0.2",
4062 - "loupe": "^2.3.6",
4063 - "pathval": "^1.1.1",
4064 - "type-detect": "^4.0.8"
4034 + "assertion-error": "^2.0.1",
4035 + "check-error": "^2.1.1",
4036 + "deep-eql": "^5.0.1",
4037 + "loupe": "^3.1.0",
4038 + "pathval": "^2.0.0"
4039 },
4040 "engines": {
4067 - "node": ">=4"
4041 + "node": ">=12"
4042 }
4043 },
4044 "node_modules/chalk": {
@@ -4082,15 +4056,12 @@
4056 }
4057 },
4058 "node_modules/check-error": {
4085 - "version": "1.0.3",
4086 - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz",
4087 - "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==",
4059 + "version": "2.1.1",
4060 + "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz",
4061 + "integrity": "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==",
4062 "dev": true,
4089 - "dependencies": {
4090 - "get-func-name": "^2.0.2"
4091 - },
4063 "engines": {
4093 - "node": "*"
4064 + "node": ">= 16"
4065 }
4066 },
4067 "node_modules/check-more-types": {
@@ -4179,18 +4150,6 @@
4150 "node": ">=8"
4151 }
4152 },
4182 - "node_modules/cli-progress": {
4183 - "version": "3.12.0",
4184 - "resolved": "https://registry.npmjs.org/cli-progress/-/cli-progress-3.12.0.tgz",
4185 - "integrity": "sha512-tRkV3HJ1ASwm19THiiLIXLO7Im7wlTuKnvkYaTkyoAPefqjNg7W7DHKUlGRxy9vxDvbyCYQkQozvptuMkGCg8A==",
4186 - "dev": true,
4187 - "dependencies": {
4188 - "string-width": "^4.2.3"
4189 - },
4190 - "engines": {
4191 - "node": ">=4"
4192 - }
4193 - },
4153 "node_modules/cli-table3": {
4154 "version": "0.6.5",
4155 "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.5.tgz",
@@ -4587,9 +4546,9 @@
4546 "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="
4547 },
4548 "node_modules/cypress": {
4590 - "version": "13.12.0",
4591 - "resolved": "https://registry.npmjs.org/cypress/-/cypress-13.12.0.tgz",
4592 - "integrity": "sha512-udzS2JilmI9ApO/UuqurEwOvThclin5ntz7K0BtnHBs+tg2Bl9QShLISXpSEMDv/u8b6mqdoAdyKeZiSqKWL8g==",
4549 + "version": "13.13.0",
4550 + "resolved": "https://registry.npmjs.org/cypress/-/cypress-13.13.0.tgz",
4551 + "integrity": "sha512-ou/MQUDq4tcDJI2FsPaod2FZpex4kpIK43JJlcBgWrX8WX7R/05ZxGTuxedOuZBfxjZxja+fbijZGyxiLP6CFA==",
4552 "dev": true,
4553 "hasInstallScript": true,
4554 "dependencies": {
@@ -4632,7 +4591,7 @@
4591 "request-progress": "^3.0.0",
4592 "semver": "^7.5.3",
4593 "supports-color": "^8.1.1",
4635 - "tmp": "~0.2.1",
4594 + "tmp": "~0.2.3",
4595 "untildify": "^4.0.0",
4596 "yauzl": "^2.10.0"
4597 },
@@ -4830,13 +4789,10 @@
4789 "dev": true
4790 },
4791 "node_modules/deep-eql": {
4833 - "version": "4.1.4",
4834 - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.4.tgz",
4835 - "integrity": "sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==",
4792 + "version": "5.0.2",
4793 + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz",
4794 + "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==",
4795 "dev": true,
4837 - "dependencies": {
4838 - "type-detect": "^4.0.0"
4839 - },
4796 "engines": {
4797 "node": ">=6"
4798 }
@@ -4852,15 +4808,6 @@
4808 "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
4809 "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ=="
4810 },
4855 - "node_modules/deepmerge": {
4856 - "version": "4.3.1",
4857 - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
4858 - "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==",
4859 - "dev": true,
4860 - "engines": {
4861 - "node": ">=0.10.0"
4862 - }
4863 - },
4811 "node_modules/default-browser": {
4812 "version": "5.2.1",
4813 "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.2.1.tgz",
@@ -4944,6 +4891,12 @@
4891 "node": ">= 0.8"
4892 }
4893 },
4894 + "node_modules/destr": {
4895 + "version": "2.0.3",
4896 + "resolved": "https://registry.npmjs.org/destr/-/destr-2.0.3.tgz",
4897 + "integrity": "sha512-2N3BOUU4gYMpTP24s5rF5iP7BDr7uNTCs4ozw3kf/eKfvWSIu93GEBi5m427YoyJoeOzQ5smuu4nNAPGb8idSQ==",
4898 + "dev": true
4899 + },
4900 "node_modules/destroy": {
4901 "version": "1.2.0",
4902 "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
@@ -4954,15 +4907,6 @@
4907 "npm": "1.2.8000 || >= 1.4.16"
4908 }
4909 },
4957 - "node_modules/detect-indent": {
4958 - "version": "7.0.1",
4959 - "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-7.0.1.tgz",
4960 - "integrity": "sha512-Mc7QhQ8s+cLrnUfU/Ji94vG/r8M26m8f++vyres4ZoojaRDpZ1eSIh/EpzLNwlWuvzSZ3UbDFspjFvTDXe6e/g==",
4961 - "dev": true,
4962 - "engines": {
4963 - "node": ">=12.20"
4964 - }
4965 - },
4910 "node_modules/detect-touch-device": {
4911 "version": "1.1.6",
4912 "resolved": "https://registry.npmjs.org/detect-touch-device/-/detect-touch-device-1.1.6.tgz",
@@ -5140,9 +5084,9 @@
5084 "dev": true
5085 },
5086 "node_modules/electron-to-chromium": {
5143 - "version": "1.4.814",
5144 - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.814.tgz",
5145 - "integrity": "sha512-GVulpHjFu1Y9ZvikvbArHmAhZXtm3wHlpjTMcXNGKl4IQ4jMQjlnz8yMQYYqdLHKi/jEL2+CBC2akWVCoIGUdw==",
5087 + "version": "1.4.820",
5088 + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.820.tgz",
5089 + "integrity": "sha512-kK/4O/YunacfboFEk/BDf7VO1HoPmDudLTJAU9NmXIOSjsV7qVIX3OrI4REZo0VmdqhcpUcncQc6N8Q3aEXlHg==",
5090 "dev": true
5091 },
5092 "node_modules/emoji-regex": {
@@ -5286,15 +5230,15 @@
5230 }
5231 },
5232 "node_modules/eslint": {
5289 - "version": "9.5.0",
5290 - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.5.0.tgz",
5291 - "integrity": "sha512-+NAOZFrW/jFTS3dASCGBxX1pkFD0/fsO+hfAkJ4TyYKwgsXZbqzrw+seCYFCcPCYXvnD67tAnglU7GQTz6kcVw==",
5233 + "version": "9.6.0",
5234 + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.6.0.tgz",
5235 + "integrity": "sha512-ElQkdLMEEqQNM9Njff+2Y4q2afHk7JpkPvrd7Xh7xefwgQynqPxwf55J7di9+MEibWUGdNjFF9ITG9Pck5M84w==",
5236 "dependencies": {
5237 "@eslint-community/eslint-utils": "^4.2.0",
5238 "@eslint-community/regexpp": "^4.6.1",
5295 - "@eslint/config-array": "^0.16.0",
5239 + "@eslint/config-array": "^0.17.0",
5240 "@eslint/eslintrc": "^3.1.0",
5297 - "@eslint/js": "9.5.0",
5241 + "@eslint/js": "9.6.0",
5242 "@humanwhocodes/module-importer": "^1.0.1",
5243 "@humanwhocodes/retry": "^0.3.0",
5244 "@nodelib/fs.walk": "^1.2.8",
@@ -5305,7 +5249,7 @@
5249 "escape-string-regexp": "^4.0.0",
5250 "eslint-scope": "^8.0.1",
5251 "eslint-visitor-keys": "^4.0.0",
5308 - "espree": "^10.0.1",
5252 + "espree": "^10.1.0",
5253 "esquery": "^1.5.0",
5254 "esutils": "^2.0.2",
5255 "fast-deep-equal": "^3.1.3",
@@ -5435,9 +5379,9 @@
5379 }
5380 },
5381 "node_modules/eslint-plugin-vue": {
5438 - "version": "9.26.0",
5439 - "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.26.0.tgz",
5440 - "integrity": "sha512-eTvlxXgd4ijE1cdur850G6KalZqk65k1JKoOI2d1kT3hr8sPD07j1q98FRFdNnpxBELGPWxZmInxeHGF/GxtqQ==",
5382 + "version": "9.27.0",
5383 + "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.27.0.tgz",
5384 + "integrity": "sha512-5Dw3yxEyuBSXTzT5/Ge1X5kIkRTQ3nvBn/VwPwInNiZBSJOO/timWMUaflONnFBzU6NhB68lxnCda7ULV5N7LA==",
5385 "dependencies": {
5386 "@eslint-community/eslint-utils": "^4.4.0",
5387 "globals": "^13.24.0",
@@ -5445,7 +5389,7 @@
5389 "nth-check": "^2.1.1",
5390 "postcss-selector-parser": "^6.0.15",
5391 "semver": "^7.6.0",
5448 - "vue-eslint-parser": "^9.4.2",
5392 + "vue-eslint-parser": "^9.4.3",
5393 "xml-name-validator": "^4.0.0"
5394 },
5395 "engines": {
@@ -5507,9 +5451,9 @@
5451 }
5452 },
5453 "node_modules/eslint/node_modules/@eslint/js": {
5510 - "version": "9.5.0",
5511 - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.5.0.tgz",
5512 - "integrity": "sha512-A7+AOT2ICkodvtsWnxZP4Xxk3NbZ3VMHd8oihydLRGrJgqqdEz1qSeEgXYyT/Cu8h1TWWsQRejIx48mtjZ5y1w==",
5454 + "version": "9.6.0",
5455 + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.6.0.tgz",
5456 + "integrity": "sha512-D9B0/3vNg44ZeWbYMpBoXqNP4j6eQD5vNwIlGAuFRRzK/WtT/jvDQW3Bi9kkf3PMDMlM7Yi+73VLUsn5bJcl8A==",
5457 "engines": {
5458 "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
5459 }
@@ -5648,9 +5592,9 @@
5592 }
5593 },
5594 "node_modules/esquery": {
5651 - "version": "1.5.0",
5652 - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz",
5653 - "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==",
5595 + "version": "1.6.0",
5596 + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz",
5597 + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==",
5598 "dependencies": {
5599 "estraverse": "^5.1.0"
5600 },
@@ -6176,9 +6120,9 @@
6120 }
6121 },
6122 "node_modules/glob": {
6179 - "version": "10.4.2",
6180 - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.2.tgz",
6181 - "integrity": "sha512-GwMlUF6PkPo3Gk21UxkCohOv0PLcIXVtKyLlpEI28R/cO/4eNOdmLk3CMW1wROV/WR/EsZOWAfBbBOqYvs88/w==",
6123 + "version": "10.4.5",
6124 + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz",
6125 + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==",
6126 "dev": true,
6127 "dependencies": {
6128 "foreground-child": "^3.1.0",
@@ -6191,9 +6135,6 @@
6135 "bin": {
6136 "glob": "dist/esm/bin.mjs"
6137 },
6194 - "engines": {
6195 - "node": ">=16 || 14 >=14.18"
6196 - },
6138 "funding": {
6139 "url": "https://github.com/sponsors/isaacs"
6140 }
@@ -6240,9 +6181,9 @@
6181 }
6182 },
6183 "node_modules/globals": {
6243 - "version": "15.6.0",
6244 - "resolved": "https://registry.npmjs.org/globals/-/globals-15.6.0.tgz",
6245 - "integrity": "sha512-UzcJi88Hw//CurUIRa9Jxb0vgOCcuD/MNjwmXp633cyaRKkCWACkoqHCtfZv43b1kqXGg/fpOa8bwgacCeXsVg==",
6184 + "version": "15.8.0",
6185 + "resolved": "https://registry.npmjs.org/globals/-/globals-15.8.0.tgz",
6186 + "integrity": "sha512-VZAJ4cewHTExBWDHR6yptdIBlx9YSSZuwojj9Nt5mBRXQzrKakDsVKQ1J63sklLvzAJm0X5+RpO4i3Y2hcOnFw==",
6187 "dev": true,
6188 "engines": {
6189 "node": ">=18"
@@ -6380,9 +6321,9 @@
6321 "integrity": "sha512-BXUKIkUuh6cmmxzi5OIbUJxrG8OAk2MqoL1DtO3Wo9D2faJg2ph5ntyuQeLqaHJmzER6H5tllCDA9ZnNe9BVGg=="
6322 },
6323 "node_modules/highlight.js": {
6383 - "version": "11.9.0",
6384 - "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.9.0.tgz",
6385 - "integrity": "sha512-fJ7cW7fQGCYAkgv4CPfwFHrfd/cLS4Hau96JuJ+ZTOWhjnhoeN1ub1tFmALm/+lW5z4WCAuAV9bm05AP0mS6Gw==",
6324 + "version": "11.10.0",
6325 + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.10.0.tgz",
6326 + "integrity": "sha512-SYVnVFswQER+zu1laSya563s+F8VDGt7o35d4utbamowvUNLLMovFqwCLSocpZTz3MgaSRA1IbqRWZv97dtErQ==",
6327 "engines": {
6328 "node": ">=12.0.0"
6329 }
@@ -6629,9 +6570,9 @@
6570 }
6571 },
6572 "node_modules/importx": {
6632 - "version": "0.3.7",
6633 - "resolved": "https://registry.npmjs.org/importx/-/importx-0.3.7.tgz",
6634 - "integrity": "sha512-K2+4GWH3ftMEbwLUK4IVC1qmk5POIofYb+2dHua1Szl5hQexSKv/QfwruTMzROqFWXnPUDJml5CnRiyk1YAesg==",
6573 + "version": "0.3.11",
6574 + "resolved": "https://registry.npmjs.org/importx/-/importx-0.3.11.tgz",
6575 + "integrity": "sha512-KsFrXKNGeNdeaBsTWU2sEhL3xo+uxquONy5FWnTBititJKebUBg8EgHW8Wl5bpNP+8iN9yOpGqIhVyjfjJigtA==",
6576 "dev": true,
6577 "dependencies": {
6578 "bundle-require": "^5.0.0",
@@ -6639,8 +6580,8 @@
6580 "esbuild": "^0.20.2",
6581 "jiti": "^1.21.6",
6582 "pathe": "^1.1.2",
6642 - "pkg-types": "^1.1.1",
6643 - "tsx": "^4.15.6"
6583 + "pkg-types": "^1.1.3",
6584 + "tsx": "^4.16.2"
6585 },
6586 "funding": {
6587 "url": "https://github.com/sponsors/antfu"
@@ -7329,15 +7270,15 @@
7270 "dev": true
7271 },
7272 "node_modules/jackspeak": {
7332 - "version": "3.4.0",
7333 - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.0.tgz",
7334 - "integrity": "sha512-JVYhQnN59LVPFCEcVa2C3CrEKYacvjRfqIQl+h8oi91aLYQVWRYbxjPcv1bUiUy/kLmQaANrYfNMCO3kuEDHfw==",
7273 + "version": "3.4.2",
7274 + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.2.tgz",
7275 + "integrity": "sha512-qH3nOSj8q/8+Eg8LUPOq3C+6HWkpUioIjDsq1+D4zY91oZvpPttw8GwtF1nReRYKXl+1AORyFqtm2f5Q1SB6/Q==",
7276 "dev": true,
7277 "dependencies": {
7278 "@isaacs/cliui": "^8.0.2"
7279 },
7280 "engines": {
7340 - "node": ">=14"
7281 + "node": "14 >=14.21 || 16 >=16.20 || >=18"
7282 },
7283 "funding": {
7284 "url": "https://github.com/sponsors/isaacs"
@@ -7368,9 +7309,9 @@
7309 }
7310 },
7311 "node_modules/jose": {
7371 - "version": "5.6.2",
7372 - "resolved": "https://registry.npmjs.org/jose/-/jose-5.6.2.tgz",
7373 - "integrity": "sha512-F1t1/WZJ4JdmCE/XoMYw1dPOW5g8JF0xGm6Ox2fwaCAPlCzt+4Bh0EWP59iQuZNHHauDkCdjx+kCZSh5z/PGow==",
7312 + "version": "5.6.3",
7313 + "resolved": "https://registry.npmjs.org/jose/-/jose-5.6.3.tgz",
7314 + "integrity": "sha512-1Jh//hEEwMhNYPDDLwXHa2ePWgWiFNNUadVmguAAw2IJ6sj9mNxV5tGXJNqlMkJAybF6Lgw1mISDxTePP/187g==",
7315 "funding": {
7316 "url": "https://github.com/sponsors/panva"
7317 }
@@ -7603,15 +7544,6 @@
7544 "json-buffer": "3.0.1"
7545 }
7546 },
7606 - "node_modules/kleur": {
7607 - "version": "3.0.3",
7608 - "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz",
7609 - "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==",
7610 - "dev": true,
7611 - "engines": {
7612 - "node": ">=6"
7613 - }
7614 - },
7547 "node_modules/koa": {
7548 "version": "2.15.3",
7549 "resolved": "https://registry.npmjs.org/koa/-/koa-2.15.3.tgz",
@@ -8125,9 +8057,9 @@
8057 }
8058 },
8059 "node_modules/loupe": {
8128 - "version": "2.3.7",
8129 - "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz",
8130 - "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==",
8060 + "version": "3.1.1",
8061 + "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.1.tgz",
8062 + "integrity": "sha512-edNu/8D5MKVfGVFRhFf8aAxiTM6Wumfz5XsaatSxlD3w4R1d/WEKUTydCdPGbl9K7QG/Ca3GnDV2sIKIpXRQcw==",
8063 "dev": true,
8064 "dependencies": {
8065 "get-func-name": "^2.0.1"
@@ -8426,6 +8358,12 @@
8358 "node": ">= 0.6"
8359 }
8360 },
8361 + "node_modules/node-fetch-native": {
8362 + "version": "1.6.4",
8363 + "resolved": "https://registry.npmjs.org/node-fetch-native/-/node-fetch-native-1.6.4.tgz",
8364 + "integrity": "sha512-IhOigYzAKHd244OC0JIMIUrjzctirCmPkaIfhDeGcEETWof5zKYUW7e7MYvChGWh/4CJeXEgsRyGzuF334rOOQ==",
8365 + "dev": true
8366 + },
8367 "node_modules/node-releases": {
8368 "version": "2.0.14",
8369 "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz",
@@ -8475,9 +8413,9 @@
8413 }
8414 },
8415 "node_modules/npm-run-all2": {
8478 - "version": "6.2.0",
8479 - "resolved": "https://registry.npmjs.org/npm-run-all2/-/npm-run-all2-6.2.0.tgz",
8480 - "integrity": "sha512-wA7yVIkthe6qJBfiJ2g6aweaaRlw72itsFGF6HuwCHKwtwAx/4BY1vVpk6bw6lS8RLMsexoasOkd0aYOmsFG7Q==",
8416 + "version": "6.2.2",
8417 + "resolved": "https://registry.npmjs.org/npm-run-all2/-/npm-run-all2-6.2.2.tgz",
8418 + "integrity": "sha512-Q+alQAGIW7ZhKcxLt8GcSi3h3ryheD6xnmXahkMRVM5LYmajcUrSITm8h+OPC9RYWMV2GR0Q1ntTUCfxaNoOJw==",
8419 "dev": true,
8420 "dependencies": {
8421 "ansi-styles": "^6.2.1",
@@ -8495,7 +8433,7 @@
8433 "run-s": "bin/run-s/index.js"
8434 },
8435 "engines": {
8498 - "node": "^14.18.0 || >=16.0.0",
8436 + "node": "^14.18.0 || ^16.13.0 || >=18.0.0",
8437 "npm": ">= 8"
8438 }
8439 },
@@ -8570,6 +8508,17 @@
8508 "url": "https://github.com/sponsors/ljharb"
8509 }
8510 },
8511 + "node_modules/ofetch": {
8512 + "version": "1.3.4",
8513 + "resolved": "https://registry.npmjs.org/ofetch/-/ofetch-1.3.4.tgz",
8514 + "integrity": "sha512-KLIET85ik3vhEfS+3fDlc/BAZiAp+43QEC/yCo5zkNoY2YaKvNkOaFr/6wCFgFH1kuYQM5pMNi0Tg8koiIemtw==",
8515 + "dev": true,
8516 + "dependencies": {
8517 + "destr": "^2.0.3",
8518 + "node-fetch-native": "^1.6.3",
8519 + "ufo": "^1.5.3"
8520 + }
8521 + },
8522 "node_modules/on-finished": {
8523 "version": "2.4.1",
8524 "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
@@ -8793,12 +8742,12 @@
8742 }
8743 },
8744 "node_modules/path-scurry/node_modules/lru-cache": {
8796 - "version": "10.3.0",
8797 - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.3.0.tgz",
8798 - "integrity": "sha512-CQl19J/g+Hbjbv4Y3mFNNXFEL/5t/KCg8POCuUqd4rMKjGG+j1ybER83hxV58zL+dFI1PTkt3GNFSHRt+d8qEQ==",
8745 + "version": "10.4.2",
8746 + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.2.tgz",
8747 + "integrity": "sha512-voV4dDrdVZVNz84n39LFKDaRzfwhdzJ7akpyXfTMxCgRUp07U3lcJUXRlhTKP17rgt09sUzLi5iCitpEAr+6ug==",
8748 "dev": true,
8749 "engines": {
8801 - "node": "14 || >=16.14"
8750 + "node": "14 || 16 || 18 || 20 || >=22"
8751 }
8752 },
8753 "node_modules/path-to-regexp": {
@@ -8822,12 +8771,12 @@
8771 "dev": true
8772 },
8773 "node_modules/pathval": {
8825 - "version": "1.1.1",
8826 - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz",
8827 - "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==",
8774 + "version": "2.0.0",
8775 + "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.0.tgz",
8776 + "integrity": "sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==",
8777 "dev": true,
8778 "engines": {
8830 - "node": "*"
8779 + "node": ">= 14.16"
8780 }
8781 },
8782 "node_modules/pause-stream": {
@@ -8962,13 +8911,13 @@
8911 }
8912 },
8913 "node_modules/pkg-types": {
8965 - "version": "1.1.1",
8966 - "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.1.1.tgz",
8967 - "integrity": "sha512-ko14TjmDuQJ14zsotODv7dBlwxKhUKQEhuhmbqo1uCi9BB0Z2alo/wAXg6q1dTR5TyuqYyWhjtfe/Tsh+X28jQ==",
8914 + "version": "1.1.3",
8915 + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.1.3.tgz",
8916 + "integrity": "sha512-+JrgthZG6m3ckicaOB74TwQ+tBWsFl3qVQg7mN8ulwSOElJ7gBhKzj2VkCPnZ4NlF6kEquYU+RIYNVAvzd54UA==",
8917 "dev": true,
8918 "dependencies": {
8919 "confbox": "^0.1.7",
8971 - "mlly": "^1.7.0",
8920 + "mlly": "^1.7.1",
8921 "pathe": "^1.1.2"
8922 }
8923 },
@@ -9005,9 +8954,9 @@
8954 }
8955 },
8956 "node_modules/postcss": {
9008 - "version": "8.4.38",
9009 - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz",
9010 - "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==",
8957 + "version": "8.4.39",
8958 + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.39.tgz",
8959 + "integrity": "sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw==",
8960 "funding": [
8961 {
8962 "type": "opencollective",
@@ -9024,7 +8973,7 @@
8973 ],
8974 "dependencies": {
8975 "nanoid": "^3.3.7",
9027 - "picocolors": "^1.0.0",
8976 + "picocolors": "^1.0.1",
8977 "source-map-js": "^1.2.0"
8978 },
8979 "engines": {
@@ -9231,19 +9180,6 @@
9180 "node": ">= 0.6.0"
9181 }
9182 },
9234 - "node_modules/prompts": {
9235 - "version": "2.4.2",
9236 - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz",
9237 - "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==",
9238 - "dev": true,
9239 - "dependencies": {
9240 - "kleur": "^3.0.3",
9241 - "sisteransi": "^1.0.5"
9242 - },
9243 - "engines": {
9244 - "node": ">= 6"
9245 - }
9246 - },
9183 "node_modules/proto-list": {
9184 "version": "1.2.4",
9185 "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz",
@@ -9663,9 +9599,9 @@
9599 "dev": true
9600 },
9601 "node_modules/rollup": {
9666 - "version": "4.18.0",
9667 - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.18.0.tgz",
9668 - "integrity": "sha512-QmJz14PX3rzbJCN1SG4Xe/bAAX2a6NpCP8ab2vfu2GiUr8AQcr2nCV/oEO3yneFarB67zk8ShlIyWb2LGTb3Sg==",
9602 + "version": "4.18.1",
9603 + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.18.1.tgz",
9604 + "integrity": "sha512-Elx2UT8lzxxOXMpy5HWQGZqkrQOtrVDDa/bm9l10+U4rQnVzbL/LgZ4NOM1MPIDyHk69W4InuYDF5dzRh4Kw1A==",
9605 "dev": true,
9606 "dependencies": {
9607 "@types/estree": "1.0.5"
@@ -9678,22 +9614,22 @@
9614 "npm": ">=8.0.0"
9615 },
9616 "optionalDependencies": {
9681 - "@rollup/rollup-android-arm-eabi": "4.18.0",
9682 - "@rollup/rollup-android-arm64": "4.18.0",
9683 - "@rollup/rollup-darwin-arm64": "4.18.0",
9684 - "@rollup/rollup-darwin-x64": "4.18.0",
9685 - "@rollup/rollup-linux-arm-gnueabihf": "4.18.0",
9686 - "@rollup/rollup-linux-arm-musleabihf": "4.18.0",
9687 - "@rollup/rollup-linux-arm64-gnu": "4.18.0",
9688 - "@rollup/rollup-linux-arm64-musl": "4.18.0",
9689 - "@rollup/rollup-linux-powerpc64le-gnu": "4.18.0",
9690 - "@rollup/rollup-linux-riscv64-gnu": "4.18.0",
9691 - "@rollup/rollup-linux-s390x-gnu": "4.18.0",
9692 - "@rollup/rollup-linux-x64-gnu": "4.18.0",
9693 - "@rollup/rollup-linux-x64-musl": "4.18.0",
9694 - "@rollup/rollup-win32-arm64-msvc": "4.18.0",
9695 - "@rollup/rollup-win32-ia32-msvc": "4.18.0",
9696 - "@rollup/rollup-win32-x64-msvc": "4.18.0",
9617 + "@rollup/rollup-android-arm-eabi": "4.18.1",
9618 + "@rollup/rollup-android-arm64": "4.18.1",
9619 + "@rollup/rollup-darwin-arm64": "4.18.1",
9620 + "@rollup/rollup-darwin-x64": "4.18.1",
9621 + "@rollup/rollup-linux-arm-gnueabihf": "4.18.1",
9622 + "@rollup/rollup-linux-arm-musleabihf": "4.18.1",
9623 + "@rollup/rollup-linux-arm64-gnu": "4.18.1",
9624 + "@rollup/rollup-linux-arm64-musl": "4.18.1",
9625 + "@rollup/rollup-linux-powerpc64le-gnu": "4.18.1",
9626 + "@rollup/rollup-linux-riscv64-gnu": "4.18.1",
9627 + "@rollup/rollup-linux-s390x-gnu": "4.18.1",
9628 + "@rollup/rollup-linux-x64-gnu": "4.18.1",
9629 + "@rollup/rollup-linux-x64-musl": "4.18.1",
9630 + "@rollup/rollup-win32-arm64-msvc": "4.18.1",
9631 + "@rollup/rollup-win32-ia32-msvc": "4.18.1",
9632 + "@rollup/rollup-win32-x64-msvc": "4.18.1",
9633 "fsevents": "~2.3.2"
9634 }
9635 },
@@ -9924,11 +9860,12 @@
9860 }
9861 },
9862 "node_modules/shiki": {
9927 - "version": "1.9.1",
9928 - "resolved": "https://registry.npmjs.org/shiki/-/shiki-1.9.1.tgz",
9929 - "integrity": "sha512-8PDkgb5ja3nfujTjvC4VytL6wGOGCtFAClUb2r3QROevYXxcq+/shVJK5s6gy0HZnjaJgFxd6BpPqpRfqne5rA==",
9863 + "version": "1.10.3",
9864 + "resolved": "https://registry.npmjs.org/shiki/-/shiki-1.10.3.tgz",
9865 + "integrity": "sha512-eneCLncGuvPdTutJuLyUGS8QNPAVFO5Trvld2wgEq1e002mwctAhJKeMGWtWVXOIEzmlcLRqcgPSorR6AVzOmQ==",
9866 "dependencies": {
9931 - "@shikijs/core": "1.9.1"
9867 + "@shikijs/core": "1.10.3",
9868 + "@types/hast": "^3.0.4"
9869 }
9870 },
9871 "node_modules/side-channel": {
@@ -10284,24 +10221,6 @@
10221 "url": "https://github.com/sponsors/sindresorhus"
10222 }
10223 },
10287 - "node_modules/strip-literal": {
10288 - "version": "2.1.0",
10289 - "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-2.1.0.tgz",
10290 - "integrity": "sha512-Op+UycaUt/8FbN/Z2TWPBLge3jWrP3xj10f3fnYxf052bKuS3EKs1ZQcVGjnEMdsNVAM+plXRdmjrZ/KgG3Skw==",
10291 - "dev": true,
10292 - "dependencies": {
10293 - "js-tokens": "^9.0.0"
10294 - },
10295 - "funding": {
10296 - "url": "https://github.com/sponsors/antfu"
10297 - }
10298 - },
10299 - "node_modules/strip-literal/node_modules/js-tokens": {
10300 - "version": "9.0.0",
10301 - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.0.tgz",
10302 - "integrity": "sha512-WriZw1luRMlmV3LGJaR6QOJjWwgLUTf89OwT2lUOyjX2dJGBwgmIkbcz+7WFZjrZM635JOIR517++e/67CP9dQ==",
10303 - "dev": true
10304 - },
10224 "node_modules/sucrase": {
10225 "version": "3.35.0",
10226 "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz",
@@ -10597,20 +10516,15 @@
10516 }
10517 },
10518 "node_modules/taze": {
10600 - "version": "0.13.9",
10601 - "resolved": "https://registry.npmjs.org/taze/-/taze-0.13.9.tgz",
10602 - "integrity": "sha512-qBKfViatIEkw7GNlHU8wV28MtRbdrpwxjcZbcqtCi6gHv2X0JAZ9+K8cp4O5UfVjEvFiafw5iSosBlKM7Fb4XA==",
10519 + "version": "0.14.2",
10520 + "resolved": "https://registry.npmjs.org/taze/-/taze-0.14.2.tgz",
10521 + "integrity": "sha512-VjOanFrc3lYIOi6o+FX4RI5m0NOhOb3d+vBK+fRoR4izS6IIGh3y1liMGsnSpC4V7SEWPmh1Z8z4Vr9AWJKFOg==",
10522 "dev": true,
10523 "dependencies": {
10524 "@antfu/ni": "^0.21.12",
10525 "@jsdevtools/ez-spawn": "^3.0.4",
10607 - "cli-progress": "^3.12.0",
10608 - "deepmerge": "^4.3.1",
10609 - "detect-indent": "^7.0.1",
10610 - "picocolors": "^1.0.1",
10611 - "prompts": "^2.4.2",
10612 - "ufo": "^1.5.3",
10613 - "unconfig": "^0.4.4",
10526 + "ofetch": "^1.3.4",
10527 + "unconfig": "^0.4.5",
10528 "yargs": "^17.7.2"
10529 },
10530 "bin": {
@@ -10621,14 +10535,14 @@
10535 }
10536 },
10537 "node_modules/taze/node_modules/unconfig": {
10624 - "version": "0.4.4",
10625 - "resolved": "https://registry.npmjs.org/unconfig/-/unconfig-0.4.4.tgz",
10626 - "integrity": "sha512-Dmz2VZAnx5yxANZ5koy5u6bLd/GJ8dgr0y6/78+40obWIsnvZdTIxLMIx6qBqsabzGTB4yUiMRIOV4hwwVM2pQ==",
10538 + "version": "0.4.5",
10539 + "resolved": "https://registry.npmjs.org/unconfig/-/unconfig-0.4.5.tgz",
10540 + "integrity": "sha512-+b4pZmGFeT3FD9EHWGkNwuOwrNzfgUq4ZoTh63+EKDyxLvYKajbowjRcKLumGExmPKNi5jxIpzhheKsPtV8dig==",
10541 "dev": true,
10542 "dependencies": {
10629 - "@antfu/utils": "^0.7.8",
10543 + "@antfu/utils": "^0.7.10",
10544 "defu": "^6.1.4",
10631 - "importx": "^0.3.6"
10545 + "importx": "^0.3.10"
10546 },
10547 "funding": {
10548 "url": "https://github.com/sponsors/antfu"
@@ -10682,18 +10596,18 @@
10596 "dev": true
10597 },
10598 "node_modules/tinypool": {
10685 - "version": "0.8.4",
10686 - "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.8.4.tgz",
10687 - "integrity": "sha512-i11VH5gS6IFeLY3gMBQ00/MmLncVP7JLXOw1vlgkytLmJK7QnEr7NXf0LBdxfmNPAeyetukOk0bOYrJrFGjYJQ==",
10599 + "version": "1.0.0",
10600 + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.0.0.tgz",
10601 + "integrity": "sha512-KIKExllK7jp3uvrNtvRBYBWBOAXSX8ZvoaD8T+7KB/QHIuoJW3Pmr60zucywjAlMb5TeXUkcs/MWeWLu0qvuAQ==",
10602 "dev": true,
10603 "engines": {
10690 - "node": ">=14.0.0"
10604 + "node": "^18.0.0 || >=20.0.0"
10605 }
10606 },
10607 "node_modules/tinyspy": {
10694 - "version": "2.2.1",
10695 - "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-2.2.1.tgz",
10696 - "integrity": "sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A==",
10608 + "version": "3.0.0",
10609 + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-3.0.0.tgz",
10610 + "integrity": "sha512-q5nmENpTHgiPVd1cJDDc9cVoYN5x4vCvwT3FMilvKPKneCBZAxn2YWQjDF0UMcE9k0Cay1gBiDfTMU0g+mPMQA==",
10611 "dev": true,
10612 "engines": {
10613 "node": ">=14.0.0"
@@ -10819,12 +10733,12 @@
10733 }
10734 },
10735 "node_modules/tsx": {
10822 - "version": "4.15.7",
10823 - "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.15.7.tgz",
10824 - "integrity": "sha512-u3H0iSFDZM3za+VxkZ1kywdCeHCn+8/qHQS1MNoO2sONDgD95HlWtt8aB23OzeTmFP9IU4/8bZUdg58Uu5J4cg==",
10736 + "version": "4.16.2",
10737 + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.16.2.tgz",
10738 + "integrity": "sha512-C1uWweJDgdtX2x600HjaFaucXTilT7tgUZHbOE4+ypskZ1OP8CRCSDkCxG6Vya9EwaFIVagWwpaVAn5wzypaqQ==",
10739 "dev": true,
10740 "dependencies": {
10827 - "esbuild": "~0.21.4",
10741 + "esbuild": "~0.21.5",
10742 "get-tsconfig": "^4.7.5"
10743 },
10744 "bin": {
@@ -10876,9 +10790,9 @@
10790 }
10791 },
10792 "node_modules/type-fest": {
10879 - "version": "4.20.1",
10880 - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.20.1.tgz",
10881 - "integrity": "sha512-R6wDsVsoS9xYOpy8vgeBlqpdOyzJ12HNfQhC/aAKWM3YoCV9TtunJzh/QpkMgeDhkoynDcw5f1y+qF9yc/HHyg==",
10793 + "version": "4.21.0",
10794 + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.21.0.tgz",
10795 + "integrity": "sha512-ADn2w7hVPcK6w1I0uWnM//y1rLXZhzB9mr0a3OirzclKF1Wp6VzevUmzz/NRAWunOT6E8HrnpGY7xOfc6K57fA==",
10796 "dev": true,
10797 "engines": {
10798 "node": ">=16"
@@ -10901,9 +10815,9 @@
10815 }
10816 },
10817 "node_modules/typescript": {
10904 - "version": "5.5.2",
10905 - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.2.tgz",
10906 - "integrity": "sha512-NcRtPEOsPFFWjobJEtfihkLCZCXZt/os3zf8nTxjVH3RvTSxjrCamJpbExGvYOF+tFHc3pA65qpdwPbzjohhew==",
10818 + "version": "5.5.3",
10819 + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.3.tgz",
10820 + "integrity": "sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ==",
10821 "peer": true,
10822 "bin": {
10823 "tsc": "bin/tsc",
@@ -10953,9 +10867,9 @@
10867 }
10868 },
10869 "node_modules/unplugin": {
10956 - "version": "1.10.1",
10957 - "resolved": "https://registry.npmjs.org/unplugin/-/unplugin-1.10.1.tgz",
10958 - "integrity": "sha512-d6Mhq8RJeGA8UfKCu54Um4lFA0eSaRa3XxdAJg8tIdxbu1ubW0hBCZUL7yI2uGyYCRndvbK8FLHzqy2XKfeMsg==",
10870 + "version": "1.11.0",
10871 + "resolved": "https://registry.npmjs.org/unplugin/-/unplugin-1.11.0.tgz",
10872 + "integrity": "sha512-3r7VWZ/webh0SGgJScpWl2/MRCZK5d3ZYFcNaeci/GQ7Teop7zf0Nl2pUuz7G21BwPd9pcUPOC5KmJ2L3WgC5g==",
10873 "dev": true,
10874 "dependencies": {
10875 "acorn": "^8.11.3",
@@ -11029,9 +10943,9 @@
10943 }
10944 },
10945 "node_modules/update-browserslist-db": {
11032 - "version": "1.0.16",
11033 - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.16.tgz",
11034 - "integrity": "sha512-KVbTxlBYlckhF5wgfyZXTWnMn7MMZjMu9XG8bPlliUOP9ThaF4QnhP8qrjrH7DRzHfSk0oQv1wToW+iA5GajEQ==",
10946 + "version": "1.1.0",
10947 + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz",
10948 + "integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==",
10949 "dev": true,
10950 "funding": [
10951 {
@@ -11133,13 +11047,13 @@
11047 }
11048 },
11049 "node_modules/vite": {
11136 - "version": "5.3.2",
11137 - "resolved": "https://registry.npmjs.org/vite/-/vite-5.3.2.tgz",
11138 - "integrity": "sha512-6lA7OBHBlXUxiJxbO5aAY2fsHHzDr1q7DvXYnyZycRs2Dz+dXBWuhpWHvmljTRTpQC2uvGmUFFkSHF2vGo90MA==",
11050 + "version": "5.3.3",
11051 + "resolved": "https://registry.npmjs.org/vite/-/vite-5.3.3.tgz",
11052 + "integrity": "sha512-NPQdeCU0Dv2z5fu+ULotpuq5yfCS1BzKUIPhNbP3YBfAMGJXbt2nS+sbTFu+qchaqWTD+H3JK++nRwr6XIcp6A==",
11053 "dev": true,
11054 "dependencies": {
11055 "esbuild": "^0.21.3",
11142 - "postcss": "^8.4.38",
11056 + "postcss": "^8.4.39",
11057 "rollup": "^4.13.0"
11058 },
11059 "bin": {
@@ -11227,15 +11141,15 @@
11141 }
11142 },
11143 "node_modules/vite-node": {
11230 - "version": "1.6.0",
11231 - "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-1.6.0.tgz",
11232 - "integrity": "sha512-de6HJgzC+TFzOu0NTC4RAIsyf/DY/ibWDYQUcuEA84EMHhcefTUGkjFHKKEJhQN4A+6I0u++kr3l36ZF2d7XRw==",
11144 + "version": "2.0.1",
11145 + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-2.0.1.tgz",
11146 + "integrity": "sha512-nVd6kyhPAql0s+xIVJzuF+RSRH8ZimNrm6U8ZvTA4MXv8CHI17TFaQwRaFiK75YX6XeFqZD4IoAaAfi9OR1XvQ==",
11147 "dev": true,
11148 "dependencies": {
11149 "cac": "^6.7.14",
11236 - "debug": "^4.3.4",
11237 - "pathe": "^1.1.1",
11238 - "picocolors": "^1.0.0",
11150 + "debug": "^4.3.5",
11151 + "pathe": "^1.1.2",
11152 + "picocolors": "^1.0.1",
11153 "vite": "^5.0.0"
11154 },
11155 "bin": {
@@ -11325,14 +11239,14 @@
11239 }
11240 },
11241 "node_modules/vite-plugin-vue-devtools": {
11328 - "version": "7.3.4",
11329 - "resolved": "https://registry.npmjs.org/vite-plugin-vue-devtools/-/vite-plugin-vue-devtools-7.3.4.tgz",
11330 - "integrity": "sha512-5WKGIFldO9/E/J6d+x286ENieFUsexcg8Qgh/js3rEJtzipHzxiD47xMJVSBhl14n1E4jABIMuwmn1FYtpwm3w==",
11242 + "version": "7.3.5",
11243 + "resolved": "https://registry.npmjs.org/vite-plugin-vue-devtools/-/vite-plugin-vue-devtools-7.3.5.tgz",
11244 + "integrity": "sha512-6omLXTfYu0bmSmncPSbj4mdMPB3t5dAZkUyriJikahGEnvv5gynHlydDsJShHT6l/5dCkvmSesSji/2a6FfutQ==",
11245 "dev": true,
11246 "dependencies": {
11333 - "@vue/devtools-core": "^7.3.4",
11334 - "@vue/devtools-kit": "^7.3.4",
11335 - "@vue/devtools-shared": "^7.3.4",
11247 + "@vue/devtools-core": "^7.3.5",
11248 + "@vue/devtools-kit": "^7.3.5",
11249 + "@vue/devtools-shared": "^7.3.5",
11250 "execa": "^8.0.1",
11251 "sirv": "^2.0.4",
11252 "vite-plugin-inspect": "^0.8.4",
@@ -11512,30 +11426,28 @@
11426 }
11427 },
11428 "node_modules/vitest": {
11515 - "version": "1.6.0",
11516 - "resolved": "https://registry.npmjs.org/vitest/-/vitest-1.6.0.tgz",
11517 - "integrity": "sha512-H5r/dN06swuFnzNFhq/dnz37bPXnq8xB2xB5JOVk8K09rUtoeNN+LHWkoQ0A/i3hvbUKKcCei9KpbxqHMLhLLA==",
11429 + "version": "2.0.1",
11430 + "resolved": "https://registry.npmjs.org/vitest/-/vitest-2.0.1.tgz",
11431 + "integrity": "sha512-PBPvNXRJiywtI9NmbnEqHIhcXlk8mB0aKf6REQIaYGY4JtWF1Pg8Am+N0vAuxdg/wUSlxPSVJr8QdjwcVxc2Hg==",
11432 "dev": true,
11433 "dependencies": {
11520 - "@vitest/expect": "1.6.0",
11521 - "@vitest/runner": "1.6.0",
11522 - "@vitest/snapshot": "1.6.0",
11523 - "@vitest/spy": "1.6.0",
11524 - "@vitest/utils": "1.6.0",
11525 - "acorn-walk": "^8.3.2",
11526 - "chai": "^4.3.10",
11527 - "debug": "^4.3.4",
11434 + "@ampproject/remapping": "^2.3.0",
11435 + "@vitest/expect": "2.0.1",
11436 + "@vitest/runner": "2.0.1",
11437 + "@vitest/snapshot": "2.0.1",
11438 + "@vitest/spy": "2.0.1",
11439 + "@vitest/utils": "2.0.1",
11440 + "chai": "^5.1.1",
11441 + "debug": "^4.3.5",
11442 "execa": "^8.0.1",
11529 - "local-pkg": "^0.5.0",
11530 - "magic-string": "^0.30.5",
11531 - "pathe": "^1.1.1",
11532 - "picocolors": "^1.0.0",
11533 - "std-env": "^3.5.0",
11534 - "strip-literal": "^2.0.0",
11535 - "tinybench": "^2.5.1",
11536 - "tinypool": "^0.8.3",
11443 + "magic-string": "^0.30.10",
11444 + "pathe": "^1.1.2",
11445 + "picocolors": "^1.0.1",
11446 + "std-env": "^3.7.0",
11447 + "tinybench": "^2.8.0",
11448 + "tinypool": "^1.0.0",
11449 "vite": "^5.0.0",
11538 - "vite-node": "1.6.0",
11450 + "vite-node": "2.0.1",
11451 "why-is-node-running": "^2.2.2"
11452 },
11453 "bin": {
@@ -11550,8 +11462,8 @@
11462 "peerDependencies": {
11463 "@edge-runtime/vm": "*",
11464 "@types/node": "^18.0.0 || >=20.0.0",
11553 - "@vitest/browser": "1.6.0",
11554 - "@vitest/ui": "1.6.0",
11465 + "@vitest/browser": "2.0.1",
11466 + "@vitest/ui": "2.0.1",
11467 "happy-dom": "*",
11468 "jsdom": "*"
11469 },
@@ -11765,9 +11677,9 @@
11677 }
11678 },
11679 "node_modules/vue-component-type-helpers": {
11768 - "version": "2.0.22",
11769 - "resolved": "https://registry.npmjs.org/vue-component-type-helpers/-/vue-component-type-helpers-2.0.22.tgz",
11770 - "integrity": "sha512-gPr2Ba7efUwy/Vfbuf735bHSVdN4ycoZUCHfypkI33M9DUH+ieRblLLVM2eImccFYaWNWwEzURx02EgoXDBmaQ==",
11680 + "version": "2.0.26",
11681 + "resolved": "https://registry.npmjs.org/vue-component-type-helpers/-/vue-component-type-helpers-2.0.26.tgz",
11682 + "integrity": "sha512-sO9qQ8oC520SW6kqlls0iqDak53gsTVSrYylajgjmkt1c0vcgjsGSy1KzlDrbEx8pm02IEYhlUkU5hCYf8rwtg==",
11683 "dev": true
11684 },
11685 "node_modules/vue-eslint-parser": {
@@ -11887,20 +11799,20 @@
11799 }
11800 },
11801 "node_modules/vue-tsc": {
11890 - "version": "2.0.22",
11891 - "resolved": "https://registry.npmjs.org/vue-tsc/-/vue-tsc-2.0.22.tgz",
11892 - "integrity": "sha512-lMBIwPBO0sxCcmvu45yt1b035AaQ8/XSXQDk8m75y4j0jSXY/y/XzfEtssQ9JMS47lDaR10O3/926oCs8OeGUw==",
11802 + "version": "2.0.26",
11803 + "resolved": "https://registry.npmjs.org/vue-tsc/-/vue-tsc-2.0.26.tgz",
11804 + "integrity": "sha512-tOhuwy2bIXbMhz82ef37qeiaQHMXKQkD6mOF6CCPl3/uYtST3l6fdNyfMxipudrQTxTfXVPlgJdMENBFfC1CfQ==",
11805 "dev": true,
11806 "dependencies": {
11895 - "@volar/typescript": "~2.3.1",
11896 - "@vue/language-core": "2.0.22",
11807 + "@volar/typescript": "~2.4.0-alpha.15",
11808 + "@vue/language-core": "2.0.26",
11809 "semver": "^7.5.4"
11810 },
11811 "bin": {
11812 "vue-tsc": "bin/vue-tsc.js"
11813 },
11814 "peerDependencies": {
11903 - "typescript": "*"
11815 + "typescript": ">=5.0.0"
11816 }
11817 },
11818 "node_modules/vue3-apexcharts": {
@@ -12064,9 +11976,9 @@
11976 }
11977 },
11978 "node_modules/why-is-node-running": {
12067 - "version": "2.2.2",
12068 - "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.2.2.tgz",
12069 - "integrity": "sha512-6tSwToZxTOcotxHeA+qGCq1mVzKR3CwcJGmVcY+QE8SHy6TnpFnh8PAvPNHYr7EcuVeG0QSMxtYCuO1ta/G/oA==",
11979 + "version": "2.3.0",
11980 + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz",
11981 + "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==",
11982 "dev": true,
11983 "dependencies": {
11984 "siginfo": "^2.0.0",
@@ -12224,9 +12136,9 @@
12136 "dev": true
12137 },
12138 "node_modules/ws": {
12227 - "version": "8.17.1",
12228 - "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz",
12229 - "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==",
12139 + "version": "8.18.0",
12140 + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz",
12141 + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==",
12142 "dev": true,
12143 "engines": {
12144 "node": ">=10.0.0"
frontend/package.json
+22 -22
@@ -36,10 +36,10 @@
36 "@fontsource/lexend": "^5.0.20",
37 "@fontsource/public-sans": "^5.0.18",
38 "@popperjs/core": "^2.11.8",
39 - "@shikijs/markdown-it": "^1.9.1",
39 + "@shikijs/markdown-it": "^1.10.3",
40 "@vueuse/components": "^10.11.0",
41 "@vueuse/core": "^10.11.0",
42 - "apexcharts": "^3.49.2",
42 + "apexcharts": "^3.50.0",
43 "bytes": "^3.1.2",
44 "colord": "^2.9.3",
45 "crypto-js": "^4.2.0",
@@ -48,7 +48,7 @@
48 "echarts": "^5.5.1",
49 "file-saver": "^2.0.5",
50 "html-entities": "^2.5.2",
51 - "jose": "^5.6.2",
51 + "jose": "^5.6.3",
52 "js-md5": "^0.8.3",
53 "lodash": "^4.17.21",
54 "mitt": "^3.0.1",
@@ -57,7 +57,7 @@
57 "pinia": "^2.1.7",
58 "pinia-plugin-persistedstate": "^3.2.1",
59 "secure-ls": "^2.0.0",
60 - "shiki": "^1.9.1",
60 + "shiki": "^1.10.3",
61 "validator": "^13.12.0",
62 "vue": "^3.4.31",
63 "vue-advanced-cropper": "^2.8.9",
@@ -79,7 +79,7 @@
79 "@types/inquirer": "^9.0.7",
80 "@types/jsdom": "^21.1.7",
81 "@types/lodash": "^4.17.6",
82 - "@types/node": "^20.14.9",
82 + "@types/node": "^20.14.10",
83 "@types/validator": "^13.12.0",
84 "@vitejs/plugin-vue": "^5.0.5",
85 "@vitejs/plugin-vue-jsx": "^4.0.0",
@@ -88,51 +88,51 @@
88 "@vue/test-utils": "^2.4.6",
89 "@vue/tsconfig": "^0.5.1",
90 "autoprefixer": "^10.4.19",
91 - "cypress": "^13.12.0",
92 - "eslint": "^9.5.0",
91 + "cypress": "^13.13.0",
92 + "eslint": "^9.6.0",
93 "eslint-plugin-cypress": "^3.3.0",
94 - "eslint-plugin-vue": "^9.26.0",
94 + "eslint-plugin-vue": "^9.27.0",
95 "flourite": "^1.3.0",
96 "fs-extra": "^11.2.0",
97 - "globals": "^15.6.0",
97 + "globals": "^15.8.0",
98 "jsdom": "^24.1.0",
99 "json5": "^2.2.3",
100 - "npm-run-all2": "^6.2.0",
100 + "npm-run-all2": "^6.2.2",
101 "picocolors": "^1.0.1",
102 - "postcss": "^8.4.38",
102 + "postcss": "^8.4.39",
103 "prettier": "^3.3.2",
104 "sass": "^1.77.6",
105 "start-server-and-test": "^2.0.4",
106 "tailwind-config-viewer": "^2.0.4",
107 "tailwindcss": "^3.4.4",
108 - "taze": "^0.13.9",
109 - "type-fest": "^4.20.1",
108 + "taze": "^0.14.2",
109 + "type-fest": "^4.21.0",
110 "unplugin-vue-components": "^0.27.2",
111 - "vite": "^5.3.2",
111 + "vite": "^5.3.3",
112 "vite-bundle-analyzer": "^0.10.3",
113 "vite-bundle-visualizer": "^1.2.1",
114 - "vite-plugin-vue-devtools": "^7.3.4",
114 + "vite-plugin-vue-devtools": "^7.3.5",
115 "vite-svg-loader": "^5.1.0",
116 - "vitest": "^1.6.0",
117 - "vue-tsc": "^2.0.22"
116 + "vitest": "^2.0.1",
117 + "vue-tsc": "^2.0.26"
118 },
119 "optionalDependencies": {
120 - "@rollup/rollup-linux-x64-gnu": "^4.18.0"
120 + "@rollup/rollup-linux-x64-gnu": "^4.18.1"
121 },
122 "overrides": {
123 "@vue/eslint-config-typescript": {
124 - "eslint": "^9.5.0"
124 + "eslint": "^9.6.0"
125 },
126 "@typescript-eslint/type-utils": {
127 - "eslint": "^9.5.0"
127 + "eslint": "^9.6.0"
128 },
129 "@typescript-eslint/utils": {
130 - "eslint": "^9.5.0"
130 + "eslint": "^9.6.0"
131 },
132 "secure-ls": {
133 "crypto-js": "^4.2.0"
134 },
135 - "ws": "^8.17.1"
135 + "ws": "^8.18.0"
136 },
137 "engines": {
138 "node": ">=18.0.0"
frontend/src/api/integrations.ts
+7
@@ -72,5 +72,12 @@ export default {
72 time_interval: 15,
73 integration_name: integrationName
74 })
75 + },
76 + darktraceProvision(customerCode: string, integrationName: string) {
77 + return HttpClient.post<FlaskBaseResponse>(`/darktrace/provision`, {
78 + customer_code: customerCode,
79 + time_interval: 15,
80 + integration_name: integrationName
81 + })
82 }
83 }
frontend/src/components/customers/integrations/CustomerIntegrationActions.vue
+35 -124
@@ -1,49 +1,6 @@
1 <template>
2 <div class="alert-actions flex gap-4 justify-end">
3 - <n-button
4 - v-if="isOffice365 && !integration.deployed"
5 - :loading="loadingOffice365Provision"
6 - @click="office365Provision()"
7 - type="success"
8 - :size="size"
9 - secondary
10 - >
11 - <template #icon><Icon :name="DeployIcon"></Icon></template>
12 - Deploy
13 - </n-button>
14 -
15 - <n-button
16 - v-if="isMimecast && !integration.deployed"
17 - :loading="loadingMimecastProvision"
18 - @click="mimecastProvision()"
19 - type="success"
20 - :size="size"
21 - secondary
22 - >
23 - <template #icon><Icon :name="DeployIcon"></Icon></template>
24 - Deploy
25 - </n-button>
26 -
27 - <n-button
28 - v-if="isCrowdstrike && !integration.deployed"
29 - :loading="loadingCrowdstrikeProvision"
30 - @click="crowdstrikeProvision()"
31 - type="success"
32 - :size="size"
33 - secondary
34 - >
35 - <template #icon><Icon :name="DeployIcon"></Icon></template>
36 - Deploy
37 - </n-button>
38 -
39 - <n-button
40 - v-if="isDuo && !integration.deployed"
41 - :loading="loadingDuoProvision"
42 - @click="duoProvision()"
43 - type="success"
44 - :size="size"
45 - secondary
46 - >
3 + <n-button v-if="isDeployEnabled" :loading="loading" @click="provision()" type="success" :size="size" secondary>
4 <template #icon><Icon :name="DeployIcon"></Icon></template>
5 Deploy
6 </n-button>
@@ -65,13 +22,13 @@
22 </template>
23
24 <script setup lang="ts">
25 +import { computed, h, ref, watch } from "vue"
26 import { NButton, useDialog, useMessage } from "naive-ui"
27 import Icon from "@/components/common/Icon.vue"
28 import Api from "@/api"
71 -import { computed, h, ref } from "vue"
72 -import { watch } from "vue"
29 import type { CustomerIntegration } from "@/types/integrations.d"
30 import type { Size } from "naive-ui/es/button/src/interface"
31 +import type { ApiCommonResponse } from "@/types/common"
32
33 const emit = defineEmits<{
34 (e: "startLoading"): void
@@ -91,26 +48,22 @@ const DeleteIcon = "ph:trash"
48
49 const dialog = useDialog()
50 const message = useMessage()
94 -const loadingOffice365Provision = ref(false)
95 -const loadingMimecastProvision = ref(false)
96 -const loadingCrowdstrikeProvision = ref(false)
97 -const loadingDuoProvision = ref(false)
98 -const loadingDelete = ref(false)
99 -const loading = computed(
100 - () =>
101 - loadingOffice365Provision.value ||
102 - loadingMimecastProvision.value ||
103 - loadingCrowdstrikeProvision.value ||
104 - loadingDuoProvision.value ||
105 - loadingDelete.value
106 -)
51
52 +const loadingProvision = ref(false)
53 +const loadingDelete = ref(false)
54 +const loading = computed(() => loadingProvision.value || loadingDelete.value)
55 const serviceName = computed(() => integration.integration_service_name)
56 const customerCode = computed(() => integration.customer_code)
57 const isOffice365 = computed(() => serviceName.value === "Office365")
58 const isMimecast = computed(() => serviceName.value === "Mimecast")
59 const isCrowdstrike = computed(() => serviceName.value === "Crowdstrike")
60 const isDuo = computed(() => serviceName.value === "DUO")
61 +const isDarktrace = computed(() => serviceName.value === "Darktrace")
62 +const isDeployEnabled = computed(
63 + () =>
64 + (isOffice365.value || isMimecast.value || isCrowdstrike.value || isDuo.value || isDarktrace.value) &&
65 + !integration.deployed
66 +)
67
68 watch(loading, val => {
69 if (val) {
@@ -120,74 +73,32 @@ watch(loading, val => {
73 }
74 })
75
123 -function office365Provision() {
124 - loadingOffice365Provision.value = true
76 +function provision() {
77 + let apiCall: Promise<ApiCommonResponse> | null = null
78
126 - Api.integrations
127 - .office365Provision(customerCode.value, serviceName.value)
128 - .then(res => {
129 - if (res.data.success) {
130 - emit("deployed")
131 - message.success(res.data?.message || "Customer integration successfully deployed.")
132 - } else {
133 - message.warning(res.data?.message || "An error occurred. Please try again later.")
134 - }
135 - })
136 - .catch(err => {
137 - message.error(err.response?.data?.message || "An error occurred. Please try again later.")
138 - })
139 - .finally(() => {
140 - loadingOffice365Provision.value = false
141 - })
142 -}
143 -
144 -function mimecastProvision() {
145 - loadingMimecastProvision.value = true
146 -
147 - Api.integrations
148 - .mimecastProvision(customerCode.value, serviceName.value)
149 - .then(res => {
150 - if (res.data.success) {
151 - emit("deployed")
152 - message.success(res.data?.message || "Customer integration successfully deployed.")
153 - } else {
154 - message.warning(res.data?.message || "An error occurred. Please try again later.")
155 - }
156 - })
157 - .catch(err => {
158 - message.error(err.response?.data?.message || "An error occurred. Please try again later.")
159 - })
160 - .finally(() => {
161 - loadingMimecastProvision.value = false
162 - })
163 -}
164 -
165 -function crowdstrikeProvision() {
166 - loadingCrowdstrikeProvision.value = true
79 + if (isOffice365.value) {
80 + apiCall = Api.integrations.office365Provision(customerCode.value, serviceName.value)
81 + }
82 + if (isMimecast.value) {
83 + apiCall = Api.integrations.mimecastProvision(customerCode.value, serviceName.value)
84 + }
85 + if (isCrowdstrike.value) {
86 + apiCall = Api.integrations.crowdstrikeProvision(customerCode.value, serviceName.value)
87 + }
88 + if (isDuo.value) {
89 + apiCall = Api.integrations.duoProvision(customerCode.value, serviceName.value)
90 + }
91 + if (isDarktrace.value) {
92 + apiCall = Api.integrations.darktraceProvision(customerCode.value, serviceName.value)
93 + }
94
168 - Api.integrations
169 - .crowdstrikeProvision(customerCode.value, serviceName.value)
170 - .then(res => {
171 - if (res.data.success) {
172 - emit("deployed")
173 - message.success(res.data?.message || "Customer integration successfully deployed.")
174 - } else {
175 - message.warning(res.data?.message || "An error occurred. Please try again later.")
176 - }
177 - })
178 - .catch(err => {
179 - message.error(err.response?.data?.message || "An error occurred. Please try again later.")
180 - })
181 - .finally(() => {
182 - loadingCrowdstrikeProvision.value = false
183 - })
184 -}
95 + if (!apiCall) {
96 + return
97 + }
98
186 -function duoProvision() {
187 - loadingDuoProvision.value = true
99 + loadingProvision.value = true
100
189 - Api.integrations
190 - .duoProvision(customerCode.value, serviceName.value)
101 + apiCall
102 .then(res => {
103 if (res.data.success) {
104 emit("deployed")
@@ -200,7 +111,7 @@ function duoProvision() {
111 message.error(err.response?.data?.message || "An error occurred. Please try again later.")
112 })
113 .finally(() => {
203 - loadingDuoProvision.value = false
114 + loadingProvision.value = false
115 })
116 }
117
frontend/src/types/common.d.ts
+4 -1
@@ -1,5 +1,8 @@
1 +import { AxiosError, AxiosResponse } from "axios"
2 +import { FlaskBaseResponse } from "./flask"
3 +
4 export type OsTypesFull = "Unknown" | "Windows" | "MacOS" | "UNIX" | "Linux"
5 export type OsTypesLower = "linux" | "windows" | "macos"
6 export type SafeAny = string | number | object
7 export type ApiError = AxiosError<FlaskBaseResponse>
5 -export type ApiCommonResponse<T extends object = {}> = AxiosResponse<FlaskBaseResponse & T>
8 +export type ApiCommonResponse<T = unknown> = AxiosResponse<FlaskBaseResponse & T>