@cryptotaxi247 / CoPilot / commits / 24f5c013

Shuffle singul2 (#463)

* Update IP address in Singul integration to use 1.1.1.1 * feat: add app-auth-search page * refactor: update router * feat: add validation for manager_orgs field in DetailedOrganization model --------- Co-authored-by: Davide Di Modica <webmaster.ddm@gmail.com>

taylor_socfortress committed Jun 25, 2025 at 14:41 UTC 24f5c013c21ab99f6478e4aa07ede13f35bf0377
13 files changed +532 -190
.vscode/settings.json
+1
@@ -56,6 +56,7 @@
56 "shikijs",
57 "SIEM",
58 "signin",
59 + "Singul",
60 "Socfortress",
61 "sparkline",
62 "Sysmon",
backend/app/connectors/shuffle/schema/organizations.py
+24
@@ -6,6 +6,7 @@ from typing import Optional
6
7 from pydantic import BaseModel
8 from pydantic import Field
9 +from pydantic import validator
10
11
12 class SyncConfig(BaseModel):
@@ -102,6 +103,29 @@ class DetailedOrganization(BaseModel):
103 region_url: str = ""
104 tutorials: List[Any] = []
105
106 + @validator("manager_orgs", pre=True, always=True)
107 + def validate_manager_orgs(cls, v):
108 + """
109 + Validate and normalize manager_orgs field.
110 + Handles various input types and converts them to proper format or None.
111 + """
112 + if v is None:
113 + return None
114 +
115 + # If it's already a list, validate each item is a string
116 + if isinstance(v, list):
117 + try:
118 + return [str(item) for item in v if item is not None]
119 + except Exception:
120 + return None
121 +
122 + # If it's a single value, convert to list
123 + if isinstance(v, (str, int)):
124 + return [str(v)]
125 +
126 + # For any other type, return None
127 + return None
128 +
129
130 class DetailedOrganizationResponse(BaseModel):
131 success: bool
backend/app/connectors/shuffle/services/singul.py
+1 -1
@@ -64,7 +64,7 @@ async def execute_singul(
64 response = singul.intel.get_ioc(
65 app="opencti_dcon",
66 org_id=await get_shuffle_org_id(),
67 - fields=[{"key": "ip", "value": "8.8.8.8"}],
67 + fields=[{"key": "ip", "value": "1.1.1.1"}],
68 )
69 logger.info(f"Singul response: {response}")
70 logger.info(f"Singul response success: {response.get('success', 'unknown')}")
frontend/package.json
+5 -4
@@ -3,7 +3,7 @@
3 "type": "module",
4 "version": "1.0.0",
5 "private": true,
6 - "packageManager": "pnpm@10.12.1+sha512.f0dda8580f0ee9481c5c79a1d927b9164f2c478e90992ad268bbb2465a736984391d6333d2c327913578b2804af33474ca554ba29c04a8b13060a717675ae3ac",
6 + "packageManager": "pnpm@10.12.2+sha512.a32540185b964ee30bb4e979e405adc6af59226b438ee4cc19f9e8773667a66d302f5bfee60a39d3cac69e35e4b96e708a71dd002b7e9359c4112a1722ac323f",
7 "engines": {
8 "node": ">=18.0.0"
9 },
@@ -46,6 +46,7 @@
46 "@fontsource/lexend": "^5.2.9",
47 "@fontsource/public-sans": "^5.2.6",
48 "@shikijs/markdown-it": "^3.7.0",
49 + "@singulio/app-auth-search": "^0.0.3",
50 "@vueuse/core": "^13.4.0",
51 "@vueuse/motion": "^3.0.3",
52 "axios": "^1.10.0",
@@ -74,7 +75,7 @@
75 "vue-advanced-cropper": "^2.8.9",
76 "vue-codemirror": "^6.1.1",
77 "vue-highlight-words": "^3.0.1",
77 - "vue-i18n": "^11.1.6",
78 + "vue-i18n": "^11.1.7",
79 "vue-router": "^4.5.1",
80 "vue-sjv": "^0.0.6",
81 "vue3-apexcharts": "^1.8.0",
@@ -87,7 +88,7 @@
88 "vueuc": "^0.4.64"
89 },
90 "devDependencies": {
90 - "@antfu/eslint-config": "^4.15.0",
91 + "@antfu/eslint-config": "^4.16.1",
92 "@clack/prompts": "^0.11.0",
93 "@iconify/vue": "^5.0.0",
94 "@tailwindcss/vite": "^4.1.10",
@@ -111,7 +112,7 @@
112 "fs-extra": "^11.3.0",
113 "jsdom": "^26.1.0",
114 "npm-run-all2": "^8.0.4",
114 - "prettier": "^3.5.3",
115 + "prettier": "^3.6.0",
116 "prettier-plugin-tailwindcss": "^0.6.13",
117 "sass": "^1.89.2",
118 "start-server-and-test": "^2.0.12",
frontend/pnpm-lock.yaml
+227 -180
@@ -38,6 +38,9 @@ importers:
38 '@shikijs/markdown-it':
39 specifier: ^3.7.0
40 version: 3.7.0
41 + '@singulio/app-auth-search':
42 + specifier: ^0.0.3
43 + version: 0.0.3
44 '@vueuse/core':
45 specifier: ^13.4.0
46 version: 13.4.0(vue@3.5.17(typescript@5.8.3))
@@ -123,8 +126,8 @@ importers:
126 specifier: ^3.0.1
127 version: 3.0.1(vue@3.5.17(typescript@5.8.3))
128 vue-i18n:
126 - specifier: ^11.1.6
127 - version: 11.1.6(vue@3.5.17(typescript@5.8.3))
129 + specifier: ^11.1.7
130 + version: 11.1.7(vue@3.5.17(typescript@5.8.3))
131 vue-router:
132 specifier: ^4.5.1
133 version: 4.5.1(vue@3.5.17(typescript@5.8.3))
@@ -142,8 +145,8 @@ importers:
145 version: 4.1.0(vue@3.5.17(typescript@5.8.3))
146 devDependencies:
147 '@antfu/eslint-config':
145 - specifier: ^4.15.0
146 - version: 4.15.0(@vue/compiler-sfc@3.5.17)(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3)(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.0.3)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(sass@1.89.2)(yaml@2.8.0))
148 + specifier: ^4.16.1
149 + version: 4.16.1(@vue/compiler-sfc@3.5.17)(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3)(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.0.3)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(sass@1.89.2)(yaml@2.8.0))
150 '@clack/prompts':
151 specifier: ^0.11.0
152 version: 0.11.0
@@ -214,11 +217,11 @@ importers:
217 specifier: ^8.0.4
218 version: 8.0.4
219 prettier:
217 - specifier: ^3.5.3
218 - version: 3.5.3
220 + specifier: ^3.6.0
221 + version: 3.6.0
222 prettier-plugin-tailwindcss:
223 specifier: ^0.6.13
221 - version: 0.6.13(prettier@3.5.3)
224 + version: 0.6.13(prettier@3.6.0)
225 sass:
226 specifier: ^1.89.2
227 version: 1.89.2
@@ -271,12 +274,64 @@ packages:
274 '@ajoelp/json-to-formdata@1.5.0':
275 resolution: {integrity: sha512-nrlfeTSL0X0dtx5r2KpzPiqLSIQquiiJjUKsQAKzWaCmO2QoYZCyb5ENZwF3YoffKronOCJr25mxaD8JRJmK8w==}
276
277 + '@algolia/client-abtesting@5.29.0':
278 + resolution: {integrity: sha512-AM/6LYMSTnZvAT5IarLEKjYWOdV+Fb+LVs8JRq88jn8HH6bpVUtjWdOZXqX1hJRXuCAY8SdQfb7F8uEiMNXdYQ==}
279 + engines: {node: '>= 14.0.0'}
280 +
281 + '@algolia/client-analytics@5.29.0':
282 + resolution: {integrity: sha512-La34HJh90l0waw3wl5zETO8TuukeUyjcXhmjYZL3CAPLggmKv74mobiGRIb+mmBENybiFDXf/BeKFLhuDYWMMQ==}
283 + engines: {node: '>= 14.0.0'}
284 +
285 + '@algolia/client-common@5.29.0':
286 + resolution: {integrity: sha512-T0lzJH/JiCxQYtCcnWy7Jf1w/qjGDXTi2npyF9B9UsTvXB97GRC6icyfXxe21mhYvhQcaB1EQ/J2575FXxi2rA==}
287 + engines: {node: '>= 14.0.0'}
288 +
289 + '@algolia/client-insights@5.29.0':
290 + resolution: {integrity: sha512-A39F1zmHY9aev0z4Rt3fTLcGN5AG1VsVUkVWy6yQG5BRDScktH+U5m3zXwThwniBTDV1HrPgiGHZeWb67GkR2Q==}
291 + engines: {node: '>= 14.0.0'}
292 +
293 + '@algolia/client-personalization@5.29.0':
294 + resolution: {integrity: sha512-ibxmh2wKKrzu5du02gp8CLpRMeo+b/75e4ORct98CT7mIxuYFXowULwCd6cMMkz/R0LpKXIbTUl15UL5soaiUQ==}
295 + engines: {node: '>= 14.0.0'}
296 +
297 + '@algolia/client-query-suggestions@5.29.0':
298 + resolution: {integrity: sha512-VZq4/AukOoJC2WSwF6J5sBtt+kImOoBwQc1nH3tgI+cxJBg7B77UsNC+jT6eP2dQCwGKBBRTmtPLUTDDnHpMgA==}
299 + engines: {node: '>= 14.0.0'}
300 +
301 + '@algolia/client-search@5.29.0':
302 + resolution: {integrity: sha512-cZ0Iq3OzFUPpgszzDr1G1aJV5UMIZ4VygJ2Az252q4Rdf5cQMhYEIKArWY/oUjMhQmosM8ygOovNq7gvA9CdCg==}
303 + engines: {node: '>= 14.0.0'}
304 +
305 + '@algolia/ingestion@1.29.0':
306 + resolution: {integrity: sha512-scBXn0wO5tZCxmO6evfa7A3bGryfyOI3aoXqSQBj5SRvNYXaUlFWQ/iKI70gRe/82ICwE0ICXbHT/wIvxOW7vw==}
307 + engines: {node: '>= 14.0.0'}
308 +
309 + '@algolia/monitoring@1.29.0':
310 + resolution: {integrity: sha512-FGWWG9jLFhsKB7YiDjM2dwQOYnWu//7Oxrb2vT96N7+s+hg1mdHHfHNRyEudWdxd4jkMhBjeqNA21VbTiOIPVg==}
311 + engines: {node: '>= 14.0.0'}
312 +
313 + '@algolia/recommend@5.29.0':
314 + resolution: {integrity: sha512-xte5+mpdfEARAu61KXa4ewpjchoZuJlAlvQb8ptK6hgHlBHDnYooy1bmOFpokaAICrq/H9HpoqNUX71n+3249A==}
315 + engines: {node: '>= 14.0.0'}
316 +
317 + '@algolia/requester-browser-xhr@5.29.0':
318 + resolution: {integrity: sha512-og+7Em75aPHhahEUScq2HQ3J7ULN63Levtd87BYMpn6Im5d5cNhaC4QAUsXu6LWqxRPgh4G+i+wIb6tVhDhg2A==}
319 + engines: {node: '>= 14.0.0'}
320 +
321 + '@algolia/requester-fetch@5.29.0':
322 + resolution: {integrity: sha512-JCxapz7neAy8hT/nQpCvOrI5JO8VyQ1kPvBiaXWNC1prVq0UMYHEL52o1BsPvtXfdQ7BVq19OIq6TjOI06mV/w==}
323 + engines: {node: '>= 14.0.0'}
324 +
325 + '@algolia/requester-node-http@5.29.0':
326 + resolution: {integrity: sha512-lVBD81RBW5VTdEYgnzCz7Pf9j2H44aymCP+/eHGJu4vhU+1O8aKf3TVBgbQr5UM6xoe8IkR/B112XY6YIG2vtg==}
327 + engines: {node: '>= 14.0.0'}
328 +
329 '@ampproject/remapping@2.3.0':
330 resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==}
331 engines: {node: '>=6.0.0'}
332
278 - '@antfu/eslint-config@4.15.0':
279 - resolution: {integrity: sha512-wNn8eDUR+L48nGqX0j8uS19+lHjlhjJsTuhOIbp5aUtnNzAqUuzeoGa7S7rfIbK3XnzcRXJ1AW+xWXsMSGu0YA==}
333 + '@antfu/eslint-config@4.16.1':
334 + resolution: {integrity: sha512-20hA+bjnEmYnZChnQFM9ugPF+FR5N2yd6UNUjhZSmTeYpaKnkJ1EvZyEWxnmVGKC5O5HNDEJY3BXUQymdOoftQ==}
335 hasBin: true
336 peerDependencies:
337 '@eslint-react/eslint-plugin': ^1.38.4
@@ -769,8 +824,8 @@ packages:
824 resolution: {integrity: sha512-3PIF4cBw/y+1u2EazflInpV+lYsSG0aByVIQzAgb1m1MhHFSbqTyNqtBKHgWf/9Ykud+DhILS9EGkmekVhbKoQ==}
825 engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
826
772 - '@eslint/markdown@6.5.0':
773 - resolution: {integrity: sha512-oSkF0p8X21vKEEAGTZASi7q3tbdTvlGduQ02Xz2A1AFncUP4RLVcNz27XurxVW4fs1JXuh0xBtvokXdtp/nN+Q==}
827 + '@eslint/markdown@6.6.0':
828 + resolution: {integrity: sha512-IsWPy2jU3gaQDlioDC4sT4I4kG1hX1OMWs/q2sWwJrPoMASHW/Z4SDw+6Aql6EsHejGbagYuJbFq9Zvx+Y1b1Q==}
829 engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
830
831 '@eslint/object-schema@2.1.6':
@@ -833,16 +888,16 @@ packages:
888 peerDependencies:
889 vue: '>=3'
890
836 - '@intlify/core-base@11.1.6':
837 - resolution: {integrity: sha512-gfMLnoWGiQkA1BwK6Qbrog/e3I6Lnkhqk08XObJb0lMq6sLG1Ggl2MazVaMfGnv/E1Td8pCS5UwR54Ys+fOxmQ==}
891 + '@intlify/core-base@11.1.7':
892 + resolution: {integrity: sha512-gYiGnQeJVp3kNBeXQ73m1uFOak0ry4av8pn+IkEWigyyPWEMGzB+xFeQdmGMFn49V+oox6294oGVff8bYOhtOw==}
893 engines: {node: '>= 16'}
894
840 - '@intlify/message-compiler@11.1.6':
841 - resolution: {integrity: sha512-w0LYo5sqgQZF3vEmjLlx+5PYk5EEiB+uigsBkka/DKoAIH2c5xlXcjAxhTgSw35Vrck+GOGriahFsfbHL+ZjPw==}
895 + '@intlify/message-compiler@11.1.7':
896 + resolution: {integrity: sha512-0ezkep1AT30NyuKj8QbRlmvMORCCRlOIIu9v8RNU8SwDjjTiFCZzczCORMns2mCH4HZ1nXgrfkKzYUbfjNRmng==}
897 engines: {node: '>= 16'}
898
844 - '@intlify/shared@11.1.6':
845 - resolution: {integrity: sha512-G1Pe4UILhiGOItuehRW+Pk9/NlnRaMFsdnhZ1fwBjiHvrzitmPNZdLx7Eo3GPfRrsk1mdkilZSfgH8SnM419vA==}
899 + '@intlify/shared@11.1.7':
900 + resolution: {integrity: sha512-4yZeMt2Aa/7n5Ehy4KalUlvt3iRLcg1tq9IBVfOgkyWFArN4oygn6WxgGIFibP3svpaH8DarbNaottq+p0gUZQ==}
901 engines: {node: '>= 16'}
902
903 '@isaacs/cliui@8.0.2':
@@ -1170,8 +1225,11 @@ packages:
1225 resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==}
1226 engines: {node: '>=18'}
1227
1173 - '@stylistic/eslint-plugin@5.0.0-beta.5':
1174 - resolution: {integrity: sha512-hYoTE1AuPKkF8gN6nwJVnBovUEkt3UGiE3zu8nNmFi3yw7F36l1/tU/VRg16CZC804rnAhUwsYTHqKnAPqICxg==}
1228 + '@singulio/app-auth-search@0.0.3':
1229 + resolution: {integrity: sha512-4U/of6Gry5hal3CdZoMkrdfbSYza43ZcvlJoh4pJ1UCm16Vpegmw3MwmbrZHjg8wiFWe+f5WnX/WkgQpuuZnHw==}
1230 +
1231 + '@stylistic/eslint-plugin@5.0.0':
1232 + resolution: {integrity: sha512-nVV2FSzeTJ3oFKw+3t9gQYQcrgbopgCASSY27QOtkhEGgSfdQQjDmzZd41NeT1myQ8Wc6l+pZllST9qIu4NKzg==}
1233 engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
1234 peerDependencies:
1235 eslint: '>=9.0.0'
@@ -1403,32 +1461,16 @@ packages:
1461 eslint: ^8.57.0 || ^9.0.0
1462 typescript: '>=4.8.4 <5.9.0'
1463
1406 - '@typescript-eslint/project-service@8.33.1':
1407 - resolution: {integrity: sha512-DZR0efeNklDIHHGRpMpR5gJITQpu6tLr9lDJnKdONTC7vvzOlLAG/wcfxcdxEWrbiZApcoBCzXqU/Z458Za5Iw==}
1408 - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
1409 - peerDependencies:
1410 - typescript: '>=4.8.4 <5.9.0'
1411 -
1464 '@typescript-eslint/project-service@8.34.1':
1465 resolution: {integrity: sha512-nuHlOmFZfuRwLJKDGQOVc0xnQrAmuq1Mj/ISou5044y1ajGNp2BNliIqp7F2LPQ5sForz8lempMFCovfeS1XoA==}
1466 engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
1467 peerDependencies:
1468 typescript: '>=4.8.4 <5.9.0'
1469
1418 - '@typescript-eslint/scope-manager@8.33.1':
1419 - resolution: {integrity: sha512-dM4UBtgmzHR9bS0Rv09JST0RcHYearoEoo3pG5B6GoTR9XcyeqX87FEhPo+5kTvVfKCvfHaHrcgeJQc6mrDKrA==}
1420 - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
1421 -
1470 '@typescript-eslint/scope-manager@8.34.1':
1471 resolution: {integrity: sha512-beu6o6QY4hJAgL1E8RaXNC071G4Kso2MGmJskCFQhRhg8VOH/FDbC8soP8NHN7e/Hdphwp8G8cE6OBzC8o41ZA==}
1472 engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
1473
1426 - '@typescript-eslint/tsconfig-utils@8.33.1':
1427 - resolution: {integrity: sha512-STAQsGYbHCF0/e+ShUQ4EatXQ7ceh3fBCXkNU7/MZVKulrlq1usH7t2FhxvCpuCi5O5oi1vmVaAjrGeL71OK1g==}
1428 - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
1429 - peerDependencies:
1430 - typescript: '>=4.8.4 <5.9.0'
1431 -
1474 '@typescript-eslint/tsconfig-utils@8.34.1':
1475 resolution: {integrity: sha512-K4Sjdo4/xF9NEeA2khOb7Y5nY6NSXBnod87uniVYW9kHP+hNlDV8trUSFeynA2uxWam4gIWgWoygPrv9VMWrYg==}
1476 engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
@@ -1442,33 +1484,16 @@ packages:
1484 eslint: ^8.57.0 || ^9.0.0
1485 typescript: '>=4.8.4 <5.9.0'
1486
1445 - '@typescript-eslint/types@8.33.1':
1446 - resolution: {integrity: sha512-xid1WfizGhy/TKMTwhtVOgalHwPtV8T32MS9MaH50Cwvz6x6YqRIPdD2WvW0XaqOzTV9p5xdLY0h/ZusU5Lokg==}
1447 - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
1448 -
1487 '@typescript-eslint/types@8.34.1':
1488 resolution: {integrity: sha512-rjLVbmE7HR18kDsjNIZQHxmv9RZwlgzavryL5Lnj2ujIRTeXlKtILHgRNmQ3j4daw7zd+mQgy+uyt6Zo6I0IGA==}
1489 engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
1490
1453 - '@typescript-eslint/typescript-estree@8.33.1':
1454 - resolution: {integrity: sha512-+s9LYcT8LWjdYWu7IWs7FvUxpQ/DGkdjZeE/GGulHvv8rvYwQvVaUZ6DE+j5x/prADUgSbbCWZ2nPI3usuVeOA==}
1455 - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
1456 - peerDependencies:
1457 - typescript: '>=4.8.4 <5.9.0'
1458 -
1491 '@typescript-eslint/typescript-estree@8.34.1':
1492 resolution: {integrity: sha512-rjCNqqYPuMUF5ODD+hWBNmOitjBWghkGKJg6hiCHzUvXRy6rK22Jd3rwbP2Xi+R7oYVvIKhokHVhH41BxPV5mA==}
1493 engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
1494 peerDependencies:
1495 typescript: '>=4.8.4 <5.9.0'
1496
1465 - '@typescript-eslint/utils@8.33.1':
1466 - resolution: {integrity: sha512-52HaBiEQUaRYqAXpfzWSR2U3gxk92Kw006+xZpElaPMg3C4PgM+A5LqwoQI1f9E5aZ/qlxAZxzm42WX+vn92SQ==}
1467 - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
1468 - peerDependencies:
1469 - eslint: ^8.57.0 || ^9.0.0
1470 - typescript: '>=4.8.4 <5.9.0'
1471 -
1497 '@typescript-eslint/utils@8.34.1':
1498 resolution: {integrity: sha512-mqOwUdZ3KjtGk7xJJnLbHxTuWVn3GO2WZZuM+Slhkun4+qthLdXx32C8xIXbO1kfCECb3jIs3eoxK3eryk7aoQ==}
1499 engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
@@ -1476,10 +1501,6 @@ packages:
1501 eslint: ^8.57.0 || ^9.0.0
1502 typescript: '>=4.8.4 <5.9.0'
1503
1479 - '@typescript-eslint/visitor-keys@8.33.1':
1480 - resolution: {integrity: sha512-3i8NrFcZeeDHJ+7ZUuDkGT+UHq+XoFGsymNK2jZCOHcfEzRQ0BdpRtdpSx/Iyf3MHLWIcLS0COuOPibKQboIiQ==}
1481 - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
1482 -
1504 '@typescript-eslint/visitor-keys@8.34.1':
1505 resolution: {integrity: sha512-xoh5rJ+tgsRKoXnkBPFRLZ7rjKM0AfVbC68UZ/ECXoDbfggb9RbEySN359acY1vS3qZ0jVTVWzbtfapwm5ztxw==}
1506 engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
@@ -1724,6 +1745,10 @@ packages:
1745 ajv@6.12.6:
1746 resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==}
1747
1748 + algoliasearch@5.29.0:
1749 + resolution: {integrity: sha512-E2l6AlTWGznM2e7vEE6T6hzObvEyXukxMOlBmVlMyixZyK1umuO/CiVc6sDBbzVH0oEviCE5IfVY1oZBmccYPQ==}
1750 + engines: {node: '>= 14.0.0'}
1751 +
1752 alien-signals@1.0.13:
1753 resolution: {integrity: sha512-OGj9yyTnJEttvzhTUWuscOvtqxq5vrhF7vL9oS0xJ2mK0ItPYP1/y+vCFebfxoEyAz0++1AIwJ5CMr+Fk3nDmg==}
1754
@@ -2401,8 +2426,8 @@ packages:
2426 peerDependencies:
2427 eslint: '*'
2428
2404 - eslint-plugin-command@3.2.1:
2405 - resolution: {integrity: sha512-PcpzWe8dvAPaBobxE9zgz1w94fO4JYvzciDzw6thlUb9Uqf5e2/gJz97itOGxvdq+mFeudi71m1OGFgvWmb93w==}
2429 + eslint-plugin-command@3.3.1:
2430 + resolution: {integrity: sha512-fBVTXQ2y48TVLT0+4A6PFINp7GcdIailHAXbvPBixE7x+YpYnNQhFZxTdvnb+aWk+COgNebQKen/7m4dmgyWAw==}
2431 peerDependencies:
2432 eslint: '*'
2433
@@ -2422,8 +2447,8 @@ packages:
2447 typescript:
2448 optional: true
2449
2425 - eslint-plugin-jsdoc@51.1.2:
2426 - resolution: {integrity: sha512-xLg40KhRnlaOX6W+YLofVavGTajOUn6VCSoVC5eWKbsaMMM/aznFAqVXysuk76wSQZJMiBOfC4V6beseIk6eOg==}
2450 + eslint-plugin-jsdoc@51.2.1:
2451 + resolution: {integrity: sha512-iE2qpG/kaA9xXfEcTNSsxNvH5O8+o38VBGLwl2oZisQaM1JRGftTLJAGQrj7YZjSkp3n9VCrNTjOpo3ONhTApQ==}
2452 engines: {node: '>=20.11.0'}
2453 peerDependencies:
2454 eslint: ^7.0.0 || ^8.0.0 || ^9.0.0
@@ -2501,10 +2526,6 @@ packages:
2526 '@vue/compiler-sfc': ^3.3.0
2527 eslint: '>=9.0.0'
2528
2504 - eslint-scope@8.3.0:
2505 - resolution: {integrity: sha512-pUNxi75F8MJ/GdeKtVLSbYg4ZI34J6C0C7sbL4YOp2exGwen7ZsuBqKzUhXd0qMQ362yET3z+uPwKeg/0C2XCQ==}
2506 - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
2507 -
2529 eslint-scope@8.4.0:
2530 resolution: {integrity: sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==}
2531 engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
@@ -2513,10 +2534,6 @@ packages:
2534 resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==}
2535 engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
2536
2516 - eslint-visitor-keys@4.2.0:
2517 - resolution: {integrity: sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==}
2518 - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
2519 -
2537 eslint-visitor-keys@4.2.1:
2538 resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==}
2539 engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
@@ -2531,10 +2548,6 @@ packages:
2548 jiti:
2549 optional: true
2550
2534 - espree@10.3.0:
2535 - resolution: {integrity: sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==}
2536 - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
2537 -
2551 espree@10.4.0:
2552 resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==}
2553 engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
@@ -2780,6 +2793,9 @@ packages:
2793 resolution: {integrity: sha512-L5bGsVkxJbJgdnwyuheIunkGatUF/zssUoxxjACCseZYAVbaqdh9Tsmmlkl8vYan09H7sbvKt4pS8GqKLBrEzA==}
2794 hasBin: true
2795
2796 + github-slugger@2.0.0:
2797 + resolution: {integrity: sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==}
2798 +
2799 glob-parent@5.1.2:
2800 resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
2801 engines: {node: '>= 6'}
@@ -3881,8 +3897,8 @@ packages:
3897 prettier-plugin-svelte:
3898 optional: true
3899
3884 - prettier@3.5.3:
3885 - resolution: {integrity: sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==}
3900 + prettier@3.6.0:
3901 + resolution: {integrity: sha512-ujSB9uXHJKzM/2GBuE0hBOUgC77CN3Bnpqa+g80bkv3T3A93wL/xlzDATHhnhkzifz/UE2SNOvmbTz5hSkDlHw==}
3902 engines: {node: '>=14'}
3903 hasBin: true
3904
@@ -4650,8 +4666,8 @@ packages:
4666 peerDependencies:
4667 vue: ^3.0.0
4668
4653 - vue-i18n@11.1.6:
4654 - resolution: {integrity: sha512-+IbsW/sTZHj7U1w0rPOYJbuSB0/7DeO1nvUo3BxvO20OQgHs+ukJ3QeLqvoUA6DiLk+8SA9+djRmKC9+FC6cAg==}
4669 + vue-i18n@11.1.7:
4670 + resolution: {integrity: sha512-CDrU7Cmyh1AxJjerQmipV9nVa//exVBdhTcWGlbfcDCN8bKp/uAe7Le6IoN4//5emIikbsSKe9Uofmf/xXkhOA==}
4671 engines: {node: '>= 16'}
4672 peerDependencies:
4673 vue: ^3.0.0
@@ -4857,18 +4873,95 @@ snapshots:
4873 dependencies:
4874 lodash: 4.17.21
4875
4876 + '@algolia/client-abtesting@5.29.0':
4877 + dependencies:
4878 + '@algolia/client-common': 5.29.0
4879 + '@algolia/requester-browser-xhr': 5.29.0
4880 + '@algolia/requester-fetch': 5.29.0
4881 + '@algolia/requester-node-http': 5.29.0
4882 +
4883 + '@algolia/client-analytics@5.29.0':
4884 + dependencies:
4885 + '@algolia/client-common': 5.29.0
4886 + '@algolia/requester-browser-xhr': 5.29.0
4887 + '@algolia/requester-fetch': 5.29.0
4888 + '@algolia/requester-node-http': 5.29.0
4889 +
4890 + '@algolia/client-common@5.29.0': {}
4891 +
4892 + '@algolia/client-insights@5.29.0':
4893 + dependencies:
4894 + '@algolia/client-common': 5.29.0
4895 + '@algolia/requester-browser-xhr': 5.29.0
4896 + '@algolia/requester-fetch': 5.29.0
4897 + '@algolia/requester-node-http': 5.29.0
4898 +
4899 + '@algolia/client-personalization@5.29.0':
4900 + dependencies:
4901 + '@algolia/client-common': 5.29.0
4902 + '@algolia/requester-browser-xhr': 5.29.0
4903 + '@algolia/requester-fetch': 5.29.0
4904 + '@algolia/requester-node-http': 5.29.0
4905 +
4906 + '@algolia/client-query-suggestions@5.29.0':
4907 + dependencies:
4908 + '@algolia/client-common': 5.29.0
4909 + '@algolia/requester-browser-xhr': 5.29.0
4910 + '@algolia/requester-fetch': 5.29.0
4911 + '@algolia/requester-node-http': 5.29.0
4912 +
4913 + '@algolia/client-search@5.29.0':
4914 + dependencies:
4915 + '@algolia/client-common': 5.29.0
4916 + '@algolia/requester-browser-xhr': 5.29.0
4917 + '@algolia/requester-fetch': 5.29.0
4918 + '@algolia/requester-node-http': 5.29.0
4919 +
4920 + '@algolia/ingestion@1.29.0':
4921 + dependencies:
4922 + '@algolia/client-common': 5.29.0
4923 + '@algolia/requester-browser-xhr': 5.29.0
4924 + '@algolia/requester-fetch': 5.29.0
4925 + '@algolia/requester-node-http': 5.29.0
4926 +
4927 + '@algolia/monitoring@1.29.0':
4928 + dependencies:
4929 + '@algolia/client-common': 5.29.0
4930 + '@algolia/requester-browser-xhr': 5.29.0
4931 + '@algolia/requester-fetch': 5.29.0
4932 + '@algolia/requester-node-http': 5.29.0
4933 +
4934 + '@algolia/recommend@5.29.0':
4935 + dependencies:
4936 + '@algolia/client-common': 5.29.0
4937 + '@algolia/requester-browser-xhr': 5.29.0
4938 + '@algolia/requester-fetch': 5.29.0
4939 + '@algolia/requester-node-http': 5.29.0
4940 +
4941 + '@algolia/requester-browser-xhr@5.29.0':
4942 + dependencies:
4943 + '@algolia/client-common': 5.29.0
4944 +
4945 + '@algolia/requester-fetch@5.29.0':
4946 + dependencies:
4947 + '@algolia/client-common': 5.29.0
4948 +
4949 + '@algolia/requester-node-http@5.29.0':
4950 + dependencies:
4951 + '@algolia/client-common': 5.29.0
4952 +
4953 '@ampproject/remapping@2.3.0':
4954 dependencies:
4955 '@jridgewell/gen-mapping': 0.3.8
4956 '@jridgewell/trace-mapping': 0.3.25
4957
4865 - '@antfu/eslint-config@4.15.0(@vue/compiler-sfc@3.5.17)(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3)(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.0.3)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(sass@1.89.2)(yaml@2.8.0))':
4958 + '@antfu/eslint-config@4.16.1(@vue/compiler-sfc@3.5.17)(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3)(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.0.3)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(sass@1.89.2)(yaml@2.8.0))':
4959 dependencies:
4960 '@antfu/install-pkg': 1.1.0
4961 '@clack/prompts': 0.11.0
4962 '@eslint-community/eslint-plugin-eslint-comments': 4.5.0(eslint@9.29.0(jiti@2.4.2))
4870 - '@eslint/markdown': 6.5.0
4871 - '@stylistic/eslint-plugin': 5.0.0-beta.5(eslint@9.29.0(jiti@2.4.2))
4963 + '@eslint/markdown': 6.6.0
4964 + '@stylistic/eslint-plugin': 5.0.0(eslint@9.29.0(jiti@2.4.2))
4965 '@typescript-eslint/eslint-plugin': 8.34.1(@typescript-eslint/parser@8.34.1(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3)
4966 '@typescript-eslint/parser': 8.34.1(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3)
4967 '@vitest/eslint-plugin': 1.2.7(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3)(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.0.3)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(sass@1.89.2)(yaml@2.8.0))
@@ -4879,9 +4972,9 @@ snapshots:
4972 eslint-flat-config-utils: 2.1.0
4973 eslint-merge-processors: 2.0.0(eslint@9.29.0(jiti@2.4.2))
4974 eslint-plugin-antfu: 3.1.1(eslint@9.29.0(jiti@2.4.2))
4882 - eslint-plugin-command: 3.2.1(eslint@9.29.0(jiti@2.4.2))
4975 + eslint-plugin-command: 3.3.1(eslint@9.29.0(jiti@2.4.2))
4976 eslint-plugin-import-lite: 0.3.0(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3)
4884 - eslint-plugin-jsdoc: 51.1.2(eslint@9.29.0(jiti@2.4.2))
4977 + eslint-plugin-jsdoc: 51.2.1(eslint@9.29.0(jiti@2.4.2))
4978 eslint-plugin-jsonc: 2.20.1(eslint@9.29.0(jiti@2.4.2))
4979 eslint-plugin-n: 17.20.0(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3)
4980 eslint-plugin-no-only-tests: 3.3.0
@@ -5265,8 +5358,8 @@ snapshots:
5358
5359 '@es-joy/jsdoccomment@0.50.2':
5360 dependencies:
5268 - '@types/estree': 1.0.7
5269 - '@typescript-eslint/types': 8.33.1
5361 + '@types/estree': 1.0.8
5362 + '@typescript-eslint/types': 8.34.1
5363 comment-parser: 1.4.1
5364 esquery: 1.6.0
5365 jsdoc-type-pratt-parser: 4.1.0
@@ -5405,10 +5498,11 @@ snapshots:
5498
5499 '@eslint/js@9.29.0': {}
5500
5408 - '@eslint/markdown@6.5.0':
5501 + '@eslint/markdown@6.6.0':
5502 dependencies:
5503 '@eslint/core': 0.14.0
5504 '@eslint/plugin-kit': 0.3.1
5505 + github-slugger: 2.0.0
5506 mdast-util-from-markdown: 2.0.2
5507 mdast-util-frontmatter: 2.0.1
5508 mdast-util-gfm: 3.1.0
@@ -5466,17 +5560,17 @@ snapshots:
5560 '@iconify/types': 2.0.0
5561 vue: 3.5.17(typescript@5.8.3)
5562
5469 - '@intlify/core-base@11.1.6':
5563 + '@intlify/core-base@11.1.7':
5564 dependencies:
5471 - '@intlify/message-compiler': 11.1.6
5472 - '@intlify/shared': 11.1.6
5565 + '@intlify/message-compiler': 11.1.7
5566 + '@intlify/shared': 11.1.7
5567
5474 - '@intlify/message-compiler@11.1.6':
5568 + '@intlify/message-compiler@11.1.7':
5569 dependencies:
5476 - '@intlify/shared': 11.1.6
5570 + '@intlify/shared': 11.1.7
5571 source-map-js: 1.2.1
5572
5479 - '@intlify/shared@11.1.6': {}
5573 + '@intlify/shared@11.1.7': {}
5574
5575 '@isaacs/cliui@8.0.2':
5576 dependencies:
@@ -5770,13 +5864,17 @@ snapshots:
5864
5865 '@sindresorhus/merge-streams@4.0.0': {}
5866
5773 - '@stylistic/eslint-plugin@5.0.0-beta.5(eslint@9.29.0(jiti@2.4.2))':
5867 + '@singulio/app-auth-search@0.0.3':
5868 + dependencies:
5869 + algoliasearch: 5.29.0
5870 +
5871 + '@stylistic/eslint-plugin@5.0.0(eslint@9.29.0(jiti@2.4.2))':
5872 dependencies:
5873 '@eslint-community/eslint-utils': 4.7.0(eslint@9.29.0(jiti@2.4.2))
5776 - '@typescript-eslint/types': 8.33.1
5874 + '@typescript-eslint/types': 8.34.1
5875 eslint: 9.29.0(jiti@2.4.2)
5778 - eslint-visitor-keys: 4.2.0
5779 - espree: 10.3.0
5876 + eslint-visitor-keys: 4.2.1
5877 + espree: 10.4.0
5878 estraverse: 5.3.0
5879 picomatch: 4.0.2
5880
@@ -5990,15 +6088,6 @@ snapshots:
6088 transitivePeerDependencies:
6089 - supports-color
6090
5993 - '@typescript-eslint/project-service@8.33.1(typescript@5.8.3)':
5994 - dependencies:
5995 - '@typescript-eslint/tsconfig-utils': 8.33.1(typescript@5.8.3)
5996 - '@typescript-eslint/types': 8.33.1
5997 - debug: 4.4.1(supports-color@8.1.1)
5998 - typescript: 5.8.3
5999 - transitivePeerDependencies:
6000 - - supports-color
6001 -
6091 '@typescript-eslint/project-service@8.34.1(typescript@5.8.3)':
6092 dependencies:
6093 '@typescript-eslint/tsconfig-utils': 8.34.1(typescript@5.8.3)
@@ -6008,20 +6097,11 @@ snapshots:
6097 transitivePeerDependencies:
6098 - supports-color
6099
6011 - '@typescript-eslint/scope-manager@8.33.1':
6012 - dependencies:
6013 - '@typescript-eslint/types': 8.33.1
6014 - '@typescript-eslint/visitor-keys': 8.33.1
6015 -
6100 '@typescript-eslint/scope-manager@8.34.1':
6101 dependencies:
6102 '@typescript-eslint/types': 8.34.1
6103 '@typescript-eslint/visitor-keys': 8.34.1
6104
6021 - '@typescript-eslint/tsconfig-utils@8.33.1(typescript@5.8.3)':
6022 - dependencies:
6023 - typescript: 5.8.3
6024 -
6105 '@typescript-eslint/tsconfig-utils@8.34.1(typescript@5.8.3)':
6106 dependencies:
6107 typescript: 5.8.3
@@ -6037,26 +6117,8 @@ snapshots:
6117 transitivePeerDependencies:
6118 - supports-color
6119
6040 - '@typescript-eslint/types@8.33.1': {}
6041 -
6120 '@typescript-eslint/types@8.34.1': {}
6121
6044 - '@typescript-eslint/typescript-estree@8.33.1(typescript@5.8.3)':
6045 - dependencies:
6046 - '@typescript-eslint/project-service': 8.33.1(typescript@5.8.3)
6047 - '@typescript-eslint/tsconfig-utils': 8.33.1(typescript@5.8.3)
6048 - '@typescript-eslint/types': 8.33.1
6049 - '@typescript-eslint/visitor-keys': 8.33.1
6050 - debug: 4.4.1(supports-color@8.1.1)
6051 - fast-glob: 3.3.3
6052 - is-glob: 4.0.3
6053 - minimatch: 9.0.5
6054 - semver: 7.7.2
6055 - ts-api-utils: 2.1.0(typescript@5.8.3)
6056 - typescript: 5.8.3
6057 - transitivePeerDependencies:
6058 - - supports-color
6059 -
6122 '@typescript-eslint/typescript-estree@8.34.1(typescript@5.8.3)':
6123 dependencies:
6124 '@typescript-eslint/project-service': 8.34.1(typescript@5.8.3)
@@ -6073,17 +6135,6 @@ snapshots:
6135 transitivePeerDependencies:
6136 - supports-color
6137
6076 - '@typescript-eslint/utils@8.33.1(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3)':
6077 - dependencies:
6078 - '@eslint-community/eslint-utils': 4.7.0(eslint@9.29.0(jiti@2.4.2))
6079 - '@typescript-eslint/scope-manager': 8.33.1
6080 - '@typescript-eslint/types': 8.33.1
6081 - '@typescript-eslint/typescript-estree': 8.33.1(typescript@5.8.3)
6082 - eslint: 9.29.0(jiti@2.4.2)
6083 - typescript: 5.8.3
6084 - transitivePeerDependencies:
6085 - - supports-color
6086 -
6138 '@typescript-eslint/utils@8.34.1(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3)':
6139 dependencies:
6140 '@eslint-community/eslint-utils': 4.7.0(eslint@9.29.0(jiti@2.4.2))
@@ -6095,11 +6146,6 @@ snapshots:
6146 transitivePeerDependencies:
6147 - supports-color
6148
6098 - '@typescript-eslint/visitor-keys@8.33.1':
6099 - dependencies:
6100 - '@typescript-eslint/types': 8.33.1
6101 - eslint-visitor-keys: 4.2.0
6102 -
6149 '@typescript-eslint/visitor-keys@8.34.1':
6150 dependencies:
6151 '@typescript-eslint/types': 8.34.1
@@ -6125,7 +6171,7 @@ snapshots:
6171
6172 '@vitest/eslint-plugin@1.2.7(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3)(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.0.3)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(sass@1.89.2)(yaml@2.8.0))':
6173 dependencies:
6128 - '@typescript-eslint/utils': 8.33.1(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3)
6174 + '@typescript-eslint/utils': 8.34.1(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3)
6175 eslint: 9.29.0(jiti@2.4.2)
6176 optionalDependencies:
6177 typescript: 5.8.3
@@ -6426,10 +6472,6 @@ snapshots:
6472
6473 abbrev@2.0.0: {}
6474
6429 - acorn-jsx@5.3.2(acorn@8.14.1):
6430 - dependencies:
6431 - acorn: 8.14.1
6432 -
6475 acorn-jsx@5.3.2(acorn@8.15.0):
6476 dependencies:
6477 acorn: 8.15.0
@@ -6452,6 +6494,22 @@ snapshots:
6494 json-schema-traverse: 0.4.1
6495 uri-js: 4.4.1
6496
6497 + algoliasearch@5.29.0:
6498 + dependencies:
6499 + '@algolia/client-abtesting': 5.29.0
6500 + '@algolia/client-analytics': 5.29.0
6501 + '@algolia/client-common': 5.29.0
6502 + '@algolia/client-insights': 5.29.0
6503 + '@algolia/client-personalization': 5.29.0
6504 + '@algolia/client-query-suggestions': 5.29.0
6505 + '@algolia/client-search': 5.29.0
6506 + '@algolia/ingestion': 1.29.0
6507 + '@algolia/monitoring': 1.29.0
6508 + '@algolia/recommend': 5.29.0
6509 + '@algolia/requester-browser-xhr': 5.29.0
6510 + '@algolia/requester-fetch': 5.29.0
6511 + '@algolia/requester-node-http': 5.29.0
6512 +
6513 alien-signals@1.0.13: {}
6514
6515 ansi-colors@4.1.3: {}
@@ -7136,7 +7194,7 @@ snapshots:
7194 dependencies:
7195 eslint: 9.29.0(jiti@2.4.2)
7196
7139 - eslint-plugin-command@3.2.1(eslint@9.29.0(jiti@2.4.2)):
7197 + eslint-plugin-command@3.3.1(eslint@9.29.0(jiti@2.4.2)):
7198 dependencies:
7199 '@es-joy/jsdoccomment': 0.50.2
7200 eslint: 9.29.0(jiti@2.4.2)
@@ -7156,7 +7214,7 @@ snapshots:
7214 optionalDependencies:
7215 typescript: 5.8.3
7216
7159 - eslint-plugin-jsdoc@51.1.2(eslint@9.29.0(jiti@2.4.2)):
7217 + eslint-plugin-jsdoc@51.2.1(eslint@9.29.0(jiti@2.4.2)):
7218 dependencies:
7219 '@es-joy/jsdoccomment': 0.52.0
7220 are-docs-informative: 0.0.2
@@ -7178,7 +7236,7 @@ snapshots:
7236 eslint: 9.29.0(jiti@2.4.2)
7237 eslint-compat-utils: 0.6.5(eslint@9.29.0(jiti@2.4.2))
7238 eslint-json-compat-utils: 0.2.1(eslint@9.29.0(jiti@2.4.2))(jsonc-eslint-parser@2.4.0)
7181 - espree: 10.3.0
7239 + espree: 10.4.0
7240 graphemer: 1.4.0
7241 jsonc-eslint-parser: 2.4.0
7242 natural-compare: 1.4.0
@@ -7189,7 +7247,7 @@ snapshots:
7247 eslint-plugin-n@17.20.0(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3):
7248 dependencies:
7249 '@eslint-community/eslint-utils': 4.7.0(eslint@9.29.0(jiti@2.4.2))
7192 - '@typescript-eslint/utils': 8.33.1(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3)
7250 + '@typescript-eslint/utils': 8.34.1(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3)
7251 enhanced-resolve: 5.18.1
7252 eslint: 9.29.0(jiti@2.4.2)
7253 eslint-plugin-es-x: 7.8.0(eslint@9.29.0(jiti@2.4.2))
@@ -7300,11 +7358,6 @@ snapshots:
7358 '@vue/compiler-sfc': 3.5.17
7359 eslint: 9.29.0(jiti@2.4.2)
7360
7303 - eslint-scope@8.3.0:
7304 - dependencies:
7305 - esrecurse: 4.3.0
7306 - estraverse: 5.3.0
7307 -
7361 eslint-scope@8.4.0:
7362 dependencies:
7363 esrecurse: 4.3.0
@@ -7312,8 +7365,6 @@ snapshots:
7365
7366 eslint-visitor-keys@3.4.3: {}
7367
7315 - eslint-visitor-keys@4.2.0: {}
7316 -
7368 eslint-visitor-keys@4.2.1: {}
7369
7370 eslint@9.29.0(jiti@2.4.2):
@@ -7358,12 +7409,6 @@ snapshots:
7409 transitivePeerDependencies:
7410 - supports-color
7411
7361 - espree@10.3.0:
7362 - dependencies:
7363 - acorn: 8.14.1
7364 - acorn-jsx: 5.3.2(acorn@8.14.1)
7365 - eslint-visitor-keys: 4.2.0
7366 -
7412 espree@10.4.0:
7413 dependencies:
7414 acorn: 8.15.0
@@ -7372,8 +7417,8 @@ snapshots:
7417
7418 espree@9.6.1:
7419 dependencies:
7375 - acorn: 8.14.1
7376 - acorn-jsx: 5.3.2(acorn@8.14.1)
7420 + acorn: 8.15.0
7421 + acorn-jsx: 5.3.2(acorn@8.15.0)
7422 eslint-visitor-keys: 3.4.3
7423
7424 esprima@4.0.1: {}
@@ -7646,6 +7691,8 @@ snapshots:
7691 nypm: 0.6.0
7692 pathe: 2.0.3
7693
7694 + github-slugger@2.0.0: {}
7695 +
7696 glob-parent@5.1.2:
7697 dependencies:
7698 is-glob: 4.0.3
@@ -7977,7 +8024,7 @@ snapshots:
8024
8025 jsonc-eslint-parser@2.4.0:
8026 dependencies:
7980 - acorn: 8.14.1
8027 + acorn: 8.15.0
8028 eslint-visitor-keys: 3.4.3
8029 espree: 9.6.1
8030 semver: 7.7.2
@@ -8824,11 +8871,11 @@ snapshots:
8871
8872 prelude-ls@1.2.1: {}
8873
8827 - prettier-plugin-tailwindcss@0.6.13(prettier@3.5.3):
8874 + prettier-plugin-tailwindcss@0.6.13(prettier@3.6.0):
8875 dependencies:
8829 - prettier: 3.5.3
8876 + prettier: 3.6.0
8877
8831 - prettier@3.5.3: {}
8878 + prettier@3.6.0: {}
8879
8880 pretty-bytes@5.6.0: {}
8881
@@ -9656,9 +9703,9 @@ snapshots:
9703 dependencies:
9704 debug: 4.4.1(supports-color@8.1.1)
9705 eslint: 9.29.0(jiti@2.4.2)
9659 - eslint-scope: 8.3.0
9660 - eslint-visitor-keys: 4.2.0
9661 - espree: 10.3.0
9706 + eslint-scope: 8.4.0
9707 + eslint-visitor-keys: 4.2.1
9708 + espree: 10.4.0
9709 esquery: 1.6.0
9710 lodash: 4.17.21
9711 semver: 7.7.2
@@ -9670,10 +9717,10 @@ snapshots:
9717 highlight-words-core: 1.2.3
9718 vue: 3.5.17(typescript@5.8.3)
9719
9673 - vue-i18n@11.1.6(vue@3.5.17(typescript@5.8.3)):
9720 + vue-i18n@11.1.7(vue@3.5.17(typescript@5.8.3)):
9721 dependencies:
9675 - '@intlify/core-base': 11.1.6
9676 - '@intlify/shared': 11.1.6
9722 + '@intlify/core-base': 11.1.7
9723 + '@intlify/shared': 11.1.7
9724 '@vue/devtools-api': 6.6.4
9725 vue: 3.5.17(typescript@5.8.3)
9726
frontend/src/App.vue
+7 -4
@@ -26,6 +26,7 @@
26 import type { Component } from "vue"
27 import type { RouteLocationNormalized } from "vue-router"
28 import type { Layout, RouterTransition, ThemeNameEnum } from "@/types/theme.d"
29 +import { defineCustomElements } from "@singulio/app-auth-search/loader"
30 import { computed, onBeforeMount, ref, watch } from "vue"
31 import { useRoute, useRouter } from "vue-router"
32 import Blank from "@/app-layouts/Blank"
@@ -37,15 +38,17 @@ import { useAuthStore } from "@/stores/auth"
38 import { useMainStore } from "@/stores/main"
39 import { useThemeStore } from "@/stores/theme"
40
40 -const router = useRouter()
41 -const route = useRoute()
42 -const loading = ref(true)
43 -
41 const layoutComponents = {
42 HorizontalNav,
43 Blank
44 }
45
46 +defineCustomElements()
47 +
48 +const router = useRouter()
49 +const route = useRoute()
50 +const loading = ref(true)
51 +
52 const themeStore = useThemeStore()
53 const mainStore = useMainStore()
54 const authStore = useAuthStore()
frontend/src/api/endpoints/shuffle.ts new
+16
@@ -0,0 +1,16 @@
1 +import type { FlaskBaseResponse } from "@/types/flask.d"
2 +import type { Organization } from "@/types/shuffle.d"
3 +import { HttpClient } from "../httpClient"
4 +
5 +export default {
6 + getOrganizations() {
7 + return HttpClient.get<FlaskBaseResponse & { data: Organization[]; total_count: number }>(
8 + `/shuffle/organizations/organizations?connector_name=Shuffle`
9 + )
10 + },
11 + getOrganization(organizationId: string) {
12 + return HttpClient.get<FlaskBaseResponse & { data: Organization }>(
13 + `/shuffle/organizations/organizations/${organizationId}?connector_name=Shuffle`
14 + )
15 + }
16 +}
frontend/src/api/index.ts
+3 -1
@@ -21,6 +21,7 @@ import networkConnectors from "./endpoints/networkConnectors"
21 import portainer from "./endpoints/portainer"
22 import reporting from "./endpoints/reporting"
23 import scheduler from "./endpoints/scheduler"
24 +import shuffle from "./endpoints/shuffle"
25 import sigma from "./endpoints/sigma"
26 import soc from "./endpoints/soc"
27 import stackProvisioning from "./endpoints/stackProvisioning"
@@ -59,5 +60,6 @@ export default {
60 users,
61 sysmonConfig,
62 mitre,
62 - portainer
63 + portainer,
64 + shuffle
65 }
frontend/src/app-layouts/common/Navbar/items.tsx
+13
@@ -380,6 +380,19 @@ export default function getItems(): MenuMixedOption[] {
380 { default: () => "Network Connectors" }
381 ),
382 key: "ExternalServices-NetworkConnectors"
383 + },
384 + {
385 + label: () =>
386 + h(
387 + RouterLink,
388 + {
389 + to: {
390 + name: "ExternalServices-SingulAppAuth"
391 + }
392 + },
393 + { default: () => "Singul App Auth" }
394 + ),
395 + key: "ExternalServices-SingulAppAuth"
396 }
397 ]
398 },
frontend/src/router/index.ts
+6
@@ -233,6 +233,12 @@ const router = createRouter({
233 name: "ExternalServices-NetworkConnectors",
234 component: () => import("@/views/externalServices/NetworkConnectors.vue"),
235 meta: { title: "Network Connectors" }
236 + },
237 + {
238 + path: "singul-app-auth",
239 + name: "ExternalServices-SingulAppAuth",
240 + component: () => import("@/views/externalServices/SingulAppAuth.vue"),
241 + meta: { title: "Singul App Auth" }
242 }
243 ]
244 },
frontend/src/types/shuffle.d.ts new
+92
@@ -0,0 +1,92 @@
1 +export interface Organization {
2 + name: string
3 + description: string | null
4 + company_type: string
5 + id: string
6 + org: string | null
7 + org_auth: OrgAuth
8 + users: string[] | null
9 + role: string
10 + roles: string[]
11 + active_apps: string[]
12 + cloud_sync: boolean
13 + cloud_sync_active: boolean
14 + sync_config: OrgSyncConfig
15 + sync_features: OrgSyncFeatures
16 + invites: string[] | null
17 + child_orgs?: string[] | null
18 + manager_orgs: string[] | null
19 + creator_org: string
20 + disabled: boolean
21 + partner_info: OrgPartnerInfo
22 + sso_config: OrgSsoConfig
23 + main_priority: string
24 + region: string
25 + region_url: string
26 + tutorials: OrgTutorial[]
27 + image?: string
28 +}
29 +
30 +export interface OrgAuth {
31 + token: string
32 + expires: Date | null
33 +}
34 +
35 +export interface OrgPartnerInfo {
36 + reseller: boolean
37 + reseller_level: string
38 +}
39 +
40 +export interface OrgSsoConfig {
41 + sso_entrypoint: string
42 + sso_certificate: string
43 + client_id: string
44 + client_secret: string
45 + openid_authorization: string
46 + openid_token: string
47 +}
48 +
49 +export interface OrgSyncConfig {
50 + interval: number
51 + api_key: string
52 + source: string
53 +}
54 +
55 +export interface OrgSyncFeatures {
56 + editing: boolean
57 + mail_sent: null | boolean
58 + app_executions: OrgSyncFeature
59 + multi_env: OrgSyncFeature
60 + multi_tenant: OrgSyncFeature
61 + multi_region: OrgSyncFeature
62 + webhook: OrgSyncFeature
63 + schedules: OrgSyncFeature
64 + user_input: OrgSyncFeature
65 + send_mail: OrgSyncFeature
66 + send_sms: OrgSyncFeature
67 + updates: OrgSyncFeature
68 + email_trigger: OrgSyncFeature
69 + notifications: OrgSyncFeature
70 + workflows: OrgSyncFeature
71 + autocomplete: OrgSyncFeature
72 + workflow_executions: OrgSyncFeature
73 + authentication: OrgSyncFeature
74 + schedule: OrgSyncFeature
75 + apps: OrgSyncFeature
76 + shuffle_gpt: OrgSyncFeature
77 +}
78 +
79 +export interface OrgSyncFeature {
80 + active: boolean
81 + description?: string
82 + usage: number
83 + limit: number
84 +}
85 +
86 +export interface OrgTutorial {
87 + name: string
88 + description: string
89 + link: string
90 + done: boolean
91 + active: boolean
92 +}
frontend/src/views/externalServices/SingulAppAuth.vue new
+132
@@ -0,0 +1,132 @@
1 +<template>
2 + <div class="flex flex-col gap-2">
3 + <n-select
4 + v-model:value="selectedOrganization"
5 + :options="organizationsOptions"
6 + :loading="loadingList"
7 + :disabled="loadingList"
8 + placeholder="Select an Organization..."
9 + />
10 +
11 + <n-spin v-if="selectedOrganization" :show="loadingToken" :size="14" class="app-auth-search-spinner">
12 + <n-el>
13 + <app-search-bar
14 + class="app-auth-search"
15 + :auth="organization?.org_auth.token"
16 + placeholder="Find an app..."
17 + :custom-styles="JSON.stringify({ height: '100px' })"
18 + ></app-search-bar>
19 + </n-el>
20 + </n-spin>
21 + </div>
22 +</template>
23 +
24 +<script setup lang="ts">
25 +import type { Organization } from "@/types/shuffle.d"
26 +import { NEl, NSelect, NSpin, useMessage } from "naive-ui"
27 +import { computed, onBeforeMount, ref, watch } from "vue"
28 +import Api from "@/api"
29 +
30 +const loadingList = ref(false)
31 +const loadingToken = ref(false)
32 +const message = useMessage()
33 +const organizations = ref<Organization[]>([])
34 +const organization = ref<Organization | null>(null)
35 +const selectedOrganization = ref<string | null>(null)
36 +const organizationsOptions = computed(() => organizations.value.map(o => ({ value: o.id, label: o.name })))
37 +
38 +function getOrganizations() {
39 + loadingList.value = true
40 +
41 + Api.shuffle
42 + .getOrganizations()
43 + .then(res => {
44 + if (res.data.success) {
45 + organizations.value = res.data?.data || []
46 + } else {
47 + message.warning(res.data?.message || "An error occurred. Please try again later.")
48 + }
49 + })
50 + .catch(err => {
51 + message.error(err.response?.data?.message || "An error occurred. Please try again later.")
52 + })
53 + .finally(() => {
54 + loadingList.value = false
55 + })
56 +}
57 +
58 +function getOrganization(id: string) {
59 + loadingToken.value = true
60 +
61 + Api.shuffle
62 + .getOrganization(id)
63 + .then(res => {
64 + if (res.data.success) {
65 + organization.value = res.data?.data || null
66 + } else {
67 + message.warning(res.data?.message || "An error occurred. Please try again later.")
68 + }
69 + })
70 + .catch(err => {
71 + message.error(err.response?.data?.message || "An error occurred. Please try again later.")
72 + })
73 + .finally(() => {
74 + loadingToken.value = false
75 + })
76 +}
77 +
78 +watch(selectedOrganization, val => {
79 + if (val) {
80 + getOrganization(val)
81 + } else {
82 + organization.value = null
83 + }
84 +})
85 +
86 +onBeforeMount(() => {
87 + getOrganizations()
88 +})
89 +</script>
90 +
91 +<style lang="scss" scoped>
92 +.app-auth-search {
93 + --search-input-bg: var(--input-color);
94 + --search-input-font-size: var(--font-size-medium);
95 + --search-input-border: 1px solid transparent;
96 + --search-input-border-radius: var(--border-radius);
97 + --search-input-padding: 7px 12px 6px 12px;
98 + --search-input-color: var(--text-color-base);
99 + --search-input-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0);
100 + --search-input-focus-border: var(--primary-color);
101 + --search-input-focus-shadow: 0 0 8px 0 rgba(var(--primary-color-rgb) / 0.4);
102 + --search-input-line-height: 1.3;
103 + --search-placeholder-color: var(--placeholder-color);
104 + --search-icon-color: var(--icon-color);
105 + --search-font-family: var(--font-family);
106 + --search-spinner-border: 1px solid transparent;
107 + --search-spinner-border-top: 1px solid rgba(var(--primary-color-rgb) / 0.4);
108 + --dropdown-bg: var(--input-color);
109 + --dropdown-border: 1px solid transparent;
110 + --dropdown-border-radius: var(--border-radius);
111 + --dropdown-item-border: 1px solid var(--divider-color);
112 + --dropdown-item-hover-bg: var(--button-color-2-hover);
113 + --app-icon-size: 40px;
114 + --app-icon-border: 1px solid var(--border-color);
115 + --app-icon-border-radius: var(--border-radius-small);
116 + --app-name-color: var(--text-color-base);
117 + --app-name-font-size: var(--font-size-medium);
118 + --empty-state-color: var(--placeholder-color);
119 + --empty-state-font-size: var(--font-size-medium);
120 +}
121 +.app-auth-search-spinner {
122 + :deep() {
123 + .n-spin-body .n-base-loading {
124 + position: relative;
125 + margin-top: 0;
126 + transform: translateY(-7px);
127 + justify-content: flex-end;
128 + padding-right: 16px;
129 + }
130 + }
131 +}
132 +</style>
frontend/vite.config.ts
+5
@@ -21,6 +21,11 @@ export default defineConfig(({ mode }) => {
21 vue({
22 script: {
23 defineModel: true
24 + },
25 + template: {
26 + compilerOptions: {
27 + isCustomElement: (tag: string) => tag === "app-search-bar"
28 + }
29 }
30 }),
31 vueJsx(),