Compare commits

...

287 Commits

Author SHA1 Message Date
Jakub P.
d31309a92d test: add delete flow tests 2024-10-16 23:33:43 +02:00
Ali BARIN
0234b4ad81 Merge pull request #2125 from automatisch/aut-1322
test(connection): write model tests
2024-10-16 13:23:17 +02:00
Ömer Faruk Aydın
59ee9c21f3 Merge pull request #2111 from automatisch/aut-1301
test(app): write model tests
2024-10-16 13:17:35 +02:00
Faruk AYDIN
00317fed24 refactor: Use endsWith for app folder path test 2024-10-16 12:56:17 +02:00
Ali BARIN
42f6311ca8 test(app): write model tests 2024-10-16 12:56:17 +02:00
Ali BARIN
0f77a1ec03 test(connection): write model tests 2024-10-16 09:38:48 +00:00
Ali BARIN
8268cd4d09 Merge pull request #2123 from automatisch/aut-1319
test(config): write model tests
2024-10-14 13:28:09 +02:00
Ali BARIN
c868070337 test(config): write model tests 2024-10-14 11:19:29 +00:00
Ömer Faruk Aydın
623ec66a79 Merge pull request #2121 from automatisch/usage-data-tests
test: Implement UsageData model tests
2024-10-10 13:03:09 +02:00
Faruk AYDIN
b51bae14ec test: Implement UsageData model tests 2024-10-10 12:08:41 +02:00
Ömer Faruk Aydın
9250456e7b Merge pull request #2119 from automatisch/execution-step-test
tests: Implement tests for ExecutionStep model
2024-10-09 16:27:39 +02:00
Faruk AYDIN
163d6a7a28 refactor: Do not use persisted instance for execution step is failed 2024-10-09 15:43:33 +02:00
Faruk AYDIN
4ce9976dbc refactor: Use isSucceededNonTestRun naming for execution steps 2024-10-09 15:43:33 +02:00
Faruk AYDIN
f6490990de tests: Implement tests for ExecutionStep model 2024-10-09 15:43:33 +02:00
Ali BARIN
f24ff606ac Merge pull request #2113 from automatisch/AUT-1196
fix: use env var for authDocUrl
2024-10-09 15:15:09 +02:00
Jakub P.
3ff53744b5 fix: use env var for authDocUrl 2024-10-09 15:02:59 +02:00
Ali BARIN
0b33c10ed8 Merge pull request #2029 from automatisch/AUT-1190
fix: limit resetting form on defaultValues change
2024-10-09 14:54:05 +02:00
Ömer Faruk Aydın
3fa87701ed Merge pull request #2114 from automatisch/AUT-929
feat: fix primary app color value and how it is displayed in the app
2024-10-09 11:02:03 +02:00
Ali BARIN
e5e0c6fa2a Merge pull request #2117 from automatisch/aut-1191-2
fix: bring back missing custom logo
2024-10-08 21:54:12 +02:00
Jakub P.
0b38a0b6af fix: bring back missing custom logo 2024-10-08 17:56:13 +00:00
Ömer Faruk Aydın
44b228777a Merge pull request #2093 from automatisch/aut-1191
feat(config): make data structure horizontal
2024-10-08 18:15:33 +02:00
Ali BARIN
dd4f658d14 test: cover static config in config controller test 2024-10-08 14:41:02 +00:00
Ali BARIN
9c66f47bca test: write config serializer cases 2024-10-08 14:34:14 +00:00
Ali BARIN
138a34d6a4 feat(config): incorporate static config as virtual attributes 2024-10-08 14:19:17 +00:00
Ali BARIN
8f2af2e863 chore: rename horizontal config migration as make_config_single_record 2024-10-08 14:18:38 +00:00
Ali BARIN
c732fe16b3 refactor(update-config): introduce updateFirstOrInsert via query builder 2024-10-08 13:18:42 +00:00
Ali BARIN
9be75e56e7 refactor(migration): simplify make_config_horizontal_scale script 2024-10-08 13:18:42 +00:00
Ali BARIN
e7d1f26034 feat(serializers): add config serializer 2024-10-08 13:18:42 +00:00
Ali BARIN
c554fff048 feat(config): add missing schema properties 2024-10-08 13:18:42 +00:00
Ali BARIN
0268521aaa test(config): fix typo in palette primary light 2024-10-08 13:18:42 +00:00
Ali BARIN
89b1cb9353 feat(web): adapt to horizontal config structure 2024-10-08 13:18:42 +00:00
Ali BARIN
8a17c5eaab feat(config): make data structure horizontal 2024-10-08 13:18:42 +00:00
Ömer Faruk Aydın
f4a1ad6c8c Merge pull request #2109 from automatisch/aut-1292
test(app-auth-client): write model tests
2024-10-08 15:09:41 +02:00
Jakub P.
93d76d8d79 feat: add hash in color to the examples in docs 2024-10-07 16:39:51 +02:00
Ali BARIN
0b956a71b9 test(models/app-auth-client): improve decrypt data test cases 2024-10-07 13:25:04 +00:00
Faruk AYDIN
26be72f76d test: Improve encrypt data tests for AppAuthClient model 2024-10-07 14:21:14 +02:00
Ali BARIN
737391c721 test(app-auth-client): write model tests 2024-10-07 09:14:18 +00:00
kasia.oczkowska
9c1d21fd1b feat: fix primary app color value and how it is displayed in the app 2024-10-04 12:34:50 +01:00
kasia.oczkowska
ef4a4c8611 fix: limit resetting form on defaultValues change 2024-10-04 11:46:12 +01:00
Ömer Faruk Aydın
13c0a8ceaa Merge pull request #2112 from automatisch/test-subscription
test: Implement subscription model tests
2024-10-02 13:53:46 +03:00
Faruk AYDIN
c2976080f6 test: Implement subscription model tests 2024-10-02 13:44:21 +03:00
Faruk AYDIN
0a1b6931af test: Add tests for Identity model 2024-10-02 10:52:05 +03:00
Ömer Faruk Aydın
5009319f91 Merge pull request #2108 from automatisch/aut-1282
test(access-token): write model tests
2024-10-02 10:16:49 +03:00
Ali BARIN
4db8683bd6 test(access-token): write model tests 2024-10-01 10:37:43 +00:00
Ali BARIN
d35cf8d31e test: add access token factory 2024-10-01 09:55:36 +00:00
Ali BARIN
5fef16131a test: add identity factory 2024-10-01 09:55:26 +00:00
Ömer Faruk Aydın
8b2235ee26 Merge pull request #2107 from automatisch/execution-tests
test: Implement execution model tests
2024-09-30 17:33:28 +03:00
Faruk AYDIN
2d8faf849e test: Implement execution model tests 2024-09-30 17:25:15 +03:00
Ali BARIN
c9de9fa185 Merge pull request #2096 from automatisch/aut-1276
test(SamlAuthProvidersRoleMapping): assert model properties
2024-09-30 16:24:46 +02:00
Ali BARIN
0618877d58 test(models/saml-auth-providers-role-mapping): assert model properties 2024-09-30 14:14:02 +00:00
Ömer Faruk Aydın
f6b4e7eef8 Merge pull request #2095 from automatisch/datastore-tests
feat: Implement datastore model tests
2024-09-30 17:12:11 +03:00
Faruk AYDIN
7abe44da19 refactor: Use matchsnapshot for datastore tests 2024-09-30 16:43:06 +03:00
Faruk AYDIN
9006a0c25f refactor: Update required validations with custom assertion 2024-09-30 16:39:06 +03:00
Faruk AYDIN
f8389ff8ab feat: Implement datastore model tests 2024-09-30 16:39:06 +03:00
Ömer Faruk Aydın
894afe8f92 Merge pull request #2104 from automatisch/remove-gql
refactor: remove whole graphql implementation
2024-09-30 15:14:14 +03:00
Ali BARIN
115394ac8c test(helpers/authentication): bring back applicable tests 2024-09-30 12:04:58 +00:00
Ali BARIN
de42eda65f refactor(helpers/authentication): remove obsolete arguments in isAuthenticated 2024-09-30 12:04:37 +00:00
Ali BARIN
0b7591edce refactor: remove whole graphql implementation 2024-09-30 12:02:25 +00:00
Ömer Faruk Aydın
a043a044ca Merge pull request #2099 from automatisch/aut-1262
feat: use REST API endpoints to create and reconnect connections
2024-09-30 13:33:52 +03:00
Ali BARIN
b1f2727beb test(create-dynamic-data): use 422 for error response 2024-09-30 08:25:56 +00:00
Ali BARIN
d6e78a48a0 feat(AddAppConnection): show meaningful error messages only 2024-09-30 08:25:56 +00:00
Ali BARIN
589fe0f5f3 feat(useAuthenticateApp): remove redundant graphql implementation 2024-09-30 08:25:56 +00:00
Ali BARIN
244eeeb816 feat(useAuthenticateApp): centralize invalidating queries 2024-09-30 08:25:56 +00:00
kasia.oczkowska
4d5fc50f1a feat: refactor verify connection mutation with the REST API endpoint 2024-09-30 08:25:54 +00:00
Ali BARIN
dc0273148c chore: remove redundant reset connection mutation 2024-09-30 08:25:09 +00:00
Ali BARIN
5e6f4bfb88 feat(useAuthenticateApp): use REST API endpoint to reset connection 2024-09-30 08:24:03 +00:00
Ali BARIN
bc0e18d074 chore: remove redundant update connection mutation 2024-09-30 08:24:02 +00:00
Ali BARIN
24d09fda4c feat(useAuthenticateApp): use REST API endpoint to update connection 2024-09-30 08:23:29 +00:00
Ali BARIN
5e20ac07d1 chore(add-authentication-steps): remove unnecessary id arguments 2024-09-30 08:23:29 +00:00
Ali BARIN
37c78e6bbd chore: remove redundant generate auth url mutation 2024-09-30 08:23:26 +00:00
Ali BARIN
7dcfb1081b feat(useAuthenticateApp): use REST API endpoint to create auth url 2024-09-30 08:23:00 +00:00
Ali BARIN
01407cf040 Merge pull request #2106 from automatisch/AUT-1265
feat: refactor update-current-user mutation with the REST API endpoint
2024-09-30 10:11:22 +02:00
Jakub P.
eb814c2fb0 test: add reset password tests 2024-09-27 23:16:16 +02:00
kasia.oczkowska
d3caadf4af feat: refactor update-current-user mutation with the REST API endpoint 2024-09-27 13:42:58 +01:00
Ali BARIN
5769c82fca Merge pull request #2098 from automatisch/aut-1258
feat(useAuthenticateApp): use REST API endpoint to create connection
2024-09-25 10:03:57 +02:00
Ali BARIN
3754783ce2 Merge pull request #2103 from automatisch/AUT-1279
test: add change own user data test
2024-09-24 21:25:41 +02:00
Jakub P.
55ebe2cc0b test: add change own user data test 2024-09-24 18:42:30 +02:00
Ali BARIN
23c1a42163 chore: remove redundant create connection mutation 2024-09-24 08:31:26 +00:00
Ali BARIN
c879ffa768 feat(useAuthenticateApp): use REST API endpoint to create connection 2024-09-24 08:30:53 +00:00
Ali BARIN
32f7bbfbab chore: remove redundant execute flow mutation 2024-09-24 10:23:33 +02:00
Ali BARIN
84d5b3b158 feat: use REST API endpoint to test step 2024-09-24 10:23:33 +02:00
Ömer Faruk Aydın
c8dae9ea9a Merge pull request #2097 from automatisch/to-require-property
feat: Introduce toRequireProperty custom assertion
2024-09-23 16:24:01 +03:00
Faruk AYDIN
cbfb5dd8a6 feat: Introduce toRequireProperty custom assertion 2024-09-23 16:16:13 +03:00
Jakub P.
09b2b7350c test: add applications settings tests 2024-09-20 13:03:22 +02:00
Ömer Faruk Aydın
e146793d32 Merge pull request #2091 from automatisch/aut-1216
feat: use REST API endpoint to update user
2024-09-20 13:32:38 +03:00
Faruk AYDIN
0bad2ead10 chore: Fix typo for useAdminUpdateUser hook 2024-09-20 13:11:46 +03:00
Jakub P
25176884e7 fix: add missing snackbar on user update error 2024-09-20 13:11:43 +03:00
Ali BARIN
266d4cddb0 chore: remove redundant update user mutation 2024-09-20 13:10:42 +03:00
Ali BARIN
6e529a4205 feat: use REST API endpoint to update user 2024-09-20 13:09:46 +03:00
Ömer Faruk Aydın
d2cce278bd Merge pull request #2089 from automatisch/aut-1266
feat: use REST API endpoint to update flow status
2024-09-19 14:10:44 +03:00
Jakub P.
b774a62f8c fix: add missing snackbars on flow status update 2024-09-19 14:03:45 +03:00
Ali BARIN
66c12e1a92 chore: remove redundant update flow status mutation 2024-09-19 14:03:43 +03:00
Ali BARIN
184d748890 feat: use REST API endpoint to update flow status 2024-09-19 14:02:51 +03:00
Ömer Faruk Aydın
8cc732c8d1 Merge pull request #2085 from automatisch/aut-1259
feat: use REST API endpoint to create user
2024-09-19 13:58:13 +03:00
Faruk AYDIN
c688d67e4b feat: Implement admin user serializer test 2024-09-19 13:51:04 +03:00
Jakub P.
3408be2840 test: search for proper snackbar on user create error 2024-09-19 13:50:11 +03:00
Ali BARIN
e126066132 chore: remove redundant create user mutation 2024-09-19 13:50:09 +03:00
Ali BARIN
cfec447d8a feat(web): use REST API endpoint to create user 2024-09-19 13:49:12 +03:00
Ali BARIN
805d1fdd52 fix(useAdminCreateRole): correct query in invalidation 2024-09-19 13:49:12 +03:00
Ali BARIN
9299948072 feat: add admin user serializer with accept invitation url 2024-09-19 13:49:12 +03:00
Ömer Faruk Aydın
b02960a5ec Merge pull request #2083 from automatisch/aut-1257
feat: write and implement REST API endpoint to update step
2024-09-19 13:40:57 +03:00
Ali BARIN
8134b6db6a refactor(update-step): move connection authorization to model 2024-09-19 13:31:33 +03:00
Ali BARIN
cd16a3cc15 chore: remove redundant update step mutation 2024-09-19 13:31:31 +03:00
Ali BARIN
074e7828f3 feat(web): use REST API endpoint to update step 2024-09-19 13:30:45 +03:00
Ali BARIN
5f7d1f9219 feat: write REST API endpoint to update step 2024-09-19 13:30:45 +03:00
Ömer Faruk Aydın
b29c6105a1 Merge pull request #2088 from automatisch/aut-1213
feat: use REST API endpoint to delete step
2024-09-19 13:15:26 +03:00
Ali BARIN
1297f5d43c chore: remove redundant delete step mutation 2024-09-19 13:08:19 +03:00
Ali BARIN
f94a5385d7 feat: use REST API endpoint to delete step 2024-09-19 13:07:37 +03:00
Ömer Faruk Aydın
8ef2000e45 Merge pull request #2087 from automatisch/aut-1261
feat: use REST API endpoint to delete flow
2024-09-19 13:06:48 +03:00
Ali BARIN
30d496076b chore: remove redundant delete flow mutation 2024-09-19 12:37:47 +03:00
Ali BARIN
5de06d4482 feat: use REST API endpoint to delete flow 2024-09-19 12:36:59 +03:00
Ömer Faruk Aydın
97fa983305 Merge pull request #2086 from automatisch/aut-1260
feat: use REST API endpoint to delete current user
2024-09-19 12:34:35 +03:00
Ali BARIN
dccc3c5bc1 chore: remove redundant delete current user mutation 2024-09-19 12:27:28 +03:00
Ali BARIN
ed12465975 feat: use REST API endpoint to delete current user 2024-09-19 12:25:58 +03:00
Ömer Faruk Aydın
b78be222d7 Merge pull request #2084 from automatisch/aut-1228
feat: use REST API endpoint to create flow
2024-09-19 12:22:33 +03:00
Ali BARIN
342990e1bf chore: remove redundant create flow mutation 2024-09-18 14:53:06 +00:00
Ali BARIN
2e5dfdbb0d feat: use REST API endpoint to create flow 2024-09-18 14:51:23 +00:00
Faruk AYDIN
1790ef0ee6 feat: Implement update flow status rest API endpoint 2024-09-17 16:07:12 +03:00
Ömer Faruk Aydın
712a5756e2 Merge pull request #2070 from automatisch/aut-1248
feat: write and implement REST API endpoint to duplicate flow
2024-09-17 14:11:27 +03:00
Faruk AYDIN
bf6ff6b0f7 refactor: Revise duplicate flow controller tests 2024-09-17 13:18:48 +03:00
Faruk AYDIN
c6003b6695 fix: Correct duplicate flow mock name 2024-09-17 13:05:23 +03:00
Ali BARIN
8352540fcb chore: remove redundant duplicate flow mutation 2024-09-17 12:50:54 +03:00
Ali BARIN
22299868fa feat: use REST API endpoint to duplicate flow 2024-09-17 12:49:16 +03:00
Ali BARIN
0d126a8e2b feat: write REST API endpoint to duplicate flow 2024-09-17 12:49:13 +03:00
Ömer Faruk Aydın
776d027dfa Merge pull request #2081 from automatisch/rest-create-user
feat: Implement rest API endpoint for admins to create user
2024-09-17 12:45:08 +03:00
Faruk AYDIN
fa9b6d1006 chore: Mark create user mutation as converted mutation 2024-09-17 11:42:29 +03:00
Faruk AYDIN
89aa7ffc73 feat: Implement rest API endpoint for admins to create user 2024-09-17 11:41:18 +03:00
Faruk AYDIN
fd971449ca chore: Mark update connection as converted mutation 2024-09-16 13:39:44 +03:00
Ömer Faruk Aydın
f7cd57e549 Merge pull request #2080 from automatisch/rest-update-connection
feat: Implement rest API endpoint to update connection
2024-09-16 13:38:43 +03:00
Faruk AYDIN
34aadbfb09 feat: Implement rest API endpoint to update connection 2024-09-16 12:55:39 +03:00
Ömer Faruk Aydın
167195a01c Merge pull request #2077 from automatisch/rest-reset-connection
refactor: Move reset logic to connection model
2024-09-15 14:01:56 +03:00
Faruk AYDIN
b0abf94191 refactor: Move reset logic to connection model 2024-09-15 01:03:17 +03:00
Faruk AYDIN
1009c71e72 chore: Move reset connection to converted mutations 2024-09-15 01:02:58 +03:00
Ömer Faruk Aydın
29b1695159 Merge pull request #2076 from automatisch/rest-delete-flow
feat: Implement rest API endpoint to delete flow
2024-09-15 00:19:45 +03:00
Faruk AYDIN
44f782221f chore: Mark delete flow as converted mutation 2024-09-15 00:11:15 +03:00
Faruk AYDIN
bab25c51d9 feat: Implement rest API endpoint to delete flow 2024-09-14 21:54:10 +03:00
Ömer Faruk Aydın
89277e1665 Merge pull request #2075 from automatisch/converted-mutations
chore: Mark create connection as converted mutation
2024-09-14 00:46:07 +03:00
Faruk AYDIN
1e9c5a1682 chore: Mark create connection as converted mutation 2024-09-14 00:27:09 +03:00
Ömer Faruk Aydın
0c75486c7a Merge pull request #2073 from automatisch/aut-1251
feat: write REST API endpoint to generate auth url
2024-09-12 14:05:39 +03:00
Faruk AYDIN
8c39739880 refactor: Use getApp method for generateAuthUrl method of connection 2024-09-12 13:58:23 +03:00
Ali BARIN
ace1f84094 feat: write REST API endpoint to generate auth url 2024-09-12 13:57:25 +03:00
Ömer Faruk Aydın
2cfd6739ca Merge pull request #2068 from automatisch/aut-1242
feat: write REST API endpoint to create connection
2024-09-12 13:51:37 +03:00
Faruk AYDIN
e0d6f0d653 refactor: Fetch role and permissions for current user in create connection tests 2024-09-12 13:41:16 +03:00
Faruk AYDIN
a4d3b387d0 refactor: Add extra empty line for create connection test block 2024-09-12 13:35:00 +03:00
Ali BARIN
7394aca02d feat: write REST API endpoint to create connection 2024-09-12 13:33:38 +03:00
Ömer Faruk Aydın
e812725182 Merge pull request #2072 from automatisch/aut-1249
feat: write and implement REST API endpoint to register user
2024-09-12 13:26:12 +03:00
Faruk AYDIN
bb76bfcd8b fix: Typo for register user tests 2024-09-12 13:19:01 +03:00
Ali BARIN
6ff6d0a7dc fix(register-user): correct trial expiry date 2024-09-12 13:19:01 +03:00
Ali BARIN
ddc9867058 chore: remove redundant register user mutation 2024-09-12 13:19:01 +03:00
Ali BARIN
ba0d46c6cd feat(web): use REST API endpoint to register user 2024-09-12 13:19:01 +03:00
Ali BARIN
369f04fdbc feat: write REST API endpoint to register user 2024-09-12 13:19:01 +03:00
Ömer Faruk Aydın
09dd8abe23 Merge pull request #2069 from automatisch/rest-update-password
feat: Implement rest API endpoint to update current user password
2024-09-12 13:10:22 +03:00
Faruk AYDIN
8c692758ae chore: Remove redundant only flag for tests 2024-09-12 13:01:49 +03:00
Faruk AYDIN
32d39b88bd feat: Ask for current password while updating user password 2024-09-12 12:54:46 +03:00
Faruk AYDIN
8bd66da511 chore: Move update current user mutation to converted ones 2024-09-11 12:51:32 +03:00
Faruk AYDIN
f86799e494 feat: Implement rest API endpoint to update current user password 2024-09-11 12:51:32 +03:00
Jakub P.
8d10f26f56 test: add pop-up notification test 2024-09-10 17:40:34 +02:00
Ali BARIN
297543f9dd feat(useAuthenticateApp): early exit connection creation at blocked pop-up 2024-09-10 17:40:34 +02:00
Ali BARIN
0c53ee8460 feat(AddAppConnection): show pop-up reminder hint 2024-09-10 17:40:34 +02:00
Ömer Faruk Aydın
862842e3e1 Merge pull request #2064 from automatisch/aut-1237
feat: write and implement REST API endpoint to delete role
2024-09-10 17:19:55 +03:00
Ali BARIN
a4fad360df Merge pull request #2066 from automatisch/aut-1240
feat: write and implement REST API endpoint to create step
2024-09-10 14:31:12 +02:00
Ali BARIN
3ba4c8b3bf chore(EditorNew): remove console log 2024-09-10 10:50:11 +00:00
Ali BARIN
2992236be4 test(create-step): make current and another user explicit 2024-09-10 10:35:19 +00:00
Ali BARIN
82161f028e test(create-step): state permission conditions explicitly 2024-09-10 10:21:42 +00:00
Ali BARIN
1bcaec144b test(create-step): use non-admin user 2024-09-10 10:15:59 +00:00
Ali BARIN
852d4bba0a chore: remove redundant create step mutation 2024-09-10 10:12:59 +00:00
Ali BARIN
af56fa2830 feat(Editor): use REST API endpoint to create step 2024-09-10 10:12:59 +00:00
Ali BARIN
813646e392 feat: write REST API endpoint to create step 2024-09-10 10:12:59 +00:00
Ali BARIN
1ce31eefc6 Merge pull request #2057 from automatisch/aut-1226
feat: write endpoint to update SamlAuthProvidersRoleMappings
2024-09-10 12:09:00 +02:00
Ali BARIN
fdf53844e1 test(update-role-mappings): use name over key 2024-09-10 10:00:40 +00:00
Ali BARIN
be57a82302 test(factories/role): re-create different role if it exists 2024-09-10 09:56:15 +00:00
Ali BARIN
fb82e863e0 test(update-role-mappings): correct the test case name 2024-09-10 09:50:54 +00:00
Ali BARIN
101483409f style(update-role-mappings): add a breakline 2024-09-10 09:50:54 +00:00
Ali BARIN
6fe863eec1 test(update-role-mappings): use explicit remote role name 2024-09-10 09:50:54 +00:00
Ali BARIN
fbb6526aac refactor(update-role-mappings): move logic to model 2024-09-10 09:50:54 +00:00
Ali BARIN
5556aea913 chore: remove upsert-saml-auth-providers-role-mappings mutation 2024-09-10 09:50:54 +00:00
Ali BARIN
95dc5fb849 refactor(RoleMappings): rewrite mutations with REST API endpoints 2024-09-10 09:50:53 +00:00
Ali BARIN
062199d0e3 feat: write endpoints to update SamlAuthProvidersRoleMappings 2024-09-10 09:50:53 +00:00
Ali BARIN
53ce327516 Merge pull request #2060 from automatisch/aut-1233
feat: write and implement REST API endpoint to update role
2024-09-10 11:35:52 +02:00
Ali BARIN
61a1ce57c2 refactor(useAdminDeleteRole): remove redundant invalidateQueries 2024-09-06 09:52:03 +00:00
Jakub P.
687295f772 test: update roles related snackbar locator 2024-09-06 09:51:22 +00:00
Ali BARIN
e5366534ed chore: remove redundant delete role mutation 2024-09-06 09:51:22 +00:00
Ali BARIN
66fe84e126 feat(DeleteRoleButton): use REST API endpoint to delete role 2024-09-06 09:51:22 +00:00
Ali BARIN
0b6c28422c feat: write REST API endpoint to delete role 2024-09-06 09:51:22 +00:00
Ali BARIN
ea667bb6a9 refactor(useAdminUpdateRole): remove redundant invalidateQueries 2024-09-06 09:26:34 +00:00
Ali BARIN
c9ba219de1 chore: remove redundant update role mutation 2024-09-05 15:35:44 +00:00
Ali BARIN
9df1b29d70 feat(EditRole): use REST API endpoint to update role 2024-09-05 15:35:44 +00:00
Ali BARIN
3e34359fa9 feat: write REST API endpoint to update role 2024-09-05 15:35:44 +00:00
Ali BARIN
1818930d2f Merge pull request #2059 from automatisch/aut-1229
feat: write and implement REST API endpoint to create role
2024-09-05 17:35:19 +02:00
Ali BARIN
c03e674001 chore: add isAdmin virtual attribute in role model 2024-09-05 12:15:37 +00:00
Ali BARIN
10a25b82e0 chore(migrations/remove_key_column_in_roles): use arrow functions 2024-09-05 12:13:33 +00:00
Ömer Faruk Aydın
3b2489d738 Merge pull request #2062 from automatisch/fix-trigger-type-problem
fix: Throw error if trigger doesn't have a type
2024-09-05 13:51:37 +03:00
Faruk AYDIN
5c4ca3c84f fix: Add missing pollInverval keys for triggers 2024-09-05 13:40:44 +03:00
Faruk AYDIN
06c4b7ed2e fix: Throw error if trigger doesn't have a type 2024-09-05 13:32:19 +03:00
Ali BARIN
5591f6ccc9 fix(migrations): backfill role.key column in down migration 2024-09-04 11:30:39 +00:00
Ali BARIN
63dfb6947e feat: make role name unique and remove key usage 2024-09-04 11:13:39 +00:00
Ali BARIN
b089069b8e test: use faker in role factory 2024-09-03 14:18:14 +00:00
Ali BARIN
e76a99fd68 chore: remove redundant create role mutation 2024-09-03 13:56:23 +00:00
Ali BARIN
a4ea6c1fad refactor(CreateRole): implement REST API endpoint to create role 2024-09-03 13:56:06 +00:00
Ali BARIN
64ebdce1b2 feat: write migration to make roles unique by key 2024-09-03 13:55:28 +00:00
Ali BARIN
2709491d59 feat: write REST API endpoint to create role 2024-09-03 13:55:18 +00:00
Ömer Faruk Aydın
81beedede6 Merge pull request #2058 from automatisch/rest-delete-current-user
feat: Implement rest API endpoint to remove current user
2024-09-03 16:13:37 +03:00
Faruk AYDIN
33a2386d74 feat: Remove associated access tokens while removing user 2024-09-03 16:03:48 +03:00
Faruk AYDIN
0df5e5283e refactor: Remove user associations before removing user 2024-09-03 16:00:24 +03:00
Faruk AYDIN
560407b972 chore: Comment delete current user mutations as converted 2024-09-03 15:51:55 +03:00
Faruk AYDIN
f8c25ae508 feat: Implement rest API endpoint to remove current user 2024-09-03 15:50:44 +03:00
Ali BARIN
c524277665 Merge pull request #2054 from automatisch/aut-1224
Split UpsertSamlAuthProvider mutation into two endpoints
2024-09-03 11:42:05 +02:00
Ömer Faruk Aydın
a70fb009c7 Merge pull request #2055 from automatisch/rest-test-step
feat: Implement rest api endpoint to test step
2024-09-02 15:22:10 +03:00
Ömer Faruk Aydın
11e67f2ea3 Merge pull request #2056 from automatisch/rest-create-flow
feat: Implement create flow rest API endpoint
2024-09-02 15:21:46 +03:00
Faruk AYDIN
e7118ffe15 chore: Comment create flow mutation as converted 2024-09-02 15:03:59 +03:00
Faruk AYDIN
79e9455244 feat: Implement create flow rest API endpoint 2024-09-02 15:01:20 +03:00
Faruk AYDIN
6ca8e8958a feat: Implement rest api endpoint to test step 2024-09-02 14:00:31 +03:00
Faruk AYDIN
d3dc207166 feat: Extend step serializer with last execution step 2024-09-02 14:00:31 +03:00
Faruk AYDIN
51e200533b feat: Introduce lastExecutionStep relation to Step model 2024-09-02 14:00:31 +03:00
Ali BARIN
b8a25b87d8 Merge pull request #2053 from automatisch/webhook-tests-improvements
test: add wait for response on update flow
2024-09-02 10:04:47 +02:00
Ali BARIN
f4fe0a0d4f refactor(SamlConfiguration): rewrite mutations with REST API endpoints 2024-08-30 11:46:35 +00:00
Ali BARIN
1d4f829d29 chore: remove upsert-saml-auth-provider mutation 2024-08-30 11:46:06 +00:00
Ali BARIN
4afa79fca4 feat: write endpoitns to create and update SamlAuthProvider 2024-08-30 10:56:56 +00:00
Jakub P.
ec22184087 test: add wait for substeps response 2024-08-30 12:53:35 +02:00
Ali BARIN
413f3db5b4 test(update-flow): align user role permissions 2024-08-30 11:07:52 +02:00
Ali BARIN
8ddfcce787 chore: remove update-flow mutation 2024-08-30 11:07:52 +02:00
Ali BARIN
562341adfe refactor(web): rewrite mutation with PATCH /v1/flows/:flowId 2024-08-30 11:07:52 +02:00
Ali BARIN
9519ec53ef feat: write PATCH /v1/flows/:flowId 2024-08-30 11:07:52 +02:00
Ali BARIN
35bada360d refactor(update-config): move logic to config model 2024-08-30 11:07:44 +02:00
Ali BARIN
1f39765efe chore: remove update-config mutation 2024-08-30 11:07:44 +02:00
Ali BARIN
cce5b3b533 refactor(web): rewrite mutation with PATCH /v1/admin/config 2024-08-30 11:07:44 +02:00
Ali BARIN
e77a03b855 feat: write PATCH /v1/admin/config 2024-08-30 11:07:44 +02:00
Ali BARIN
7a54ff212e feat: incorporate NotAuthorized error in error handler 2024-08-30 10:23:28 +02:00
Ali BARIN
01340f4597 chore: remove redundant update-app-config mutation 2024-08-29 15:31:50 +02:00
Ali BARIN
af6fa80d20 test(reset-connection): cover formattedData with DB changes 2024-08-29 11:20:09 +02:00
Ali BARIN
e7474dcb9e refactor(reset-connection): streamline patches 2024-08-29 11:20:09 +02:00
Ali BARIN
0eb906d5df test(reset-connection): remove unnecessary read connection permission 2024-08-29 11:20:09 +02:00
Ali BARIN
c7babf227c feat: write POST /v1/connections/:connectionId/reset 2024-08-29 11:20:09 +02:00
Ali BARIN
d5c81c14f5 fix(FlowAppIcons): fix crash when no steps exist 2024-08-29 10:44:50 +02:00
Ali BARIN
59278378e5 chore: remove delete-connection mutation 2024-08-29 09:26:24 +02:00
Ali BARIN
990e69143d refactor(web): rewrite mutation with DELETE /v1/connections/:connectionId 2024-08-29 09:26:24 +02:00
Ali BARIN
c413ae06dc feat: write DELETE /v1/connections/:connectionId 2024-08-29 09:26:24 +02:00
Ali BARIN
456f8a30cc test(update-app-config): correct test case name 2024-08-29 09:26:16 +02:00
Ali BARIN
19c4561feb chore: remove update-app-config mutation 2024-08-29 09:26:16 +02:00
Ali BARIN
1392fed023 refactor(web): rewrite mutation with PATCH /v1/admin/apps/:appKey/config 2024-08-29 09:26:16 +02:00
Ali BARIN
ca81e14d63 feat: write PATCH /v1/admin/apps/:appKey/config 2024-08-29 09:26:16 +02:00
Ömer Faruk Aydın
8e7a8a02ec Merge pull request #2045 from automatisch/rest-admin-update-user
feat: Implement rest API endpoint to update users for admin
2024-08-28 18:07:24 +03:00
Faruk AYDIN
e45dfa94ed fix: Use updateUserMock instead of updateCurrentUserMock for admin API endpoint 2024-08-28 17:55:06 +03:00
Faruk AYDIN
a153787ae6 chore: Use patch instead of get for update user tests 2024-08-28 17:54:15 +03:00
Faruk AYDIN
cf37c43bc7 chore: Add update user mutation to converted mutations 2024-08-28 17:50:06 +03:00
Faruk AYDIN
d0aa2bca69 feat: Implement rest API endpoint to update users for admin 2024-08-28 17:49:38 +03:00
Ömer Faruk Aydın
7b3811e6ee Merge pull request #2044 from automatisch/rest-update-user
feat: Implement update user rest API endpoint
2024-08-28 17:21:54 +03:00
Faruk AYDIN
4054f551d4 feat: Implement update user rest API endpoint 2024-08-28 17:07:13 +03:00
Ömer Faruk Aydın
4eeda10f3f Merge pull request #2041 from automatisch/remove-redundant-async-handler-wrapper
fix: remove redundant asyncHandler wrapper
2024-08-28 12:38:36 +03:00
Ali BARIN
4231784ed2 fix: remove redundant asyncHandler wrapper 2024-08-28 09:20:30 +00:00
Ali BARIN
61ff6986d3 test(update-auth-client): cover HTTP 422 response 2024-08-28 11:16:46 +02:00
Ali BARIN
09bc0bba1e refactor(web): rewrite mutation with PATCH /v1/admin/apps/:appKey/auth-clients/:appAuthClientId 2024-08-28 11:16:46 +02:00
Ali BARIN
b2bda8479e feat: write PATCH /v1/admin/apps/:appKey/auth-clients/:appAuthClientId 2024-08-28 11:16:46 +02:00
Ömer Faruk Aydın
09b255f99e Merge pull request #2037 from automatisch/refactor-async-errors
refactor: Use express-async-errors instead of express-async-handler
2024-08-28 12:13:22 +03:00
Ali BARIN
0800642a2a refactor(create-config): move unique violation error handling to error-handler 2024-08-28 10:32:06 +02:00
Ali BARIN
48b2b006c0 refactor(web): rewrite mutation with POST /v1/admin/apps/:appKey/config 2024-08-28 10:32:06 +02:00
Ali BARIN
af4c1f08ec feat: write POST /v1/admin/apps/:key/config 2024-08-28 10:32:06 +02:00
Ali BARIN
87b26b6342 fix(app-config): add missing createdAt updatedAt fields in schema 2024-08-28 10:32:06 +02:00
Ali BARIN
706fb8d82f chore(backend): add test:watch script 2024-08-28 10:32:06 +02:00
Faruk AYDIN
f7ca59bd5f refactor: Use express-async-errors instead of express-async-handler 2024-08-28 11:10:31 +03:00
Ali BARIN
6540d0ea53 fix(AdminApplicationCreateAuthClient): correct typo in auth word 2024-08-27 16:34:09 +02:00
Ali BARIN
5995038e21 fix(error-handler): use HTTP 422 for validation errors 2024-08-27 16:34:09 +02:00
Ali BARIN
337ba6ea87 test(create-auth-client): cover error handler 2024-08-27 16:34:09 +02:00
Ali BARIN
04c6183752 refactor(create-auth-client): accept only auth client schema fields 2024-08-27 16:34:09 +02:00
Ali BARIN
0b63922f46 feat: map and expose objection.js errors 2024-08-27 16:34:09 +02:00
Ali BARIN
81c39d7d93 refactor: rewrite create-app-auth-client mutation as REST endpoint 2024-08-27 16:34:09 +02:00
Ömer Faruk Aydın
164d31dfbc Merge pull request #2034 from automatisch/rest-verify-connection-api
feat: Implement rest API endpoint to verify connection
2024-08-27 15:11:53 +03:00
Faruk AYDIN
1a833aad52 feat: Implement rest API endpoint to verify connection 2024-08-27 14:51:28 +03:00
Ömer Faruk Aydın
77246c1fde Merge pull request #2033 from automatisch/refactor-test-connection
Refactor test connection action
2024-08-26 16:35:16 +03:00
Faruk AYDIN
56c08a3587 fix: Solve truncate deadlock problem for test suite 2024-08-26 16:26:29 +03:00
Faruk AYDIN
ce6214dc0f refactor: Rename create test action as test connection 2024-08-26 16:26:03 +03:00
Faruk AYDIN
22002d50ac chore: Comment converted graphQL mutations 2024-08-26 16:01:15 +03:00
Ali BARIN
ab4e94695d Merge pull request #2030 from automatisch/AUT-1132
fix: prevent resetting test data until data is loaded
2024-08-26 11:37:37 +02:00
Ömer Faruk Aydın
47a01cec7e Merge pull request #2032 from automatisch/rest-delete-step
feat: Implement delete step rest API endpoint
2024-08-23 17:44:23 +03:00
Faruk AYDIN
0cf9bc1a32 feat: Implement delete step rest API endpoint 2024-08-23 16:55:44 +03:00
kasia.oczkowska
6552ebcd3c fix: prevent resetting test data until data is loaded 2024-08-23 13:07:05 +01:00
Ali BARIN
5af1d94fc0 Merge pull request #2028 from automatisch/AUT-1183
feat: update step only when data changes
2024-08-22 16:22:16 +02:00
Ali BARIN
a4ec7b3047 feat(compute-parameters): add valueType with parse option and string by default (#2025)
* feat(compute-parameters): add valueType with parse option and string by default

* test(compute-parameters): write tests for valueType with parse and undefined

* fix(compute-parameters): cover valueType = parse in nested objects

* test(compute-parameters): cover valueType = 'parse' in nested non-primitives

* fix(compute-parameters): mark fields optional
2024-08-22 16:20:18 +02:00
Ali BARIN
66f5003d91 Merge pull request #2027 from automatisch/harden-webhook-tests
test: harden webhook tests
2024-08-22 16:19:51 +02:00
kasia.oczkowska
0c754e4b4b feat: update step only when data changes 2024-08-22 11:57:25 +01:00
Jakub P.
e008087c4a test: harden webhook tests 2024-08-22 12:05:52 +02:00
Ali BARIN
53f63996bd Merge pull request #2024 from kuba618/AUT-1186
test: add simple webhook flow test
2024-08-22 11:16:22 +02:00
Ali BARIN
4fedf77991 Merge pull request #2026 from automatisch/aut-1187
refactor(compute-parameters): rewrite logic
2024-08-22 10:18:49 +02:00
Ali BARIN
34331d8763 refactor(compute-parameters) rename functions and variables 2024-08-21 11:35:09 +00:00
Jakub P.
2c21b7762c test: add simple webhook flow test 2024-08-20 19:17:08 +02:00
Ömer Faruk Aydın
7f9c2b687f Merge pull request #2022 from automatisch/use-objects-as-variables
feat(PowerInput): support whole objects as variables
2024-08-19 14:21:52 +03:00
Ali BARIN
b452ed648c feat(PowerInput): support whole objects as variables 2024-08-16 13:22:31 +00:00
465 changed files with 12171 additions and 4299 deletions

View File

@@ -12,6 +12,9 @@ on:
workflow_dispatch:
env:
BULLMQ_DASHBOARD_USERNAME: root
BULLMQ_DASHBOARD_PASSWORD: sample
ENABLE_BULLMQ_DASHBOARD: true
ENCRYPTION_KEY: sample_encryption_key
WEBHOOK_SECRET_KEY: sample_webhook_secret_key
APP_SECRET_KEY: sample_app_secret_key
@@ -22,6 +25,7 @@ env:
POSTGRES_PASSWORD: automatisch_password
REDIS_HOST: localhost
APP_ENV: production
PORT: 3000
LICENSE_KEY: dummy_license_key
jobs:

View File

@@ -10,7 +10,7 @@ import process from 'process';
async function fetchAdminRole() {
const role = await Role.query()
.where({
key: 'admin',
name: 'Admin',
})
.limit(1)
.first();

View File

@@ -11,6 +11,7 @@
"start:worker": "node src/worker.js",
"pretest": "APP_ENV=test node ./test/setup/prepare-test-env.js",
"test": "APP_ENV=test vitest run",
"test:watch": "APP_ENV=test vitest watch",
"lint": "eslint .",
"db:create": "node ./bin/database/create.js",
"db:seed:user": "node ./bin/database/seed-user.js",
@@ -22,8 +23,6 @@
"dependencies": {
"@bull-board/express": "^3.10.1",
"@casl/ability": "^6.5.0",
"@graphql-tools/graphql-file-loader": "^7.3.4",
"@graphql-tools/load": "^7.5.2",
"@node-saml/passport-saml": "^4.0.4",
"@rudderstack/rudder-sdk-node": "^1.1.2",
"@sentry/node": "^7.42.0",
@@ -38,13 +37,9 @@
"debug": "~2.6.9",
"dotenv": "^10.0.0",
"express": "~4.18.2",
"express-async-handler": "^1.2.0",
"express-async-errors": "^3.1.1",
"express-basic-auth": "^1.2.1",
"express-graphql": "^0.12.0",
"fast-xml-parser": "^4.0.11",
"graphql-middleware": "^6.1.15",
"graphql-shield": "^7.5.0",
"graphql-tools": "^8.2.0",
"handlebars": "^4.7.7",
"http-errors": "~1.6.3",
"http-proxy-agent": "^7.0.0",
@@ -106,7 +101,9 @@
"access": "public"
},
"nodemonConfig": {
"watch": [ "src/" ],
"watch": [
"src/"
],
"ext": "js"
}
}

View File

@@ -1,5 +1,6 @@
import createError from 'http-errors';
import express from 'express';
import 'express-async-errors';
import cors from 'cors';
import appConfig from './config/app.js';

View File

@@ -12,7 +12,7 @@ export default defineApp({
apiBaseUrl: 'https://api.airtable.com',
iconUrl: '{BASE_URL}/apps/airtable/assets/favicon.svg',
authDocUrl: '{DOCS_URL}/apps/airtable/connection',
primaryColor: 'FFBF00',
primaryColor: '#FFBF00',
supportsConnections: true,
beforeRequest: [addAuthHeader],
auth,

View File

@@ -12,7 +12,7 @@ export default defineApp({
apiBaseUrl: 'https://cloud.appwrite.io',
iconUrl: '{BASE_URL}/apps/appwrite/assets/favicon.svg',
authDocUrl: '{DOCS_URL}/apps/appwrite/connection',
primaryColor: 'FD366E',
primaryColor: '#FD366E',
supportsConnections: true,
beforeRequest: [setBaseUrl, addAuthHeader],
auth,

View File

@@ -12,7 +12,7 @@ export default defineApp({
apiBaseUrl: '',
iconUrl: '{BASE_URL}/apps/azure-openai/assets/favicon.svg',
authDocUrl: '{DOCS_URL}/apps/azure-openai/connection',
primaryColor: '000000',
primaryColor: '#000000',
supportsConnections: true,
beforeRequest: [setBaseUrl, addAuthHeader],
auth,

View File

@@ -11,7 +11,7 @@ export default defineApp({
supportsConnections: true,
baseUrl: 'https://carbone.io',
apiBaseUrl: 'https://api.carbone.io',
primaryColor: '6f42c1',
primaryColor: '#6f42c1',
beforeRequest: [addAuthHeader],
auth,
actions,

View File

@@ -12,8 +12,8 @@ export default defineApp({
baseUrl: 'https://clickup.com',
apiBaseUrl: 'https://api.clickup.com/api',
iconUrl: '{BASE_URL}/apps/clickup/assets/favicon.svg',
authDocUrl: 'https://automatisch.io/docs/apps/clickup/connection',
primaryColor: 'FD71AF',
authDocUrl: '{DOCS_URL}/apps/clickup/connection',
primaryColor: '#FD71AF',
supportsConnections: true,
beforeRequest: [addAuthHeader],
auth,

View File

@@ -33,6 +33,7 @@ export default defineAction({
type: 'string',
required: true,
variables: true,
valueType: 'parse',
},
],
},

View File

@@ -8,7 +8,7 @@ export default defineApp({
apiBaseUrl: '',
iconUrl: '{BASE_URL}/apps/code/assets/favicon.svg',
authDocUrl: '{DOCS_URL}/apps/code/connection',
primaryColor: '000000',
primaryColor: '#000000',
supportsConnections: false,
actions,
});

View File

@@ -9,6 +9,6 @@ export default defineApp({
supportsConnections: false,
baseUrl: '',
apiBaseUrl: '',
primaryColor: '001F52',
primaryColor: '#001F52',
actions,
});

View File

@@ -9,6 +9,6 @@ export default defineApp({
supportsConnections: false,
baseUrl: '',
apiBaseUrl: '',
primaryColor: '001F52',
primaryColor: '#001F52',
actions,
});

View File

@@ -11,7 +11,7 @@ export default defineApp({
supportsConnections: true,
baseUrl: 'https://deepl.com',
apiBaseUrl: 'https://api.deepl.com',
primaryColor: '0d2d45',
primaryColor: '#0d2d45',
beforeRequest: [addAuthHeader],
auth,
actions,

View File

@@ -9,6 +9,6 @@ export default defineApp({
supportsConnections: false,
baseUrl: '',
apiBaseUrl: '',
primaryColor: '001F52',
primaryColor: '#001F52',
actions,
});

View File

@@ -14,7 +14,7 @@ export default defineApp({
supportsConnections: true,
baseUrl: 'https://discord.com',
apiBaseUrl: 'https://discord.com/api',
primaryColor: '5865f2',
primaryColor: '#5865f2',
beforeRequest: [addAuthHeader],
auth,
dynamicData,

View File

@@ -11,7 +11,7 @@ export default defineApp({
apiBaseUrl: 'https://disqus.com/api',
iconUrl: '{BASE_URL}/apps/disqus/assets/favicon.svg',
authDocUrl: '{DOCS_URL}/apps/disqus/connection',
primaryColor: '2E9FFF',
primaryColor: '#2E9FFF',
supportsConnections: true,
beforeRequest: [addAuthHeader],
auth,

View File

@@ -11,7 +11,7 @@ export default defineApp({
supportsConnections: true,
baseUrl: 'https://dropbox.com',
apiBaseUrl: 'https://api.dropboxapi.com',
primaryColor: '0061ff',
primaryColor: '#0061ff',
beforeRequest: [addAuthHeader],
auth,
actions,

View File

@@ -9,6 +9,6 @@ export default defineApp({
supportsConnections: false,
baseUrl: '',
apiBaseUrl: '',
primaryColor: '001F52',
primaryColor: '#001F52',
actions,
});

View File

@@ -10,7 +10,7 @@ export default defineApp({
iconUrl: '{BASE_URL}/apps/flickr/assets/favicon.svg',
authDocUrl: '{DOCS_URL}/apps/flickr/connection',
docUrl: 'https://automatisch.io/docs/flickr',
primaryColor: '000000',
primaryColor: '#000000',
supportsConnections: true,
baseUrl: 'https://www.flickr.com/',
apiBaseUrl: 'https://www.flickr.com/services',

View File

@@ -11,7 +11,7 @@ export default defineApp({
supportsConnections: true,
baseUrl: 'https://flowers-software.com',
apiBaseUrl: 'https://webapp.flowers-software.com/api',
primaryColor: '02AFC7',
primaryColor: '#02AFC7',
beforeRequest: [addAuthHeader],
auth,
triggers,

View File

@@ -10,7 +10,7 @@ export default defineApp({
supportsConnections: false,
baseUrl: '',
apiBaseUrl: '',
primaryColor: '001F52',
primaryColor: '#001F52',
actions,
dynamicFields,
});

View File

@@ -11,7 +11,7 @@ export default defineApp({
apiBaseUrl: '',
iconUrl: '{BASE_URL}/apps/ghost/assets/favicon.svg',
authDocUrl: '{DOCS_URL}/apps/ghost/connection',
primaryColor: '15171A',
primaryColor: '#15171A',
supportsConnections: true,
beforeRequest: [setBaseUrl, addAuthHeader],
auth,

View File

@@ -12,7 +12,7 @@ export default defineApp({
apiBaseUrl: 'https://api.github.com',
iconUrl: '{BASE_URL}/apps/github/assets/favicon.svg',
authDocUrl: '{DOCS_URL}/apps/github/connection',
primaryColor: '000000',
primaryColor: '#000000',
supportsConnections: true,
beforeRequest: [addAuthHeader],
auth,

View File

@@ -12,7 +12,7 @@ export default defineApp({
apiBaseUrl: 'https://gitlab.com',
iconUrl: '{BASE_URL}/apps/gitlab/assets/favicon.svg',
authDocUrl: '{DOCS_URL}/apps/gitlab/connection',
primaryColor: 'FC6D26',
primaryColor: '#FC6D26',
supportsConnections: true,
beforeRequest: [setBaseUrl, addAuthHeader],
auth,

View File

@@ -11,7 +11,7 @@ export default defineApp({
apiBaseUrl: 'https://www.googleapis.com/calendar',
iconUrl: '{BASE_URL}/apps/google-calendar/assets/favicon.svg',
authDocUrl: '{DOCS_URL}/apps/google-calendar/connection',
primaryColor: '448AFF',
primaryColor: '#448AFF',
supportsConnections: true,
beforeRequest: [addAuthHeader],
auth,

View File

@@ -11,7 +11,7 @@ export default defineApp({
apiBaseUrl: 'https://www.googleapis.com/drive',
iconUrl: '{BASE_URL}/apps/google-drive/assets/favicon.svg',
authDocUrl: '{DOCS_URL}/apps/google-drive/connection',
primaryColor: '1FA463',
primaryColor: '#1FA463',
supportsConnections: true,
beforeRequest: [addAuthHeader],
auth,

View File

@@ -11,7 +11,7 @@ export default defineApp({
apiBaseUrl: 'https://forms.googleapis.com',
iconUrl: '{BASE_URL}/apps/google-forms/assets/favicon.svg',
authDocUrl: '{DOCS_URL}/apps/google-forms/connection',
primaryColor: '673AB7',
primaryColor: '#673AB7',
supportsConnections: true,
beforeRequest: [addAuthHeader],
auth,

View File

@@ -13,7 +13,7 @@ export default defineApp({
apiBaseUrl: 'https://sheets.googleapis.com',
iconUrl: '{BASE_URL}/apps/google-sheets/assets/favicon.svg',
authDocUrl: '{DOCS_URL}/apps/google-sheets/connection',
primaryColor: '0F9D58',
primaryColor: '#0F9D58',
supportsConnections: true,
beforeRequest: [addAuthHeader],
auth,

View File

@@ -12,7 +12,7 @@ export default defineApp({
apiBaseUrl: 'https://tasks.googleapis.com',
iconUrl: '{BASE_URL}/apps/google-tasks/assets/favicon.svg',
authDocUrl: '{DOCS_URL}/apps/google-tasks/connection',
primaryColor: '0066DA',
primaryColor: '#0066DA',
supportsConnections: true,
beforeRequest: [addAuthHeader],
auth,

View File

@@ -11,7 +11,7 @@ export default defineApp({
apiBaseUrl: 'https://app.tryhelix.ai',
iconUrl: '{BASE_URL}/apps/helix/assets/favicon.svg',
authDocUrl: '{DOCS_URL}/apps/helix/connection',
primaryColor: '000000',
primaryColor: '#000000',
supportsConnections: true,
beforeRequest: [setBaseUrl, addAuthHeader],
auth,

View File

@@ -9,6 +9,6 @@ export default defineApp({
supportsConnections: false,
baseUrl: '',
apiBaseUrl: '',
primaryColor: '000000',
primaryColor: '#000000',
actions,
});

View File

@@ -11,7 +11,7 @@ export default defineApp({
supportsConnections: true,
baseUrl: 'https://www.hubspot.com',
apiBaseUrl: 'https://api.hubapi.com',
primaryColor: 'F95C35',
primaryColor: '#F95C35',
beforeRequest: [addAuthHeader],
auth,
actions,

View File

@@ -13,7 +13,7 @@ export default defineApp({
apiBaseUrl: 'https://invoicing.co/api',
iconUrl: '{BASE_URL}/apps/invoice-ninja/assets/favicon.svg',
authDocUrl: '{DOCS_URL}/apps/invoice-ninja/connection',
primaryColor: '000000',
primaryColor: '#000000',
supportsConnections: true,
beforeRequest: [setBaseUrl, addAuthHeader],
auth,

View File

@@ -9,11 +9,11 @@ export default defineApp({
name: 'Jotform',
key: 'jotform',
iconUrl: '{BASE_URL}/apps/jotform/assets/favicon.svg',
authDocUrl: 'https://automatisch.io/docs/apps/jotform/connection',
authDocUrl: '{DOCS_URL}/apps/jotform/connection',
supportsConnections: true,
baseUrl: 'https://www.jotform.com',
apiBaseUrl: 'https://api.jotform.com',
primaryColor: 'FF6100',
primaryColor: '#FF6100',
beforeRequest: [setBaseUrl, addAuthHeader],
auth,
triggers,

View File

@@ -12,8 +12,8 @@ export default defineApp({
baseUrl: 'https://mailchimp.com',
apiBaseUrl: '',
iconUrl: '{BASE_URL}/apps/mailchimp/assets/favicon.svg',
authDocUrl: 'https://automatisch.io/docs/apps/mailchimp/connection',
primaryColor: '000000',
authDocUrl: '{DOCS_URL}/apps/mailchimp/connection',
primaryColor: '#000000',
supportsConnections: true,
beforeRequest: [setBaseUrl, addAuthHeader],
auth,

View File

@@ -7,11 +7,11 @@ export default defineApp({
name: 'MailerLite',
key: 'mailerlite',
iconUrl: '{BASE_URL}/apps/mailerlite/assets/favicon.svg',
authDocUrl: 'https://automatisch.io/docs/apps/mailerlite/connection',
authDocUrl: '{DOCS_URL}/apps/mailerlite/connection',
supportsConnections: true,
baseUrl: 'https://www.mailerlite.com',
apiBaseUrl: 'https://connect.mailerlite.com/api',
primaryColor: '09C269',
primaryColor: '#09C269',
beforeRequest: [addAuthHeader],
auth,
triggers,

View File

@@ -13,7 +13,7 @@ export default defineApp({
authDocUrl: '{DOCS_URL}/apps/mattermost/connection',
baseUrl: 'https://mattermost.com',
apiBaseUrl: '', // there is no cloud version of this app, user always need to provide address of own instance when creating connection
primaryColor: '4a154b',
primaryColor: '#4a154b',
supportsConnections: true,
beforeRequest: [setBaseUrl, addXRequestedWithHeader, addAuthHeader],
auth,

View File

@@ -11,7 +11,7 @@ export default defineApp({
apiBaseUrl: 'https://api.miro.com',
iconUrl: '{BASE_URL}/apps/miro/assets/favicon.svg',
authDocUrl: '{DOCS_URL}/apps/miro/connection',
primaryColor: 'F2CA02',
primaryColor: '#F2CA02',
supportsConnections: true,
beforeRequest: [addAuthHeader],
auth,

View File

@@ -13,7 +13,7 @@ export default defineApp({
apiBaseUrl: 'https://api.notion.com',
iconUrl: '{BASE_URL}/apps/notion/assets/favicon.svg',
authDocUrl: '{DOCS_URL}/apps/notion/connection',
primaryColor: '000000',
primaryColor: '#000000',
supportsConnections: true,
beforeRequest: [addAuthHeader, addNotionVersionHeader],
auth,

View File

@@ -11,7 +11,7 @@ export default defineApp({
supportsConnections: true,
baseUrl: 'https://ntfy.sh',
apiBaseUrl: 'https://ntfy.sh',
primaryColor: '56bda8',
primaryColor: '#56bda8',
beforeRequest: [addAuthHeader],
auth,
actions,

View File

@@ -10,7 +10,7 @@ export default defineApp({
supportsConnections: true,
baseUrl: 'https://odoo.com',
apiBaseUrl: '',
primaryColor: '9c5789',
primaryColor: '#9c5789',
auth,
actions,
});

View File

@@ -11,7 +11,7 @@ export default defineApp({
apiBaseUrl: 'https://api.openai.com',
iconUrl: '{BASE_URL}/apps/openai/assets/favicon.svg',
authDocUrl: '{DOCS_URL}/apps/openai/connection',
primaryColor: '000000',
primaryColor: '#000000',
supportsConnections: true,
beforeRequest: [addAuthHeader],
auth,

View File

@@ -13,7 +13,7 @@ export default defineApp({
apiBaseUrl: '',
iconUrl: '{BASE_URL}/apps/pipedrive/assets/favicon.svg',
authDocUrl: '{DOCS_URL}/apps/pipedrive/connection',
primaryColor: 'FFFFFF',
primaryColor: '#FFFFFF',
supportsConnections: true,
beforeRequest: [setBaseUrl, addAuthHeader],
auth,

View File

@@ -12,7 +12,7 @@ export default defineApp({
supportsConnections: true,
baseUrl: 'https://placetel.de',
apiBaseUrl: 'https://api.placetel.de',
primaryColor: '069dd9',
primaryColor: '#069dd9',
beforeRequest: [addAuthHeader],
auth,
triggers,

View File

@@ -10,7 +10,7 @@ export default defineApp({
supportsConnections: true,
baseUrl: '',
apiBaseUrl: '',
primaryColor: '336791',
primaryColor: '#336791',
auth,
actions,
});

View File

@@ -10,7 +10,7 @@ export default defineApp({
apiBaseUrl: 'https://api.pushover.net',
iconUrl: '{BASE_URL}/apps/pushover/assets/favicon.svg',
authDocUrl: '{DOCS_URL}/apps/pushover/connection',
primaryColor: '249DF1',
primaryColor: '#249DF1',
supportsConnections: true,
auth,
actions,

View File

@@ -11,7 +11,7 @@ export default defineApp({
apiBaseUrl: 'https://oauth.reddit.com',
iconUrl: '{BASE_URL}/apps/reddit/assets/favicon.svg',
authDocUrl: '{DOCS_URL}/apps/reddit/connection',
primaryColor: 'FF4500',
primaryColor: '#FF4500',
supportsConnections: true,
beforeRequest: [addAuthHeader],
auth,

View File

@@ -11,7 +11,7 @@ export default defineApp({
supportsConnections: true,
baseUrl: 'https://www.remove.bg',
apiBaseUrl: 'https://api.remove.bg/v1.0',
primaryColor: '55636c',
primaryColor: '#55636c',
beforeRequest: [addAuthHeader],
auth,
actions,

View File

@@ -9,6 +9,6 @@ export default defineApp({
supportsConnections: false,
baseUrl: '',
apiBaseUrl: '',
primaryColor: 'ff8800',
primaryColor: '#ff8800',
triggers,
});

View File

@@ -13,7 +13,7 @@ export default defineApp({
supportsConnections: true,
baseUrl: 'https://salesforce.com',
apiBaseUrl: '',
primaryColor: '00A1E0',
primaryColor: '#00A1E0',
beforeRequest: [addAuthHeader],
auth,
triggers,

View File

@@ -9,7 +9,7 @@ export default defineApp({
authDocUrl: '{DOCS_URL}/apps/scheduler/connection',
baseUrl: '',
apiBaseUrl: '',
primaryColor: '0059F7',
primaryColor: '#0059F7',
supportsConnections: false,
triggers,
});

View File

@@ -12,7 +12,7 @@ export default defineApp({
apiBaseUrl: '',
iconUrl: '{BASE_URL}/apps/self-hosted-llm/assets/favicon.svg',
authDocUrl: '{DOCS_URL}/apps/self-hosted-llm/connection',
primaryColor: '000000',
primaryColor: '#000000',
supportsConnections: true,
beforeRequest: [setBaseUrl, addAuthHeader],
auth,

View File

@@ -13,7 +13,7 @@ export default defineApp({
supportsConnections: true,
baseUrl: 'https://signalwire.com',
apiBaseUrl: '',
primaryColor: '044cf6',
primaryColor: '#044cf6',
beforeRequest: [addAuthHeader],
auth,
triggers,

View File

@@ -13,7 +13,7 @@ export default defineApp({
supportsConnections: true,
baseUrl: 'https://slack.com',
apiBaseUrl: 'https://slack.com/api',
primaryColor: '4a154b',
primaryColor: '#4a154b',
beforeRequest: [addAuthHeader],
auth,
actions,

View File

@@ -10,7 +10,7 @@ export default defineApp({
supportsConnections: true,
baseUrl: '',
apiBaseUrl: '',
primaryColor: '2DAAE1',
primaryColor: '#2DAAE1',
auth,
actions,
});

View File

@@ -11,7 +11,7 @@ export default defineApp({
supportsConnections: true,
baseUrl: 'https://spotify.com',
apiBaseUrl: 'https://api.spotify.com',
primaryColor: '000000',
primaryColor: '#000000',
beforeRequest: [addAuthHeader],
auth,
actions,

View File

@@ -11,7 +11,7 @@ export default defineApp({
supportsConnections: true,
baseUrl: 'https://www.strava.com',
apiBaseUrl: 'https://www.strava.com/api',
primaryColor: 'fc4c01',
primaryColor: '#fc4c01',
beforeRequest: [addAuthHeader],
auth,
actions,

View File

@@ -11,7 +11,7 @@ export default defineApp({
supportsConnections: true,
baseUrl: 'https://stripe.com',
apiBaseUrl: 'https://api.stripe.com',
primaryColor: '635bff',
primaryColor: '#635bff',
beforeRequest: [addAuthHeader],
auth,
triggers,

View File

@@ -11,7 +11,7 @@ export default defineApp({
supportsConnections: true,
baseUrl: 'https://telegram.org',
apiBaseUrl: 'https://api.telegram.org',
primaryColor: '2AABEE',
primaryColor: '#2AABEE',
beforeRequest: [addAuthHeader],
auth,
actions,

View File

@@ -13,7 +13,7 @@ export default defineApp({
supportsConnections: true,
baseUrl: 'https://todoist.com',
apiBaseUrl: 'https://api.todoist.com/rest/v2',
primaryColor: 'e44332',
primaryColor: '#e44332',
beforeRequest: [addAuthHeader],
auth,
triggers,

View File

@@ -12,7 +12,7 @@ export default defineApp({
iconUrl: '{BASE_URL}/apps/trello/assets/favicon.svg',
authDocUrl: '{DOCS_URL}/apps/trello/connection',
supportsConnections: true,
primaryColor: '0079bf',
primaryColor: '#0079bf',
beforeRequest: [addAuthHeader],
auth,
actions,

View File

@@ -13,7 +13,7 @@ export default defineApp({
supportsConnections: true,
baseUrl: 'https://twilio.com',
apiBaseUrl: 'https://api.twilio.com',
primaryColor: 'e1000f',
primaryColor: '#e1000f',
beforeRequest: [addAuthHeader],
auth,
triggers,

View File

@@ -12,7 +12,7 @@ export default defineApp({
supportsConnections: true,
baseUrl: 'https://twitter.com',
apiBaseUrl: 'https://api.twitter.com',
primaryColor: '1da1f2',
primaryColor: '#1da1f2',
beforeRequest: [addAuthHeader],
auth,
triggers,

View File

@@ -12,7 +12,7 @@ export default defineApp({
supportsConnections: true,
baseUrl: 'https://typeform.com',
apiBaseUrl: 'https://api.typeform.com',
primaryColor: '262627',
primaryColor: '#262627',
beforeRequest: [addAuthHeader],
auth,
triggers,

View File

@@ -14,7 +14,7 @@ export default defineApp({
supportsConnections: true,
baseUrl: '',
apiBaseUrl: '',
primaryColor: '39a86d',
primaryColor: '#39a86d',
beforeRequest: [setBaseUrl, addAuthHeader],
auth,
triggers,

View File

@@ -10,7 +10,7 @@ export default defineApp({
supportsConnections: false,
baseUrl: '',
apiBaseUrl: '',
primaryColor: '0059F7',
primaryColor: '#0059F7',
actions,
triggers,
});

View File

@@ -13,7 +13,7 @@ export default defineApp({
supportsConnections: true,
baseUrl: 'https://wordpress.com',
apiBaseUrl: '',
primaryColor: '464342',
primaryColor: '#464342',
beforeRequest: [setBaseUrl, addAuthHeader],
auth,
triggers,

View File

@@ -4,6 +4,7 @@ export default defineTrigger({
name: 'New comment',
key: 'newComment',
description: 'Triggers when a new comment is created.',
pollInterval: 15,
arguments: [
{
label: 'Status',

View File

@@ -3,6 +3,7 @@ import defineTrigger from '../../../../helpers/define-trigger.js';
export default defineTrigger({
name: 'New page',
key: 'newPage',
pollInterval: 15,
description: 'Triggers when a new page is created.',
arguments: [
{

View File

@@ -3,6 +3,7 @@ import defineTrigger from '../../../../helpers/define-trigger.js';
export default defineTrigger({
name: 'New post',
key: 'newPost',
pollInterval: 15,
description: 'Triggers when a new post is created.',
arguments: [
{

View File

@@ -11,7 +11,7 @@ export default defineApp({
apiBaseUrl: 'https://api.xero.com',
iconUrl: '{BASE_URL}/apps/xero/assets/favicon.svg',
authDocUrl: '{DOCS_URL}/apps/xero/connection',
primaryColor: '13B5EA',
primaryColor: '#13B5EA',
supportsConnections: true,
beforeRequest: [addAuthHeader],
auth,

View File

@@ -10,7 +10,7 @@ export default defineApp({
apiBaseUrl: 'https://api.ynab.com/v1',
iconUrl: '{BASE_URL}/apps/you-need-a-budget/assets/favicon.svg',
authDocUrl: '{DOCS_URL}/apps/you-need-a-budget/connection',
primaryColor: '19223C',
primaryColor: '#19223C',
supportsConnections: true,
beforeRequest: [addAuthHeader],
auth,

View File

@@ -10,7 +10,7 @@ export default defineApp({
apiBaseUrl: 'https://www.googleapis.com/youtube',
iconUrl: '{BASE_URL}/apps/youtube/assets/favicon.svg',
authDocUrl: '{DOCS_URL}/apps/youtube/connection',
primaryColor: 'FF0000',
primaryColor: '#FF0000',
supportsConnections: true,
beforeRequest: [addAuthHeader],
auth,

View File

@@ -3,6 +3,7 @@ import defineTrigger from '../../../../helpers/define-trigger.js';
export default defineTrigger({
name: 'New video by search',
key: 'newVideoBySearch',
pollInterval: 15,
description:
'Triggers when a new video is uploaded that matches a specific search string.',
arguments: [

View File

@@ -3,6 +3,7 @@ import defineTrigger from '../../../../helpers/define-trigger.js';
export default defineTrigger({
name: 'New video in channel',
key: 'newVideoInChannel',
pollInterval: 15,
description:
'Triggers when a new video is published to a specific Youtube channel.',
arguments: [

View File

@@ -12,7 +12,7 @@ export default defineApp({
apiBaseUrl: '',
iconUrl: '{BASE_URL}/apps/zendesk/assets/favicon.svg',
authDocUrl: '{DOCS_URL}/apps/zendesk/connection',
primaryColor: '17494d',
primaryColor: '#17494d',
supportsConnections: true,
beforeRequest: [addAuthHeader],
auth,

View File

@@ -2,7 +2,7 @@ import appConfig from './app.js';
const corsOptions = {
origin: appConfig.webAppUrl,
methods: 'GET,HEAD,POST,DELETE',
methods: 'GET,HEAD,POST,PATCH,DELETE',
credentials: true,
optionsSuccessStatus: 200,
};

View File

@@ -11,5 +11,5 @@ export default async (request, response) => {
await accessToken.revoke();
response.status(204).send();
response.status(204).end();
};

View File

@@ -0,0 +1,25 @@
import { renderObject } from '../../../../../helpers/renderer.js';
import AppConfig from '../../../../../models/app-config.js';
export default async (request, response) => {
const appConfig = await AppConfig.query()
.findOne({ key: request.params.appKey })
.throwIfNotFound();
const appAuthClient = await appConfig
.$relatedQuery('appAuthClients')
.insert(appAuthClientParams(request));
renderObject(response, appAuthClient, { status: 201 });
};
const appAuthClientParams = (request) => {
const { active, appKey, name, formattedAuthDefaults } = request.body;
return {
active,
appKey,
name,
formattedAuthDefaults,
};
};

View File

@@ -0,0 +1,94 @@
import { vi, describe, it, expect, beforeEach } from 'vitest';
import request from 'supertest';
import app from '../../../../../app.js';
import createAuthTokenByUserId from '../../../../../helpers/create-auth-token-by-user-id.js';
import { createUser } from '../../../../../../test/factories/user.js';
import { createRole } from '../../../../../../test/factories/role.js';
import createAppAuthClientMock from '../../../../../../test/mocks/rest/api/v1/admin/apps/create-auth-client.js';
import { createAppConfig } from '../../../../../../test/factories/app-config.js';
import * as license from '../../../../../helpers/license.ee.js';
describe('POST /api/v1/admin/apps/:appKey/auth-clients', () => {
let currentUser, adminRole, token;
beforeEach(async () => {
vi.spyOn(license, 'hasValidLicense').mockResolvedValue(true);
adminRole = await createRole({ name: 'Admin' });
currentUser = await createUser({ roleId: adminRole.id });
token = await createAuthTokenByUserId(currentUser.id);
});
it('should return created response for valid app config', async () => {
await createAppConfig({
key: 'gitlab',
});
const appAuthClient = {
active: true,
appKey: 'gitlab',
name: 'First auth client',
formattedAuthDefaults: {
clientid: 'sample client ID',
clientSecret: 'sample client secret',
instanceUrl: 'https://gitlab.com',
oAuthRedirectUrl: 'http://localhost:3001/app/gitlab/connection/add',
},
};
const response = await request(app)
.post('/api/v1/admin/apps/gitlab/auth-clients')
.set('Authorization', token)
.send(appAuthClient)
.expect(201);
const expectedPayload = createAppAuthClientMock(appAuthClient);
expect(response.body).toMatchObject(expectedPayload);
});
it('should return not found response for not existing app config', async () => {
const appAuthClient = {
active: true,
appKey: 'gitlab',
name: 'First auth client',
formattedAuthDefaults: {
clientid: 'sample client ID',
clientSecret: 'sample client secret',
instanceUrl: 'https://gitlab.com',
oAuthRedirectUrl: 'http://localhost:3001/app/gitlab/connection/add',
},
};
await request(app)
.post('/api/v1/admin/apps/gitlab/auth-clients')
.set('Authorization', token)
.send(appAuthClient)
.expect(404);
});
it('should return bad request response for missing required fields', async () => {
await createAppConfig({
key: 'gitlab',
});
const appAuthClient = {
appKey: 'gitlab',
};
const response = await request(app)
.post('/api/v1/admin/apps/gitlab/auth-clients')
.set('Authorization', token)
.send(appAuthClient)
.expect(422);
expect(response.body.meta.type).toEqual('ModelValidation');
expect(response.body.errors).toMatchObject({
name: ["must have required property 'name'"],
formattedAuthDefaults: [
"must have required property 'formattedAuthDefaults'",
],
});
});
});

View File

@@ -0,0 +1,21 @@
import { renderObject } from '../../../../../helpers/renderer.js';
import AppConfig from '../../../../../models/app-config.js';
export default async (request, response) => {
const createdAppConfig = await AppConfig.query().insertAndFetch(
appConfigParams(request)
);
renderObject(response, createdAppConfig, { status: 201 });
};
const appConfigParams = (request) => {
const { allowCustomConnection, shared, disabled } = request.body;
return {
key: request.params.appKey,
allowCustomConnection,
shared,
disabled,
};
};

View File

@@ -0,0 +1,67 @@
import { vi, describe, it, expect, beforeEach } from 'vitest';
import request from 'supertest';
import app from '../../../../../app.js';
import createAuthTokenByUserId from '../../../../../helpers/create-auth-token-by-user-id.js';
import { createUser } from '../../../../../../test/factories/user.js';
import { createRole } from '../../../../../../test/factories/role.js';
import createAppConfigMock from '../../../../../../test/mocks/rest/api/v1/admin/apps/create-config.js';
import { createAppConfig } from '../../../../../../test/factories/app-config.js';
import * as license from '../../../../../helpers/license.ee.js';
describe('POST /api/v1/admin/apps/:appKey/config', () => {
let currentUser, adminRole, token;
beforeEach(async () => {
vi.spyOn(license, 'hasValidLicense').mockResolvedValue(true);
adminRole = await createRole({ name: 'Admin' });
currentUser = await createUser({ roleId: adminRole.id });
token = await createAuthTokenByUserId(currentUser.id);
});
it('should return created app config', async () => {
const appConfig = {
allowCustomConnection: true,
shared: true,
disabled: false,
};
const response = await request(app)
.post('/api/v1/admin/apps/gitlab/config')
.set('Authorization', token)
.send(appConfig)
.expect(201);
const expectedPayload = createAppConfigMock({
...appConfig,
key: 'gitlab',
});
expect(response.body).toMatchObject(expectedPayload);
});
it('should return HTTP 422 for already existing app config', async () => {
const appConfig = {
key: 'gitlab',
allowCustomConnection: true,
shared: true,
disabled: false,
};
await createAppConfig(appConfig);
const response = await request(app)
.post('/api/v1/admin/apps/gitlab/config')
.set('Authorization', token)
.send({
disabled: false,
})
.expect(422);
expect(response.body.meta.type).toEqual('UniqueViolationError');
expect(response.body.errors).toMatchObject({
key: ["'key' must be unique."],
});
});
});

View File

@@ -15,7 +15,7 @@ describe('GET /api/v1/admin/apps/:appKey/auth-clients/:appAuthClientId', () => {
beforeEach(async () => {
vi.spyOn(license, 'hasValidLicense').mockResolvedValue(true);
adminRole = await createRole({ key: 'admin' });
adminRole = await createRole({ name: 'Admin' });
currentUser = await createUser({ roleId: adminRole.id });
currentAppAuthClient = await createAppAuthClient({

View File

@@ -14,7 +14,7 @@ describe('GET /api/v1/admin/apps/:appKey/auth-clients', () => {
beforeEach(async () => {
vi.spyOn(license, 'hasValidLicense').mockResolvedValue(true);
adminRole = await createRole({ key: 'admin' });
adminRole = await createRole({ name: 'Admin' });
currentUser = await createUser({ roleId: adminRole.id });
token = await createAuthTokenByUserId(currentUser.id);

View File

@@ -0,0 +1,22 @@
import { renderObject } from '../../../../../helpers/renderer.js';
import AppAuthClient from '../../../../../models/app-auth-client.js';
export default async (request, response) => {
const appAuthClient = await AppAuthClient.query()
.findById(request.params.appAuthClientId)
.throwIfNotFound();
await appAuthClient.$query().patchAndFetch(appAuthClientParams(request));
renderObject(response, appAuthClient);
};
const appAuthClientParams = (request) => {
const { active, name, formattedAuthDefaults } = request.body;
return {
active,
name,
formattedAuthDefaults,
};
};

View File

@@ -0,0 +1,104 @@
import { vi, describe, it, expect, beforeEach } from 'vitest';
import request from 'supertest';
import Crypto from 'crypto';
import app from '../../../../../app.js';
import createAuthTokenByUserId from '../../../../../helpers/create-auth-token-by-user-id.js';
import { createUser } from '../../../../../../test/factories/user.js';
import { createRole } from '../../../../../../test/factories/role.js';
import updateAppAuthClientMock from '../../../../../../test/mocks/rest/api/v1/admin/apps/update-auth-client.js';
import { createAppConfig } from '../../../../../../test/factories/app-config.js';
import { createAppAuthClient } from '../../../../../../test/factories/app-auth-client.js';
import * as license from '../../../../../helpers/license.ee.js';
describe('PATCH /api/v1/admin/apps/:appKey/auth-clients', () => {
let currentUser, adminRole, token;
beforeEach(async () => {
vi.spyOn(license, 'hasValidLicense').mockResolvedValue(true);
adminRole = await createRole({ name: 'Admin' });
currentUser = await createUser({ roleId: adminRole.id });
token = await createAuthTokenByUserId(currentUser.id);
await createAppConfig({
key: 'gitlab',
});
});
it('should return updated entity for valid app auth client', async () => {
const appAuthClient = {
active: true,
appKey: 'gitlab',
formattedAuthDefaults: {
clientid: 'sample client ID',
clientSecret: 'sample client secret',
instanceUrl: 'https://gitlab.com',
oAuthRedirectUrl: 'http://localhost:3001/app/gitlab/connection/add',
},
};
const existingAppAuthClient = await createAppAuthClient({
appKey: 'gitlab',
name: 'First auth client',
});
const response = await request(app)
.patch(
`/api/v1/admin/apps/gitlab/auth-clients/${existingAppAuthClient.id}`
)
.set('Authorization', token)
.send(appAuthClient)
.expect(200);
const expectedPayload = updateAppAuthClientMock({
...existingAppAuthClient,
...appAuthClient,
});
expect(response.body).toMatchObject(expectedPayload);
});
it('should return not found response for not existing app auth client', async () => {
const notExistingAppAuthClientId = Crypto.randomUUID();
await request(app)
.patch(
`/api/v1/admin/apps/gitlab/auth-clients/${notExistingAppAuthClientId}`
)
.set('Authorization', token)
.expect(404);
});
it('should return bad request response for invalid UUID', async () => {
await request(app)
.patch('/api/v1/admin/apps/gitlab/auth-clients/invalidAuthClientUUID')
.set('Authorization', token)
.expect(400);
});
it('should return HTTP 422 for invalid payload', async () => {
const appAuthClient = {
formattedAuthDefaults: 'invalid input',
};
const existingAppAuthClient = await createAppAuthClient({
appKey: 'gitlab',
name: 'First auth client',
});
const response = await request(app)
.patch(
`/api/v1/admin/apps/gitlab/auth-clients/${existingAppAuthClient.id}`
)
.set('Authorization', token)
.send(appAuthClient)
.expect(422);
expect(response.body.meta.type).toBe('ModelValidation');
expect(response.body.errors).toMatchObject({
formattedAuthDefaults: ['must be object'],
});
});
});

View File

@@ -0,0 +1,24 @@
import { renderObject } from '../../../../../helpers/renderer.js';
import AppConfig from '../../../../../models/app-config.js';
export default async (request, response) => {
const appConfig = await AppConfig.query()
.findOne({
key: request.params.appKey,
})
.throwIfNotFound();
await appConfig.$query().patchAndFetch(appConfigParams(request));
renderObject(response, appConfig);
};
const appConfigParams = (request) => {
const { allowCustomConnection, shared, disabled } = request.body;
return {
allowCustomConnection,
shared,
disabled,
};
};

View File

@@ -0,0 +1,91 @@
import { vi, describe, it, expect, beforeEach } from 'vitest';
import request from 'supertest';
import app from '../../../../../app.js';
import createAuthTokenByUserId from '../../../../../helpers/create-auth-token-by-user-id.js';
import { createUser } from '../../../../../../test/factories/user.js';
import { createRole } from '../../../../../../test/factories/role.js';
import createAppConfigMock from '../../../../../../test/mocks/rest/api/v1/admin/apps/create-config.js';
import { createAppConfig } from '../../../../../../test/factories/app-config.js';
import * as license from '../../../../../helpers/license.ee.js';
describe('PATCH /api/v1/admin/apps/:appKey/config', () => {
let currentUser, adminRole, token;
beforeEach(async () => {
vi.spyOn(license, 'hasValidLicense').mockResolvedValue(true);
adminRole = await createRole({ name: 'Admin' });
currentUser = await createUser({ roleId: adminRole.id });
token = await createAuthTokenByUserId(currentUser.id);
});
it('should return updated app config', async () => {
const appConfig = {
key: 'gitlab',
allowCustomConnection: true,
shared: true,
disabled: false,
};
await createAppConfig(appConfig);
const newAppConfigValues = {
shared: false,
disabled: true,
allowCustomConnection: false,
};
const response = await request(app)
.patch('/api/v1/admin/apps/gitlab/config')
.set('Authorization', token)
.send(newAppConfigValues)
.expect(200);
const expectedPayload = createAppConfigMock({
...newAppConfigValues,
key: 'gitlab',
});
expect(response.body).toMatchObject(expectedPayload);
});
it('should return not found response for unexisting app config', async () => {
const appConfig = {
shared: false,
disabled: true,
allowCustomConnection: false,
};
await request(app)
.patch('/api/v1/admin/apps/gitlab/config')
.set('Authorization', token)
.send(appConfig)
.expect(404);
});
it('should return HTTP 422 for invalid app config data', async () => {
const appConfig = {
key: 'gitlab',
allowCustomConnection: true,
shared: true,
disabled: false,
};
await createAppConfig(appConfig);
const response = await request(app)
.patch('/api/v1/admin/apps/gitlab/config')
.set('Authorization', token)
.send({
disabled: 'invalid value type',
})
.expect(422);
expect(response.body.meta.type).toEqual('ModelValidation');
expect(response.body.errors).toMatchObject({
disabled: ['must be boolean'],
});
});
});

View File

@@ -0,0 +1,28 @@
import { renderObject } from '../../../../../helpers/renderer.js';
import Config from '../../../../../models/config.js';
export default async (request, response) => {
const config = await Config.query().updateFirstOrInsert(
configParams(request)
);
renderObject(response, config);
};
const configParams = (request) => {
const {
logoSvgData,
palettePrimaryDark,
palettePrimaryLight,
palettePrimaryMain,
title,
} = request.body;
return {
logoSvgData,
palettePrimaryDark,
palettePrimaryLight,
palettePrimaryMain,
title,
};
};

View File

@@ -0,0 +1,88 @@
import { vi, describe, it, expect, beforeEach } from 'vitest';
import request from 'supertest';
import app from '../../../../../app.js';
import createAuthTokenByUserId from '../../../../../helpers/create-auth-token-by-user-id.js';
import { createUser } from '../../../../../../test/factories/user.js';
import { createRole } from '../../../../../../test/factories/role.js';
import { updateConfig } from '../../../../../../test/factories/config.js';
import * as license from '../../../../../helpers/license.ee.js';
describe('PATCH /api/v1/admin/config', () => {
let currentUser, adminRole, token;
beforeEach(async () => {
vi.spyOn(license, 'hasValidLicense').mockResolvedValue(true);
adminRole = await createRole({ name: 'Admin' });
currentUser = await createUser({ roleId: adminRole.id });
token = await createAuthTokenByUserId(currentUser.id);
});
it('should return updated config', async () => {
const title = 'Test environment - Automatisch';
const palettePrimaryMain = '#00adef';
const palettePrimaryDark = '#222222';
const palettePrimaryLight = '#f90707';
const logoSvgData =
'<svg width="25" height="25" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 100 100"><rect width="100%" height="100%" fill="white" /><text x="10" y="40" font-family="Arial" font-size="40" fill="black">A</text></svg>';
const appConfig = {
title,
palettePrimaryMain: palettePrimaryMain,
palettePrimaryDark: palettePrimaryDark,
palettePrimaryLight: palettePrimaryLight,
logoSvgData: logoSvgData,
};
await updateConfig(appConfig);
const newTitle = 'Updated title';
const newConfigValues = {
title: newTitle,
};
const response = await request(app)
.patch('/api/v1/admin/config')
.set('Authorization', token)
.send(newConfigValues)
.expect(200);
expect(response.body.data.title).toEqual(newTitle);
expect(response.body.meta.type).toEqual('Config');
});
it('should return created config for unexisting config', async () => {
const newTitle = 'Updated title';
const newConfigValues = {
title: newTitle,
};
const response = await request(app)
.patch('/api/v1/admin/config')
.set('Authorization', token)
.send(newConfigValues)
.expect(200);
expect(response.body.data.title).toEqual(newTitle);
expect(response.body.meta.type).toEqual('Config');
});
it('should return null for deleted config entry', async () => {
const newConfigValues = {
title: null,
};
const response = await request(app)
.patch('/api/v1/admin/config')
.set('Authorization', token)
.send(newConfigValues)
.expect(200);
expect(response.body.data.title).toBeNull();
expect(response.body.meta.type).toEqual('Config');
});
});

View File

@@ -11,7 +11,7 @@ describe('GET /api/v1/admin/permissions/catalog', () => {
let role, currentUser, token;
beforeEach(async () => {
role = await createRole({ key: 'admin' });
role = await createRole({ name: 'Admin' });
currentUser = await createUser({ roleId: role.id });
token = await createAuthTokenByUserId(currentUser.id);

View File

@@ -0,0 +1,22 @@
import { renderObject } from '../../../../../helpers/renderer.js';
import Role from '../../../../../models/role.js';
export default async (request, response) => {
const roleData = roleParams(request);
const roleWithPermissions = await Role.query().insertGraphAndFetch(roleData, {
relate: ['permissions'],
});
renderObject(response, roleWithPermissions, { status: 201 });
};
const roleParams = (request) => {
const { name, description, permissions } = request.body;
return {
name,
description,
permissions,
};
};

View File

@@ -0,0 +1,109 @@
import { vi, describe, it, expect, beforeEach } from 'vitest';
import request from 'supertest';
import app from '../../../../../app.js';
import Role from '../../../../../models/role.js';
import createAuthTokenByUserId from '../../../../../helpers/create-auth-token-by-user-id.js';
import { createRole } from '../../../../../../test/factories/role.js';
import { createUser } from '../../../../../../test/factories/user.js';
import createRoleMock from '../../../../../../test/mocks/rest/api/v1/admin/roles/create-role.ee.js';
import * as license from '../../../../../helpers/license.ee.js';
describe('POST /api/v1/admin/roles', () => {
let role, currentUser, token;
beforeEach(async () => {
vi.spyOn(license, 'hasValidLicense').mockResolvedValue(true);
role = await createRole({ name: 'Admin' });
currentUser = await createUser({ roleId: role.id });
token = await createAuthTokenByUserId(currentUser.id);
});
it('should return the created role along with permissions', async () => {
const roleData = {
name: 'Viewer',
description: '',
permissions: [
{
action: 'read',
subject: 'Flow',
conditions: ['isCreator'],
},
],
};
const response = await request(app)
.post('/api/v1/admin/roles')
.set('Authorization', token)
.send(roleData)
.expect(201);
const createdRole = await Role.query()
.withGraphFetched({ permissions: true })
.findOne({ name: 'Viewer' })
.throwIfNotFound();
const expectedPayload = await createRoleMock(
{
...createdRole,
...roleData,
isAdmin: createdRole.isAdmin,
},
[
{
...createdRole.permissions[0],
...roleData.permissions[0],
},
]
);
expect(response.body).toEqual(expectedPayload);
});
it('should return unprocessable entity response for invalid role data', async () => {
const roleData = {
description: '',
permissions: [],
};
const response = await request(app)
.post('/api/v1/admin/roles')
.set('Authorization', token)
.send(roleData)
.expect(422);
expect(response.body).toStrictEqual({
errors: {
name: ["must have required property 'name'"],
},
meta: {
type: 'ModelValidation',
},
});
});
it('should return unprocessable entity response for duplicate role', async () => {
await createRole({ name: 'Viewer' });
const roleData = {
name: 'Viewer',
permissions: [],
};
const response = await request(app)
.post('/api/v1/admin/roles')
.set('Authorization', token)
.send(roleData)
.expect(422);
expect(response.body).toStrictEqual({
errors: {
name: ["'name' must be unique."],
},
meta: {
type: 'UniqueViolationError',
},
});
});
});

View File

@@ -0,0 +1,11 @@
import Role from '../../../../../models/role.js';
export default async (request, response) => {
const role = await Role.query()
.findById(request.params.roleId)
.throwIfNotFound();
await role.deleteWithPermissions();
response.status(204).end();
};

View File

@@ -0,0 +1,112 @@
import Crypto from 'node:crypto';
import { vi, describe, it, expect, beforeEach } from 'vitest';
import request from 'supertest';
import app from '../../../../../app.js';
import createAuthTokenByUserId from '../../../../../helpers/create-auth-token-by-user-id.js';
import { createRole } from '../../../../../../test/factories/role.js';
import { createPermission } from '../../../../../../test/factories/permission.js';
import { createSamlAuthProvider } from '../../../../../../test/factories/saml-auth-provider.ee.js';
import { createUser } from '../../../../../../test/factories/user.js';
import * as license from '../../../../../helpers/license.ee.js';
describe('DELETE /api/v1/admin/roles/:roleId', () => {
let adminRole, currentUser, token;
beforeEach(async () => {
vi.spyOn(license, 'hasValidLicense').mockResolvedValue(true);
adminRole = await createRole({ name: 'Admin' });
currentUser = await createUser({ roleId: adminRole.id });
token = await createAuthTokenByUserId(currentUser.id);
});
it('should return HTTP 204 for unused role', async () => {
const role = await createRole();
const permission = await createPermission({ roleId: role.id });
await request(app)
.delete(`/api/v1/admin/roles/${role.id}`)
.set('Authorization', token)
.expect(204);
const refetchedRole = await role.$query();
const refetchedPermission = await permission.$query();
expect(refetchedRole).toBeUndefined();
expect(refetchedPermission).toBeUndefined();
});
it('should return HTTP 404 for not existing role UUID', async () => {
const notExistingRoleUUID = Crypto.randomUUID();
await request(app)
.delete(`/api/v1/admin/roles/${notExistingRoleUUID}`)
.set('Authorization', token)
.expect(404);
});
it('should return not authorized response for deleting admin role', async () => {
await request(app)
.delete(`/api/v1/admin/roles/${adminRole.id}`)
.set('Authorization', token)
.expect(403);
});
it('should return unprocessable entity response for role used by users', async () => {
const role = await createRole();
await createUser({ roleId: role.id });
const response = await request(app)
.delete(`/api/v1/admin/roles/${role.id}`)
.set('Authorization', token)
.expect(422);
expect(response.body).toStrictEqual({
errors: {
role: [`All users must be migrated away from the "${role.name}" role.`],
},
meta: {
type: 'ValidationError',
},
});
});
it('should return unprocessable entity response for role used by saml auth providers', async () => {
const samlAuthProvider = await createSamlAuthProvider();
const response = await request(app)
.delete(`/api/v1/admin/roles/${samlAuthProvider.defaultRoleId}`)
.set('Authorization', token)
.expect(422);
expect(response.body).toStrictEqual({
errors: {
samlAuthProvider: [
'You need to change the default role in the SAML configuration before deleting this role.',
],
},
meta: {
type: 'ValidationError',
},
});
});
it('should not delete role and permissions on unsuccessful response', async () => {
const role = await createRole();
const permission = await createPermission({ roleId: role.id });
await createUser({ roleId: role.id });
await request(app)
.delete(`/api/v1/admin/roles/${role.id}`)
.set('Authorization', token)
.expect(422);
const refetchedRole = await role.$query();
const refetchedPermission = await permission.$query();
expect(refetchedRole).toStrictEqual(role);
expect(refetchedPermission).toStrictEqual(permission);
});
});

View File

@@ -13,7 +13,7 @@ describe('GET /api/v1/admin/roles/:roleId', () => {
let role, currentUser, token, permissionOne, permissionTwo;
beforeEach(async () => {
role = await createRole({ key: 'admin' });
role = await createRole({ name: 'Admin' });
permissionOne = await createPermission({ roleId: role.id });
permissionTwo = await createPermission({ roleId: role.id });
currentUser = await createUser({ roleId: role.id });

View File

@@ -11,8 +11,8 @@ describe('GET /api/v1/admin/roles', () => {
let roleOne, roleTwo, currentUser, token;
beforeEach(async () => {
roleOne = await createRole({ key: 'admin' });
roleTwo = await createRole({ key: 'user' });
roleOne = await createRole({ name: 'Admin' });
roleTwo = await createRole({ name: 'User' });
currentUser = await createUser({ roleId: roleOne.id });
token = await createAuthTokenByUserId(currentUser.id);

View File

@@ -0,0 +1,24 @@
import { renderObject } from '../../../../../helpers/renderer.js';
import Role from '../../../../../models/role.js';
export default async (request, response) => {
const role = await Role.query()
.findById(request.params.roleId)
.throwIfNotFound();
const updatedRoleWithPermissions = await role.updateWithPermissions(
roleParams(request)
);
renderObject(response, updatedRoleWithPermissions);
};
const roleParams = (request) => {
const { name, description, permissions } = request.body;
return {
name,
description,
permissions,
};
};

View File

@@ -0,0 +1,177 @@
import { vi, describe, it, expect, beforeEach } from 'vitest';
import request from 'supertest';
import app from '../../../../../app.js';
import createAuthTokenByUserId from '../../../../../helpers/create-auth-token-by-user-id.js';
import { createRole } from '../../../../../../test/factories/role.js';
import { createPermission } from '../../../../../../test/factories/permission.js';
import { createUser } from '../../../../../../test/factories/user.js';
import updateRoleMock from '../../../../../../test/mocks/rest/api/v1/admin/roles/update-role.ee.js';
import * as license from '../../../../../helpers/license.ee.js';
describe('PATCH /api/v1/admin/roles/:roleId', () => {
let adminRole, viewerRole, currentUser, token;
beforeEach(async () => {
vi.spyOn(license, 'hasValidLicense').mockResolvedValue(true);
adminRole = await createRole({ name: 'Admin' });
viewerRole = await createRole({ name: 'Viewer' });
await createPermission({
action: 'read',
subject: 'Connection',
});
await createPermission({
action: 'read',
subject: 'Flow',
});
currentUser = await createUser({ roleId: adminRole.id });
token = await createAuthTokenByUserId(currentUser.id);
});
it('should return the updated role along with permissions', async () => {
const roleData = {
name: 'Updated role name',
description: 'A new description',
permissions: [
{
action: 'read',
subject: 'Execution',
conditions: ['isCreator'],
},
],
};
const response = await request(app)
.patch(`/api/v1/admin/roles/${viewerRole.id}`)
.set('Authorization', token)
.send(roleData)
.expect(200);
const refetchedViewerRole = await viewerRole
.$query()
.withGraphFetched({ permissions: true });
const expectedPayload = await updateRoleMock(
{
...refetchedViewerRole,
...roleData,
isAdmin: false,
},
[
{
...refetchedViewerRole.permissions[0],
...roleData.permissions[0],
},
]
);
expect(response.body).toStrictEqual(expectedPayload);
});
it('should return the updated role with sanitized permissions', async () => {
const validPermission = {
action: 'create',
subject: 'Connection',
conditions: ['isCreator'],
};
const invalidPermission = {
action: 'publish',
subject: 'Connection',
conditions: ['isCreator'],
};
const roleData = {
permissions: [validPermission, invalidPermission],
};
const response = await request(app)
.patch(`/api/v1/admin/roles/${viewerRole.id}`)
.set('Authorization', token)
.send(roleData)
.expect(200);
const refetchedViewerRole = await viewerRole.$query().withGraphFetched({
permissions: true,
});
const expectedPayload = updateRoleMock(refetchedViewerRole, [
{
...refetchedViewerRole.permissions[0],
...validPermission,
},
]);
expect(response.body).toStrictEqual(expectedPayload);
});
it('should return not authorized response for updating admin role', async () => {
const roleData = {
name: 'Updated role name',
description: 'A new description',
permissions: [
{
action: 'read',
subject: 'Execution',
conditions: ['isCreator'],
},
],
};
await request(app)
.patch(`/api/v1/admin/roles/${adminRole.id}`)
.set('Authorization', token)
.send(roleData)
.expect(403);
});
it('should return unprocessable entity response for invalid role data', async () => {
const roleData = {
description: 123,
permissions: [],
};
const response = await request(app)
.patch(`/api/v1/admin/roles/${viewerRole.id}`)
.set('Authorization', token)
.send(roleData)
.expect(422);
expect(response.body).toStrictEqual({
errors: {
description: ['must be string,null'],
},
meta: {
type: 'ModelValidation',
},
});
});
it('should return unique violation response for duplicate role data', async () => {
await createRole({ name: 'Editor' });
const roleData = {
name: 'Editor',
permissions: [],
};
const response = await request(app)
.patch(`/api/v1/admin/roles/${viewerRole.id}`)
.set('Authorization', token)
.send(roleData)
.expect(422);
expect(response.body).toStrictEqual({
errors: {
name: ["'name' must be unique."],
},
meta: {
type: 'UniqueViolationError',
},
});
});
});

Some files were not shown because too many files have changed in this diff Show More