@budibase/server 1.0.218 → 1.0.219-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (257) hide show
  1. package/__mocks__/node-fetch.ts +9 -0
  2. package/builder/assets/index.00d6b4be.js +977 -0
  3. package/builder/assets/index.7786f497.css +6 -0
  4. package/builder/assets/{vendor.9bf2fcb4.js → vendor.001dcf8c.js} +163 -163
  5. package/builder/index.html +3 -3
  6. package/coverage/clover.xml +868 -794
  7. package/coverage/coverage-final.json +26 -26
  8. package/coverage/lcov-report/api/controllers/apikeys.js.html +1 -1
  9. package/coverage/lcov-report/api/controllers/auth.js.html +1 -1
  10. package/coverage/lcov-report/api/controllers/automation.js.html +111 -12
  11. package/coverage/lcov-report/api/controllers/backup.js.html +9 -6
  12. package/coverage/lcov-report/api/controllers/cloud.js.html +1 -1
  13. package/coverage/lcov-report/api/controllers/component.js.html +1 -1
  14. package/coverage/lcov-report/api/controllers/datasource.js.html +16 -16
  15. package/coverage/lcov-report/api/controllers/dev.js.html +1 -1
  16. package/coverage/lcov-report/api/controllers/index.html +21 -21
  17. package/coverage/lcov-report/api/controllers/integration.js.html +1 -1
  18. package/coverage/lcov-report/api/controllers/layout.js.html +1 -1
  19. package/coverage/lcov-report/api/controllers/metadata.js.html +1 -1
  20. package/coverage/lcov-report/api/controllers/migrations.js.html +1 -1
  21. package/coverage/lcov-report/api/controllers/permission.js.html +1 -1
  22. package/coverage/lcov-report/api/controllers/query/index.html +1 -1
  23. package/coverage/lcov-report/api/controllers/query/validation.js.html +1 -1
  24. package/coverage/lcov-report/api/controllers/role.js.html +1 -1
  25. package/coverage/lcov-report/api/controllers/routing.js.html +1 -1
  26. package/coverage/lcov-report/api/controllers/row/external.js.html +47 -17
  27. package/coverage/lcov-report/api/controllers/row/index.html +34 -34
  28. package/coverage/lcov-report/api/controllers/row/internal.js.html +1 -1
  29. package/coverage/lcov-report/api/controllers/row/internalSearch.js.html +95 -11
  30. package/coverage/lcov-report/api/controllers/row/staticFormula.js.html +1 -1
  31. package/coverage/lcov-report/api/controllers/row/utils.js.html +17 -8
  32. package/coverage/lcov-report/api/controllers/screen.js.html +1 -1
  33. package/coverage/lcov-report/api/controllers/script.js.html +1 -1
  34. package/coverage/lcov-report/api/controllers/table/bulkFormula.js.html +1 -1
  35. package/coverage/lcov-report/api/controllers/table/external.js.html +1 -1
  36. package/coverage/lcov-report/api/controllers/table/index.html +1 -1
  37. package/coverage/lcov-report/api/controllers/table/index.js.html +1 -1
  38. package/coverage/lcov-report/api/controllers/templates.js.html +1 -1
  39. package/coverage/lcov-report/api/controllers/user.js.html +1 -1
  40. package/coverage/lcov-report/api/controllers/view/exporters.js.html +1 -1
  41. package/coverage/lcov-report/api/controllers/view/index.html +1 -1
  42. package/coverage/lcov-report/api/controllers/view/index.js.html +1 -1
  43. package/coverage/lcov-report/api/controllers/view/utils.js.html +1 -1
  44. package/coverage/lcov-report/api/controllers/view/viewBuilder.js.html +1 -1
  45. package/coverage/lcov-report/api/controllers/webhook.js.html +1 -1
  46. package/coverage/lcov-report/api/index.html +15 -15
  47. package/coverage/lcov-report/api/index.js.html +22 -13
  48. package/coverage/lcov-report/api/routes/analytics.js.html +1 -1
  49. package/coverage/lcov-report/api/routes/apikeys.js.html +1 -1
  50. package/coverage/lcov-report/api/routes/auth.js.html +1 -1
  51. package/coverage/lcov-report/api/routes/automation.js.html +32 -2
  52. package/coverage/lcov-report/api/routes/backup.js.html +1 -1
  53. package/coverage/lcov-report/api/routes/cloud.js.html +1 -1
  54. package/coverage/lcov-report/api/routes/component.js.html +1 -1
  55. package/coverage/lcov-report/api/routes/datasource.js.html +1 -1
  56. package/coverage/lcov-report/api/routes/deploy.js.html +1 -1
  57. package/coverage/lcov-report/api/routes/dev.js.html +1 -1
  58. package/coverage/lcov-report/api/routes/index.html +1 -1
  59. package/coverage/lcov-report/api/routes/integration.js.html +1 -1
  60. package/coverage/lcov-report/api/routes/layout.js.html +1 -1
  61. package/coverage/lcov-report/api/routes/metadata.js.html +1 -1
  62. package/coverage/lcov-report/api/routes/migrations.js.html +1 -1
  63. package/coverage/lcov-report/api/routes/permission.js.html +1 -1
  64. package/coverage/lcov-report/api/routes/query.js.html +1 -1
  65. package/coverage/lcov-report/api/routes/role.js.html +1 -1
  66. package/coverage/lcov-report/api/routes/routing.js.html +1 -1
  67. package/coverage/lcov-report/api/routes/screen.js.html +1 -1
  68. package/coverage/lcov-report/api/routes/script.js.html +1 -1
  69. package/coverage/lcov-report/api/routes/table.js.html +1 -1
  70. package/coverage/lcov-report/api/routes/templates.js.html +1 -1
  71. package/coverage/lcov-report/api/routes/user.js.html +1 -1
  72. package/coverage/lcov-report/api/routes/utils/index.html +1 -1
  73. package/coverage/lcov-report/api/routes/utils/validators.js.html +1 -1
  74. package/coverage/lcov-report/api/routes/view.js.html +1 -1
  75. package/coverage/lcov-report/api/routes/webhook.js.html +1 -1
  76. package/coverage/lcov-report/automations/actions.js.html +1 -1
  77. package/coverage/lcov-report/automations/automationUtils.js.html +57 -12
  78. package/coverage/lcov-report/automations/bullboard.js.html +1 -1
  79. package/coverage/lcov-report/automations/index.html +17 -17
  80. package/coverage/lcov-report/automations/index.js.html +1 -1
  81. package/coverage/lcov-report/automations/steps/bash.js.html +1 -1
  82. package/coverage/lcov-report/automations/steps/delay.js.html +1 -1
  83. package/coverage/lcov-report/automations/steps/discord.js.html +1 -1
  84. package/coverage/lcov-report/automations/steps/executeQuery.js.html +1 -1
  85. package/coverage/lcov-report/automations/steps/executeScript.js.html +1 -1
  86. package/coverage/lcov-report/automations/steps/filter.js.html +58 -34
  87. package/coverage/lcov-report/automations/steps/index.html +11 -11
  88. package/coverage/lcov-report/automations/steps/integromat.js.html +1 -1
  89. package/coverage/lcov-report/automations/steps/loop.js.html +1 -1
  90. package/coverage/lcov-report/automations/steps/outgoingWebhook.js.html +1 -1
  91. package/coverage/lcov-report/automations/steps/queryRows.js.html +1 -1
  92. package/coverage/lcov-report/automations/steps/sendSmtpEmail.js.html +1 -1
  93. package/coverage/lcov-report/automations/steps/serverLog.js.html +1 -1
  94. package/coverage/lcov-report/automations/steps/slack.js.html +1 -1
  95. package/coverage/lcov-report/automations/steps/updateRow.js.html +1 -1
  96. package/coverage/lcov-report/automations/steps/utils.js.html +1 -1
  97. package/coverage/lcov-report/automations/steps/zapier.js.html +1 -1
  98. package/coverage/lcov-report/automations/triggerInfo/app.js.html +1 -1
  99. package/coverage/lcov-report/automations/triggerInfo/cron.js.html +1 -1
  100. package/coverage/lcov-report/automations/triggerInfo/index.html +1 -1
  101. package/coverage/lcov-report/automations/triggerInfo/index.js.html +1 -1
  102. package/coverage/lcov-report/automations/triggerInfo/rowDeleted.js.html +1 -1
  103. package/coverage/lcov-report/automations/triggerInfo/rowSaved.js.html +1 -1
  104. package/coverage/lcov-report/automations/triggerInfo/rowUpdated.js.html +1 -1
  105. package/coverage/lcov-report/automations/triggerInfo/webhook.js.html +1 -1
  106. package/coverage/lcov-report/automations/triggers.js.html +4 -4
  107. package/coverage/lcov-report/constants/index.html +1 -1
  108. package/coverage/lcov-report/constants/index.js.html +1 -1
  109. package/coverage/lcov-report/constants/layouts.js.html +1 -1
  110. package/coverage/lcov-report/constants/screens.js.html +1 -1
  111. package/coverage/lcov-report/db/inMemoryView.js.html +1 -1
  112. package/coverage/lcov-report/db/index.html +14 -14
  113. package/coverage/lcov-report/db/index.js.html +1 -1
  114. package/coverage/lcov-report/db/linkedRows/LinkController.js.html +1 -1
  115. package/coverage/lcov-report/db/linkedRows/index.html +13 -13
  116. package/coverage/lcov-report/db/linkedRows/index.js.html +10 -7
  117. package/coverage/lcov-report/db/linkedRows/linkUtils.js.html +1 -1
  118. package/coverage/lcov-report/db/newid.js.html +2 -2
  119. package/coverage/lcov-report/db/utils.js.html +27 -51
  120. package/coverage/lcov-report/events/AutomationEmitter.js.html +1 -1
  121. package/coverage/lcov-report/events/index.html +1 -1
  122. package/coverage/lcov-report/events/index.js.html +1 -1
  123. package/coverage/lcov-report/events/utils.js.html +1 -1
  124. package/coverage/lcov-report/index.html +74 -74
  125. package/coverage/lcov-report/integrations/tests/TestConfiguration.js.html +1 -1
  126. package/coverage/lcov-report/integrations/tests/index.html +1 -1
  127. package/coverage/lcov-report/middleware/appInfo.js.html +1 -1
  128. package/coverage/lcov-report/middleware/builder.js.html +12 -12
  129. package/coverage/lcov-report/middleware/currentapp.js.html +33 -33
  130. package/coverage/lcov-report/middleware/index.html +1 -1
  131. package/coverage/lcov-report/middleware/joi-validator.js.html +10 -10
  132. package/coverage/lcov-report/middleware/publicApi.js.html +1 -1
  133. package/coverage/lcov-report/middleware/resourceId.js.html +7 -7
  134. package/coverage/lcov-report/middleware/selfhost.js.html +1 -1
  135. package/coverage/lcov-report/middleware/utils.js.html +2 -2
  136. package/coverage/lcov-report/threads/automation.js.html +18 -9
  137. package/coverage/lcov-report/threads/index.html +25 -25
  138. package/coverage/lcov-report/threads/query.js.html +283 -76
  139. package/coverage/lcov-report/threads/utils.js.html +4 -4
  140. package/coverage/lcov-report/utilities/budibaseDir.js.html +1 -1
  141. package/coverage/lcov-report/utilities/centralPath.js.html +1 -1
  142. package/coverage/lcov-report/utilities/csvParser.js.html +1 -1
  143. package/coverage/lcov-report/utilities/global.js.html +14 -14
  144. package/coverage/lcov-report/utilities/index.html +1 -1
  145. package/coverage/lcov-report/utilities/index.js.html +9 -9
  146. package/coverage/lcov-report/utilities/queue/inMemoryQueue.js.html +2 -2
  147. package/coverage/lcov-report/utilities/queue/index.html +1 -1
  148. package/coverage/lcov-report/utilities/routing/index.html +1 -1
  149. package/coverage/lcov-report/utilities/routing/index.js.html +1 -1
  150. package/coverage/lcov-report/utilities/rowProcessor/index.html +1 -1
  151. package/coverage/lcov-report/utilities/rowProcessor/index.js.html +1 -1
  152. package/coverage/lcov-report/utilities/rowProcessor/utils.js.html +1 -1
  153. package/coverage/lcov-report/utilities/scriptRunner.js.html +1 -1
  154. package/coverage/lcov-report/utilities/security.js.html +2 -2
  155. package/coverage/lcov-report/utilities/statusCodes.js.html +1 -1
  156. package/coverage/lcov-report/utilities/usageQuota/index.html +1 -1
  157. package/coverage/lcov-report/utilities/usageQuota/rows.js.html +1 -1
  158. package/coverage/lcov-report/utilities/usageQuota/usageQuoteReset.js.html +1 -1
  159. package/coverage/lcov-report/utilities/users.js.html +1 -1
  160. package/coverage/lcov-report/utilities/workerRequests.js.html +1 -1
  161. package/coverage/lcov.info +1553 -1425
  162. package/dist/api/controllers/application.js +18 -15
  163. package/dist/api/controllers/automation.js +28 -2
  164. package/dist/api/controllers/backup.js +3 -2
  165. package/dist/api/controllers/query/index.js +25 -0
  166. package/dist/api/controllers/row/external.js +19 -7
  167. package/dist/api/controllers/row/internalSearch.js +22 -1
  168. package/dist/api/controllers/row/utils.js +3 -0
  169. package/dist/api/index.js +4 -1
  170. package/dist/api/routes/automation.js +2 -0
  171. package/dist/automations/automationUtils.js +16 -4
  172. package/dist/automations/logging/index.js +70 -0
  173. package/dist/automations/steps/filter.js +38 -29
  174. package/dist/automations/triggers.js +1 -1
  175. package/dist/db/linkedRows/index.js +1 -0
  176. package/dist/db/utils.js +4 -31
  177. package/dist/definitions/datasource.js +1 -0
  178. package/dist/environment.js +1 -0
  179. package/dist/integrations/airtable.js +1 -0
  180. package/dist/integrations/arangodb.js +1 -0
  181. package/dist/integrations/base/sql.js +20 -3
  182. package/dist/integrations/couchdb.js +1 -0
  183. package/dist/integrations/dynamodb.js +1 -0
  184. package/dist/integrations/elasticsearch.js +1 -0
  185. package/dist/integrations/firebase.js +1 -0
  186. package/dist/integrations/googlesheets.js +1 -0
  187. package/dist/integrations/index.js +4 -0
  188. package/dist/integrations/microsoftSqlServer.js +2 -1
  189. package/dist/integrations/mongodb.js +1 -0
  190. package/dist/integrations/mysql.js +2 -1
  191. package/dist/integrations/oracle.js +1 -0
  192. package/dist/integrations/postgres.js +2 -1
  193. package/dist/integrations/queries/sql.js +3 -0
  194. package/dist/integrations/redis.js +1 -0
  195. package/dist/integrations/rest.js +2 -1
  196. package/dist/integrations/s3.js +1 -0
  197. package/dist/integrations/snowflake.js +102 -0
  198. package/dist/package.json +7 -6
  199. package/dist/tests/utilities/TestConfiguration.js +19 -6
  200. package/dist/threads/automation.js +6 -3
  201. package/dist/threads/index.js +15 -1
  202. package/dist/threads/query.js +54 -8
  203. package/dist/tsconfig.build.tsbuildinfo +1 -1
  204. package/dist/utilities/fileSystem/index.js +16 -6
  205. package/package.json +8 -7
  206. package/scripts/integrations/oracle/instantclient/linux/arm64/basiclite-19.10.zip +0 -0
  207. package/scripts/integrations/oracle/instantclient/linux/arm64/install.sh +23 -0
  208. package/scripts/integrations/oracle/instantclient/linux/install.sh +10 -0
  209. package/src/api/controllers/application.ts +18 -14
  210. package/src/api/controllers/automation.js +35 -2
  211. package/src/api/controllers/backup.js +3 -2
  212. package/src/api/controllers/query/index.ts +29 -1
  213. package/src/api/controllers/row/external.js +19 -9
  214. package/src/api/controllers/row/internalSearch.js +28 -0
  215. package/src/api/controllers/row/utils.js +3 -0
  216. package/src/api/index.js +4 -1
  217. package/src/api/routes/automation.js +10 -0
  218. package/src/api/routes/tests/query.spec.js +166 -0
  219. package/src/automations/automationUtils.js +19 -4
  220. package/src/automations/logging/index.ts +35 -0
  221. package/src/automations/steps/filter.js +36 -28
  222. package/src/automations/tests/filter.spec.js +2 -1
  223. package/src/automations/triggers.js +1 -1
  224. package/src/db/linkedRows/index.js +1 -0
  225. package/src/db/utils.js +5 -13
  226. package/src/definitions/common.ts +1 -0
  227. package/src/definitions/datasource.ts +2 -0
  228. package/src/environment.js +1 -0
  229. package/src/integrations/airtable.ts +1 -0
  230. package/src/integrations/arangodb.ts +1 -0
  231. package/src/integrations/base/sql.ts +25 -11
  232. package/src/integrations/couchdb.ts +1 -0
  233. package/src/integrations/dynamodb.ts +1 -0
  234. package/src/integrations/elasticsearch.ts +1 -0
  235. package/src/integrations/firebase.ts +1 -0
  236. package/src/integrations/googlesheets.ts +1 -0
  237. package/src/integrations/index.ts +4 -0
  238. package/src/integrations/microsoftSqlServer.ts +2 -0
  239. package/src/integrations/mongodb.ts +1 -0
  240. package/src/integrations/mysql.ts +2 -0
  241. package/src/integrations/oracle.ts +1 -0
  242. package/src/integrations/postgres.ts +2 -0
  243. package/src/integrations/queries/sql.ts +3 -1
  244. package/src/integrations/redis.ts +1 -0
  245. package/src/integrations/rest.ts +2 -1
  246. package/src/integrations/s3.ts +1 -0
  247. package/src/integrations/snowflake.ts +99 -0
  248. package/src/integrations/tests/rest.spec.js +16 -1
  249. package/src/migrations/tests/index.spec.ts +18 -2
  250. package/src/module.d.ts +2 -0
  251. package/src/tests/utilities/TestConfiguration.js +22 -3
  252. package/src/threads/automation.js +6 -3
  253. package/src/threads/index.ts +5 -1
  254. package/src/threads/query.js +79 -10
  255. package/src/utilities/fileSystem/index.js +22 -8
  256. package/builder/assets/index.24307ca0.css +0 -6
  257. package/builder/assets/index.36419068.js +0 -1316
@@ -155,12 +155,27 @@ describe("REST Integration", () => {
155
155
  expect(output.headers["Content-Type"]).toEqual("application/json")
156
156
  })
157
157
 
158
- it("should allow XML", () => {
158
+ it("should allow raw XML", () => {
159
+ const output = config.integration.addBody("xml", "<a>1</a><b>2</b>", {})
160
+ expect(output.body.includes("<a>1</a>")).toEqual(true)
161
+ expect(output.body.includes("<b>2</b>")).toEqual(true)
162
+ expect(output.headers["Content-Type"]).toEqual("application/xml")
163
+ })
164
+
165
+ it("should allow a valid js object and parse the contents to xml", () => {
159
166
  const output = config.integration.addBody("xml", input, {})
160
167
  expect(output.body.includes("<a>1</a>")).toEqual(true)
161
168
  expect(output.body.includes("<b>2</b>")).toEqual(true)
162
169
  expect(output.headers["Content-Type"]).toEqual("application/xml")
163
170
  })
171
+
172
+ it("should allow a valid json string and parse the contents to xml", () => {
173
+ const output = config.integration.addBody("xml", JSON.stringify(input), {})
174
+ expect(output.body.includes("<a>1</a>")).toEqual(true)
175
+ expect(output.body.includes("<b>2</b>")).toEqual(true)
176
+ expect(output.headers["Content-Type"]).toEqual("application/xml")
177
+ })
178
+
164
179
  })
165
180
 
166
181
  describe("response", () => {
@@ -93,8 +93,24 @@ describe("migrations", () => {
93
93
  await clearMigrations()
94
94
  const appId = config.prodAppId
95
95
  const roles = { [appId]: "role_12345" }
96
- await config.createUser(undefined, undefined, false, true, roles) // admin only
97
- await config.createUser(undefined, undefined, false, false, roles) // non admin non builder
96
+ await config.createUser(
97
+ undefined,
98
+ undefined,
99
+ undefined,
100
+ undefined,
101
+ false,
102
+ true,
103
+ roles
104
+ ) // admin only
105
+ await config.createUser(
106
+ undefined,
107
+ undefined,
108
+ undefined,
109
+ undefined,
110
+ false,
111
+ false,
112
+ roles
113
+ ) // non admin non builder
98
114
  await config.createTable()
99
115
  await config.createRow()
100
116
  await config.createRow()
package/src/module.d.ts CHANGED
@@ -8,3 +8,5 @@ declare module "@budibase/backend-core/constants"
8
8
  declare module "@budibase/backend-core/auth"
9
9
  declare module "@budibase/backend-core/sessions"
10
10
  declare module "@budibase/backend-core/encryption"
11
+ declare module "@budibase/backend-core/utils"
12
+ declare module "@budibase/backend-core/redis"
@@ -28,6 +28,8 @@ const { encrypt } = require("@budibase/backend-core/encryption")
28
28
 
29
29
  const GLOBAL_USER_ID = "us_uuid1"
30
30
  const EMAIL = "babs@babs.com"
31
+ const FIRSTNAME = "Barbara"
32
+ const LASTNAME = "Barbington"
31
33
  const CSRF_TOKEN = "e3727778-7af0-4226-b5eb-f43cbe60a306"
32
34
 
33
35
  class TestConfiguration {
@@ -59,6 +61,15 @@ class TestConfiguration {
59
61
  return this.prodAppId
60
62
  }
61
63
 
64
+ getUserDetails() {
65
+ return {
66
+ globalId: GLOBAL_USER_ID,
67
+ email: EMAIL,
68
+ firstName: FIRSTNAME,
69
+ lastName: LASTNAME,
70
+ }
71
+ }
72
+
62
73
  async doInContext(appId, task) {
63
74
  if (!appId) {
64
75
  appId = this.appId
@@ -118,6 +129,8 @@ class TestConfiguration {
118
129
  // USER / AUTH
119
130
  async globalUser({
120
131
  id = GLOBAL_USER_ID,
132
+ firstName = FIRSTNAME,
133
+ lastName = LASTNAME,
121
134
  builder = true,
122
135
  admin = false,
123
136
  email = EMAIL,
@@ -135,6 +148,8 @@ class TestConfiguration {
135
148
  ...existing,
136
149
  roles: roles || {},
137
150
  tenantId: TENANT_ID,
151
+ firstName,
152
+ lastName,
138
153
  }
139
154
  await createASession(id, {
140
155
  sessionId: "sessionid",
@@ -161,6 +176,8 @@ class TestConfiguration {
161
176
 
162
177
  async createUser(
163
178
  id = null,
179
+ firstName = FIRSTNAME,
180
+ lastName = LASTNAME,
164
181
  email = EMAIL,
165
182
  builder = true,
166
183
  admin = false,
@@ -169,6 +186,8 @@ class TestConfiguration {
169
186
  const globalId = !id ? `us_${Math.random()}` : `us_${id}`
170
187
  const resp = await this.globalUser({
171
188
  id: globalId,
189
+ firstName,
190
+ lastName,
172
191
  email,
173
192
  builder,
174
193
  admin,
@@ -520,14 +539,14 @@ class TestConfiguration {
520
539
 
521
540
  // QUERY
522
541
 
523
- async previewQuery(request, config, datasource, fields) {
542
+ async previewQuery(request, config, datasource, fields, params, verb) {
524
543
  return request
525
544
  .post(`/api/queries/preview`)
526
545
  .send({
527
546
  datasourceId: datasource._id,
528
- parameters: {},
547
+ parameters: params || {},
529
548
  fields,
530
- queryVerb: "read",
549
+ queryVerb: verb || "read",
531
550
  name: datasource.name,
532
551
  })
533
552
  .set(config.defaultHeaders())
@@ -9,11 +9,12 @@ const { doInTenant } = require("@budibase/backend-core/tenancy")
9
9
  const { definitions: triggerDefs } = require("../automations/triggerInfo")
10
10
  const { doInAppContext, getAppDB } = require("@budibase/backend-core/context")
11
11
  const { AutomationErrors, LoopStepTypes } = require("../constants")
12
+ const { storeLog } = require("../automations/logging")
12
13
  const FILTER_STEP_ID = actions.ACTION_DEFINITIONS.FILTER.stepId
13
14
  const LOOP_STEP_ID = actions.ACTION_DEFINITIONS.LOOP.stepId
14
15
 
15
16
  const CRON_STEP_ID = triggerDefs.CRON.stepId
16
- const STOPPED_STATUS = { success: false, status: "STOPPED" }
17
+ const STOPPED_STATUS = { success: true, status: "STOPPED" }
17
18
  const { cloneDeep } = require("lodash/fp")
18
19
  const env = require("../environment")
19
20
 
@@ -218,7 +219,7 @@ class Orchestrator {
218
219
  }
219
220
  }
220
221
  if (
221
- index === parseInt(env.AUTOMATION_MAX_ITERATIONS) ||
222
+ index === env.AUTOMATION_MAX_ITERATION ||
222
223
  index === parseInt(loopStep.inputs.iterations)
223
224
  ) {
224
225
  this.updateContextAndOutput(loopStepNumber, step, tempOutput, {
@@ -275,7 +276,7 @@ class Orchestrator {
275
276
  this._context.steps[stepCount] = outputs
276
277
  // if filter causes us to stop execution don't break the loop, set a var
277
278
  // so that we can finish iterating through the steps and record that it stopped
278
- if (step.stepId === FILTER_STEP_ID && !outputs.success) {
279
+ if (step.stepId === FILTER_STEP_ID && !outputs.result) {
279
280
  stopped = true
280
281
  this.updateExecutionOutput(step.id, step.stepId, step.inputs, {
281
282
  ...outputs,
@@ -325,6 +326,8 @@ class Orchestrator {
325
326
  }
326
327
  }
327
328
 
329
+ // store the logs for the automation run
330
+ await storeLog(this._automation, this.executionOutput)
328
331
  return this.executionOutput
329
332
  }
330
333
  }
@@ -77,7 +77,7 @@ export class Thread {
77
77
  })
78
78
  }
79
79
 
80
- static shutdown() {
80
+ static stopThreads() {
81
81
  return new Promise<void>(resolve => {
82
82
  if (Thread.workerRefs.length === 0) {
83
83
  resolve()
@@ -95,4 +95,8 @@ export class Thread {
95
95
  Thread.workerRefs = []
96
96
  })
97
97
  }
98
+
99
+ static async shutdown() {
100
+ await Thread.stopThreads()
101
+ }
98
102
  }
@@ -4,6 +4,13 @@ const ScriptRunner = require("../utilities/scriptRunner")
4
4
  const { integrations } = require("../integrations")
5
5
  const { processStringSync } = require("@budibase/string-templates")
6
6
  const { doInAppContext, getAppDB } = require("@budibase/backend-core/context")
7
+ const {
8
+ refreshOAuthToken,
9
+ updateUserOAuth,
10
+ } = require("@budibase/backend-core/auth")
11
+ const { user: userCache } = require("@budibase/backend-core/cache")
12
+ const { getGlobalIDFromUserMetadataID } = require("../db/utils")
13
+
7
14
  const { isSQL } = require("../integrations/utils")
8
15
  const {
9
16
  enrichQueryFields,
@@ -21,29 +28,56 @@ class QueryRunner {
21
28
  this.queryId = input.queryId
22
29
  this.noRecursiveQuery = flags.noRecursiveQuery
23
30
  this.cachedVariables = []
31
+ // Additional context items for enrichment
32
+ this.ctx = input.ctx
24
33
  // allows the response from a query to be stored throughout this
25
34
  // execution so that if it needs to be re-used for another variable
26
35
  // it can be
27
36
  this.queryResponse = {}
28
37
  this.hasRerun = false
38
+ this.hasRefreshedOAuth = false
29
39
  }
30
40
 
31
41
  async execute() {
32
42
  let { datasource, fields, queryVerb, transformer } = this
43
+
33
44
  const Integration = integrations[datasource.source]
34
45
  if (!Integration) {
35
46
  throw "Integration type does not exist."
36
47
  }
48
+
49
+ if (datasource.config.authConfigs) {
50
+ datasource.config.authConfigs = datasource.config.authConfigs.map(
51
+ config => {
52
+ return enrichQueryFields(config, this.ctx)
53
+ }
54
+ )
55
+ }
56
+
37
57
  const integration = new Integration(datasource.config)
38
58
 
39
59
  // pre-query, make sure datasource variables are added to parameters
40
60
  const parameters = await this.addDatasourceVariables()
61
+
62
+ // Enrich the parameters with the addition context items.
63
+ // 'user' is now a reserved variable key in mapping parameters
64
+ const enrichedParameters = enrichQueryFields(parameters, this.ctx)
65
+ const enrichedContext = { ...enrichedParameters, ...this.ctx }
66
+
67
+ // Parse global headers
68
+ if (datasource.config.defaultHeaders) {
69
+ datasource.config.defaultHeaders = enrichQueryFields(
70
+ datasource.config.defaultHeaders,
71
+ enrichedContext
72
+ )
73
+ }
74
+
41
75
  let query
42
76
  // handle SQL injections by interpolating the variables
43
77
  if (isSQL(datasource)) {
44
- query = interpolateSQL(fields, parameters, integration)
78
+ query = interpolateSQL(fields, enrichedParameters, integration)
45
79
  } else {
46
- query = enrichQueryFields(fields, parameters)
80
+ query = enrichQueryFields(fields, enrichedContext)
47
81
  }
48
82
 
49
83
  // Add pagination values for REST queries
@@ -67,20 +101,24 @@ class QueryRunner {
67
101
  if (transformer) {
68
102
  const runner = new ScriptRunner(transformer, {
69
103
  data: rows,
70
- params: parameters,
104
+ params: enrichedParameters,
71
105
  })
72
106
  rows = runner.execute()
73
107
  }
74
108
 
75
109
  // if the request fails we retry once, invalidating the cached value
76
- if (
77
- info &&
78
- info.code >= 400 &&
79
- this.cachedVariables.length > 0 &&
80
- !this.hasRerun
81
- ) {
110
+ if (info && info.code >= 400 && !this.hasRerun) {
111
+ if (
112
+ this.ctx.user?.provider &&
113
+ info.code === 401 &&
114
+ !this.hasRefreshedOAuth
115
+ ) {
116
+ await this.refreshOAuth2(this.ctx)
117
+ // Attempt to refresh the access token from the provider
118
+ this.hasRefreshedOAuth = true
119
+ }
120
+
82
121
  this.hasRerun = true
83
- // invalidate the cache value
84
122
  await threadUtils.invalidateDynamicVariables(this.cachedVariables)
85
123
  return this.execute()
86
124
  }
@@ -126,6 +164,37 @@ class QueryRunner {
126
164
  ).execute()
127
165
  }
128
166
 
167
+ async refreshOAuth2(ctx) {
168
+ const { oauth2, providerType, _id } = ctx.user
169
+ const { configId } = ctx.auth
170
+
171
+ if (!providerType || !oauth2?.refreshToken) {
172
+ throw new Error("No refresh token found for authenticated user")
173
+ }
174
+
175
+ const resp = await refreshOAuthToken(
176
+ oauth2.refreshToken,
177
+ providerType,
178
+ configId
179
+ )
180
+
181
+ // Refresh session flow. Should be in same location as refreshOAuthToken
182
+ // There are several other properties available in 'resp'
183
+ if (!resp.err) {
184
+ const globalUserId = getGlobalIDFromUserMetadataID(_id)
185
+ await updateUserOAuth(globalUserId, resp)
186
+ this.ctx.user = await userCache.getUser(globalUserId)
187
+ } else {
188
+ // In this event the user may have oAuth issues that
189
+ // could require re-authenticating with their provider.
190
+ throw new Error(
191
+ "OAuth2 access token could not be refreshed: " + resp.err.toString()
192
+ )
193
+ }
194
+
195
+ return resp
196
+ }
197
+
129
198
  async getDynamicVariable(variable) {
130
199
  let { parameters } = this
131
200
  const queryId = variable.queryId,
@@ -21,6 +21,7 @@ const env = require("../../environment")
21
21
  const {
22
22
  USER_METDATA_PREFIX,
23
23
  LINK_USER_METADATA_PREFIX,
24
+ TABLE_ROW_PREFIX,
24
25
  } = require("../../db/utils")
25
26
  const MemoryStream = require("memorystream")
26
27
  const { getAppId } = require("@budibase/backend-core/context")
@@ -109,6 +110,23 @@ exports.apiFileReturn = contents => {
109
110
  return fs.createReadStream(path)
110
111
  }
111
112
 
113
+ exports.defineFilter = excludeRows => {
114
+ if (excludeRows) {
115
+ return doc =>
116
+ !(
117
+ doc._id.includes(USER_METDATA_PREFIX) ||
118
+ doc._id.includes(LINK_USER_METADATA_PREFIX) ||
119
+ doc._id.includes(TABLE_ROW_PREFIX)
120
+ )
121
+ } else if (!excludeRows) {
122
+ return doc =>
123
+ !(
124
+ doc._id.includes(USER_METDATA_PREFIX) ||
125
+ doc._id.includes(LINK_USER_METADATA_PREFIX)
126
+ )
127
+ }
128
+ }
129
+
112
130
  /**
113
131
  * Local utility to back up the database state for an app, excluding global user
114
132
  * data or user relationships.
@@ -116,14 +134,10 @@ exports.apiFileReturn = contents => {
116
134
  * @param {object} config Config to send to export DB
117
135
  * @returns {*} either a string or a stream of the backup
118
136
  */
119
- const backupAppData = async (appId, config) => {
137
+ const backupAppData = async (appId, config, includeRows) => {
120
138
  return await exports.exportDB(appId, {
121
139
  ...config,
122
- filter: doc =>
123
- !(
124
- doc._id.includes(USER_METDATA_PREFIX) ||
125
- doc._id.includes(LINK_USER_METADATA_PREFIX)
126
- ),
140
+ filter: exports.defineFilter(includeRows),
127
141
  })
128
142
  }
129
143
 
@@ -142,8 +156,8 @@ exports.performBackup = async (appId, backupName) => {
142
156
  * @param {string} appId The ID of the app which is to be backed up.
143
157
  * @returns {*} a readable stream of the backup which is written in real time
144
158
  */
145
- exports.streamBackup = async appId => {
146
- return await backupAppData(appId, { stream: true })
159
+ exports.streamBackup = async (appId, includeRows) => {
160
+ return await backupAppData(appId, { stream: true }, includeRows)
147
161
  }
148
162
 
149
163
  /**