Compare commits

..

431 Commits

Author SHA1 Message Date
missingscrews
d4e625a9c2 Fix: Upgrade docker base image version to provide shared object dependencies (#1044) 2023-10-27 16:19:33 +02:00
dependabot[bot]
e724ec8883 Bump google.golang.org/grpc from 1.57.0 to 1.57.1 (#1042)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-25 23:52:14 +02:00
dependabot[bot]
0e19b80dd5 Bump decode-uri-component from 0.2.0 to 0.2.2 in /ui (#1041)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-24 00:41:48 +02:00
dependabot[bot]
a7e031151b Bump word-wrap from 1.2.3 to 1.2.5 in /ui (#1037)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-24 00:33:37 +02:00
dependabot[bot]
752d06702e Bump @babel/traverse from 7.19.3 to 7.23.2 in /ui (#1038)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-24 00:32:52 +02:00
dependabot[bot]
a37ceec393 Bump semver from 5.7.1 to 5.7.2 in /ui (#1035)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-24 00:32:13 +02:00
Jonas Plum
f27e20f002 Delete .github/renovate.json 2023-10-24 00:25:46 +02:00
renovate[bot]
7951196c4d Update vue monorepo to v2.7.15 (#1032)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-23 20:54:00 +00:00
renovate[bot]
e00426a4ef Update actions/setup-node action to v4 (#1034)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-23 22:47:29 +02:00
renovate[bot]
2918d39771 Update module github.com/aws/aws-sdk-go to v1.46.2 (#1033)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-23 19:11:48 +00:00
renovate[bot]
e39578a841 Update module github.com/aws/aws-sdk-go to v1.46.1 (#1031)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-20 22:37:38 +00:00
renovate[bot]
4d4f87156b Update dependency eslint-plugin-jest to v27.4.3 (#1030)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-20 22:36:35 +00:00
renovate[bot]
39ec9d82f4 Update dependency @vue/compiler-sfc to v3.3.6 (#1029)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-20 14:03:33 +00:00
renovate[bot]
8f6c437be1 Update module github.com/coreos/go-oidc/v3 to v3.7.0 (#1028)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-20 11:15:13 +00:00
renovate[bot]
efacd28d2b Update dependency core-js to v3.33.1 (#1027)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-20 08:01:30 +00:00
renovate[bot]
f3f9174949 Update dependency @vue/compiler-sfc to v3.3.5 (#1026)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-20 04:14:15 +00:00
renovate[bot]
4b9e9fbe40 Update module github.com/aws/aws-sdk-go to v1.46.0 (#1014)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-19 23:21:45 +02:00
renovate[bot]
0ffa48849d Update actions/checkout action to v4 (#987)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-19 13:52:34 +02:00
renovate[bot]
e349891102 Update dependency @mdi/font to v7.3.67 (#1016)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-18 23:32:09 +00:00
renovate[bot]
e7dede18de Update dependency @types/prismjs to v1.26.2 (#1010)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-18 23:31:05 +00:00
renovate[bot]
f0aa1792eb Update dependency @types/lodash to v4.14.200 (#1008)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-18 23:30:30 +00:00
renovate[bot]
67dd6a2ead Update dependency sass to v1.69.4 (#1019)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-18 23:17:08 +00:00
renovate[bot]
d246db506a Update dependency eslint-plugin-jest to v27.4.2 (#1018)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-18 23:16:32 +00:00
renovate[bot]
e64e024140 Update dependency core-js to v3.33.0 (#1017)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-18 23:16:06 +00:00
renovate[bot]
9ad2c4c4dd Update dependency @koumoul/vjsf to v2.23.2 (#1004)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-18 23:12:50 +00:00
renovate[bot]
7dce84a3b5 Update dependency axios to v1.5.1 (#1012)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-18 23:10:28 +00:00
renovate[bot]
7ca552a225 Update module github.com/alecthomas/kong to v0.8.1 (#1013)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-18 23:10:14 +00:00
renovate[bot]
84d337394e Update dependency @types/vue-markdown to v2.2.3 (#1011)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-18 23:09:43 +00:00
renovate[bot]
4449e2096b Update dependency @types/luxon to v3.3.3 (#1009)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-18 23:07:29 +00:00
renovate[bot]
a6cb83e8c7 Update dependency @types/jest to v29.5.6 (#1006)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-18 23:05:18 +00:00
renovate[bot]
a78c355f3f Update golang.org/x/exp digest to 7918f67 (#1003)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-18 23:04:10 +00:00
renovate[bot]
69981ab975 Update docker/metadata-action action to v5 (#1023)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-19 00:44:03 +02:00
Jonas Plum
e0a8e3e479 Uplift (#1025) 2023-10-19 00:41:37 +02:00
missingscrews
e41c50c9c2 Configurable S3 Region (#1007)
Co-authored-by: Jonas Plum <cugu@users.noreply.github.com>
2023-10-18 22:45:49 +02:00
Jonas Plum
494fee194b Create CODEOWNERS 2023-10-16 13:25:31 +02:00
renovate[bot]
a3a38990bc Update docker/build-push-action action to v5 (#1001)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-09 23:45:55 +02:00
renovate[bot]
430584e5ed Update docker/login-action action to v3 (#1002)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-09 23:45:47 +02:00
renovate[bot]
7b5acb19a4 Update module github.com/aws/aws-sdk-go to v1.45.7 2023-09-11 21:05:23 +00:00
renovate[bot]
a2341423d7 Update module github.com/aws/aws-sdk-go to v1.45.6 2023-09-08 23:39:12 +00:00
renovate[bot]
42ea4b1f31 Update module github.com/aws/aws-sdk-go to v1.45.5 2023-09-08 02:08:48 +00:00
renovate[bot]
17230ef232 Update dependency core-js to v3.32.2 2023-09-07 16:59:10 +00:00
renovate[bot]
b2bc5932d0 Update module github.com/aws/aws-sdk-go to v1.45.4 2023-09-07 01:15:16 +00:00
renovate[bot]
853577c5ba Update module github.com/tus/tusd to v1.13.0 2023-09-06 12:26:51 +00:00
renovate[bot]
0722369c7a Update module golang.org/x/oauth2 to v0.12.0 2023-09-06 10:18:13 +00:00
renovate[bot]
0620fd40bd Update module github.com/aws/aws-sdk-go to v1.45.3 2023-09-06 08:34:06 +00:00
renovate[bot]
0798c2e196 Update dependency @types/lodash to v4.14.198 2023-09-06 04:41:21 +00:00
renovate[bot]
d1566d0cd0 Update golang.org/x/exp digest to 9212866 2023-09-06 01:18:46 +00:00
renovate[bot]
778a27d3b9 Update dependency luxon to v3.4.3 2023-09-05 21:04:03 +00:00
renovate[bot]
a7a1564726 Update dependency @babel/eslint-parser to v7.22.15 2023-09-05 16:45:41 +00:00
renovate[bot]
43f11dc054 Update dependency @koumoul/vjsf to v2.22.0 2023-09-05 12:29:41 +00:00
renovate[bot]
89afb1aab2 Update module github.com/aws/aws-sdk-go to v1.45.2 2023-09-01 23:06:10 +00:00
renovate[bot]
f9d129eae3 Update module github.com/aws/aws-sdk-go to v1.45.1 2023-09-01 00:52:36 +00:00
renovate[bot]
e13ffb75be Update dependency @types/luxon to v3.3.2 2023-08-31 01:28:36 +00:00
renovate[bot]
dd647fee1e Update module github.com/aws/aws-sdk-go to v1.45.0 2023-08-30 22:32:36 +00:00
renovate[bot]
4f7491f360 Update dependency axios to v1.5.0 2023-08-30 01:55:55 +00:00
renovate[bot]
f54bb043de Update module github.com/aws/aws-sdk-go to v1.44.334 2023-08-29 21:20:31 +00:00
renovate[bot]
f5144c6771 Update dependency luxon to v3.4.2 2023-08-26 23:39:12 +00:00
renovate[bot]
6056e5eaba Update dependency @babel/eslint-parser to v7.22.11 2023-08-26 02:58:10 +00:00
renovate[bot]
9c94208aa9 Update module github.com/aws/aws-sdk-go to v1.44.332 2023-08-25 22:48:17 +00:00
renovate[bot]
cf680816c0 Update module github.com/aws/aws-sdk-go to v1.44.330 2023-08-23 22:19:30 +00:00
renovate[bot]
9d12b41175 Update module github.com/aws/aws-sdk-go to v1.44.329 2023-08-23 07:31:26 +00:00
renovate[bot]
53d9192258 Update dependency luxon to v3.4.1 2023-08-23 03:14:44 +00:00
renovate[bot]
1dc7901bdf Update dependency @types/jest to v29.5.4 2023-08-23 00:47:27 +00:00
renovate[bot]
ee7cd96aee Update module github.com/aws/aws-sdk-go to v1.44.328 2023-08-22 00:33:11 +00:00
renovate[bot]
d23c7e721a Update module github.com/google/uuid to v1.3.1 2023-08-21 23:10:04 +00:00
renovate[bot]
7b0eb2d186 Update dependency sass to v1.66.1 2023-08-19 04:56:17 +00:00
renovate[bot]
b468a4a4cb Update dependency core-js to v3.32.1 2023-08-19 01:55:15 +00:00
renovate[bot]
8e4fe069b4 Update module github.com/aws/aws-sdk-go to v1.44.327 2023-08-18 21:51:21 +00:00
renovate[bot]
e53f5c9d7f Update dependency sass to v1.66.0 2023-08-18 04:50:23 +00:00
renovate[bot]
31a2153446 Update module github.com/aws/aws-sdk-go to v1.44.326 2023-08-18 01:51:24 +00:00
renovate[bot]
8b24418b6e Update golang.org/x/exp digest to d852ddb 2023-08-17 21:06:47 +00:00
renovate[bot]
3c8cd48cab Update module github.com/aws/aws-sdk-go to v1.44.325 2023-08-16 21:34:08 +00:00
renovate[bot]
4a0d50d7cc Update module github.com/aws/aws-sdk-go to v1.44.324 2023-08-15 21:08:45 +00:00
renovate[bot]
aedfd06d4b Update module github.com/aws/aws-sdk-go to v1.44.323 2023-08-14 21:46:30 +00:00
renovate[bot]
8057aa5cc8 Update golang.org/x/exp digest to 89c5cff 2023-08-11 19:10:37 +00:00
renovate[bot]
ca1a5815c5 Update module github.com/aws/aws-sdk-go to v1.44.321 2023-08-10 21:29:14 +00:00
renovate[bot]
ef0ca9946c Update module github.com/tidwall/gjson to v1.16.0 2023-08-10 17:06:03 +00:00
renovate[bot]
7caf657cc2 Update module github.com/gobwas/ws to v1.3.0 2023-08-10 13:38:29 +00:00
renovate[bot]
6276a587a3 Update module github.com/aws/aws-sdk-go to v1.44.320 2023-08-10 09:07:26 +00:00
renovate[bot]
793e68e802 Update golang.org/x/exp digest to 352e893 2023-08-10 08:20:59 +00:00
renovate[bot]
f6923f9b25 Update dependency sass to v1.65.1 2023-08-10 04:43:14 +00:00
renovate[bot]
3b34a5c65e Update dependency @types/lodash to v4.14.197 2023-08-10 01:56:30 +00:00
renovate[bot]
a2e9d6c36f Update dependency luxon to v3.4.0 2023-08-09 23:25:16 +00:00
renovate[bot]
dec44b6d1d Update golang.org/x/exp digest to 7b3493d 2023-08-09 20:46:31 +00:00
renovate[bot]
0b99764eb1 Update module github.com/aws/aws-sdk-go to v1.44.319 2023-08-09 16:23:04 +00:00
renovate[bot]
a317490f61 Update dependency vuetify to v2.7.1 2023-08-09 14:22:56 +00:00
renovate[bot]
55caa99e2f Update golang.org/x/exp digest to 050eac2 2023-08-08 03:11:43 +00:00
renovate[bot]
c927e5f338 Update module github.com/aws/aws-sdk-go to v1.44.318 2023-08-08 00:07:38 +00:00
renovate[bot]
6140b124bf Update dependency @babel/eslint-parser to v7.22.10 2023-08-07 21:39:58 +00:00
renovate[bot]
25b6895c9d Update dependency less to v4.2.0 2023-08-05 22:33:41 +00:00
renovate[bot]
8c2d666e5e Update module golang.org/x/oauth2 to v0.11.0 2023-08-05 07:46:19 +00:00
renovate[bot]
6aaabe9cbf Update module github.com/aws/aws-sdk-go to v1.44.317 2023-08-04 23:00:41 +00:00
renovate[bot]
a5f666a142 Update module github.com/aws/aws-sdk-go to v1.44.315 2023-08-02 22:13:59 +00:00
renovate[bot]
b4a1fcdfbe Update dependency json-schema-editor-vue to v2.2.3 2023-08-02 16:18:59 +00:00
renovate[bot]
657b2d4431 Update module github.com/aws/aws-sdk-go to v1.44.314 2023-08-01 21:44:00 +00:00
renovate[bot]
064abf7bb8 Update golang.org/x/exp digest to d63ba01 2023-08-01 16:47:53 +00:00
renovate[bot]
f7a80a841c Update dependency sass to v1.64.2 2023-08-01 07:14:47 +00:00
renovate[bot]
65cbf35611 Update module github.com/aws/aws-sdk-go to v1.44.313 2023-07-31 23:06:31 +00:00
renovate[bot]
4181439e71 Update module github.com/aws/aws-sdk-go to v1.44.312 2023-07-29 03:30:47 +00:00
renovate[bot]
39a9ebe778 Update golang.org/x/exp digest to b0cb94b 2023-07-29 00:09:54 +00:00
renovate[bot]
3edde1b7c7 Update module github.com/aws/aws-sdk-go to v1.44.311 2023-07-28 06:03:23 +00:00
renovate[bot]
fda16aca30 Update dependency core-js to v3.32.0 2023-07-28 03:37:12 +00:00
renovate[bot]
8d68f8fc6d Update module github.com/aws/aws-sdk-go to v1.44.310 2023-07-28 00:35:49 +00:00
renovate[bot]
826811034e Update module github.com/tidwall/gjson to v1.15.0 2023-07-27 18:15:47 +00:00
renovate[bot]
0c90b855a6 Update module github.com/aws/aws-sdk-go to v1.44.309 2023-07-26 21:02:01 +00:00
renovate[bot]
365649c709 Update dependency @types/lodash to v4.14.196 2023-07-26 03:17:05 +00:00
renovate[bot]
23d2aa2cf4 Update module github.com/aws/aws-sdk-go to v1.44.308 2023-07-26 01:21:45 +00:00
renovate[bot]
985975a2a1 Update module github.com/tus/tusd to v1.12.1 2023-07-25 22:00:19 +00:00
renovate[bot]
8a10d38d72 Update golang.org/x/exp digest to 515e97e 2023-07-25 14:35:49 +00:00
renovate[bot]
a79267f213 Update golang.org/x/exp digest to 302865e 2023-07-25 06:50:08 +00:00
renovate[bot]
b79a721fb7 Update module github.com/aws/aws-sdk-go to v1.44.307 2023-07-24 21:26:56 +00:00
renovate[bot]
ce8485f8d2 Update dependency sass to v1.64.1 2023-07-22 04:40:04 +00:00
renovate[bot]
a14baa49c6 Update module github.com/aws/aws-sdk-go to v1.44.306 2023-07-21 23:26:53 +00:00
renovate[bot]
c623859f64 Update dependency @vue/test-utils to v2.4.1 2023-07-21 08:10:43 +00:00
renovate[bot]
7bc401041c Update dependency @types/luxon to v3.3.1 2023-07-21 04:25:19 +00:00
renovate[bot]
1504ee4cf6 Update module github.com/aws/aws-sdk-go to v1.44.305 2023-07-20 21:10:15 +00:00
renovate[bot]
4b263b4e7b Update module github.com/aws/aws-sdk-go to v1.44.304 2023-07-20 09:42:37 +00:00
renovate[bot]
dda21ad4de Update dependency sass to v1.64.0 2023-07-20 03:23:00 +00:00
renovate[bot]
b54c8ab813 Update module github.com/aws/aws-sdk-go to v1.44.303 2023-07-19 22:38:13 +00:00
renovate[bot]
268647084d Update module github.com/aws/aws-sdk-go to v1.44.302 2023-07-19 02:08:37 +00:00
renovate[bot]
d6452271d1 Update module github.com/aws/aws-sdk-go to v1.44.301 2023-07-17 23:08:38 +00:00
renovate[bot]
4b48bc312b Update module github.com/go-chi/chi/v5 to v5.0.10 2023-07-14 06:28:03 +00:00
renovate[bot]
e3a30e173d Update dependency eslint-plugin-jest to v27.2.3 2023-07-14 03:26:42 +00:00
renovate[bot]
0d4d0cc596 Update golang.org/x/exp digest to 613f0c0 2023-07-14 00:15:16 +00:00
renovate[bot]
34cdfc6339 Update module github.com/aws/aws-sdk-go to v1.44.300 2023-07-13 21:20:25 +00:00
renovate[bot]
07ae578686 Update module github.com/blevesearch/bleve/v2 to v2.3.9 2023-07-13 08:10:57 +00:00
renovate[bot]
caf47c20ab Update module github.com/iancoleman/strcase to v0.3.0 2023-07-13 03:25:57 +00:00
renovate[bot]
37e2d4e299 Update dependency @babel/eslint-parser to v7.22.9 2023-07-12 22:23:25 +00:00
renovate[bot]
d41fdac3bf Update golang.org/x/exp digest to 06a737e 2023-07-11 18:27:34 +00:00
renovate[bot]
4960d1a28f Update module github.com/aws/aws-sdk-go to v1.44.299 2023-07-11 09:25:00 +00:00
renovate[bot]
e0e0b4108b Update golang.org/x/exp digest to fffb143 2023-07-11 06:51:09 +00:00
renovate[bot]
bc71eb8bc9 Update typescript-eslint monorepo to v5.62.0 2023-07-10 21:47:53 +00:00
renovate[bot]
2f665be433 Update dependency @types/jest to v29.5.3 2023-07-10 20:32:18 +00:00
renovate[bot]
701740d7c6 Update module github.com/aws/aws-sdk-go to v1.44.298 2023-07-07 21:54:32 +00:00
renovate[bot]
8720ab1485 Update dependency @babel/eslint-parser to v7.22.7 2023-07-07 00:47:57 +00:00
renovate[bot]
185c47c791 Update module github.com/aws/aws-sdk-go to v1.44.297 2023-07-06 22:55:32 +00:00
renovate[bot]
5a935b391c Update module golang.org/x/oauth2 to v0.10.0 2023-07-06 07:31:01 +00:00
renovate[bot]
680ac096f0 Update dependency core-js to v3.31.1 2023-07-06 04:57:35 +00:00
renovate[bot]
34bd77b2b2 Update module github.com/aws/aws-sdk-go to v1.44.296 2023-07-05 21:28:41 +00:00
renovate[bot]
a9184a149a Update dependency vuetify to v2.7.0 2023-07-05 19:02:59 +00:00
renovate[bot]
b4e9438420 Update dependency @babel/eslint-parser to v7.22.6 2023-07-04 10:55:47 +00:00
renovate[bot]
38f7d4639b Update module github.com/aws/aws-sdk-go to v1.44.295 2023-07-04 02:17:36 +00:00
renovate[bot]
b210d90d53 Update typescript-eslint monorepo to v5.61.0 2023-07-03 21:49:06 +00:00
renovate[bot]
c9c5e2ca1c Update module github.com/aws/aws-sdk-go to v1.44.294 2023-07-01 08:47:26 +00:00
renovate[bot]
543bbd4460 Update module github.com/aws/aws-sdk-go to v1.44.293 2023-06-30 00:51:27 +00:00
renovate[bot]
3784e8fc98 Update dependency typescript to v5.1.6 2023-06-29 03:19:30 +00:00
renovate[bot]
2cd5ca81c5 Update module github.com/aws/aws-sdk-go to v1.44.292 2023-06-28 22:17:01 +00:00
renovate[bot]
067d544c60 Update module github.com/tus/tusd to v1.11.0 2023-06-28 12:18:51 +02:00
renovate[bot]
54adc98e2c Update dependency @babel/eslint-parser to v7.22.5 2023-06-28 12:18:42 +02:00
renovate[bot]
beaf9c0088 Update typescript-eslint monorepo to v5.60.1 2023-06-28 09:56:01 +02:00
renovate[bot]
a3a7708da7 Update vue monorepo 2023-06-28 09:55:48 +02:00
renovate[bot]
6fdca18a32 Replace dependency babel-eslint with @babel/eslint-parser 7.11.0 2023-06-28 09:55:32 +02:00
renovate[bot]
2216823f51 Update nginx Docker tag to v1.25 2023-06-28 09:55:11 +02:00
renovate[bot]
c3b998cba4 Update module golang.org/x/oauth2 to v0.9.0 2023-06-28 09:54:39 +02:00
renovate[bot]
42f0ece838 Update module github.com/alecthomas/kong to v0.8.0 2023-06-28 09:54:28 +02:00
renovate[bot]
cce8320acf Update module github.com/arangodb/go-driver to v1.6.0 2023-06-28 06:05:03 +00:00
renovate[bot]
ec7263bc19 Update module github.com/alecthomas/kong-yaml to v0.2.0 2023-06-28 04:00:34 +00:00
renovate[bot]
bb5b01577f Update dependency typescript to v5.1.5 2023-06-28 02:23:37 +00:00
renovate[bot]
567e90d3b6 Update module github.com/aws/aws-sdk-go to v1.44.291 2023-06-27 23:22:07 +00:00
renovate[bot]
ad104c3d01 Update dependency sass to v1.63.6 2023-06-27 20:07:25 +00:00
renovate[bot]
c947365a56 Update dependency core-js to v3.31.0 2023-06-27 17:12:43 +00:00
renovate[bot]
f69363a35b Update dependency @vue/test-utils to v2.4.0 2023-06-27 12:35:04 +00:00
renovate[bot]
3d058d67ae Update module github.com/stretchr/testify to v1.8.4 2023-06-27 09:12:18 +00:00
renovate[bot]
1b8a9519b4 Update module github.com/imdario/mergo to v0.3.16 2023-06-27 06:43:04 +00:00
renovate[bot]
45589c1304 Update golang.org/x/exp digest to 97b1e66 2023-06-27 03:24:21 +00:00
renovate[bot]
2701a4b8fe Update module github.com/aws/aws-sdk-go to v1.44.290 2023-06-27 00:41:54 +00:00
renovate[bot]
10f9cf5246 Update dependency less-loader to v11.1.3 2023-06-26 21:53:20 +00:00
renovate[bot]
57e38f3545 Update dependency eslint-plugin-jest to v27.2.2 2023-06-26 19:21:08 +00:00
renovate[bot]
8b4aff0ce3 Update dependency d3 to v7.8.5 2023-06-26 17:19:50 +00:00
renovate[bot]
d21924133c Update dependency @types/lodash to v4.14.195 2023-06-26 14:22:41 +00:00
renovate[bot]
f59e18a09a Update dependency @types/jest to v29.5.2 2023-06-26 11:53:38 +00:00
renovate[bot]
ac994bfde7 Update dependency @testing-library/vue to v7 2023-06-26 08:51:07 +02:00
renovate[bot]
73cc97b3dc Update dependency typescript to v5 2023-06-26 08:50:55 +02:00
renovate[bot]
d07081f503 Update module github.com/gobwas/ws to v1.2.1 2023-05-25 07:55:23 +00:00
renovate[bot]
4843338d5e Update module github.com/coreos/go-oidc/v3 to v3.6.0 2023-05-25 04:43:59 +00:00
renovate[bot]
bca4667cb5 Update dependency sass to v1.62.1 2023-05-25 01:45:11 +00:00
renovate[bot]
2a6a77274a Update module github.com/aws/aws-sdk-go to v1.44.269 2023-05-24 22:52:13 +00:00
renovate[bot]
f992b6d3cb Update dependency core-js to v3.30.2 2023-05-24 19:23:26 +00:00
renovate[bot]
3950800a3e Update dependency axios to v1.4.0 2023-05-24 15:10:57 +00:00
renovate[bot]
1dfbbf9f6e Update dependency @types/luxon to v3.3.0 2023-05-24 11:21:21 +00:00
renovate[bot]
d0db3c0829 Update module github.com/imdario/mergo to v0.3.15 2023-05-24 06:33:26 +00:00
renovate[bot]
cb233072ca Update module github.com/aws/aws-sdk-go to v1.44.268 2023-05-24 02:20:02 +00:00
renovate[bot]
cba34f34d5 Update module github.com/stretchr/testify to v1.8.3 2023-05-23 16:14:42 +00:00
renovate[bot]
a048ceb503 Update module github.com/aws/aws-sdk-go to v1.44.267 2023-05-23 10:47:26 +00:00
renovate[bot]
df2672f819 Update dependency @koumoul/vjsf to v2.21.4 2023-05-23 07:02:17 +00:00
renovate[bot]
90440cdbf4 Update golang.org/x/exp digest to 2e198f4 2023-05-22 22:13:50 +00:00
renovate[bot]
fad7b4138d Update module github.com/blevesearch/bleve/v2 to v2.3.8 2023-05-22 18:41:49 +00:00
renovate[bot]
a2618fef27 Update dependency vuetify to v2.6.15 2023-05-22 11:36:51 +00:00
renovate[bot]
550df2a831 Update dependency json-schema-editor-vue to v2.2.2 2023-05-22 06:23:45 +00:00
renovate[bot]
b7a9adaa9f Update dependency d3 to v7.8.4 2023-05-22 03:52:47 +00:00
renovate[bot]
9dd0e166e6 Update dependency @vue/test-utils to v2.3.2 2023-05-22 00:38:23 +00:00
renovate[bot]
f47bc8230c Update dependency @types/jest to v29.5.1 2023-05-21 21:36:07 +00:00
renovate[bot]
22fe237fbd Update dependency @types/lodash to v4.14.194 2023-05-21 20:27:35 +02:00
renovate[bot]
065f67ff6c Update dependency @mdi/font to v7.2.96 2023-05-21 17:44:26 +00:00
renovate[bot]
6ea69d6903 Update github.com/icza/dyno digest to 09f820a 2023-05-21 15:09:16 +00:00
renovate[bot]
7d21b06bab Update golang.org/x/exp digest to 03e9162 2023-05-21 14:35:15 +02:00
Jonas Plum
25b9d693af Fix linter issues 2023-05-21 13:52:26 +02:00
Jonas Plum
c96e2ebe06 Change readme 2023-05-21 13:35:41 +02:00
renovate[bot]
41e55756cf Update actions/setup-go action to v4 (#825)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-03-26 11:07:34 +02:00
renovate[bot]
a377a4ccb8 Update module github.com/blevesearch/bleve/v2 to v2.3.7 2023-03-17 22:13:38 +00:00
renovate[bot]
2944ae2100 Update module github.com/aws/aws-sdk-go to v1.44.224 2023-03-17 20:23:19 +00:00
renovate[bot]
519d9152c8 Update module github.com/aws/aws-sdk-go to v1.44.223 2023-03-16 20:55:41 +00:00
renovate[bot]
3769743904 Update dependency @types/jest to v29.5.0 2023-03-16 18:06:30 +00:00
renovate[bot]
d9f4c979de Update module github.com/imdario/mergo to v0.3.14 2023-03-16 10:16:47 +00:00
renovate[bot]
b51d70c586 Update module github.com/aws/aws-sdk-go to v1.44.222 2023-03-16 10:00:41 +00:00
renovate[bot]
6f66584807 Update dependency d3 to v7.8.2 2023-03-16 04:31:12 +00:00
renovate[bot]
6a81e5cdf8 Update dependency @types/jest to v29.4.4 2023-03-16 03:44:57 +00:00
renovate[bot]
7ab504659f Update dependency @crinkles/digl to v2.0.3 2023-03-16 00:54:23 +00:00
renovate[bot]
3b379f9a36 Update golang.org/x/exp digest to 642cace 2023-03-15 22:52:06 +00:00
renovate[bot]
2048312a63 Update dependency @types/jest to v29.4.2 2023-03-15 08:30:50 +00:00
renovate[bot]
358f6d8f38 Update dependency sass to v1.59.3 2023-03-15 00:54:24 +00:00
renovate[bot]
32fd39bac4 Update module github.com/aws/aws-sdk-go to v1.44.221 2023-03-14 21:53:03 +00:00
renovate[bot]
1d1a40d768 Update golang.org/x/exp digest to db07412 2023-03-14 20:46:09 +00:00
renovate[bot]
7b68319912 Update typescript-eslint monorepo to v5.55.0 2023-03-14 06:05:44 +00:00
renovate[bot]
95498051cc Update module github.com/aws/aws-sdk-go to v1.44.220 2023-03-14 04:55:27 +00:00
renovate[bot]
979bbeb468 Update dependency core-js to v3.29.1 2023-03-14 03:56:29 +00:00
renovate[bot]
3c2a247241 Update dependency @types/jest to v29.4.1 2023-03-14 00:38:08 +00:00
renovate[bot]
d5dcd23380 Update dependency sass to v1.59.2 2023-03-11 04:00:09 +00:00
renovate[bot]
f0d5925918 Update module github.com/aws/aws-sdk-go to v1.44.219 2023-03-11 01:40:03 +00:00
renovate[bot]
cc33031751 Update golang.org/x/exp digest to 522b1b5 2023-03-10 21:36:46 +00:00
renovate[bot]
202f015f0d Update module github.com/aws/aws-sdk-go to v1.44.218 2023-03-10 01:52:30 +00:00
renovate[bot]
cc3ce0377f Update dependency @vue/test-utils to v2.3.1 2023-03-09 07:17:19 +00:00
renovate[bot]
fb5002d5fc Update module github.com/aws/aws-sdk-go to v1.44.217 2023-03-08 21:29:17 +00:00
renovate[bot]
3bff4444a2 Update module github.com/aws/aws-sdk-go to v1.44.216 2023-03-08 03:35:18 +00:00
renovate[bot]
1e2efe6ae4 Update golang.org/x/exp digest to 24139be 2023-03-08 00:10:16 +00:00
renovate[bot]
497d3a5b45 Update typescript-eslint monorepo to v5.54.1 2023-03-07 13:41:55 +00:00
renovate[bot]
fd624ebe79 Update module github.com/aws/aws-sdk-go to v1.44.215 2023-03-07 10:17:46 +00:00
renovate[bot]
82d65430e8 Update golang.org/x/exp digest to f0f767c 2023-03-07 06:42:31 +00:00
renovate[bot]
51aa1f6333 Update module golang.org/x/oauth2 to v0.6.0 2023-03-05 07:33:06 +00:00
renovate[bot]
458ec5a5e0 Update dependency luxon to v3.3.0 2023-03-04 18:58:50 +00:00
renovate[bot]
0dc2b31d74 Update golang.org/x/exp digest to 9ff063c 2023-03-04 16:01:29 +00:00
renovate[bot]
215bb60c5b Update module github.com/aws/aws-sdk-go to v1.44.214 2023-03-04 13:35:03 +00:00
renovate[bot]
94ea23ab7f Update golang.org/x/exp digest to 44a13b0 2023-03-04 08:40:02 +00:00
renovate[bot]
dd97863db1 Update module github.com/aws/aws-sdk-go to v1.44.213 2023-03-03 03:21:29 +00:00
renovate[bot]
ca8028e6f3 Update module github.com/aws/aws-sdk-go to v1.44.212 2023-03-02 01:02:08 +00:00
renovate[bot]
dab3c43ed6 Update module github.com/arangodb/go-driver to v1.5.2 2023-03-01 16:21:21 +00:00
renovate[bot]
19ced1c158 Update module github.com/aws/aws-sdk-go to v1.44.211 2023-02-28 22:18:46 +00:00
renovate[bot]
6df41e1725 Update module github.com/aws/aws-sdk-go to v1.44.210 2023-02-28 03:26:02 +00:00
renovate[bot]
5efd237486 Update typescript-eslint monorepo to v5.54.0 2023-02-27 22:49:46 +00:00
renovate[bot]
e3008f3e32 Update dependency core-js to v3.29.0 2023-02-27 00:03:17 +00:00
renovate[bot]
68ff808737 Update module github.com/stretchr/testify to v1.8.2 2023-02-25 17:39:48 +00:00
renovate[bot]
1f6bcfb2f4 Update module github.com/aws/aws-sdk-go to v1.44.209 2023-02-25 06:10:39 +00:00
renovate[bot]
f6093bbf46 Update golang.org/x/exp digest to c95f2b4 2023-02-25 00:48:29 +00:00
renovate[bot]
52da58314a Update module github.com/aws/aws-sdk-go to v1.44.208 2023-02-24 06:35:42 +00:00
renovate[bot]
4a57413229 Update golang.org/x/exp digest to 50820d9 2023-02-24 03:11:53 +00:00
renovate[bot]
197507cf9b Update module github.com/aws/aws-sdk-go to v1.44.207 2023-02-23 08:38:26 +00:00
renovate[bot]
ae36ce5cfb Update dependency axios to v1.3.4 2023-02-23 03:07:44 +00:00
renovate[bot]
4b8691137c Update module github.com/aws/aws-sdk-go to v1.44.206 2023-02-22 03:32:47 +00:00
renovate[bot]
93f39c8c9a Update typescript-eslint monorepo to v5.53.0 2023-02-21 04:32:14 +00:00
renovate[bot]
7845a8406e Update module github.com/aws/aws-sdk-go to v1.44.205 2023-02-21 01:01:12 +00:00
renovate[bot]
5e8813cb60 Update dependency @vue/test-utils to v2.3.0 2023-02-20 05:24:45 +00:00
renovate[bot]
24618b7b43 Update dependency sass to v1.58.3 2023-02-18 06:03:04 +00:00
renovate[bot]
7850e0b95e Update module github.com/aws/aws-sdk-go to v1.44.204 2023-02-18 01:48:44 +00:00
renovate[bot]
994c7e9b29 Update module github.com/arangodb/go-driver to v1.5.0 2023-02-17 18:08:51 +00:00
renovate[bot]
8d3b9b800f Update dependency sass to v1.58.2 2023-02-17 12:36:06 +00:00
renovate[bot]
9bef926de0 Update module github.com/aws/aws-sdk-go to v1.44.203 2023-02-17 06:47:16 +00:00
renovate[bot]
f4a22a1b89 Update module github.com/aws/aws-sdk-go to v1.44.202 2023-02-15 22:45:28 +00:00
renovate[bot]
37bb0f480e Update typescript-eslint monorepo to v5.52.0 2023-02-15 04:52:24 +00:00
renovate[bot]
b26ce2099a Update module github.com/aws/aws-sdk-go to v1.44.201 2023-02-15 02:50:49 +00:00
renovate[bot]
941b10caf7 Update dependency core-js to v3.28.0 2023-02-14 23:41:58 +00:00
renovate[bot]
c3ba3e4f6d Update module github.com/aws/aws-sdk-go to v1.44.200 2023-02-14 18:53:58 +00:00
renovate[bot]
897733b90a Update dependency sass to v1.58.1 2023-02-14 12:52:37 +00:00
renovate[bot]
c6cb853729 Update golang.org/x/exp digest to 5e25df0 2023-02-14 06:55:46 +00:00
renovate[bot]
ae05ef9e44 Update dependency axios to v1.3.3 2023-02-14 02:52:26 +00:00
renovate[bot]
6293b1e876 Update golang.org/x/exp digest to a684f29 2023-02-12 20:08:35 +00:00
renovate[bot]
d35359bd9b Update module github.com/aws/aws-sdk-go to v1.44.199 2023-02-11 05:21:21 +00:00
renovate[bot]
6dcda40b39 Update golang.org/x/exp digest to 062eb4c 2023-02-11 02:07:44 +00:00
renovate[bot]
71b6788582 Update module github.com/aws/aws-sdk-go to v1.44.198 2023-02-10 01:22:02 +00:00
renovate[bot]
4978d9fccf Update module golang.org/x/oauth2 to v0.5.0 2023-02-09 06:00:20 +00:00
renovate[bot]
f7c99548db Update module github.com/aws/aws-sdk-go to v1.44.197 2023-02-09 02:43:10 +00:00
renovate[bot]
d576fbe697 Update module github.com/aws/aws-sdk-go to v1.44.196 2023-02-08 04:05:39 +00:00
renovate[bot]
a81df1f857 Update module github.com/aws/aws-sdk-go to v1.44.195 2023-02-07 06:00:12 +00:00
renovate[bot]
394e505742 Update typescript-eslint monorepo to v5.51.0 2023-02-07 02:13:02 +00:00
renovate[bot]
7223027209 Update golang.org/x/exp digest to 46f607a 2023-02-07 00:01:06 +00:00
renovate[bot]
7eaa98dc5b Update docker/build-push-action action to v4 (#723)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-02-05 02:24:21 +01:00
Jonas Plum
c8b6a6b482 Hide API key when view is changed (#743) 2023-02-05 02:24:05 +01:00
Jonas Plum
aee0be7a68 Allow @ in usernames (#742) 2023-02-05 01:45:33 +01:00
renovate[bot]
188ca256af Update dependency axios to v1.3.2 2023-02-04 05:34:05 +00:00
renovate[bot]
3b7af3bf08 Update module github.com/aws/aws-sdk-go to v1.44.194 2023-02-04 01:25:45 +00:00
renovate[bot]
e0d28bb36b Update golang.org/x/exp digest to 98cc5a0 2023-02-03 21:59:58 +00:00
renovate[bot]
16c4bb3d37 Update module github.com/aws/aws-sdk-go to v1.44.193 2023-02-03 09:59:53 +00:00
renovate[bot]
7a78066000 Update dependency @vue/test-utils to v2.2.10 2023-02-03 06:27:51 +00:00
renovate[bot]
bdb0a638f8 Update dependency axios to v1.3.1 2023-02-03 03:08:01 +00:00
renovate[bot]
b669b0e742 Update golang.org/x/exp digest to 54bba9f 2023-02-02 22:09:55 +00:00
renovate[bot]
ef046cbac1 Update module github.com/aws/aws-sdk-go to v1.44.192 2023-02-02 06:08:24 +00:00
renovate[bot]
0806f320b1 Update dependency @vue/test-utils to v2.2.9 2023-02-02 03:18:29 +00:00
renovate[bot]
0ccdde0522 Update dependency sass to v1.58.0 2023-02-01 09:29:25 +00:00
renovate[bot]
911d60d80f Update dependency axios to v1.3.0 2023-02-01 05:21:08 +00:00
renovate[bot]
f94bc2044f Update module github.com/aws/aws-sdk-go to v1.44.191 2023-02-01 01:50:07 +00:00
renovate[bot]
1e0a3393bf Update golang.org/x/exp digest to f062dba 2023-01-31 21:20:22 +00:00
renovate[bot]
570c413c3d Update typescript-eslint monorepo to v5.50.0 2023-01-31 16:58:20 +00:00
renovate[bot]
fa8494fe0d Update module github.com/aws/aws-sdk-go to v1.44.190 2023-01-31 12:30:49 +00:00
renovate[bot]
3fb22e10ce Update golang.org/x/exp digest to aae9b4e 2023-01-31 08:47:02 +00:00
renovate[bot]
af22af2334 Update dependency typescript to v4.9.5 2023-01-31 04:25:37 +00:00
renovate[bot]
2bf0d511bf Update golang.org/x/exp digest to a960b37 2023-01-29 20:44:37 +00:00
renovate[bot]
bd31f7b2a7 Update dependency axios to v1.2.6 2023-01-28 21:59:23 +00:00
renovate[bot]
123f334c71 Update dependency @vue/test-utils to v2.2.8 2023-01-28 06:22:03 +00:00
renovate[bot]
c3b7fd9f73 Update golang.org/x/exp digest to 31bee51 2023-01-28 02:13:30 +00:00
renovate[bot]
d6104db54f Update module github.com/aws/aws-sdk-go to v1.44.189 2023-01-27 22:50:07 +00:00
renovate[bot]
527cd0d828 Update module github.com/aws/aws-sdk-go to v1.44.188 2023-01-27 07:48:11 +00:00
renovate[bot]
56828c57bd Update dependency axios to v1.2.5 2023-01-27 05:04:35 +00:00
renovate[bot]
81feebcd4e Update golang.org/x/exp digest to a67bb56 2023-01-27 01:37:31 +00:00
renovate[bot]
d56adb814d Update golang.org/x/exp digest to b3c2aaf 2023-01-26 03:58:15 +00:00
renovate[bot]
14b79304e1 Update module github.com/aws/aws-sdk-go to v1.44.187 2023-01-26 00:48:40 +00:00
renovate[bot]
8e9250a1e9 Update dependency @types/jest to v29.4.0 2023-01-25 14:19:22 +00:00
renovate[bot]
43d2d71609 Update module github.com/aws/aws-sdk-go to v1.44.186 2023-01-25 06:49:21 +00:00
renovate[bot]
571af85383 Update golang.org/x/exp digest to d38c7dc 2023-01-25 03:23:28 +00:00
renovate[bot]
ddeff78bb4 Update dependency axios to v1.2.4 2023-01-24 23:26:52 +00:00
renovate[bot]
416d438c4b Update golang.org/x/exp digest to 7f5a42a 2023-01-24 19:35:38 +00:00
renovate[bot]
116aa53b4f Update typescript-eslint monorepo to v5.49.0 2023-01-24 03:57:20 +00:00
renovate[bot]
876cbfde02 Update module github.com/aws/aws-sdk-go to v1.44.185 2023-01-24 00:23:49 +00:00
renovate[bot]
c866758207 Update dependency @koumoul/vjsf to v2.21.3 2023-01-23 20:52:33 +00:00
renovate[bot]
ffd16770b7 Update dependency @koumoul/vjsf to v2.21.2 2023-01-23 12:25:20 +00:00
Jonas Plum
27f1b0df79 Add playbook editor (#702) 2023-01-21 23:25:55 +01:00
renovate[bot]
ee9d906e28 Update module github.com/aws/aws-sdk-go to v1.44.184 2023-01-21 00:27:55 +00:00
renovate[bot]
341097e69e Update module github.com/aws/aws-sdk-go to v1.44.183 2023-01-20 05:33:33 +00:00
renovate[bot]
bfd1cf19aa Update module github.com/aws/aws-sdk-go to v1.44.182 2023-01-19 10:52:11 +00:00
renovate[bot]
ede96d46f3 Update dependency core-js to v3.27.2 2023-01-19 06:38:27 +00:00
renovate[bot]
07045eb3f4 Update dependency @types/jest to v29.2.6 2023-01-19 02:43:25 +00:00
renovate[bot]
9aa0b9dbd2 Update module github.com/tus/tusd to v1.10.1 2023-01-18 22:58:20 +00:00
renovate[bot]
e735667619 Update golang.org/x/exp digest to a68e582 2023-01-18 18:12:58 +00:00
renovate[bot]
971ff2c2cf Update typescript-eslint monorepo to v5.48.2 2023-01-18 10:31:23 +00:00
renovate[bot]
4371883922 Update module github.com/aws/aws-sdk-go to v1.44.181 2023-01-18 06:22:11 +00:00
renovate[bot]
40d134a482 Update module golang.org/x/oauth2 to v0.4.0 2023-01-17 18:11:57 +00:00
renovate[bot]
82962f12ed Update dependency eslint-plugin-jest to v27.2.1 2023-01-17 10:24:55 +01:00
renovate[bot]
ab954f1b2c Update dependency core-js to v3.27.1 2023-01-17 10:24:47 +01:00
renovate[bot]
982102c98a Update dependency luxon to v3.2.1 2023-01-17 10:24:35 +01:00
renovate[bot]
a019615053 Update module github.com/coreos/go-oidc/v3 to v3.5.0 2023-01-17 10:24:13 +01:00
renovate[bot]
23580c5ba2 Update dependency vuetify to v2.6.14 2023-01-17 08:10:03 +00:00
renovate[bot]
2cd98dd1e4 Update dependency json-schema-editor-vue to v2.2.1 2023-01-17 04:11:12 +00:00
renovate[bot]
7817abce77 Update dependency axios to v1.2.2 2023-01-17 00:49:00 +00:00
renovate[bot]
43b0703843 Update dependency @vue/test-utils to v2.2.7 2023-01-16 20:48:24 +00:00
renovate[bot]
82c5ac8b7f Update dependency @types/jest to v29.2.5 2023-01-16 16:30:44 +00:00
renovate[bot]
c72764a507 Update dependency @koumoul/vjsf to v2.21.1 2023-01-16 16:21:55 +00:00
renovate[bot]
f6c8f033eb Update dependency ajv to v8.12.0 (#681)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-01-16 13:54:50 +01:00
renovate[bot]
dc8061e050 Update module github.com/aws/aws-sdk-go to v1.44.180 (#680)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-01-16 13:52:45 +01:00
renovate[bot]
b0c634f9a1 Update golang.org/x/exp digest to 1de6713 2023-01-16 12:47:51 +00:00
Jonas Plum
df1454e223 Add version flag (#674) 2022-12-27 16:22:00 +01:00
renovate[bot]
8984e509e1 Update dependency json-schema-editor-vue to v2.2.0 2022-12-21 06:46:15 +00:00
renovate[bot]
709d7d43fa Update dependency sass to v1.57.1 2022-12-21 04:05:21 +00:00
renovate[bot]
ca1f9f01f9 Update module github.com/aws/aws-sdk-go to v1.44.164 2022-12-21 01:33:55 +00:00
renovate[bot]
bd07e86379 Update typescript-eslint monorepo to v5.47.0 2022-12-19 22:19:33 +00:00
renovate[bot]
aefb07770c Update dependency just-kebab-case to v4.2.0 2022-12-18 01:17:12 +00:00
renovate[bot]
0c2d6d4da0 Update golang.org/x/exp digest to 3c43f8b 2022-12-17 20:05:13 +00:00
renovate[bot]
70a5244eec Update dependency sass to v1.57.0 2022-12-17 05:26:36 +00:00
renovate[bot]
e616bb25d5 Update module github.com/aws/aws-sdk-go to v1.44.162 2022-12-17 02:08:48 +00:00
renovate[bot]
b1f082cb91 Update module github.com/blevesearch/bleve/v2 to v2.3.6 2022-12-16 08:28:53 +00:00
renovate[bot]
0ed03bf2b9 Update dependency eslint-plugin-jest to v27.1.7 2022-12-16 05:19:58 +00:00
renovate[bot]
25c6f190e6 Update module github.com/aws/aws-sdk-go to v1.44.161 2022-12-16 02:20:38 +00:00
renovate[bot]
48b5853d88 Update golang.org/x/exp digest to 0915cd7 2022-12-15 23:30:24 +00:00
renovate[bot]
07df2affa2 Update module github.com/aws/aws-sdk-go to v1.44.160 2022-12-14 23:19:53 +00:00
renovate[bot]
3b433e5601 Update module github.com/arangodb/go-driver to v1.4.1 2022-12-14 14:12:09 +00:00
renovate[bot]
8fafcb42d0 Update typescript-eslint monorepo to v5.46.1 2022-12-14 04:41:34 +00:00
renovate[bot]
0e3eb7953e Update dependency vuetify to v2.6.13 2022-12-14 02:14:37 +00:00
renovate[bot]
1c3f337e7c Update module github.com/aws/aws-sdk-go to v1.44.159 2022-12-14 00:06:27 +00:00
renovate[bot]
d79407f645 Update golang.org/x/exp digest to fae10dd 2022-12-12 22:18:30 +00:00
renovate[bot]
65aba08ffb Update dependency @mdi/font to v7.1.96 2022-12-11 23:48:23 +00:00
renovate[bot]
37406a11ee Update golang.org/x/exp digest to ad323de 2022-12-11 16:27:31 +00:00
renovate[bot]
6f72fd74ca Update module github.com/aws/aws-sdk-go to v1.44.157 2022-12-09 23:33:33 +00:00
renovate[bot]
d34f2cd300 Update typescript-eslint monorepo to v5.46.0 2022-12-09 12:01:22 +00:00
renovate[bot]
356b55fccc Update dependency sass to v1.56.2 2022-12-09 08:53:44 +00:00
renovate[bot]
6e209cf328 Update golang.org/x/exp digest to 732eee0 2022-12-09 05:22:59 +00:00
renovate[bot]
c5bcf67875 Update module github.com/aws/aws-sdk-go to v1.44.156 2022-12-09 02:55:13 +00:00
renovate[bot]
68fc41b88f Update dependency typescript to v4.9.4 2022-12-08 13:43:01 +00:00
renovate[bot]
2b34fdb3a6 Update golang.org/x/exp digest to 44028be 2022-12-08 10:33:08 +00:00
renovate[bot]
22fa8ec90f Update github.com/warjiang/gojsonschema digest to b076d39 2022-12-08 08:05:26 +00:00
renovate[bot]
82d2b35f61 Update golang.org/x/exp digest to 99ab8fa 2022-12-08 04:47:12 +00:00
renovate[bot]
71a5a4f3d9 Update module github.com/go-chi/chi/v5 to v5.0.8 2022-12-07 20:17:23 +00:00
renovate[bot]
01b6bdba5d Update module github.com/aws/aws-sdk-go to v1.44.154 2022-12-06 22:50:01 +00:00
renovate[bot]
6be20911b0 Update module golang.org/x/oauth2 to v0.3.0 2022-12-06 20:04:16 +00:00
renovate[bot]
c28a49c486 Update typescript-eslint monorepo to v5.45.1 2022-12-06 09:25:35 +00:00
renovate[bot]
f4c0b024a3 Update module github.com/aws/aws-sdk-go to v1.44.153 2022-12-06 07:01:32 +00:00
renovate[bot]
f3c0f69c5f Update golang.org/x/exp digest to 47842c8 2022-12-06 04:05:41 +00:00
renovate[bot]
008f08e5fb Update dependency axios to v1.2.1 2022-12-06 00:44:43 +00:00
renovate[bot]
13f2d10d3d Update dependency @types/jest to v29.2.4 2022-12-05 13:20:41 +00:00
renovate[bot]
47aeae44ab Update dependency @vue/test-utils to v2.2.6 2022-12-05 09:26:11 +00:00
renovate[bot]
a7951cf67f Update golang.org/x/exp digest to 6dcec33 2022-12-04 18:18:11 +00:00
renovate[bot]
23efb200c7 Update module github.com/aws/aws-sdk-go to v1.44.152 2022-12-03 00:21:31 +00:00
renovate[bot]
2b0c6f7286 Update dependency @types/lodash to v4.14.191 2022-12-02 20:59:03 +00:00
renovate[bot]
189b5ed532 Update dependency @vue/test-utils to v2.2.5 2022-12-02 17:13:40 +00:00
renovate[bot]
a89f11efbc Update module github.com/aws/aws-sdk-go to v1.44.149 2022-11-30 01:41:50 +00:00
renovate[bot]
2045b1057e Update module github.com/aws/aws-sdk-go to v1.44.147 2022-11-29 12:48:44 +00:00
renovate[bot]
c84470eb7e Update dependency luxon to v3.1.1 2022-11-29 09:55:52 +00:00
renovate[bot]
06a5c6a688 Update typescript-eslint monorepo to v5.45.0 2022-11-28 21:46:59 +00:00
renovate[bot]
5599c3b035 Update module github.com/aws/aws-sdk-go to v1.44.146 2022-11-28 06:49:28 +00:00
renovate[bot]
da423e3a51 Update golang.org/x/exp digest to 6ab00d0 2022-11-26 19:22:08 +00:00
renovate[bot]
501134de7c Update dependency eslint-plugin-jest to v27.1.6 2022-11-24 23:29:56 +00:00
renovate[bot]
a8a1bfdf8a Update module github.com/aws/aws-sdk-go to v1.44.145 2022-11-24 02:05:04 +00:00
renovate[bot]
a2f0d127d9 Update dependency @types/lodash to v4.14.190 2022-11-23 23:39:49 +00:00
renovate[bot]
2cc371fbde Update dependency axios to v1.2.0 (#616)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-11-23 01:39:50 +01:00
renovate[bot]
b574fcc5d8 Update dependency cypress to v11.2.0 (#617)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-11-23 01:39:42 +01:00
Jonas Plum
a6f8259400 Fix playbook editor task schema (#618) 2022-11-23 01:39:32 +01:00
renovate[bot]
f99f7d98c7 Update module github.com/aws/aws-sdk-go to v1.44.144 2022-11-22 22:27:09 +00:00
renovate[bot]
ae09e09b98 Update module github.com/tidwall/gjson to v1.14.4 2022-11-22 06:24:02 +00:00
renovate[bot]
fcc34e6f84 Update module github.com/aws/aws-sdk-go to v1.44.143 2022-11-22 00:25:37 +00:00
renovate[bot]
ad437c5a5a Update typescript-eslint monorepo to v5.44.0 2022-11-21 21:34:54 +00:00
renovate[bot]
220848edd8 Update dependency @vue/test-utils to v2.2.4 2022-11-21 02:23:14 +00:00
renovate[bot]
e6fd4d1f53 Update module github.com/aws/aws-sdk-go to v1.44.142 2022-11-19 02:47:24 +00:00
renovate[bot]
1562977173 Update module github.com/aws/aws-sdk-go to v1.44.140 2022-11-17 23:03:24 +00:00
renovate[bot]
2bd73e6281 Update module github.com/aws/aws-sdk-go to v1.44.139 2022-11-16 23:48:40 +00:00
renovate[bot]
70c5045bbe Update dependency cypress to v11 2022-11-16 09:59:08 +01:00
renovate[bot]
73abe2ef18 Update dependency typescript to v4.9.3 2022-11-16 02:31:58 +00:00
renovate[bot]
eb7b6b6387 Update module github.com/aws/aws-sdk-go to v1.44.138 2022-11-15 23:36:52 +00:00
renovate[bot]
e556cfe0fc Update dependency @vue/test-utils to v2.2.3 2022-11-15 13:26:43 +00:00
renovate[bot]
26a6194583 Update typescript-eslint monorepo to v5.43.0 2022-11-15 10:59:56 +00:00
renovate[bot]
3d32e21170 Update module github.com/aws/aws-sdk-go to v1.44.137 2022-11-15 07:52:39 +00:00
renovate[bot]
8aac1eb6d6 Update dependency @types/lodash to v4.14.189 2022-11-15 05:50:21 +00:00
renovate[bot]
0d67f85313 Update dependency @types/jest to v29.2.3 2022-11-15 02:51:45 +00:00
renovate[bot]
df6b3b9a75 Update golang.org/x/exp digest to 8509921 2022-11-14 23:53:38 +00:00
renovate[bot]
95bb9c1746 Update dependency ajv to v8.11.2 2022-11-14 01:06:48 +00:00
renovate[bot]
bfb8301c65 Update dependency core-js to v3.26.1 2022-11-13 22:44:51 +00:00
renovate[bot]
975138dce7 Update dependency @vue/test-utils to v2.2.2 2022-11-13 12:48:32 +00:00
renovate[bot]
4c3225173e Update module github.com/alecthomas/kong to v0.7.1 2022-11-13 01:37:11 +00:00
renovate[bot]
094051f2f0 Update golang.org/x/exp digest to 129d8d6 2022-11-12 04:06:59 +00:00
renovate[bot]
1a7881ffa2 Update module github.com/aws/aws-sdk-go to v1.44.136 2022-11-12 01:28:22 +00:00
renovate[bot]
7f9e5dcd4e Update golang.org/x/exp digest to ab4555d 2022-11-11 13:09:55 +00:00
renovate[bot]
9bbf237731 Update dependency eslint-plugin-jest to v27.1.5 2022-11-11 02:13:24 +00:00
renovate[bot]
4494f1afdd Update module github.com/aws/aws-sdk-go to v1.44.135 2022-11-11 00:04:21 +00:00
renovate[bot]
2957eee40a Update golang.org/x/exp digest to d0897a7 2022-11-10 21:17:45 +00:00
renovate[bot]
2570aed5d9 Update module golang.org/x/oauth2 to v0.2.0 2022-11-10 15:47:30 +00:00
renovate[bot]
309522eb72 Update golang.org/x/exp digest to fc8884a 2022-11-10 03:19:13 +00:00
renovate[bot]
57830be851 Update module github.com/aws/aws-sdk-go to v1.44.134 2022-11-10 00:17:16 +00:00
renovate[bot]
45f443540d Update golang.org/x/exp digest to 9ce248d 2022-11-09 18:22:22 +00:00
renovate[bot]
f5875ff23e Update dependency sass to v1.56.1 2022-11-09 06:45:47 +00:00
renovate[bot]
182181ae7b Update golang.org/x/exp digest to 5d53382 2022-11-09 04:03:28 +00:00
renovate[bot]
75b87074fb Update module github.com/aws/aws-sdk-go to v1.44.133 2022-11-09 00:38:27 +00:00
renovate[bot]
e01ccc8f90 Update typescript-eslint monorepo to v5.42.1 2022-11-08 09:43:51 +00:00
renovate[bot]
bba495c0a6 Update dependency json-schema-editor-vue to v2.1.2 2022-11-08 06:35:39 +00:00
renovate[bot]
717c4cb48e Update module github.com/aws/aws-sdk-go to v1.44.132 2022-11-08 01:06:15 +00:00
renovate[bot]
838a24ee71 Update golang.org/x/exp digest to f965990 2022-11-06 14:20:57 +01:00
renovate[bot]
0eeafffd5e Update github.com/jonas-plum/maut digest to ed984fd 2022-11-05 19:39:52 +00:00
42 changed files with 3560 additions and 1297 deletions

36
.github/renovate.json vendored
View File

@@ -1,36 +0,0 @@
{
"extends": [
"config:base"
],
"packageRules": [
{
"datasources": [
"go"
],
"extends": [
":automergeDigest",
":automergeMinor",
":automergePr"
],
"postUpdateOptions": [
"gomodTidy"
]
},
{
"datasources": [
"npm"
],
"extends": [
":automergeDigest",
":automergeMinor",
":automergePr"
]
}
],
"assignees": [
"cugu"
],
"ignoreDeps": [
"sass-loader"
]
}

18
.github/stale.yml vendored
View File

@@ -1,18 +0,0 @@
# Number of days of inactivity before an issue becomes stale
daysUntilStale: 60
# Number of days of inactivity before a stale issue is closed
daysUntilClose: 7
# Issues with these labels will never be considered stale
exemptLabels:
- feature
- bug
- enhancement
# Label to use when marking an issue as stale
staleLabel: stale
# Comment to post when marking an issue as stale. Set to `false` to disable
markComment: >
This issue has been automatically marked as stale because it has not had
recent activity. It will be closed if no further activity occurs. Thank you
for your contributions.
# Comment to post when closing a stale issue. Set to `false` to disable
closeComment: false

View File

@@ -13,34 +13,29 @@ jobs:
name: Lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-go@v3
with: { go-version: '1.19' }
- uses: actions/checkout@v4
- uses: actions/setup-go@v4
with: { go-version: '1.21' }
- run: |
mkdir -p ui/dist/img
touch ui/dist/index.html ui/dist/favicon.ico ui/dist/manifest.json ui/dist/img/fake.png
- uses: golangci/golangci-lint-action@v3
with: { version: 'v1.54' }
test:
name: Test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: '14', cache: 'yarn', cache-dependency-path: 'ui/yarn.lock' }
- uses: actions/setup-go@v3
with: { go-version: '1.19', cache: true }
- uses: actions/setup-go@v4
with: { go-version: '1.21' }
- run: |
mkdir -p ui/dist/img
touch ui/dist/index.html ui/dist/favicon.ico ui/dist/manifest.json ui/dist/img/fake.png
- run: docker compose up --quiet-pull --detach
working-directory: dev
- name: Install ArangoDB
run: |
curl -OL https://download.arangodb.com/arangodb38/DEBIAN/Release.key
sudo apt-key add Release.key
sudo apt-add-repository 'deb https://download.arangodb.com/arangodb38/DEBIAN/ /'
sudo apt-get update -y && sudo apt-get -y install arangodb3
- run: go test -coverprofile=cover.out -coverpkg=./... ./...
- run: go tool cover -func=cover.out
- uses: codecov/codecov-action@v3
@@ -52,10 +47,10 @@ jobs:
auth: [ authelia ]
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
- uses: actions/setup-go@v3
with: { go-version: '1.18' }
- uses: actions/setup-node@v3
- uses: actions/checkout@v4
- uses: actions/setup-go@v4
with: { go-version: '1.21' }
- uses: actions/setup-node@v4
with: { node-version: '14' }
# run UI
- run: |
@@ -92,8 +87,8 @@ jobs:
name: Build npm
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: '14', cache: 'yarn', cache-dependency-path: 'ui/yarn.lock' }
- run: yarn install && yarn build
working-directory: ui
@@ -106,9 +101,9 @@ jobs:
runs-on: ubuntu-latest
needs: [ build-npm, test ]
steps:
- uses: actions/checkout@v3
- uses: actions/setup-go@v3
with: { go-version: '1.19', cache: true }
- uses: actions/checkout@v4
- uses: actions/setup-go@v4
with: { go-version: '1.21' }
- uses: actions/download-artifact@v3
with: { name: ui, path: ui/dist }
- name: Version
@@ -117,17 +112,17 @@ jobs:
echo ${{ github.ref_name }}
echo ${{ github.ref_name }} > VERSION
- run: go build -o catalyst ./cmd/catalyst/.
- uses: docker/login-action@v2
- uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@v4
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
- uses: docker/build-push-action@v3
- uses: docker/build-push-action@v5
with:
context: .
push: true

1
.gitignore vendored
View File

@@ -81,6 +81,7 @@ dist
node_modules
profile.cov
cover.out
generated/caql/parser/*.interp
generated/caql/parser/*.tokens

View File

@@ -9,7 +9,6 @@ linters:
- asciicheck
- containedctx
- decorder
- depguard
- dogsled
- durationcheck
- errchkjson
@@ -71,6 +70,7 @@ linters:
- nestif
# disable
- depguard
- dupl
- exhaustivestruct
- funlen
@@ -118,4 +118,6 @@ issues:
- path: caql
linters: [ forcetypeassert ]
- text: github.com/go-chi/chi/v5.Router
linters: [ ireturn ]
linters: [ ireturn ]
- path: ui/ui.go
linters: [ typecheck ]

1
CODEOWNERS Normal file
View File

@@ -0,0 +1 @@
* @cugu

View File

@@ -1,4 +1,4 @@
FROM ubuntu:18.04
FROM ubuntu:23.04
RUN apt-get update -y && apt-get -y install curl gnupg2 software-properties-common
RUN curl -OL https://download.arangodb.com/arangodb34/DEBIAN/Release.key

9
Makefile Normal file
View File

@@ -0,0 +1,9 @@
.PHONY: lint
lint:
golangci-lint run ./...
.PHONY: fmt
fmt:
gci write -s standard -s default -s "prefix(github.com/SecurityBrewery/catalyst)" .
# gofumpt -l -w .
# wsl --fix ./...

View File

@@ -9,11 +9,6 @@
-
<a href="https://try.catalyst-soar.com">Try online</a>
</h4>
<h4 align="center">
<a href="https://twitter.com/securitybrewery">Twitter</a>
-
<a href="https://discord.gg/nrmpveWvZX">Discord</a>
</h4>
Catalyst is an incident response platform or SOAR (Security Orchestration, Automation and Response) system. It can help

View File

@@ -82,7 +82,7 @@ func (c *catalystResolver) UserByIDAndPassword(ctx context.Context, username str
return mapMautUser(user), nil
}
func (c *catalystResolver) Role(ctx context.Context, roleID string) (r *maut.Role, err error) {
func (c *catalystResolver) Role(_ context.Context, roleID string) (r *maut.Role, err error) {
switch roleID {
case "admin":
return Admin, nil

155
backup.go
View File

@@ -1,155 +0,0 @@
package catalyst
import (
"archive/zip"
"bytes"
"io"
"io/fs"
"net/http"
"os"
"os/exec"
"path"
"strings"
"github.com/aws/aws-sdk-go/service/s3"
"github.com/SecurityBrewery/catalyst/database"
"github.com/SecurityBrewery/catalyst/generated/api"
"github.com/SecurityBrewery/catalyst/storage"
)
func backupHandler(catalystStorage *storage.Storage, c *database.Config) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Disposition", "attachment; filename=backup.zip")
w.Header().Set("Content-Type", "application/zip")
err := Backup(catalystStorage, c, w)
if err != nil {
api.JSONError(w, err)
}
}
}
type WriterAtBuffer struct {
bytes.Buffer
}
func (fw WriterAtBuffer) WriteAt(p []byte, offset int64) (n int, err error) {
return fw.Write(p)
}
func Backup(catalystStorage *storage.Storage, c *database.Config, writer io.Writer) error {
archive := zip.NewWriter(writer)
defer archive.Close()
err := archive.SetComment(GetVersion())
if err != nil {
return err
}
// S3
if err := backupS3(catalystStorage, archive); err != nil {
return err
}
// Arango
return backupArango(c, archive)
}
func backupS3(catalystStorage *storage.Storage, archive *zip.Writer) error {
buckets, err := catalystStorage.S3().ListBuckets(nil)
if err != nil {
return err
}
for _, bucket := range buckets.Buckets {
objects, err := catalystStorage.S3().ListObjectsV2(&s3.ListObjectsV2Input{
Bucket: bucket.Name,
})
if err != nil {
return err
}
for _, content := range objects.Contents {
rbuf := &WriterAtBuffer{}
_, err := catalystStorage.Downloader().Download(rbuf, &s3.GetObjectInput{
Bucket: bucket.Name,
Key: content.Key,
})
if err != nil {
return err
}
a, err := archive.Create(path.Join("minio", *bucket.Name, *content.Key))
if err != nil {
return err
}
if _, err := io.Copy(a, rbuf); err != nil {
return err
}
}
}
return nil
}
func backupArango(c *database.Config, archive *zip.Writer) error {
dir, err := os.MkdirTemp("", "catalyst-backup")
if err != nil {
return err
}
defer os.RemoveAll(dir)
if err := arangodump(dir, c); err != nil {
return err
}
return zipDump(dir, archive)
}
func zipDump(dir string, archive *zip.Writer) error {
fsys := os.DirFS(dir)
return fs.WalkDir(fsys, ".", func(p string, d fs.DirEntry, err error) error {
if err != nil {
return err
}
if d.IsDir() {
return nil
}
a, err := archive.Create(path.Join("arango", p))
if err != nil {
return err
}
f, err := fsys.Open(p)
if err != nil {
return err
}
if _, err := io.Copy(a, f); err != nil {
return err
}
return nil
})
}
func arangodump(dir string, config *database.Config) error {
host := strings.Replace(config.Host, "http", "tcp", 1)
name := config.Name
if config.Name == "" {
name = database.Name
}
args := []string{
"--output-directory", dir, "--server.endpoint", host,
"--server.username", config.User, "--server.password", config.Password,
"--server.database", name,
}
cmd := exec.Command("arangodump", args...)
return cmd.Run()
}

View File

@@ -79,11 +79,7 @@ func copyFile(ctx context.Context, cli *client.Client, path string, contentStrin
return err
}
if err := cli.CopyToContainer(ctx, id, "/", tarBuf, types.CopyToContainerOptions{}); err != nil {
return err
}
return nil
return cli.CopyToContainer(ctx, id, "/", tarBuf, types.CopyToContainerOptions{})
}
func runDocker(ctx context.Context, jobID, containerID string, db *database.Database) (stdout []byte, stderr []byte, err error) {

View File

@@ -238,7 +238,7 @@ func (s *aqlBuilder) ExitReference(ctx *parser.ReferenceContext) {
}
// ExitCompound_value is called when production compound_value is exited.
func (s *aqlBuilder) ExitCompound_value(ctx *parser.Compound_valueContext) {
func (s *aqlBuilder) ExitCompound_value(_ *parser.Compound_valueContext) {
// pass
}

View File

@@ -181,7 +181,7 @@ func (s *aqlInterpreter) ExitReference(ctx *parser.ReferenceContext) {
}
// ExitCompound_value is called when production compound_value is exited.
func (s *aqlInterpreter) ExitCompound_value(ctx *parser.Compound_valueContext) {
func (s *aqlInterpreter) ExitCompound_value(_ *parser.Compound_valueContext) {
// pass
}

View File

@@ -104,18 +104,18 @@ type errorListener struct {
errs []error
}
func (el *errorListener) SyntaxError(recognizer antlr.Recognizer, offendingSymbol any, line, column int, msg string, e antlr.RecognitionException) {
func (el *errorListener) SyntaxError(_ antlr.Recognizer, _ any, line, column int, msg string, _ antlr.RecognitionException) {
el.errs = append(el.errs, fmt.Errorf("line "+strconv.Itoa(line)+":"+strconv.Itoa(column)+" "+msg))
}
func (el *errorListener) ReportAmbiguity(recognizer antlr.Parser, dfa *antlr.DFA, startIndex, stopIndex int, exact bool, ambigAlts *antlr.BitSet, configs antlr.ATNConfigSet) {
func (el *errorListener) ReportAmbiguity(_ antlr.Parser, _ *antlr.DFA, _, _ int, _ bool, _ *antlr.BitSet, _ antlr.ATNConfigSet) {
el.errs = append(el.errs, errors.New("ReportAmbiguity"))
}
func (el *errorListener) ReportAttemptingFullContext(recognizer antlr.Parser, dfa *antlr.DFA, startIndex, stopIndex int, conflictingAlts *antlr.BitSet, configs antlr.ATNConfigSet) {
func (el *errorListener) ReportAttemptingFullContext(_ antlr.Parser, _ *antlr.DFA, _, _ int, _ *antlr.BitSet, _ antlr.ATNConfigSet) {
el.errs = append(el.errs, errors.New("ReportAttemptingFullContext"))
}
func (el *errorListener) ReportContextSensitivity(recognizer antlr.Parser, dfa *antlr.DFA, startIndex, stopIndex, prediction int, configs antlr.ATNConfigSet) {
func (el *errorListener) ReportContextSensitivity(_ antlr.Parser, _ *antlr.DFA, _, _, _ int, _ antlr.ATNConfigSet) {
el.errs = append(el.errs, errors.New("ReportContextSensitivity"))
}

View File

@@ -49,6 +49,9 @@ type CLI struct {
S3Host string `env:"S3_HOST" default:"http://minio:9000" name:"s3-host"`
S3User string `env:"S3_USER" default:"minio" name:"s3-user"`
S3Password string `env:"S3_PASSWORD" required:"" name:"s3-password"`
S3Region string `env:"S3_REGION" default:"us-east-1" name:"s3-region"`
Version kong.VersionFlag `help:"Show version."`
}
func ParseCatalystConfig() (*catalyst.Config, error) {
@@ -57,6 +60,7 @@ func ParseCatalystConfig() (*catalyst.Config, error) {
&cli,
kong.Configuration(kong.JSON, "/etc/catalyst.json", ".catalyst.json"),
kong.Configuration(kongyaml.Loader, "/etc/catalyst.yaml", ".catalyst.yaml"),
kong.Vars{"version": catalyst.GetVersion()},
)
if cli.OIDCEnable {
@@ -81,7 +85,7 @@ func MapConfig(cli CLI) (*catalyst.Config, error) {
User: cli.ArangoDBUser,
Password: cli.ArangoDBPassword,
},
Storage: &storage.Config{Host: cli.S3Host, User: cli.S3User, Password: cli.S3Password},
Storage: &storage.Config{Host: cli.S3Host, User: cli.S3User, Region: cli.S3Region, Password: cli.S3Password},
ExternalAddress: cli.ExternalAddress,
InternalAddress: cli.CatalystAddress,
Port: cli.Port,

View File

@@ -82,7 +82,7 @@ func NewCollection[T any](internal driver.Collection, db *BusDatabase) *Collecti
return &Collection[T]{internal: internal, db: db}
}
func (c *Collection[T]) CreateDocument(ctx, newctx context.Context, key string, document *T) (meta driver.DocumentMeta, err error) {
func (c *Collection[T]) CreateDocument(_, newctx context.Context, key string, document *T) (meta driver.DocumentMeta, err error) {
defer func() { err = toHTTPErr(err) }()
meta, err = c.internal.CreateDocument(newctx, &Keyed[T]{Key: key, Doc: document})
@@ -95,7 +95,7 @@ func (c *Collection[T]) CreateDocument(ctx, newctx context.Context, key string,
return meta, nil
}
func (c *Collection[T]) CreateEdge(ctx, newctx context.Context, edge *driver.EdgeDocument) (meta driver.DocumentMeta, err error) {
func (c *Collection[T]) CreateEdge(_, newctx context.Context, edge *driver.EdgeDocument) (meta driver.DocumentMeta, err error) {
defer func() { err = toHTTPErr(err) }()
meta, err = c.internal.CreateDocument(newctx, edge)

View File

@@ -93,7 +93,7 @@ func (db *Database) UserCreate(ctx context.Context, newUser *model.UserForm) (*m
var doc model.User
newctx := driver.WithReturnNew(ctx, &doc)
meta, err := db.userCollection.CreateDocument(ctx, newctx, strcase.ToKebab(newUser.ID), toUser(newUser, sha256Hash))
meta, err := db.userCollection.CreateDocument(ctx, newctx, newUser.ID, toUser(newUser, sha256Hash))
if err != nil {
return nil, err
}

View File

@@ -1,13 +1,13 @@
users:
alice:
alice@example.com:
displayname: Alice
password: "$argon2id$v=19$m=65536,t=3,p=4$S3hTSS90U1QycjNEWURZTw$aJP1fI/byC/3A7NCz5lyrXR7NS+l+1YMnqj5qFopZRk"
email: alice@example.com
bob:
bob@example.com:
displayname: "Bob"
password: "$argon2id$v=19$m=65536,t=3,p=4$amxRcURFVUk4TlhPOXFmWg$sPRsvGg9rrqefRp0fFA7wQG3O8OcMnQhj4IckHYPEz8"
email: bob@example.com
admin:
admin@example.com:
displayname: "Admin"
password: "$argon2id$v=19$m=65536,t=3,p=4$SFBXa1BXblNZKytoZ1ZLYQ$JruWROu9opYmcPNw1cIiHms4k4466DqrKIPvJe94nfA"
email: admin@example.com

View File

@@ -1,7 +1,7 @@
version: '2.4'
services:
nginx:
image: nginx:1.23
image: nginx:1.25
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
ports: [ "80:80", "8529:8529", "9000:9000", "8082:8082", "9003:9003" ]

1
dev/start_dev.sh Normal file → Executable file
View File

@@ -11,6 +11,7 @@ export OIDC_CLIENT_SECRET=secret
export ARANGO_DB_HOST=http://localhost:8529
export ARANGO_DB_PASSWORD=foobar
export S3_HOST=http://localhost:9000
export S3_REGION=eu-central-1
export S3_PASSWORD=minio123
export AUTH_BLOCK_NEW=false

89
go.mod
View File

@@ -2,67 +2,68 @@ module github.com/SecurityBrewery/catalyst
go 1.19
replace github.com/xeipuuv/gojsonschema => github.com/warjiang/gojsonschema v1.2.1-0.20210329105853-aa9f9a8cfec7
replace github.com/xeipuuv/gojsonschema => github.com/warjiang/gojsonschema v1.2.1-0.20201027075954-b076d39a02e5
require (
github.com/alecthomas/kong v0.7.0
github.com/alecthomas/kong-yaml v0.1.1
github.com/alecthomas/kong v0.8.1
github.com/alecthomas/kong-yaml v0.2.0
github.com/antlr/antlr4/runtime/Go/antlr v0.0.0-20220816024939-bc8df83d7b9d
github.com/arangodb/go-driver v1.4.0
github.com/aws/aws-sdk-go v1.44.131
github.com/blevesearch/bleve/v2 v2.3.5
github.com/coreos/go-oidc/v3 v3.4.0
github.com/arangodb/go-driver v1.6.0
github.com/aws/aws-sdk-go v1.46.2
github.com/blevesearch/bleve/v2 v2.3.10
github.com/coreos/go-oidc/v3 v3.7.0
github.com/docker/docker v17.12.0-ce-rc1.0.20201201034508-7d75c1d40d88+incompatible
github.com/go-chi/chi/v5 v5.0.7
github.com/gobwas/ws v1.1.0
github.com/google/uuid v1.3.0
github.com/iancoleman/strcase v0.2.0
github.com/icza/dyno v0.0.0-20220812133438-f0b6f8a18845
github.com/imdario/mergo v0.3.13
github.com/jonas-plum/maut v0.0.0-20221001191853-1856efe6da0b
github.com/go-chi/chi/v5 v5.0.10
github.com/gobwas/ws v1.3.0
github.com/google/uuid v1.3.1
github.com/iancoleman/strcase v0.3.0
github.com/icza/dyno v0.0.0-20230330125955-09f820a8d9c0
github.com/imdario/mergo v0.3.16
github.com/jonas-plum/maut v0.0.0-20221105155335-ed984fd96915
github.com/mingrammer/commonregex v1.0.1
github.com/stretchr/testify v1.8.1
github.com/tidwall/gjson v1.14.3
github.com/stretchr/testify v1.8.4
github.com/tidwall/gjson v1.17.0
github.com/tidwall/sjson v1.2.5
github.com/tus/tusd v1.10.0
github.com/tus/tusd v1.13.0
github.com/xeipuuv/gojsonschema v1.2.0
golang.org/x/exp v0.0.0-20221031165847-c99f073a8326
golang.org/x/oauth2 v0.1.0
golang.org/x/exp v0.0.0-20231006140011-7918f672742d
golang.org/x/oauth2 v0.13.0
gopkg.in/yaml.v3 v3.0.1
)
require (
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
github.com/Microsoft/go-winio v0.5.1 // indirect
github.com/RoaringBitmap/roaring v0.9.4 // indirect
github.com/RoaringBitmap/roaring v1.6.0 // indirect
github.com/arangodb/go-velocypack v0.0.0-20200318135517-5af53c29c67e // indirect
github.com/bits-and-blooms/bitset v1.2.1 // indirect
github.com/blevesearch/bleve_index_api v1.0.4 // indirect
github.com/blevesearch/geo v0.1.15 // indirect
github.com/bits-and-blooms/bitset v1.10.0 // indirect
github.com/blevesearch/bleve_index_api v1.0.6 // indirect
github.com/blevesearch/geo v0.1.18 // indirect
github.com/blevesearch/go-porterstemmer v1.0.3 // indirect
github.com/blevesearch/gtreap v0.1.1 // indirect
github.com/blevesearch/mmap-go v1.0.4 // indirect
github.com/blevesearch/scorch_segment_api/v2 v2.1.3 // indirect
github.com/blevesearch/segment v0.9.0 // indirect
github.com/blevesearch/scorch_segment_api/v2 v2.1.6 // indirect
github.com/blevesearch/segment v0.9.1 // indirect
github.com/blevesearch/snowballstem v0.9.0 // indirect
github.com/blevesearch/upsidedown_store_api v1.0.1 // indirect
github.com/blevesearch/vellum v1.0.9 // indirect
github.com/blevesearch/zapx/v11 v11.3.6 // indirect
github.com/blevesearch/zapx/v12 v12.3.6 // indirect
github.com/blevesearch/zapx/v13 v13.3.6 // indirect
github.com/blevesearch/zapx/v14 v14.3.6 // indirect
github.com/blevesearch/zapx/v15 v15.3.6 // indirect
github.com/blevesearch/upsidedown_store_api v1.0.2 // indirect
github.com/blevesearch/vellum v1.0.10 // indirect
github.com/blevesearch/zapx/v11 v11.3.10 // indirect
github.com/blevesearch/zapx/v12 v12.3.10 // indirect
github.com/blevesearch/zapx/v13 v13.3.10 // indirect
github.com/blevesearch/zapx/v14 v14.3.10 // indirect
github.com/blevesearch/zapx/v15 v15.3.13 // indirect
github.com/bmizerany/pat v0.0.0-20210406213842-e4b6760bdd6f // indirect
github.com/containerd/containerd v1.6.8 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/docker/distribution v2.7.1+incompatible // indirect
github.com/docker/go-connections v0.4.0 // indirect
github.com/docker/go-units v0.4.0 // indirect
github.com/go-jose/go-jose/v3 v3.0.0 // indirect
github.com/gobwas/httphead v0.1.0 // indirect
github.com/gobwas/pool v0.2.1 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/geo v0.0.0-20210211234256-740aa86cb551 // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/golang/geo v0.0.0-20230421003525-6adc56603217 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/golang/snappy v0.0.4 // indirect
github.com/gorilla/securecookie v1.1.1 // indirect
github.com/gorilla/sessions v1.2.1 // indirect
@@ -78,18 +79,16 @@ require (
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/sirupsen/logrus v1.9.0 // indirect
github.com/tidwall/match v1.1.1 // indirect
github.com/tidwall/pretty v1.2.0 // indirect
github.com/tidwall/pretty v1.2.1 // indirect
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
go.etcd.io/bbolt v1.3.6 // indirect
golang.org/x/crypto v0.0.0-20220926161630-eccd6366d1be // indirect
golang.org/x/net v0.1.0 // indirect
golang.org/x/sys v0.1.0 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/genproto v0.0.0-20220920201722-2b89144ce006 // indirect
google.golang.org/grpc v1.50.0 // indirect
google.golang.org/protobuf v1.28.1 // indirect
gopkg.in/square/go-jose.v2 v2.6.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
go.etcd.io/bbolt v1.3.7 // indirect
golang.org/x/crypto v0.14.0 // indirect
golang.org/x/net v0.17.0 // indirect
golang.org/x/sys v0.13.0 // indirect
google.golang.org/appengine v1.6.8 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20230807174057-1744710a1577 // indirect
google.golang.org/grpc v1.57.1 // indirect
google.golang.org/protobuf v1.31.0 // indirect
gotest.tools v2.2.0+incompatible // indirect
)

1252
go.sum

File diff suppressed because it is too large Load Diff

View File

@@ -1,176 +0,0 @@
package catalyst
import (
"archive/zip"
"bytes"
"context"
"errors"
"fmt"
"io"
"io/fs"
"net/http"
"os"
"os/exec"
"path"
"strings"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/service/s3"
"github.com/aws/aws-sdk-go/service/s3/s3manager"
"github.com/SecurityBrewery/catalyst/database"
"github.com/SecurityBrewery/catalyst/generated/api"
"github.com/SecurityBrewery/catalyst/generated/pointer"
"github.com/SecurityBrewery/catalyst/storage"
)
func restoreHandler(catalystStorage *storage.Storage, db *database.Database, c *database.Config) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
uf, header, err := r.FormFile("backup")
if err != nil {
api.JSONError(w, err)
return
}
if err = Restore(r.Context(), catalystStorage, db, c, uf, header.Size); err != nil {
api.JSONError(w, err)
return
}
}
}
func Restore(ctx context.Context, catalystStorage *storage.Storage, db *database.Database, c *database.Config, r io.Reader, size int64) error {
b, err := io.ReadAll(r)
if err != nil {
return err
}
ra := bytes.NewReader(b)
fsys, err := zip.NewReader(ra, size)
if err != nil {
return err
}
if fsys.Comment != GetVersion() {
return fmt.Errorf("wrong version, got: %s, want: %s", fsys.Comment, GetVersion())
}
dir, err := os.MkdirTemp("", "catalyst-restore")
if err != nil {
return err
}
defer os.RemoveAll(dir)
if err = unzip(fsys, dir); err != nil {
return err
}
if err := restoreS3(catalystStorage, path.Join(dir, "minio")); err != nil {
return err
}
if err := arangorestore(path.Join(dir, "arango"), c); err != nil {
return err
}
return db.IndexRebuild(ctx)
}
func restoreS3(catalystStorage *storage.Storage, p string) error {
minioDir := os.DirFS(p)
entries, err := fs.ReadDir(minioDir, ".")
if err != nil {
// directory might not exist
return nil
}
for _, entry := range entries {
if err := restoreBucket(catalystStorage, entry, minioDir); err != nil {
return err
}
}
return nil
}
func restoreBucket(catalystStorage *storage.Storage, entry fs.DirEntry, minioDir fs.FS) error {
_, err := catalystStorage.S3().CreateBucket(&s3.CreateBucketInput{Bucket: pointer.String(entry.Name())})
if err != nil {
var awsError awserr.Error
if errors.As(err, &awsError) && (awsError.Code() == s3.ErrCodeBucketAlreadyExists || awsError.Code() == s3.ErrCodeBucketAlreadyOwnedByYou) {
return nil
}
return err
}
uploader := catalystStorage.Uploader()
f, err := minioDir.Open(entry.Name())
if err != nil {
return err
}
defer f.Close()
err = fs.WalkDir(minioDir, ".", func(path string, d fs.DirEntry, err error) error {
if err != nil {
return nil
}
_, err = uploader.Upload(&s3manager.UploadInput{Body: f, Bucket: pointer.String(entry.Name()), Key: pointer.String(path)})
return err
})
if err != nil {
return err
}
return nil
}
func unzip(archive *zip.Reader, dir string) error {
return fs.WalkDir(archive, ".", func(p string, d fs.DirEntry, err error) error {
if err != nil {
return err
}
if d.IsDir() {
_ = os.MkdirAll(path.Join(dir, p), os.ModePerm)
return nil
}
f, err := archive.Open(p)
if err != nil {
return err
}
defer f.Close()
b, err := io.ReadAll(f)
if err != nil {
return err
}
return os.WriteFile(path.Join(dir, p), b, os.ModePerm)
})
}
func arangorestore(dir string, config *database.Config) error {
host := strings.Replace(config.Host, "http", "tcp", 1)
name := config.Name
if config.Name == "" {
name = database.Name
}
args := []string{
"--batch-size", "524288",
"--input-directory", dir, "--server.endpoint", host,
"--server.username", config.User, "--server.password", config.Password,
"--server.database", name,
}
cmd := exec.Command("arangorestore", args...)
return cmd.Run()
}

View File

@@ -74,7 +74,7 @@ func New(hooks *hooks.Hooks, config *Config) (*Server, error) {
return nil, fmt.Errorf("failed to create authenticator: %w", err)
}
apiServer, err := setupAPI(authenticator, catalystService, catalystStorage, catalystDatabase, config.DB, catalystBus, config)
apiServer, err := setupAPI(authenticator, catalystService, catalystStorage, catalystDatabase, catalystBus, config)
if err != nil {
return nil, fmt.Errorf("failed to create api server: %w", err)
}
@@ -88,7 +88,7 @@ func New(hooks *hooks.Hooks, config *Config) (*Server, error) {
}, nil
}
func setupAPI(authenticator *maut.Authenticator, catalystService *service.Service, catalystStorage *storage.Storage, catalystDatabase *database.Database, dbConfig *database.Config, bus *bus.Bus, config *Config) (chi.Router, error) {
func setupAPI(authenticator *maut.Authenticator, catalystService *service.Service, catalystStorage *storage.Storage, catalystDatabase *database.Database, bus *bus.Bus, config *Config) (chi.Router, error) {
middlewares := []func(next http.Handler) http.Handler{
authenticator.Authenticate(),
authenticator.AuthorizeBlockedUser(),
@@ -97,7 +97,6 @@ func setupAPI(authenticator *maut.Authenticator, catalystService *service.Servic
// create server
apiServer := api.NewServer(catalystService, permissionAuth(authenticator), middlewares...)
apiServer.Mount("/files", fileServer(authenticator, catalystDatabase, bus, catalystStorage, config))
apiServer.Mount("/backup", backupServer(authenticator, catalystStorage, catalystDatabase, dbConfig))
server := chi.NewRouter()
server.Use(middleware.RequestID, middleware.RealIP, middleware.Logger, middleware.Recoverer)
@@ -130,11 +129,3 @@ func fileServer(authenticator *maut.Authenticator, catalystDatabase *database.Da
return server
}
func backupServer(authenticator *maut.Authenticator, catalystStorage *storage.Storage, catalystDatabase *database.Database, dbConfig *database.Config) *chi.Mux {
server := chi.NewRouter()
server.With(authenticator.AuthorizePermission("backup:create")).Get("/create", backupHandler(catalystStorage, dbConfig))
server.With(authenticator.AuthorizePermission("backup:restore")).Post("/restore", restoreHandler(catalystStorage, catalystDatabase, dbConfig))
return server
}

View File

@@ -4,6 +4,7 @@ import (
"context"
"errors"
"fmt"
"net/url"
"github.com/arangodb/go-driver"
maut "github.com/jonas-plum/maut/auth"
@@ -20,14 +21,6 @@ func newUserResponseID(user *model.NewUserResponse) []driver.DocumentID {
return userID(user.ID)
}
func userResponseID(user *model.UserResponse) []driver.DocumentID {
if user == nil {
return nil
}
return userID(user.ID)
}
func userID(id string) []driver.DocumentID {
return []driver.DocumentID{driver.DocumentID(fmt.Sprintf("%s/%s", database.UserCollectionName, id))}
}
@@ -42,20 +35,35 @@ func (s *Service) CreateUser(ctx context.Context, form *model.UserForm) (doc *mo
return s.database.UserCreate(ctx, form)
}
func (s *Service) GetUser(ctx context.Context, s2 string) (*model.UserResponse, error) {
return s.database.UserGet(ctx, s2)
func (s *Service) GetUser(ctx context.Context, id string) (*model.UserResponse, error) {
decodedValue, err := url.QueryUnescape(id)
if err == nil {
id = decodedValue
}
return s.database.UserGet(ctx, id)
}
func (s *Service) UpdateUser(ctx context.Context, s2 string, form *model.UserForm) (doc *model.UserResponse, err error) {
defer s.publishRequest(ctx, err, "UpdateUser", userID(s2))
func (s *Service) UpdateUser(ctx context.Context, id string, form *model.UserForm) (doc *model.UserResponse, err error) {
decodedValue, err := url.QueryUnescape(id)
if err == nil {
id = decodedValue
}
return s.database.UserUpdate(ctx, s2, form)
defer s.publishRequest(ctx, err, "UpdateUser", userID(id))
return s.database.UserUpdate(ctx, id, form)
}
func (s *Service) DeleteUser(ctx context.Context, s2 string) (err error) {
defer s.publishRequest(ctx, err, "DeleteUser", userID(s2))
func (s *Service) DeleteUser(ctx context.Context, id string) (err error) {
decodedValue, err := url.QueryUnescape(id)
if err == nil {
id = decodedValue
}
return s.database.UserDelete(ctx, s2)
defer s.publishRequest(ctx, err, "DeleteUser", userID(id))
return s.database.UserDelete(ctx, id)
}
func (s *Service) CurrentUser(ctx context.Context) (*model.UserResponse, error) {

View File

@@ -4,6 +4,7 @@ import (
"context"
"errors"
"fmt"
"net/url"
"github.com/arangodb/go-driver"
maut "github.com/jonas-plum/maut/auth"
@@ -29,10 +30,20 @@ func (s *Service) ListUserData(ctx context.Context) (doc []*model.UserDataRespon
}
func (s *Service) GetUserData(ctx context.Context, id string) (*model.UserDataResponse, error) {
decodedValue, err := url.QueryUnescape(id)
if err == nil {
id = decodedValue
}
return s.database.UserDataGet(ctx, id)
}
func (s *Service) UpdateUserData(ctx context.Context, id string, data *model.UserData) (doc *model.UserDataResponse, err error) {
decodedValue, err := url.QueryUnescape(id)
if err == nil {
id = decodedValue
}
defer s.publishRequest(ctx, err, "UpdateUserData", userDataResponseID(doc))
return s.database.UserDataUpdate(ctx, id, data)

View File

@@ -20,6 +20,7 @@ type Storage struct {
type Config struct {
Host string
User string
Region string
Password string
}
@@ -27,7 +28,7 @@ func New(config *Config) (*Storage, error) {
s, err := session.NewSession(&aws.Config{
Credentials: credentials.NewStaticCredentials(config.User, config.Password, ""),
Endpoint: aws.String(config.Host),
Region: aws.String("us-east-1"),
Region: aws.String(config.Region),
DisableSSL: aws.Bool(true),
S3ForcePathStyle: aws.Bool(true),
})

View File

@@ -1,262 +0,0 @@
package test
import (
"archive/zip"
"bytes"
"context"
"encoding/json"
"io"
"log"
"mime/multipart"
"net/http"
"net/http/httptest"
"regexp"
"runtime"
"testing"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/s3"
"github.com/aws/aws-sdk-go/service/s3/s3manager"
"github.com/stretchr/testify/assert"
"github.com/SecurityBrewery/catalyst"
"github.com/SecurityBrewery/catalyst/generated/model"
"github.com/SecurityBrewery/catalyst/generated/pointer"
)
func TestBackupAndRestore(t *testing.T) {
t.Parallel()
log.SetFlags(log.LstdFlags | log.Lshortfile)
if runtime.GOARCH == "arm64" {
t.Skip("test does not run on arm")
}
type want struct {
status int
}
tests := []struct {
name string
want want
}{
{name: "Backup", want: want{status: http.StatusOK}},
}
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
ctx, _, server, err := Catalyst(t)
if err != nil {
t.Fatal(err)
}
if err := SetupTestData(ctx, server.DB); err != nil {
t.Fatal(err)
}
createFile(ctx, server)
zipB := assertBackup(t, server)
assertZipFile(t, readZipFile(t, zipB))
clearAllDatabases(server)
_, err = server.DB.UserCreateSetupAPIKey(ctx, "test")
if err != nil {
log.Fatal(err)
}
deleteAllBuckets(t, server)
assertRestore(t, zipB, server)
assertTicketExists(t, server)
assertFileExists(t, server)
})
}
}
func assertBackup(t *testing.T, server *catalyst.Server) []byte {
t.Helper()
// setup request
req := httptest.NewRequest(http.MethodGet, "/api/backup/create", nil)
req.Header.Set("PRIVATE-TOKEN", "test")
// run request
backupRequestRecorder := httptest.NewRecorder()
server.Server.ServeHTTP(backupRequestRecorder, req)
backupResult := backupRequestRecorder.Result()
// assert results
assert.Equal(t, http.StatusOK, backupResult.StatusCode)
zipBuf := &bytes.Buffer{}
if _, err := io.Copy(zipBuf, backupResult.Body); err != nil {
t.Fatal(err)
}
assert.NoError(t, backupResult.Body.Close())
return zipBuf.Bytes()
}
func assertZipFile(t *testing.T, r *zip.Reader) {
t.Helper()
var names []string
for _, f := range r.File {
names = append(names, f.Name)
}
if !includes(t, names, "minio/catalyst-8125/test.txt") {
t.Error("Minio file missing")
}
for _, p := range []string{
"arango/ENCRYPTION", "arango/automations_.*.data.json.gz", "arango/automations_.*.structure.json", "arango/dump.json", "arango/jobs_.*.data.json.gz", "arango/jobs_.*.structure.json", "arango/logs_.*.data.json.gz", "arango/logs_.*.structure.json", "arango/migrations_.*.data.json.gz", "arango/migrations_.*.structure.json", "arango/playbooks_.*.data.json.gz", "arango/playbooks_.*.structure.json", "arango/related_.*.data.json.gz", "arango/related_.*.structure.json", "arango/templates_.*.data.json.gz", "arango/templates_.*.structure.json", "arango/tickets_.*.data.json.gz", "arango/tickets_.*.structure.json", "arango/tickettypes_.*.data.json.gz", "arango/tickettypes_.*.structure.json", "arango/userdata_.*.data.json.gz", "arango/userdata_.*.structure.json", "arango/users_.*.data.json.gz", "arango/users_.*.structure.json",
} {
if !includes(t, names, p) {
t.Errorf("Arango file missing: %s", p)
}
}
}
func clearAllDatabases(server *catalyst.Server) {
server.DB.Truncate(context.Background())
}
func deleteAllBuckets(t *testing.T, server *catalyst.Server) {
t.Helper()
buckets, err := server.Storage.S3().ListBuckets(&s3.ListBucketsInput{})
for _, bucket := range buckets.Buckets {
_, _ = server.Storage.S3().DeleteBucket(&s3.DeleteBucketInput{
Bucket: bucket.Name,
})
}
if err != nil {
t.Fatal(err)
}
}
func assertRestore(t *testing.T, zipB []byte, server *catalyst.Server) {
t.Helper()
bodyBuf := &bytes.Buffer{}
bodyWriter := multipart.NewWriter(bodyBuf)
fileWriter, err := bodyWriter.CreateFormFile("backup", "backup.zip")
if err != nil {
log.Fatal(err)
}
_, err = fileWriter.Write(zipB)
if err != nil {
log.Fatal(err)
}
assert.NoError(t, bodyWriter.Close())
req := httptest.NewRequest(http.MethodPost, "/api/backup/restore", bodyBuf)
req.Header.Set("PRIVATE-TOKEN", "test")
req.Header.Set("Content-Type", bodyWriter.FormDataContentType())
// run request
restoreRequestRecorder := httptest.NewRecorder()
server.Server.ServeHTTP(restoreRequestRecorder, req)
restoreResult := restoreRequestRecorder.Result()
if !assert.Equal(t, http.StatusOK, restoreResult.StatusCode) {
b, _ := io.ReadAll(restoreResult.Body)
log.Println(string(b))
t.FailNow()
}
}
func createFile(ctx context.Context, server *catalyst.Server) {
buf := bytes.NewBufferString("test text")
_, _ = server.Storage.S3().CreateBucket(&s3.CreateBucketInput{Bucket: pointer.String("catalyst-8125")})
if _, err := server.Storage.Uploader().Upload(&s3manager.UploadInput{Body: buf, Bucket: pointer.String("catalyst-8125"), Key: pointer.String("test.txt")}); err != nil {
log.Fatal(err)
}
if _, err := server.DB.AddFile(ctx, 8125, &model.File{Key: "test.txt", Name: "test.txt"}); err != nil {
log.Fatal(err)
}
}
func assertTicketExists(t *testing.T, server *catalyst.Server) {
t.Helper()
req := httptest.NewRequest(http.MethodGet, "/api/tickets/8125", nil)
req.Header.Set("PRIVATE-TOKEN", "test")
// run request
backupRequestRecorder := httptest.NewRecorder()
server.Server.ServeHTTP(backupRequestRecorder, req)
backupResult := backupRequestRecorder.Result()
// assert results
assert.Equal(t, http.StatusOK, backupResult.StatusCode)
zipBuf := &bytes.Buffer{}
if _, err := io.Copy(zipBuf, backupResult.Body); err != nil {
t.Fatal(err)
}
assert.NoError(t, backupResult.Body.Close())
var ticket model.Ticket
assert.NoError(t, json.Unmarshal(zipBuf.Bytes(), &ticket))
assert.Equal(t, "phishing from selenafadel@von.com detected", ticket.Name)
}
func assertFileExists(t *testing.T, server *catalyst.Server) {
t.Helper()
obj, err := server.Storage.S3().GetObject(&s3.GetObjectInput{
Bucket: aws.String("catalyst-8125"),
Key: aws.String("test.txt"),
})
assert.NoError(t, err)
b, err := io.ReadAll(obj.Body)
assert.NoError(t, err)
assert.Equal(t, "test text", string(b))
}
func includes(t *testing.T, names []string, s string) bool {
t.Helper()
for _, name := range names {
match, err := regexp.MatchString(s, name)
if err != nil {
t.Fatal(err)
}
if match {
return true
}
}
return false
}
func readZipFile(t *testing.T, b []byte) *zip.Reader {
t.Helper()
buf := bytes.NewReader(b)
zr, err := zip.NewReader(buf, int64(buf.Len()))
if err != nil {
t.Fatal(string(b), err)
}
return zr
}

View File

@@ -30,7 +30,7 @@ func Context() context.Context {
return maut.UserContext(context.Background(), Bob, nil) // TODO add permissions ?
}
func Config(ctx context.Context) (*catalyst.Config, error) {
func Config(_ context.Context) (*catalyst.Config, error) {
config := &catalyst.Config{
IndexPath: "index.bleve",
Network: "catalyst",
@@ -42,6 +42,7 @@ func Config(ctx context.Context) (*catalyst.Config, error) {
Storage: &storage.Config{
Host: "http://localhost:9000",
User: "minio",
Region: "eu-central-1",
Password: "minio123",
},
Auth: &maut.Config{

View File

@@ -26,7 +26,7 @@ Cypress.Commands.add('login', (options = {}) => {
cy.get("#kc-login").click();
} else if (Cypress.env('AUTH') === 'authelia') {
cy.contains("Login with OIDC").should('be.visible').click();
cy.get("#username-textfield").should('be.visible').type("bob");
cy.get("#username-textfield").should('be.visible').type("bob@example.com");
cy.get("#password-textfield").type("bob");
cy.get("#sign-in-button").click();
cy.get("#accept-button").should('be.visible').click();

View File

@@ -9,31 +9,34 @@
"lint": "vue-cli-service lint"
},
"dependencies": {
"@koumoul/vjsf": "2.21.0",
"@mdi/font": "7.0.96",
"@crinkles/digl": "^2.0.2",
"@koumoul/vjsf": "2.23.2",
"@mdi/font": "7.3.67",
"@mdi/util": "0.3.2",
"@types/luxon": "3.1.0",
"@types/prismjs": "1.26.0",
"@types/luxon": "3.3.3",
"@types/prismjs": "1.26.2",
"@uppy/core": "1.20.1",
"@uppy/tus": "1.9.2",
"@uppy/vue": "0.2.7",
"ajv": "8.11.0",
"ajv": "8.12.0",
"ant-design-vue": "1.7.8",
"antlr4": "4.11.0",
"axios": "1.1.3",
"axios": "1.5.1",
"chart.js": "2.9.4",
"core-js": "3.26.0",
"core-js": "3.33.1",
"d3": "^7.8.0",
"graphlib": "2.1.8",
"json-schema-editor-vue": "2.1.1",
"just-kebab-case": "4.1.1",
"less": "4.1.3",
"less-loader": "11.1.0",
"json-schema-editor-vue": "2.2.3",
"just-kebab-case": "4.2.0",
"less": "4.2.0",
"less-loader": "11.1.3",
"lodash": "4.17.21",
"luxon": "3.1.0",
"luxon": "3.4.3",
"panzoom": "^9.4.3",
"register-service-worker": "1.7.2",
"splitpanes": "2.4.1",
"swagger-ui": "4.13.0",
"vue": "2.7.10",
"vue": "2.7.15",
"vue-axios": "3.5.2",
"vue-chartjs": "3.5.1",
"vue-class-component": "7.2.6",
@@ -47,17 +50,17 @@
"vue-prism-editor": "1.3.0",
"vue-property-decorator": "9.1.2",
"vue-router": "3.6.5",
"vuetify": "2.6.12",
"vuetify": "2.7.1",
"vuex": "3.6.2",
"yaml": "2.0.1"
},
"devDependencies": {
"@testing-library/vue": "6.6.1",
"@types/jest": "29.2.2",
"@types/lodash": "4.14.188",
"@types/vue-markdown": "2.2.1",
"@typescript-eslint/eslint-plugin": "5.42.0",
"@typescript-eslint/parser": "5.42.0",
"@testing-library/vue": "7.0.0",
"@types/jest": "29.5.6",
"@types/lodash": "4.14.200",
"@types/vue-markdown": "2.2.3",
"@typescript-eslint/eslint-plugin": "5.62.0",
"@typescript-eslint/parser": "5.62.0",
"@vue/cli-plugin-babel": "4.5.19",
"@vue/cli-plugin-eslint": "4.5.19",
"@vue/cli-plugin-pwa": "4.5.19",
@@ -66,19 +69,19 @@
"@vue/cli-plugin-unit-jest": "4.5.19",
"@vue/cli-plugin-vuex": "4.5.19",
"@vue/cli-service": "4.5.19",
"@vue/compiler-sfc": "3.2.40",
"@vue/compiler-sfc": "3.3.6",
"@vue/eslint-config-typescript": "10.0.0",
"@vue/test-utils": "2.2.1",
"babel-eslint": "10.1.0",
"cypress": "10.11.0",
"@vue/test-utils": "2.4.1",
"@babel/eslint-parser": "7.22.15",
"cypress": "11.2.0",
"eslint": "7.32.0",
"eslint-plugin-jest": "27.1.4",
"eslint-plugin-jest": "27.4.3",
"eslint-plugin-vue": "7.20.0",
"sass": "1.56.0",
"sass": "1.69.4",
"sass-loader": "^10",
"typescript": "4.8.4",
"typescript": "5.1.6",
"vue-cli-plugin-vuetify": "2.5.8",
"vue-template-compiler": "2.7.10",
"vue-template-compiler": "2.7.15",
"vuetify-loader": "1.9.2"
}
}

View File

@@ -0,0 +1,273 @@
<template>
<v-card data-app outlined>
<v-card-title class="d-flex">
<span>Edit Task</span>
<v-spacer/>
<v-dialog v-model="deleteDialog" max-width="400">
<template #activator="{ on }">
<v-btn outlined v-on="on" class="mr-2" small>
<v-icon>mdi-delete</v-icon>
</v-btn>
</template>
<v-card>
<v-card-title class="headline">Delete Task</v-card-title>
<v-card-text>Are you sure you want to delete this task?</v-card-text>
<v-card-actions>
<v-spacer/>
<v-btn color="blue darken-1" text @click="deleteDialog = false">Cancel</v-btn>
<v-btn color="blue darken-1" text @click="deleteTask">Delete</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
<v-btn @click="close" outlined small>
<v-icon>mdi-close</v-icon>
</v-btn>
</v-card-title>
<v-card-text>
<v-text-field
v-model="task.name"
label="Name"
variant="underlined"/>
<v-textarea
v-model="task.description"
label="Description"
auto-grow
rows="1"
variant="underlined"/>
<v-select
v-model="task.type"
:items="['input','automation','task']"
label="Type"
variant="underlined"/>
<AdvancedJSONSchemaEditor
v-if="task.type === 'input'"
:schema="task.schema"
@save="task.schema = JSON.parse($event)" />
<v-select
v-if="task.type === 'automation'"
v-model="task.automation"
:items="automations"
item-text="id"
item-value="id"
label="Automation"
variant="underlined"/>
<v-list v-if="task.type === 'automation'">
<v-subheader class="pa-0" style="padding-inline-start: 0 !important;">Payload Mapping</v-subheader>
<v-toolbar v-for="(expr, key) in task.payload" :key="key" class="next-row" flat dense>
{{ key }}:
<v-text-field
v-model="task.payload[key]"
label="Expression"
variant="solo"
clearable
hide-details
density="compact"
bg-color="surface"
/>
<v-btn @click="deletePayloadMapping(key)" color="error" class="pa-0 ma-0" icon>
<v-icon>mdi-delete</v-icon>
</v-btn>
</v-toolbar>
<v-toolbar class="next-row" flat dense>
<v-text-field
v-model="newPayloadMapping"
label="Payload Field"
variant="solo"
bg-color="surface"
hide-details
density="compact"
/>:
<v-text-field
v-model="newExpression"
label="CAQL Expression"
variant="solo"
hide-details
density="compact"
bg-color="surface"
/>
<v-btn
@click="addPayloadMapping"
:disabled="!newPayloadMapping || !newExpression"
class="pa-0 ma-0"
icon>
<v-icon>mdi-plus</v-icon>
</v-btn>
</v-toolbar>
</v-list>
<v-list v-if="task.next || possibleNexts.length > 1">
<v-subheader class="pa-0" style="padding-inline-start: 0 !important;">Next Task(s)</v-subheader>
<v-toolbar v-for="(expr, key) in task.next" :key="key" class="next-row" flat dense>
If
<v-text-field
v-model="task.next[key]"
label="Condition (leave empty to always run)"
variant="solo"
clearable
hide-details
density="compact"
bg-color="surface"
/>
run
<span class="font-weight-black">
{{ playbook.tasks[key].name }}
</span>
<v-btn @click="deleteNext(key)" color="error" class="pa-0 ma-0" icon>
<v-icon>mdi-delete</v-icon>
</v-btn>
</v-toolbar>
<v-toolbar v-if="possibleNexts.length > 0" class="next-row" flat dense>
If
<v-text-field
v-model="newCondition"
label="Condition (leave empty to always run)"
variant="solo"
clearable
hide-details
density="compact"
bg-color="surface"
/>
run
<v-select
v-model="newNext"
item-text="name"
item-value="key"
:items="possibleNexts"
variant="solo"
bg-color="surface"
hide-details
density="compact"
/>
<v-btn
@click="addNext"
:disabled="!newNext"
class="pa-0 ma-0"
icon>
<v-icon>mdi-plus</v-icon>
</v-btn>
</v-toolbar>
</v-list>
<v-switch
v-if="parents.length > 1"
label="Join (Require all previous tasks to be completed)"
v-model="task.join"
color="primary"/>
</v-card-text>
</v-card>
</template>
<script setup lang="ts">
import {defineProps, ref, watch, defineEmits, del, set, onMounted, computed} from "vue";
import AdvancedJSONSchemaEditor from "@/components/AdvancedJSONSchemaEditor.vue";
import {API} from "@/services/api";
import {AutomationResponse} from "@/client";
interface Task {
name: string;
description: string;
type: string;
next: Record<string, string>;
payload: Record<string, string>;
join: boolean;
}
const props = defineProps<{
value: Task;
possibleNexts: Array<Record<string, string>>;
parents: Array<string>;
playbook: object;
}>();
const emit = defineEmits(["input", "delete", "close"]);
const deleteDialog = ref(false);
const deleteTask = () => emit("delete");
const close = () => {
emit("close");
};
const task = ref(props.value);
watch(() => props.value, (value) => {
task.value = value;
});
watch(task, (value) => {
emit("input", value);
});
// const task = computed({
// get: () => {
// console.log("get", props.value);
// return props.value;
// },
// set: (value) => {
// console.log("set", value);
// emit("input", value);
// }
// });
const deleteNext = (key: string) => {
del(task.value.next, key);
};
const deletePayloadMapping = (key: string) => {
del(task.value.payload, key);
};
const newNext = ref('');
const newCondition = ref('');
const newPayloadMapping = ref('');
const newExpression = ref('');
watch(() => props.possibleNexts, () => {
if (props.possibleNexts.length > 0) {
newNext.value = props.possibleNexts[0].key;
}
}, {deep: true, immediate: true});
const addNext = () => {
if (task.value.next === undefined) {
// task.value.next = {};
set(task.value, 'next', {});
}
// task.value.next[newNext.value] = newCondition.value;
set(task.value.next, newNext.value, newCondition.value);
newNext.value = "";
newCondition.value = "";
};
const addPayloadMapping = () => {
if (task.value.payload === undefined) {
// task.value.payload = {};
set(task.value, 'payload', {});
}
// task.value.payload[newPayloadMapping.value] = newExpression.value;
set(task.value.payload, newPayloadMapping.value, newExpression.value);
newPayloadMapping.value = "";
newExpression.value = "";
};
const automations = ref<Array<AutomationResponse>>([]);
onMounted(() => {
API.listAutomations().then((response) => {
automations.value = response.data;
});
});
</script>
<style>
.next-row {
padding-top: 10px;
background: none !important;
}
.next-row .v-toolbar__content {
gap: 5px;
padding: 0;
}
</style>

View File

@@ -0,0 +1,80 @@
<template>
<v-card outlined>
<v-card-title>
Create a new step
<v-spacer />
<v-btn @click="close" outlined small>
<v-icon>mdi-close</v-icon>
</v-btn>
</v-card-title>
<v-card-text>
<v-form v-model="valid">
<v-text-field
v-model="newTask.name"
label="Name"
:rules="[val => (val || '').length > 0 || 'This field is required']"
variant="underlined"/>
<v-textarea
v-model="newTask.description"
label="Description"
auto-grow
rows="1"
variant="underlined"/>
<v-text-field
v-model="newTask.key"
label="Key (generated automatically)"
readonly
disabled
:rules="[val => (val || '').length > 0 || 'This field is required']"
variant="underlined"/>
</v-form>
</v-card-text>
<v-card-actions>
<v-spacer/>
<v-btn color="primary" @click="createTask" :disabled="!valid">Create</v-btn>
</v-card-actions>
</v-card>
</template>
<script setup lang="ts">
import {defineProps, ref, watch, defineEmits} from "vue";
const props = defineProps<{
playbook: any;
}>();
const valid = ref(false);
const newTask = ref({
name: '',
description: '',
key: '',
next: {},
});
watch(newTask, (val) => {
if (val.name) {
const newKeyBase = val.name.toLowerCase().replace(/ /g, '_');
let newKey = newKeyBase;
if (!(newKey in props.playbook.tasks)) {
newTask.value.key = newKey;
} else {
let i = 1;
while (newKey in props.playbook.tasks) {
newKey = newKeyBase + '_' + i;
i++;
}
newTask.value.key = newKey;
}
}
}, {deep: true});
const emit = defineEmits(["createTask", "close"]);
const createTask = () => {
emit('createTask', newTask.value);
};
const close = () => {
emit("close");
};
</script>

View File

@@ -0,0 +1,164 @@
<template>
<div id="graphwrapper">
<div id="gab">
<slot name="actionbar"/>
</div>
<v-toolbar
id="gtb"
class="ma-2"
floating
dense
>
<v-btn @click.prevent.stop="reset" title="Reset" icon>
<v-icon color="#000">mdi-image-filter-center-focus</v-icon>
</v-btn>
<v-btn @click.prevent.stop="zoomIn" title="Zoom in" :disabled="isMaxZoom" icon>
<v-icon color="#000">mdi-magnify-plus-outline</v-icon>
</v-btn>
<v-btn @click.prevent.stop="zoomOut" title="Zoom out" :disabled="isMinZoom" icon>
<v-icon color="#000">mdi-magnify-minus-outline</v-icon>
</v-btn>
<slot name="toolbar"/>
</v-toolbar>
<div id="panzoom">
<slot/>
</div>
</div>
</template>
<script setup lang="ts">
import {computed, onMounted, ref, defineProps, defineExpose} from "vue";
import createPanZoom from "panzoom";
import * as panzoom from "panzoom";
const props = defineProps<{
config: panzoom.PanZoomOptions
}>();
const panZoom = ref<panzoom.PanZoom | null>(null);
const zoomLevel = ref<number>(1);
const minZoom = ref<number>(0.5);
const maxZoom = ref<number>(1.5);
const isMaxZoom = computed(() => {
if (zoomLevel.value) {
return zoomLevel.value >= maxZoom.value;
}
return false;
});
const isMinZoom = computed(() => {
if (zoomLevel.value) {
return zoomLevel.value <= minZoom.value;
}
return false;
});
const initialZoom = ref<number>(1);
onMounted(() => {
const canvas = document.getElementById("panzoom")
if (!canvas) {
throw new Error("No element with id panzoom")
}
const firstChild = canvas.firstElementChild
if (!firstChild) {
throw new Error("No child element")
}
const startX = canvas.getBoundingClientRect().width / 2 - firstChild.getBoundingClientRect().width / 2
const startY = canvas.getBoundingClientRect().height / 2 - firstChild.getBoundingClientRect().height / 2
initialZoom.value = props.config.initialZoom ? props.config.initialZoom : 1
minZoom.value = props.config.initialZoom / 2
maxZoom.value = props.config.initialZoom * 2
panZoom.value = createPanZoom(canvas, {
...props.config,
zoomDoubleClickSpeed: 1, // disable double click zoom
autocenter: true,
initialX: startX,
initialY: startY,
minZoom: minZoom.value,
maxZoom: maxZoom.value,
});
panZoom.value.on("zoom", (e: panzoom.PanZoom) => {
zoomLevel.value = e.getTransform().scale;
});
reset(false);
});
const ZOOM_FACTOR = 0.255
const zoomIn = () => {
if (!panZoom.value) return
const currentZoom = panZoom.value.getTransform().scale
panZoom.value.smoothZoomAbs(0, 0, currentZoom + ZOOM_FACTOR)
}
const zoomOut = () => {
if (!panZoom.value) return
const currentZoom = panZoom.value.getTransform().scale
panZoom.value.smoothZoomAbs(0, 0, currentZoom - ZOOM_FACTOR)
}
const reset = (smooth = true) => {
if (!panZoom.value) return
const canvas = document.getElementById("panzoom")
if (!canvas) {
throw new Error("No element with id panzoom")
}
const firstChild = canvas.firstElementChild
if (!firstChild) {
throw new Error("No child element")
}
const startX = canvas.getBoundingClientRect().width / 2 - firstChild.getBoundingClientRect().width / 2
const startY = canvas.getBoundingClientRect().height / 2 - firstChild.getBoundingClientRect().height / 2
panZoom.value.pause()
if (smooth) {
panZoom.value.smoothZoomAbs(0, 0, initialZoom.value)
panZoom.value.smoothMoveTo(startX * 0.5, startY)
} else {
panZoom.value.zoomTo(0, 0, initialZoom.value)
panZoom.value.moveTo(startX * 0.5, startY)
}
panZoom.value.resume()
}
defineExpose({
reset,
zoomIn,
zoomOut,
zoomLevel,
isMaxZoom,
isMinZoom,
});
</script>
<style>
#graphwrapper {
position: relative;
width: 100%;
height: 100%;
}
#gtb .v-toolbar__content {
padding: 0;
}
#panzoom {
width: 100%;
height: 100%;
position: relative;
cursor: move;
}
</style>

View File

@@ -0,0 +1,235 @@
<template>
<v-row style="position: relative; min-height: 600px">
<v-col :cols="(selectedStep && selectedStep in playbook.tasks) || showNewDialog ? 8 :12">
<v-card style="overflow: hidden" outlined>
<v-card-text>
<PanZoom ref="panZoomPanel" :config="panZoomConfig">
<template #default>
<PlaybookGraph
v-if="playbook"
:playbook="playbook"
:horizontal="horizontal"
:selected="selectedStep"
@update:selected="showNewDialog = false; selectedStep = $event"
/>
</template>
<template #actionbar>
<v-btn @click="showNewDialog = true; selectedStep = ''" large rounded>
<v-icon color="#000">mdi-plus</v-icon>
New Step
</v-btn>
</template>
<template #toolbar>
<v-btn @click="toggleOrientation" label="Toggle Orientation" icon>
<v-icon color="#000">mdi-format-rotate-90</v-icon>
</v-btn>
</template>
</PanZoom>
</v-card-text>
</v-card>
</v-col>
<v-col
v-if="(selectedStep && selectedStep in playbook.tasks) || showNewDialog"
cols="4"
>
<EditTask
v-if="selectedStep && selectedStep in playbook.tasks"
:value="playbook.tasks[selectedStep]"
@input="updateTask"
:possibleNexts="possibleNexts"
:parents="parents"
:playbook="playbook"
@delete="deleteTask"
@close="unselectStep"/>
<NewTask
v-else-if="showNewDialog"
:playbook="playbook"
@createTask="createTask"
@close="showNewDialog = false"/>
</v-col>
</v-row>
</template>
<script lang="ts" setup>
import {computed, nextTick, ref, defineProps, set, defineEmits, del} from "vue";
import PlaybookGraph from "@/components/playbookeditor/PlaybookGraph.vue";
import PanZoom from "@/components/playbookeditor/PanZoom.vue";
import EditTask from "@/components/playbookeditor/EditTask.vue";
import NewTask from "@/components/playbookeditor/NewTask.vue";
const props = defineProps({
'value': {
type: Object,
required: true
}
});
const emit = defineEmits(['input']);
const playbook = computed({
get: () => props.value,
set: (value) => {
emit('input', value);
}
});
// selected step
const selectedStep = ref("")
const unselectStep = () => {
selectedStep.value = "";
}
const updateTask = (task: any) => {
set(playbook.value.tasks, selectedStep.value, task);
emit('input', playbook.value);
}
const deleteTask = () => {
const parents = Array<any>();
for (const task in playbook.value.tasks) {
if (playbook.value.tasks[task].next && playbook.value.tasks[task].next[selectedStep.value]) {
parents.push(task);
}
}
const children = Array<any>();
if (playbook.value.tasks[selectedStep.value].next) {
for (const next in playbook.value.tasks[selectedStep.value].next) {
children.push(next);
}
}
for (const parent of parents) {
del(playbook.value.tasks[parent].next, selectedStep.value);
for (const child of children) {
set(playbook.value.tasks[parent].next, child, playbook.value.tasks[selectedStep.value].next[child]);
}
}
del(playbook.value.tasks, selectedStep.value);
// for (const task in playbook.value.tasks) {
// if (playbook.value.tasks[task].next && playbook.value.tasks[task].next[selectedStep.value]) {
// del(playbook.value.tasks[task].next, selectedStep.value);
// }
// }
// del(playbook.value.tasks, selectedStep.value);
emit('input', playbook.value);
}
const panZoomConfig = ref({})
const panZoomPanel = ref(null);
const horizontal = ref(false);
const toggleOrientation = () => {
horizontal.value = !horizontal.value;
nextTick(() => {
panZoomPanel.value?.reset(false);
});
}
const showNewDialog = ref(false);
const createTask = (task: any) => {
const t = {
name: task.name,
description: task.description,
type: 'task',
next: {}
};
set(playbook.value.tasks, task.key, t);
selectedStep.value = task.key;
};
// edit task
const possibleNexts = computed(() => {
if (!selectedStep.value) {
return [];
}
let nexts = Object.keys(playbook.value.tasks);
nexts = nexts.filter((n) => n !== selectedStep.value);
// remove any nexts that are already in the list
if (playbook.value.tasks[selectedStep.value] && 'next' in playbook.value.tasks[selectedStep.value]) {
for (const next in playbook.value.tasks[selectedStep.value].next) {
nexts = nexts.filter((n) => n !== next);
}
}
// remove parents recursively
const parents = findAncestor(selectedStep.value);
for (const parent of parents) {
nexts = nexts.filter((n) => n !== parent);
}
const result: Array<Record<string, string>> = [];
for (const next of nexts) {
if (next && playbook.value.tasks[next].name) {
result.push({"key": next, "name": playbook.value.tasks[next].name});
}
}
return result;
});
const findAncestor = (step: string): Array<string> => {
const parents: Array<string> = [];
for (const task in playbook.value.tasks) {
for (const next in playbook.value.tasks[task].next) {
if (next === step) {
if (!parents.includes(task)) {
parents.push(task);
parents.push(...findAncestor(task));
}
}
}
}
return parents;
};
const parents = computed(() => {
const parents: Array<string> = [];
for (const task in playbook.value.tasks) {
for (const next in playbook.value.tasks[task].next) {
if (next === selectedStep.value) {
if (!parents.includes(task)) {
parents.push(task);
}
}
}
}
return parents;
});
</script>
<style>
#graphwrapper {
padding: 20px;
}
#gab {
position: absolute;
left: 10px;
top: 20px;
border-radius: 30px;
z-index: 200;
}
#gtb {
position: absolute;
left: 0;
bottom: 20px;
border-radius: 30px;
z-index: 200;
}
#gtb .v-toolbar__content > .v-btn:first-child {
margin-inline-start: 0;
}
#gtb .v-toolbar__content > .v-btn:last-child {
margin-inline-end: 0;
}
</style>

View File

@@ -0,0 +1,511 @@
<template>
<svg
class="pe-graph"
:width="width * scale"
:height="height * scale"
:viewBox="`${minX - config.graphPadding} ${minY - config.graphPadding} ${maxX - minX + config.boxWidth + config.graphPadding * 2} ${maxY - minY + config.boxHeight + config.graphPadding * 2}`"
>
<defs>
<path
id="cog"
d="M12,15.5A3.5,3.5 0 0,1 8.5,12A3.5,3.5 0 0,1 12,8.5A3.5,3.5 0 0,1 15.5,12A3.5,3.5 0 0,1 12,15.5M19.43,12.97C19.47,12.65 19.5,12.33 19.5,12C19.5,11.67 19.47,11.34 19.43,11L21.54,9.37C21.73,9.22 21.78,8.95 21.66,8.73L19.66,5.27C19.54,5.05 19.27,4.96 19.05,5.05L16.56,6.05C16.04,5.66 15.5,5.32 14.87,5.07L14.5,2.42C14.46,2.18 14.25,2 14,2H10C9.75,2 9.54,2.18 9.5,2.42L9.13,5.07C8.5,5.32 7.96,5.66 7.44,6.05L4.95,5.05C4.73,4.96 4.46,5.05 4.34,5.27L2.34,8.73C2.21,8.95 2.27,9.22 2.46,9.37L4.57,11C4.53,11.34 4.5,11.67 4.5,12C4.5,12.33 4.53,12.65 4.57,12.97L2.46,14.63C2.27,14.78 2.21,15.05 2.34,15.27L4.34,18.73C4.46,18.95 4.73,19.03 4.95,18.95L7.44,17.94C7.96,18.34 8.5,18.68 9.13,18.93L9.5,21.58C9.54,21.82 9.75,22 10,22H14C14.25,22 14.46,21.82 14.5,21.58L14.87,18.93C15.5,18.67 16.04,18.34 16.56,17.94L19.05,18.95C19.27,19.03 19.54,18.95 19.66,18.73L21.66,15.27C21.78,15.05 21.73,14.78 21.54,14.63L19.43,12.97Z"/>
<path
id="clipboard-outline"
d="M19,3H14.82C14.4,1.84 13.3,1 12,1C10.7,1 9.6,1.84 9.18,3H5A2,2 0 0,0 3,5V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19V5A2,2 0 0,0 19,3M12,3A1,1 0 0,1 13,4A1,1 0 0,1 12,5A1,1 0 0,1 11,4A1,1 0 0,1 12,3M7,7H17V5H19V19H5V5H7V7Z"/>
<path
id="keyboard"
d="M19,10H17V8H19M19,13H17V11H19M16,10H14V8H16M16,13H14V11H16M16,17H8V15H16M7,10H5V8H7M7,13H5V11H7M8,11H10V13H8M8,8H10V10H8M11,11H13V13H11M11,8H13V10H11M20,5H4C2.89,5 2,5.89 2,7V17A2,2 0 0,0 4,19H20A2,2 0 0,0 22,17V7C22,5.89 21.1,5 20,5Z"/>
<path
id="star"
d="M12,17.27L18.18,21L16.54,13.97L22,9.24L14.81,8.62L12,2L9.19,8.62L2,9.24L7.45,13.97L5.82,21L12,17.27Z"/>
</defs>
<g class="pe-links">
<path v-for="(link, index) in links" :key="index" :d="link.path"/>
</g>
<g class="pe-activelinks">
<path
v-for="(link, index) in links"
:key="index"
:d="link.path"
:class="{
'hovered': !selectedNode && (link.source === hoverNode || link.target === hoverNode),
'selected': link.source === selectedNode || link.target === selectedNode
}"
/>
</g>
<g class="pe-nodes">
<g
v-for="(node, index) in positionedNodes"
:key="index">
<g
v-if="node.type === 'start'"
:transform="`translate(${props.horizontal ? node.x + config.boxWidth : node.x + (config.boxWidth / 2)}, ${node.y})`"
class="start"
>
<circle
:transform="`translate(0, ${config.boxHeight / 2})`"
r="20"
/>
<g
class="icon"
:transform="`translate(${0 - 12}, ${(config.boxHeight - 24) / 2})`"
>
<use href="#star" fill="white"/>
</g>
</g>
<g
v-else
:transform="`translate(${node.x}, ${node.y})`"
:class="{
'pe-node': true,
'start': node.type === 'start',
'hovered': node.id === hoverNode,
'selected': node.id === selectedNode,
'unhovered': hoverNode && !selectedNode && node.id !== hoverNode,
'unselected': selectedNode && node.id !== selectedNode,
}"
@mouseover="hoverNode = node.id"
@mouseout="hoverNode = null"
@click="selectedNode === node.id ? selectedNode = null : selectedNode = node.id"
>
<rect
class="pe-box"
:width="config.boxWidth"
:height="config.boxHeight"
:rx="config.boxRadius"
:ry="config.boxRadius"
/>
<g
class="pe-icon"
:transform="`translate(10, ${(config.boxHeight - 24) / 2})`"
>
<use v-if="node.type === 'automation'" href="#cog"/>
<use v-else-if="node.type === 'start'" href="#star"/>
<use v-else-if="node.type === 'input'" href="#keyboard"/>
<use v-else href="#clipboard-outline"/>
</g>
<text
class="pe-text"
:x="config.boxWidth / 2"
:y="config.boxHeight / 2"
>
{{ node.label ? node.label : node.id }}
</text>
<g
class="add"
:transform="`translate(${config.boxWidth - 34}, ${(config.boxHeight - 24) / 2})`"
>
<use href="#star" fill="none"/>
</g>
</g>
</g>
</g>
<g class="pe-connectors">
<g
v-for="(link, index) in links"
:key="index"
:class="{
'pe-connector': true,
'hovered': !selectedNode && (link.source === hoverNode || link.target === hoverNode),
'selected': link.source === selectedNode || link.target === selectedNode
}"
>
<circle
v-if="link.source !== 'start'"
:cx="link.start.x"
:cy="link.start.y"
:r="4"/>
<circle
:cx="link.end.x"
:cy="link.end.y"
:r="7"/>
<circle
:cx="link.end.x"
:cy="link.end.y"
:r="5"
fill="white"/>
</g>
</g>
</svg>
</template>
<script setup lang="ts">
import * as d3 from "d3";
import {digl} from "@crinkles/digl";
import {Edge as DiglEdge, Node as DiglNode, Position, Rank} from "@crinkles/digl/dist/types";
import {computed, defineEmits, ref, Ref, defineProps, ComputedRef} from "vue";
interface Config {
graphPadding: number;
boxWidth: number;
boxHeight: number;
boxMarginX: number;
boxMarginY: number;
boxRadius: number;
lineDistance: number;
}
const props = defineProps({
playbook: {
type: Object,
required: true
},
selected: {
type: String,
required: false,
default: null
},
horizontal: {
type: Boolean,
required: false,
default: false
},
scale: {
type: Number,
required: false,
default: 1
}
})
const config = ref({
graphPadding: 10,
boxWidth: 220,
boxHeight: 40,
boxMarginX: 60,
boxMarginY: 70,
boxRadius: 20,
lineDistance: 0,
});
interface Edge extends DiglEdge {
label?: { text: string, x: number, y: number };
}
interface Node extends DiglNode {
type: 'automation' | 'input' | 'task' | 'start';
}
const edges = computed(() => {
const edges: Array<Edge> = [];
for (const key in props.playbook.tasks) {
for (const next in props.playbook.tasks[key].next) {
edges.push({
source: key,
target: next,
label: props.playbook.tasks[key].next[next]
});
}
}
const rootNodes = nodes.value.filter(node => edges.every(edge => edge.target !== node.id));
for (const node of rootNodes) {
if (node.id !== 'start') {
edges.push({
source: 'start',
target: node.id
});
}
}
return edges;
});
const nodes: ComputedRef<Array<Node>> = computed(() => {
const nodes = [{
id: "start",
label: "Start",
type: "start" as 'automation' | 'input' | 'task' | 'start',
}];
for (const key in props.playbook.tasks) {
nodes.push({
id: key,
label: props.playbook.tasks[key].name,
type: props.playbook.tasks[key].type
});
}
return nodes;
});
const hoverNode: Ref<string | null> = ref(null);
const emits = defineEmits(['update:selected']);
const selectedNode = computed({
get: () => props.selected,
set: (newVal) => {
emits('update:selected', newVal);
}
});
const rankses: Ref<Array<Array<Rank>>> = computed(() => {
return digl(edges.value);
});
const ranks = computed(() => {
return rankses.value.length > 0 ? rankses.value[0] : [];
});
const positionedNodes = computed(() => {
return positioning(config.value, props.horizontal, nodes.value, ranks.value);
});
const width = computed(() => {
return maxX.value - minX.value + config.value.graphPadding * 2 + config.value.boxWidth;
});
const height = computed(() => {
return maxY.value - minY.value + config.value.graphPadding * 2 + config.value.boxHeight;
});
const minX = computed(() => {
if (props.horizontal) {
return Math.min(...positionedNodes.value.map(node => node.x)) + config.value.boxWidth - 22;
}
return Math.min(...positionedNodes.value.map(node => node.x));
});
const minY = computed(() => {
if (!props.horizontal) {
return Math.min(...positionedNodes.value.map(node => node.y)) + config.value.boxHeight - 30;
}
return Math.min(...positionedNodes.value.map(node => node.y));
});
const maxX = computed(() => {
return Math.max(...positionedNodes.value.map(node => node.x));
});
const maxY = computed(() => {
return Math.max(...positionedNodes.value.map(node => node.y)) + 50;
});
const links = computed(() => {
return edges.value.map(edge => {
const source = positionedNodes.value.find(node => node.id === edge.source);
const target = positionedNodes.value.find(node => node.id === edge.target);
if (!source || !target) return;
// index within rank
const sourceIndex = ranks.value.find(rank => rank.includes(edge.source))?.indexOf(edge.source);
if (sourceIndex === undefined) {
throw new Error(`sourceIndex is undefined for ${edge.source}`);
}
const path = props.horizontal ?
horizontalConnectionLine(source, target, sourceIndex, config.value) :
verticalConnectionLine(source, target, sourceIndex, config.value);
const start = props.horizontal ?
{x: source.x + config.value.boxWidth, y: source.y + config.value.boxHeight / 2} :
{x: source.x + config.value.boxWidth / 2, y: source.y + config.value.boxHeight};
const end = props.horizontal ?
{x: target.x, y: target.y + config.value.boxHeight / 2} :
{x: target.x + config.value.boxWidth / 2, y: target.y};
return {
source: edge.source,
target: edge.target,
path: path.toString(),
start: start,
end: end,
};
}).filter(link => link);
});
interface PositionedNode extends Node, Position {
}
function positioning(
config: Config,
horizontal: boolean,
nodes: Node[],
ranks: Rank[]
): PositionedNode[] {
const _nodes: PositionedNode[] = [];
const _h = horizontal;
ranks.forEach((rank, i) => {
const xStart = _h
? (config.boxWidth + config.boxMarginX) * i
: -0.5 * (rank.length - 1) * (config.boxWidth + config.boxMarginX);
const yStart = _h
? -0.5 * (rank.length - 1) * (config.boxHeight + config.boxMarginY)
: (config.boxHeight + config.boxMarginY) * i;
rank.forEach((nodeId, nIndex) => {
const _node: Node = nodes.find((n) => n.id == nodeId) as Node;
if (!_node) return;
const x = _h ? xStart : xStart + (config.boxWidth + config.boxMarginX) * nIndex;
const y = _h ? yStart + (config.boxHeight + config.boxMarginY) * nIndex : yStart;
_nodes.push({..._node, x, y});
});
});
return _nodes;
}
function verticalConnectionLine(source: PositionedNode, target: PositionedNode, sourceIndex: number, config: Config) {
const sourceBottomCenter = {
x: source.x + config.boxWidth / 2,
y: source.y + config.boxHeight,
};
const targetTopCenter = {
x: target.x + config.boxWidth / 2,
y: target.y,
};
const path = d3.path();
path.moveTo(sourceBottomCenter.x, sourceBottomCenter.y);
const lineCurve = config.boxMarginY / 2;
if (sourceBottomCenter.x == targetTopCenter.x) {
path.lineTo(targetTopCenter.x, targetTopCenter.y);
} else if (sourceBottomCenter.x < targetTopCenter.x) {
if (target.y !== source.y + config.boxHeight + config.boxMarginY) {
path.lineTo(sourceBottomCenter.x, target.y - config.boxMarginY);
}
sourceBottomCenter.y = target.y - config.boxMarginY;
path.quadraticCurveTo(
sourceBottomCenter.x, sourceBottomCenter.y + lineCurve + sourceIndex * config.lineDistance,
sourceBottomCenter.x + lineCurve, sourceBottomCenter.y + lineCurve + sourceIndex * config.lineDistance,
);
path.lineTo(targetTopCenter.x - lineCurve, targetTopCenter.y - lineCurve + sourceIndex * config.lineDistance);
path.quadraticCurveTo(
targetTopCenter.x, targetTopCenter.y - lineCurve + sourceIndex * config.lineDistance,
targetTopCenter.x, targetTopCenter.y,
);
} else {
if (target.y !== source.y + config.boxHeight + config.boxMarginY) {
path.lineTo(sourceBottomCenter.x, target.y - config.boxMarginY);
}
sourceBottomCenter.y = target.y - config.boxMarginY;
path.quadraticCurveTo(
sourceBottomCenter.x, sourceBottomCenter.y + lineCurve + sourceIndex * config.lineDistance,
sourceBottomCenter.x - lineCurve, sourceBottomCenter.y + lineCurve + sourceIndex * config.lineDistance,
);
path.lineTo(targetTopCenter.x + lineCurve, targetTopCenter.y - lineCurve + sourceIndex * config.lineDistance);
path.quadraticCurveTo(
targetTopCenter.x, targetTopCenter.y - lineCurve + sourceIndex * config.lineDistance,
targetTopCenter.x, targetTopCenter.y,
);
}
return path;
}
function horizontalConnectionLine(source: PositionedNode, target: PositionedNode, sourceIndex: number, config: Config) {
const sourceRightCenter = {
x: source.x + config.boxWidth,
y: source.y + config.boxHeight / 2,
};
const targetLeftCenter = {
x: target.x,
y: target.y + config.boxHeight / 2,
};
const path = d3.path();
path.moveTo(sourceRightCenter.x, sourceRightCenter.y);
const lineCurve = config.boxMarginX / 2;
if (sourceRightCenter.y == targetLeftCenter.y) {
path.lineTo(targetLeftCenter.x, targetLeftCenter.y);
} else if (sourceRightCenter.y < targetLeftCenter.y) {
if (target.x !== source.x + config.boxWidth + config.boxMarginX) {
path.lineTo(target.x - config.boxMarginX, sourceRightCenter.y);
}
sourceRightCenter.x = target.x - config.boxMarginX;
path.quadraticCurveTo(
sourceRightCenter.x + lineCurve + sourceIndex * config.lineDistance, sourceRightCenter.y,
sourceRightCenter.x + lineCurve + sourceIndex * config.lineDistance, sourceRightCenter.y + lineCurve,
);
path.lineTo(targetLeftCenter.x - lineCurve + sourceIndex * config.lineDistance, targetLeftCenter.y - lineCurve);
path.quadraticCurveTo(
targetLeftCenter.x - lineCurve + sourceIndex * config.lineDistance, targetLeftCenter.y,
targetLeftCenter.x, targetLeftCenter.y,
);
} else {
if (target.x !== source.x + config.boxWidth + config.boxMarginX) {
path.lineTo(target.x - config.boxMarginX, sourceRightCenter.y);
}
sourceRightCenter.x = target.x - config.boxMarginX;
path.quadraticCurveTo(
sourceRightCenter.x + lineCurve + sourceIndex * config.lineDistance, sourceRightCenter.y,
sourceRightCenter.x + lineCurve + sourceIndex * config.lineDistance, sourceRightCenter.y - lineCurve,
);
path.lineTo(targetLeftCenter.x - lineCurve + sourceIndex * config.lineDistance, targetLeftCenter.y + lineCurve);
path.quadraticCurveTo(
targetLeftCenter.x - lineCurve + sourceIndex * config.lineDistance, targetLeftCenter.y,
targetLeftCenter.x, targetLeftCenter.y,
);
}
return path;
}
</script>
<style>
svg .pe-node.unhovered {
opacity: 0.5;
}
svg .pe-node .pe-box {
fill: white;
stroke: #4C566A;
stroke-width: 1px;
filter: drop-shadow(0 1.5px 1.5px rgba(0, 0, 0, .15));
}
svg .pe-node.selected .pe-box {
stroke: #88C0D0;
stroke-width: 2;
}
svg .pe-node text {
text-anchor: middle;
dominant-baseline: middle;
font-size: 16px;
}
svg .pe-node:hover .pe-box {
filter: drop-shadow(0 0 0.1rem #333);
}
svg .pe-node:hover .pe-box,
svg .pe-node:hover text {
cursor: pointer;
}
svg .pe-node:hover .add use {
/* fill: red !important; */
}
svg .pe-links path {
stroke: black;
fill: none;
stroke-width: 2;
stroke-linecap: round;
stroke-linejoin: round;
filter: drop-shadow(0 2px 2px rgba(0, 0, 0, .15));
}
svg .pe-activelinks path {
stroke: none;
fill: none;
stroke-width: 2;
stroke-linejoin: round;
}
svg .pe-activelinks path.selected,
svg .pe-activelinks path.hovered {
stroke-width: 3;
stroke-linejoin: round;
stroke: #88C0D0;
filter: drop-shadow(0 0 0.1rem #88C0D0);
}
</style>

View File

@@ -1,5 +1,5 @@
<template>
<div class="fill-height">
<div class="network-graph fill-height">
<v-card
v-if="selected !== undefined"
class="mt-3 ml-3 px-0"
@@ -184,33 +184,33 @@ export default Vue.extend({
</script>
<style>
.node,
.node.selected {
.network-graph .node,
.network-graph .node.selected {
stroke: #388E3C !important;
}
.node.event {
.network-graph .node.event {
stroke: #D32F2F !important;
}
.node.center {
.network-graph .node.center {
stroke: #FFEB3B !important;
fill: #FFEB3B !important;
}
.theme--dark .node-label,
.theme--dark .node-label.event {
.theme--dark .network-graph .node-label,
.theme--dark .network-graph .node-label.event {
fill: #ffffff !important;
}
.node-label,
.node-label.event {
.network-graph .node-label,
.network-graph .node-label.event {
fill: #000000 !important;
}
.link {
.network-graph .link {
stroke: #424242 !important;
}
.link.selected,
.link:hover,.node:hover{
.network-graph .link.selected,
.network-graph .link:hover,.node:hover{
stroke: #FFEB3B !important;
}
</style>

View File

@@ -19,25 +19,35 @@
<v-alert v-else-if="error" color="warning">
{{ error }}
</v-alert>
<div v-else class="px-4 overflow-scroll">
<vue-pipeline
v-if="pipelineData"
ref="pipeline"
:x="50"
:y="55"
:data="pipelineData"
:showArrow="true"
:ystep="70"
:xstep="100"
lineStyle="default"
/>
</div>
<v-subheader class="pl-0 py-0" style="height: 20px; font-size: 12px">
Playbook
</v-subheader>
<div class="flex-grow-1 flex-shrink-1 overflow-scroll">
<Editor v-model="playbook.yaml" @input="updatePipeline" lang="yaml" :readonly="readonly"></Editor>
<v-tabs
v-model="tab"
background-color="transparent"
>
<v-tab>Graph (experimental)</v-tab>
<v-tab>YAML</v-tab>
</v-tabs>
<v-tabs-items v-model="tab" style="background: transparent">
<v-tab-item>
<v-text-field
v-model="playbook.name"
label="Name"
outlined
dense
:readonly="readonly"
class="mt-4"
/>
<PlaybookEditor
v-if="playbookJSON"
v-model="playbookJSON" />
</v-tab-item>
<v-tab-item>
<v-card class="py-2">
<Editor v-model="playbookYAML" lang="yaml" :readonly="readonly"></Editor>
</v-card>
</v-tab-item>
</v-tabs-items>
</div>
<v-row v-if="!readonly" class="px-3 my-6 flex-grow-0 flex-shrink-0">
@@ -62,6 +72,7 @@ import Editor from "../components/Editor.vue";
import {alg, Graph} from "graphlib";
import yaml from 'yaml';
import Ajv from "ajv";
import PlaybookEditor from "@/components/playbookeditor/PlaybookEditor.vue";
const playbookSchema = {
type: "object",
@@ -83,7 +94,7 @@ const taskSchema = {
properties: {
automation: { type: "string" },
join: { type: "boolean" },
msg: { type: "object", additionalProperties: { type: "string" } },
payload: { type: "object", additionalProperties: { type: "string" } },
name: { type: "string" },
next: {
type: "object",
@@ -100,8 +111,10 @@ interface State {
playbook?: PlaybookTemplate;
g: Record<string, any>;
selected: any;
pipelineData: any;
error: string;
tab: number;
playbookYAML: string;
playbookJSON: any;
}
interface TaskWithID {
@@ -129,8 +142,8 @@ const inityaml = "name: VirusTotal hash check\n" +
" name: Hash the word\n" +
" type: automation\n" +
" automation: hash.sha1\n" +
" msg:\n" +
" payload: \"playbook.tasks['input'].data['word']\"\n" +
" payload:\n" +
" default: \"playbook.tasks['input'].data['word']\"\n" +
" next:\n" +
" end:\n" +
"\n" +
@@ -140,17 +153,26 @@ const inityaml = "name: VirusTotal hash check\n" +
export default Vue.extend({
name: "Playbook",
components: { Editor },
components: { Editor, PlaybookEditor },
data: (): State => ({
playbook: undefined,
g: {},
selected: undefined,
pipelineData: undefined,
error: "",
tab: 1,
playbookJSON: undefined,
playbookYAML: inityaml
}),
watch: {
'$route': function () {
this.loadPlaybook();
},
tab: function (value) {
if (value === 0) {
this.playbookJSON = yaml.parse(this.playbookYAML);
} else {
this.playbookYAML = yaml.stringify(this.playbookJSON);
}
}
},
computed: {
@@ -198,77 +220,26 @@ export default Vue.extend({
}
return tasks;
},
updatePipeline: function () {
if (this.playbook) {
this.pipeline(this.playbook.yaml);
}
},
pipeline: function(playbookYAML: string) {
try {
let playbook = yaml.parse(playbookYAML);
this.error = "";
let g = new Graph();
for (const stepKey in playbook.tasks) {
g.setNode(stepKey);
}
this.lodash.forEach(playbook.tasks, (task: Task, stepKey: string) => {
if ("next" in task) {
this.lodash.forEach(task.next, (condition, nextKey) => {
g.setEdge(stepKey, nextKey);
});
}
});
let tasks = this.tasks(g, playbook);
let elements = [] as Array<any>;
this.lodash.forEach(tasks, task => {
elements.push({
id: task.id,
name: task.task.name,
next: [],
status: "unknown"
});
});
this.lodash.forEach(tasks, (task: TaskWithID) => {
if ("next" in task.task) {
this.lodash.forEach(task.task.next, (condition, nextKey) => {
let nextID = this.lodash.findIndex(elements, ["id", nextKey]);
let stepID = this.lodash.findIndex(elements, ["id", task.id]);
if (nextID !== -1) {
// TODO: invalid schema
elements[stepID].next.push({index: nextID});
}
});
}
});
this.pipelineData = undefined;
this.$nextTick(() => {
this.pipelineData = this.lodash.values(elements);
})
}
catch (e: unknown) {
console.log(e);
this.error = this.lodash.toString(e);
}
},
save() {
if (this.playbook === undefined) {
return;
}
let playbook = this.playbook;
if (this.tab === 0) {
let jsonData = this.playbookJSON;
jsonData["name"] = playbook.name;
playbook.yaml = yaml.stringify(jsonData);
} else {
playbook.yaml = this.playbookYAML;
}
if (this.$route.params.id == 'new') {
let playbook = this.playbook;
// playbook.id = kebabCase(playbook.name);
API.createPlaybook(playbook).then(() => {
this.$store.dispatch("alertSuccess", { name: "Playbook created" });
});
} else {
API.updatePlaybook(this.$route.params.id, this.playbook).then(() => {
API.updatePlaybook(this.$route.params.id, playbook).then(() => {
this.$store.dispatch("alertSuccess", { name: "Playbook saved" });
});
}
@@ -279,9 +250,13 @@ export default Vue.extend({
}
if (this.$route.params.id == 'new') {
this.playbook = { name: "MyPlaybook", yaml: inityaml }
this.playbookJSON = yaml.parse(this.playbook.yaml);
this.playbookYAML = this.playbook.yaml;
} else {
API.getPlaybook(this.$route.params.id).then((response) => {
this.playbook = response.data;
this.playbookJSON = yaml.parse(this.playbook.yaml);
this.playbookYAML = this.playbook.yaml;
});
}
},
@@ -290,7 +265,7 @@ export default Vue.extend({
return this.lodash.includes(this.$store.state.settings.roles, s);
}
return false;
}
},
},
mounted() {
this.loadPlaybook();

View File

@@ -295,19 +295,13 @@
<v-icon small>mdi-close-circle</v-icon>
</v-btn>
</v-card-subtitle>
<div style="overflow-x: scroll">
<vue-pipeline
v-if="showPipelines"
ref="pipeline"
:x="50"
:y="55"
:data="pipeline(playbook)"
:showArrow="true"
:ystep="70"
:xstep="90"
lineStyle="default"
@select="select"
class="mx-4"
<div style="overflow-x: scroll; text-align: center">
<PlaybookGraph
v-if="playbook"
:playbook="playbook"
horizontal
:scale="0.3"
style="margin: 0 auto"
/>
</div>
<v-list dense color="cards" class="tasks py-0">
@@ -319,7 +313,6 @@
link
@click="selectTask(taskwithid, playbookid)"
>
<!--template v-slot:activator-->
<v-list-item-icon>
<v-icon
:class="{
@@ -863,6 +856,8 @@ import {DateTime} from "luxon";
import VueMarkdown from "vue-markdown";
import JSONHTML from "../components/JSONHTML.vue";
import TicketNew from "@/views/TicketNew.vue";
import yaml from "yaml";
import PlaybookGraph from "@/components/playbookeditor/PlaybookGraph.vue";
interface State {
valid: boolean;
@@ -929,6 +924,7 @@ interface TaskWithID {
export default Vue.extend({
name: "Ticket",
components: {
PlaybookGraph,
TicketNew,
Dashboard,
ArtifactSnippet,
@@ -999,6 +995,9 @@ export default Vue.extend({
}
},
computed: {
yaml() {
return yaml
},
schema: function() {
if (this.ticket !== undefined && this.ticket.schema !== undefined) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any

View File

@@ -99,6 +99,7 @@ export default Vue.extend({
watch: {
'$route': function () {
this.loadUser();
this.newUserResponse = undefined;
}
},
methods: {

File diff suppressed because it is too large Load Diff