@budibase/server 1.0.212-alpha.13 → 1.0.212-alpha.14

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 (178) hide show
  1. package/__mocks__/node-fetch.ts +9 -0
  2. package/builder/assets/index.1f366fcc.js +977 -0
  3. package/builder/assets/{index.92958011.css → index.7786f497.css} +1 -1
  4. package/builder/assets/{vendor.b4361801.js → vendor.001dcf8c.js} +2 -2
  5. package/builder/index.html +3 -3
  6. package/coverage/clover.xml +217 -209
  7. package/coverage/coverage-final.json +14 -14
  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 +1 -1
  11. package/coverage/lcov-report/api/controllers/backup.js.html +1 -1
  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 +1 -1
  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 +1 -1
  27. package/coverage/lcov-report/api/controllers/row/index.html +1 -1
  28. package/coverage/lcov-report/api/controllers/row/internal.js.html +1 -1
  29. package/coverage/lcov-report/api/controllers/row/internalSearch.js.html +1 -1
  30. package/coverage/lcov-report/api/controllers/row/staticFormula.js.html +1 -1
  31. package/coverage/lcov-report/api/controllers/row/utils.js.html +1 -1
  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 +1 -1
  47. package/coverage/lcov-report/api/index.js.html +5 -5
  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 +1 -1
  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 +1 -1
  78. package/coverage/lcov-report/automations/bullboard.js.html +1 -1
  79. package/coverage/lcov-report/automations/index.html +1 -1
  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 +1 -1
  87. package/coverage/lcov-report/automations/steps/index.html +1 -1
  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 +1 -1
  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 +1 -1
  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 +1 -1
  116. package/coverage/lcov-report/db/linkedRows/index.js.html +1 -1
  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 +12 -12
  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 +18 -18
  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 +1 -1
  137. package/coverage/lcov-report/threads/index.html +19 -19
  138. package/coverage/lcov-report/threads/query.js.html +143 -68
  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 +1 -1
  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 +395 -381
  162. package/dist/api/controllers/query/index.js +6 -0
  163. package/dist/integrations/queries/sql.js +3 -0
  164. package/dist/integrations/rest.js +1 -1
  165. package/dist/package.json +6 -6
  166. package/dist/tests/utilities/TestConfiguration.js +19 -6
  167. package/dist/threads/query.js +18 -3
  168. package/dist/tsconfig.build.tsbuildinfo +1 -1
  169. package/package.json +7 -7
  170. package/src/api/controllers/query/index.ts +6 -0
  171. package/src/api/routes/tests/query.spec.js +166 -0
  172. package/src/integrations/queries/sql.ts +3 -1
  173. package/src/integrations/rest.ts +1 -1
  174. package/src/integrations/tests/rest.spec.js +16 -1
  175. package/src/migrations/tests/index.spec.ts +18 -2
  176. package/src/tests/utilities/TestConfiguration.js +22 -3
  177. package/src/threads/query.js +28 -3
  178. package/builder/assets/index.8653aa05.js +0 -977
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@budibase/server",
3
3
  "email": "hi@budibase.com",
4
- "version": "1.0.212-alpha.13",
4
+ "version": "1.0.212-alpha.14",
5
5
  "description": "Budibase Web Server",
6
6
  "main": "src/index.ts",
7
7
  "repository": {
@@ -77,11 +77,11 @@
77
77
  "license": "GPL-3.0",
78
78
  "dependencies": {
79
79
  "@apidevtools/swagger-parser": "10.0.3",
80
- "@budibase/backend-core": "^1.0.212-alpha.13",
81
- "@budibase/client": "^1.0.212-alpha.13",
82
- "@budibase/pro": "1.0.212-alpha.12",
83
- "@budibase/string-templates": "^1.0.212-alpha.13",
84
- "@budibase/types": "^1.0.212-alpha.13",
80
+ "@budibase/backend-core": "^1.0.212-alpha.14",
81
+ "@budibase/client": "^1.0.212-alpha.14",
82
+ "@budibase/pro": "1.0.212-alpha.13",
83
+ "@budibase/string-templates": "^1.0.212-alpha.14",
84
+ "@budibase/types": "^1.0.212-alpha.14",
85
85
  "@bull-board/api": "3.7.0",
86
86
  "@bull-board/koa": "3.9.4",
87
87
  "@elastic/elasticsearch": "7.10.0",
@@ -195,5 +195,5 @@
195
195
  "optionalDependencies": {
196
196
  "oracledb": "5.3.0"
197
197
  },
198
- "gitHead": "1b460f45a10f98573cb9fe7ca5269550155c5bed"
198
+ "gitHead": "5147929cb55fe0ad5fa21adf64774458b7176c7e"
199
199
  }
@@ -129,6 +129,9 @@ export async function preview(ctx: any) {
129
129
  parameters,
130
130
  transformer,
131
131
  queryId,
132
+ ctx: {
133
+ user: ctx.user,
134
+ },
132
135
  })
133
136
 
134
137
  const { rows, keys, info, extra } = await quotas.addQuery(runFn)
@@ -172,6 +175,9 @@ async function execute(ctx: any, opts = { rowsOnly: false }) {
172
175
  parameters: enrichedParameters,
173
176
  transformer: query.transformer,
174
177
  queryId: ctx.params.queryId,
178
+ ctx: {
179
+ user: ctx.user,
180
+ },
175
181
  })
176
182
 
177
183
  const { rows, pagination, extra } = await quotas.addQuery(runFn)
@@ -346,4 +346,170 @@ describe("/queries", () => {
346
346
  expect(contents).toBe(null)
347
347
  })
348
348
  })
349
+
350
+ describe("Current User Request Mapping", () => {
351
+
352
+ async function previewGet(datasource, fields, params) {
353
+ return config.previewQuery(request, config, datasource, fields, params)
354
+ }
355
+
356
+ async function previewPost(datasource, fields, params) {
357
+ return config.previewQuery(request, config, datasource, fields, params, "create")
358
+ }
359
+
360
+ it("should parse global and query level header mappings", async () => {
361
+ const userDetails = config.getUserDetails()
362
+
363
+ const datasource = await config.restDatasource({
364
+ defaultHeaders: {
365
+ "test": "headerVal",
366
+ "emailHdr": "{{[user].[email]}}"
367
+ }
368
+ })
369
+ const res = await previewGet(datasource, {
370
+ path: "www.google.com",
371
+ queryString: "email={{[user].[email]}}",
372
+ headers: {
373
+ queryHdr : "{{[user].[firstName]}}",
374
+ secondHdr : "1234"
375
+ }
376
+ })
377
+
378
+ const parsedRequest = JSON.parse(res.body.extra.raw)
379
+ expect(parsedRequest.opts.headers).toEqual({
380
+ "test": "headerVal",
381
+ "emailHdr": userDetails.email,
382
+ "queryHdr": userDetails.firstName,
383
+ "secondHdr" : "1234"
384
+ })
385
+ expect(res.body.rows[0].url).toEqual("http://www.google.com?email=" + userDetails.email)
386
+ })
387
+
388
+ it("should bind the current user to query parameters", async () => {
389
+ const userDetails = config.getUserDetails()
390
+
391
+ const datasource = await config.restDatasource()
392
+
393
+ const res = await previewGet(datasource, {
394
+ path: "www.google.com",
395
+ queryString: "test={{myEmail}}&testName={{myName}}&testParam={{testParam}}",
396
+ }, {
397
+ "myEmail" : "{{[user].[email]}}",
398
+ "myName" : "{{[user].[firstName]}}",
399
+ "testParam" : "1234"
400
+ })
401
+
402
+ expect(res.body.rows[0].url).toEqual("http://www.google.com?test=" + userDetails.email +
403
+ "&testName=" + userDetails.firstName + "&testParam=1234")
404
+ })
405
+
406
+ it("should bind the current user the request body - plain text", async () => {
407
+ const userDetails = config.getUserDetails()
408
+ const datasource = await config.restDatasource()
409
+
410
+ const res = await previewPost(datasource, {
411
+ path: "www.google.com",
412
+ queryString: "testParam={{testParam}}",
413
+ requestBody: "This is plain text and this is my email: {{[user].[email]}}. This is a test param: {{testParam}}",
414
+ bodyType: "text"
415
+ }, {
416
+ "testParam" : "1234"
417
+ })
418
+
419
+ const parsedRequest = JSON.parse(res.body.extra.raw)
420
+ expect(parsedRequest.opts.body).toEqual(`This is plain text and this is my email: ${userDetails.email}. This is a test param: 1234`)
421
+ expect(res.body.rows[0].url).toEqual("http://www.google.com?testParam=1234")
422
+ })
423
+
424
+ it("should bind the current user the request body - json", async () => {
425
+ const userDetails = config.getUserDetails()
426
+ const datasource = await config.restDatasource()
427
+
428
+ const res = await previewPost(datasource, {
429
+ path: "www.google.com",
430
+ queryString: "testParam={{testParam}}",
431
+ requestBody: "{\"email\":\"{{[user].[email]}}\",\"queryCode\":{{testParam}},\"userRef\":\"{{userRef}}\"}",
432
+ bodyType: "json"
433
+ }, {
434
+ "testParam" : "1234",
435
+ "userRef" : "{{[user].[firstName]}}"
436
+ })
437
+
438
+ const parsedRequest = JSON.parse(res.body.extra.raw)
439
+ const test = `{"email":"${userDetails.email}","queryCode":1234,"userRef":"${userDetails.firstName}"}`
440
+ expect(parsedRequest.opts.body).toEqual(test)
441
+ expect(res.body.rows[0].url).toEqual("http://www.google.com?testParam=1234")
442
+ })
443
+
444
+ it("should bind the current user the request body - xml", async () => {
445
+ const userDetails = config.getUserDetails()
446
+ const datasource = await config.restDatasource()
447
+
448
+ const res = await previewPost(datasource, {
449
+ path: "www.google.com",
450
+ queryString: "testParam={{testParam}}",
451
+ requestBody: "<note> <email>{{[user].[email]}}</email> <code>{{testParam}}</code> " +
452
+ "<ref>{{userId}}</ref> <somestring>testing</somestring> </note>",
453
+ bodyType: "xml"
454
+ }, {
455
+ "testParam" : "1234",
456
+ "userId" : "{{[user].[firstName]}}"
457
+ })
458
+
459
+ const parsedRequest = JSON.parse(res.body.extra.raw)
460
+ const test = `<note> <email>${userDetails.email}</email> <code>1234</code> <ref>${userDetails.firstName}</ref> <somestring>testing</somestring> </note>`
461
+
462
+ expect(parsedRequest.opts.body).toEqual(test)
463
+ expect(res.body.rows[0].url).toEqual("http://www.google.com?testParam=1234")
464
+ })
465
+
466
+ it("should bind the current user the request body - form-data", async () => {
467
+ const userDetails = config.getUserDetails()
468
+ const datasource = await config.restDatasource()
469
+
470
+ const res = await previewPost(datasource, {
471
+ path: "www.google.com",
472
+ queryString: "testParam={{testParam}}",
473
+ requestBody: "{\"email\":\"{{[user].[email]}}\",\"queryCode\":{{testParam}},\"userRef\":\"{{userRef}}\"}",
474
+ bodyType: "form"
475
+ }, {
476
+ "testParam" : "1234",
477
+ "userRef" : "{{[user].[firstName]}}"
478
+ })
479
+
480
+ const parsedRequest = JSON.parse(res.body.extra.raw)
481
+
482
+ const emailData = parsedRequest.opts.body._streams[1]
483
+ expect(emailData).toEqual(userDetails.email)
484
+
485
+ const queryCodeData = parsedRequest.opts.body._streams[4]
486
+ expect(queryCodeData).toEqual("1234")
487
+
488
+ const userRef = parsedRequest.opts.body._streams[7]
489
+ expect(userRef).toEqual(userDetails.firstName)
490
+
491
+ expect(res.body.rows[0].url).toEqual("http://www.google.com?testParam=1234")
492
+ })
493
+
494
+ it("should bind the current user the request body - encoded", async () => {
495
+ const userDetails = config.getUserDetails()
496
+ const datasource = await config.restDatasource()
497
+
498
+ const res = await previewPost(datasource, {
499
+ path: "www.google.com",
500
+ queryString: "testParam={{testParam}}",
501
+ requestBody: "{\"email\":\"{{[user].[email]}}\",\"queryCode\":{{testParam}},\"userRef\":\"{{userRef}}\"}",
502
+ bodyType: "encoded"
503
+ }, {
504
+ "testParam" : "1234",
505
+ "userRef" : "{{[user].[firstName]}}"
506
+ })
507
+ const parsedRequest = JSON.parse(res.body.extra.raw)
508
+
509
+ expect(parsedRequest.opts.body.email).toEqual(userDetails.email)
510
+ expect(parsedRequest.opts.body.queryCode).toEqual("1234")
511
+ expect(parsedRequest.opts.body.userRef).toEqual(userDetails.firstName)
512
+ })
513
+
514
+ });
349
515
  })
@@ -9,7 +9,9 @@ export function enrichQueryFields(
9
9
  parameters = {}
10
10
  ) {
11
11
  const enrichedQuery: { [key: string]: any } = Array.isArray(fields) ? [] : {}
12
-
12
+ if (!fields || !parameters) {
13
+ return enrichedQuery
14
+ }
13
15
  // enrich the fields with dynamic parameters
14
16
  for (let key of Object.keys(fields)) {
15
17
  if (fields[key] == null) {
@@ -287,7 +287,7 @@ module RestModule {
287
287
  input.body = form
288
288
  break
289
289
  case BodyTypes.XML:
290
- if (object != null) {
290
+ if (object != null && Object.keys(object).length) {
291
291
  string = new XmlBuilder().buildObject(object)
292
292
  }
293
293
  input.body = string
@@ -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()
@@ -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())
@@ -21,6 +21,8 @@ class QueryRunner {
21
21
  this.queryId = input.queryId
22
22
  this.noRecursiveQuery = flags.noRecursiveQuery
23
23
  this.cachedVariables = []
24
+ // Additional context items for enrichment
25
+ this.ctx = input.ctx
24
26
  // allows the response from a query to be stored throughout this
25
27
  // execution so that if it needs to be re-used for another variable
26
28
  // it can be
@@ -34,16 +36,39 @@ class QueryRunner {
34
36
  if (!Integration) {
35
37
  throw "Integration type does not exist."
36
38
  }
39
+
40
+ if (datasource.config.authConfigs) {
41
+ datasource.config.authConfigs = datasource.config.authConfigs.map(
42
+ config => {
43
+ return enrichQueryFields(config, this.ctx)
44
+ }
45
+ )
46
+ }
47
+
37
48
  const integration = new Integration(datasource.config)
38
49
 
39
50
  // pre-query, make sure datasource variables are added to parameters
40
51
  const parameters = await this.addDatasourceVariables()
52
+
53
+ // Enrich the parameters with the addition context items.
54
+ // 'user' is now a reserved variable key in mapping parameters
55
+ const enrichedParameters = enrichQueryFields(parameters, this.ctx)
56
+ const enrichedContext = { ...enrichedParameters, ...this.ctx }
57
+
58
+ // Parse global headers
59
+ if (datasource.config.defaultHeaders) {
60
+ datasource.config.defaultHeaders = enrichQueryFields(
61
+ datasource.config.defaultHeaders,
62
+ enrichedContext
63
+ )
64
+ }
65
+
41
66
  let query
42
67
  // handle SQL injections by interpolating the variables
43
68
  if (isSQL(datasource)) {
44
- query = interpolateSQL(fields, parameters, integration)
69
+ query = interpolateSQL(fields, enrichedParameters, integration)
45
70
  } else {
46
- query = enrichQueryFields(fields, parameters)
71
+ query = enrichQueryFields(fields, enrichedContext)
47
72
  }
48
73
 
49
74
  // Add pagination values for REST queries
@@ -67,7 +92,7 @@ class QueryRunner {
67
92
  if (transformer) {
68
93
  const runner = new ScriptRunner(transformer, {
69
94
  data: rows,
70
- params: parameters,
95
+ params: enrichedParameters,
71
96
  })
72
97
  rows = runner.execute()
73
98
  }