@budibase/server 1.0.167 → 1.0.170

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 (175) hide show
  1. package/__mocks__/pg.ts +3 -1
  2. package/builder/assets/{index.9ee2182c.js → index.12a8256a.js} +1 -1
  3. package/builder/index.html +1 -1
  4. package/coverage/clover.xml +64 -51
  5. package/coverage/coverage-final.json +5 -5
  6. package/coverage/lcov-report/api/controllers/analytics.js.html +1 -1
  7. package/coverage/lcov-report/api/controllers/apikeys.js.html +1 -1
  8. package/coverage/lcov-report/api/controllers/auth.js.html +1 -1
  9. package/coverage/lcov-report/api/controllers/automation.js.html +1 -1
  10. package/coverage/lcov-report/api/controllers/backup.js.html +1 -1
  11. package/coverage/lcov-report/api/controllers/cloud.js.html +1 -1
  12. package/coverage/lcov-report/api/controllers/component.js.html +1 -1
  13. package/coverage/lcov-report/api/controllers/datasource.js.html +1 -1
  14. package/coverage/lcov-report/api/controllers/dev.js.html +1 -1
  15. package/coverage/lcov-report/api/controllers/index.html +1 -1
  16. package/coverage/lcov-report/api/controllers/integration.js.html +1 -1
  17. package/coverage/lcov-report/api/controllers/layout.js.html +1 -1
  18. package/coverage/lcov-report/api/controllers/metadata.js.html +1 -1
  19. package/coverage/lcov-report/api/controllers/migrations.js.html +1 -1
  20. package/coverage/lcov-report/api/controllers/permission.js.html +1 -1
  21. package/coverage/lcov-report/api/controllers/query/index.html +1 -1
  22. package/coverage/lcov-report/api/controllers/query/validation.js.html +1 -1
  23. package/coverage/lcov-report/api/controllers/role.js.html +1 -1
  24. package/coverage/lcov-report/api/controllers/routing.js.html +1 -1
  25. package/coverage/lcov-report/api/controllers/row/external.js.html +1 -1
  26. package/coverage/lcov-report/api/controllers/row/index.html +1 -1
  27. package/coverage/lcov-report/api/controllers/row/internal.js.html +1 -1
  28. package/coverage/lcov-report/api/controllers/row/internalSearch.js.html +1 -1
  29. package/coverage/lcov-report/api/controllers/row/staticFormula.js.html +1 -1
  30. package/coverage/lcov-report/api/controllers/row/utils.js.html +1 -1
  31. package/coverage/lcov-report/api/controllers/screen.js.html +1 -1
  32. package/coverage/lcov-report/api/controllers/script.js.html +1 -1
  33. package/coverage/lcov-report/api/controllers/table/bulkFormula.js.html +1 -1
  34. package/coverage/lcov-report/api/controllers/table/external.js.html +1 -1
  35. package/coverage/lcov-report/api/controllers/table/index.html +1 -1
  36. package/coverage/lcov-report/api/controllers/table/index.js.html +1 -1
  37. package/coverage/lcov-report/api/controllers/templates.js.html +1 -1
  38. package/coverage/lcov-report/api/controllers/user.js.html +1 -1
  39. package/coverage/lcov-report/api/controllers/view/exporters.js.html +1 -1
  40. package/coverage/lcov-report/api/controllers/view/index.html +1 -1
  41. package/coverage/lcov-report/api/controllers/view/index.js.html +1 -1
  42. package/coverage/lcov-report/api/controllers/view/utils.js.html +1 -1
  43. package/coverage/lcov-report/api/controllers/view/viewBuilder.js.html +1 -1
  44. package/coverage/lcov-report/api/controllers/webhook.js.html +1 -1
  45. package/coverage/lcov-report/api/index.html +1 -1
  46. package/coverage/lcov-report/api/index.js.html +1 -1
  47. package/coverage/lcov-report/api/routes/analytics.js.html +1 -1
  48. package/coverage/lcov-report/api/routes/apikeys.js.html +1 -1
  49. package/coverage/lcov-report/api/routes/auth.js.html +1 -1
  50. package/coverage/lcov-report/api/routes/automation.js.html +1 -1
  51. package/coverage/lcov-report/api/routes/backup.js.html +1 -1
  52. package/coverage/lcov-report/api/routes/cloud.js.html +1 -1
  53. package/coverage/lcov-report/api/routes/component.js.html +1 -1
  54. package/coverage/lcov-report/api/routes/datasource.js.html +1 -1
  55. package/coverage/lcov-report/api/routes/deploy.js.html +1 -1
  56. package/coverage/lcov-report/api/routes/dev.js.html +1 -1
  57. package/coverage/lcov-report/api/routes/index.html +1 -1
  58. package/coverage/lcov-report/api/routes/integration.js.html +1 -1
  59. package/coverage/lcov-report/api/routes/layout.js.html +1 -1
  60. package/coverage/lcov-report/api/routes/metadata.js.html +1 -1
  61. package/coverage/lcov-report/api/routes/migrations.js.html +1 -1
  62. package/coverage/lcov-report/api/routes/permission.js.html +1 -1
  63. package/coverage/lcov-report/api/routes/query.js.html +1 -1
  64. package/coverage/lcov-report/api/routes/role.js.html +1 -1
  65. package/coverage/lcov-report/api/routes/routing.js.html +1 -1
  66. package/coverage/lcov-report/api/routes/screen.js.html +1 -1
  67. package/coverage/lcov-report/api/routes/script.js.html +1 -1
  68. package/coverage/lcov-report/api/routes/table.js.html +1 -1
  69. package/coverage/lcov-report/api/routes/templates.js.html +1 -1
  70. package/coverage/lcov-report/api/routes/user.js.html +1 -1
  71. package/coverage/lcov-report/api/routes/utils/index.html +1 -1
  72. package/coverage/lcov-report/api/routes/utils/validators.js.html +1 -1
  73. package/coverage/lcov-report/api/routes/view.js.html +1 -1
  74. package/coverage/lcov-report/api/routes/webhook.js.html +1 -1
  75. package/coverage/lcov-report/automations/actions.js.html +1 -1
  76. package/coverage/lcov-report/automations/automationUtils.js.html +1 -1
  77. package/coverage/lcov-report/automations/bullboard.js.html +1 -1
  78. package/coverage/lcov-report/automations/index.html +1 -1
  79. package/coverage/lcov-report/automations/index.js.html +1 -1
  80. package/coverage/lcov-report/automations/steps/bash.js.html +1 -1
  81. package/coverage/lcov-report/automations/steps/delay.js.html +1 -1
  82. package/coverage/lcov-report/automations/steps/discord.js.html +1 -1
  83. package/coverage/lcov-report/automations/steps/executeQuery.js.html +1 -1
  84. package/coverage/lcov-report/automations/steps/executeScript.js.html +1 -1
  85. package/coverage/lcov-report/automations/steps/filter.js.html +1 -1
  86. package/coverage/lcov-report/automations/steps/index.html +1 -1
  87. package/coverage/lcov-report/automations/steps/integromat.js.html +1 -1
  88. package/coverage/lcov-report/automations/steps/loop.js.html +1 -1
  89. package/coverage/lcov-report/automations/steps/outgoingWebhook.js.html +1 -1
  90. package/coverage/lcov-report/automations/steps/queryRows.js.html +1 -1
  91. package/coverage/lcov-report/automations/steps/sendSmtpEmail.js.html +1 -1
  92. package/coverage/lcov-report/automations/steps/serverLog.js.html +1 -1
  93. package/coverage/lcov-report/automations/steps/slack.js.html +1 -1
  94. package/coverage/lcov-report/automations/steps/updateRow.js.html +1 -1
  95. package/coverage/lcov-report/automations/steps/utils.js.html +1 -1
  96. package/coverage/lcov-report/automations/steps/zapier.js.html +1 -1
  97. package/coverage/lcov-report/automations/triggerInfo/app.js.html +1 -1
  98. package/coverage/lcov-report/automations/triggerInfo/cron.js.html +1 -1
  99. package/coverage/lcov-report/automations/triggerInfo/index.html +1 -1
  100. package/coverage/lcov-report/automations/triggerInfo/index.js.html +1 -1
  101. package/coverage/lcov-report/automations/triggerInfo/rowDeleted.js.html +1 -1
  102. package/coverage/lcov-report/automations/triggerInfo/rowSaved.js.html +1 -1
  103. package/coverage/lcov-report/automations/triggerInfo/rowUpdated.js.html +1 -1
  104. package/coverage/lcov-report/automations/triggerInfo/webhook.js.html +1 -1
  105. package/coverage/lcov-report/automations/triggers.js.html +1 -1
  106. package/coverage/lcov-report/constants/index.html +1 -1
  107. package/coverage/lcov-report/constants/index.js.html +1 -1
  108. package/coverage/lcov-report/constants/layouts.js.html +1 -1
  109. package/coverage/lcov-report/constants/screens.js.html +1 -1
  110. package/coverage/lcov-report/db/inMemoryView.js.html +1 -1
  111. package/coverage/lcov-report/db/index.html +1 -1
  112. package/coverage/lcov-report/db/index.js.html +1 -1
  113. package/coverage/lcov-report/db/linkedRows/LinkController.js.html +1 -1
  114. package/coverage/lcov-report/db/linkedRows/index.html +1 -1
  115. package/coverage/lcov-report/db/linkedRows/index.js.html +1 -1
  116. package/coverage/lcov-report/db/linkedRows/linkUtils.js.html +1 -1
  117. package/coverage/lcov-report/db/newid.js.html +1 -1
  118. package/coverage/lcov-report/db/utils.js.html +6 -6
  119. package/coverage/lcov-report/events/AutomationEmitter.js.html +1 -1
  120. package/coverage/lcov-report/events/index.html +1 -1
  121. package/coverage/lcov-report/events/index.js.html +1 -1
  122. package/coverage/lcov-report/events/utils.js.html +1 -1
  123. package/coverage/lcov-report/index.html +18 -18
  124. package/coverage/lcov-report/integrations/tests/TestConfiguration.js.html +1 -1
  125. package/coverage/lcov-report/integrations/tests/index.html +1 -1
  126. package/coverage/lcov-report/middleware/appInfo.js.html +1 -1
  127. package/coverage/lcov-report/middleware/builder.js.html +1 -1
  128. package/coverage/lcov-report/middleware/currentapp.js.html +1 -1
  129. package/coverage/lcov-report/middleware/index.html +1 -1
  130. package/coverage/lcov-report/middleware/joi-validator.js.html +1 -1
  131. package/coverage/lcov-report/middleware/publicApi.js.html +1 -1
  132. package/coverage/lcov-report/middleware/resourceId.js.html +1 -1
  133. package/coverage/lcov-report/middleware/selfhost.js.html +1 -1
  134. package/coverage/lcov-report/middleware/utils.js.html +1 -1
  135. package/coverage/lcov-report/threads/automation.js.html +1 -1
  136. package/coverage/lcov-report/threads/index.html +1 -1
  137. package/coverage/lcov-report/threads/query.js.html +1 -1
  138. package/coverage/lcov-report/threads/utils.js.html +1 -1
  139. package/coverage/lcov-report/utilities/bcrypt.js.html +1 -1
  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 +1 -1
  144. package/coverage/lcov-report/utilities/index.html +19 -19
  145. package/coverage/lcov-report/utilities/index.js.html +2 -2
  146. package/coverage/lcov-report/utilities/queue/inMemoryQueue.js.html +1 -1
  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 +23 -23
  158. package/coverage/lcov-report/utilities/usageQuota/usageQuoteReset.js.html +1 -1
  159. package/coverage/lcov-report/utilities/users.js.html +73 -10
  160. package/coverage/lcov-report/utilities/workerRequests.js.html +13 -13
  161. package/coverage/lcov.info +101 -78
  162. package/dist/api/controllers/application.js +7 -0
  163. package/dist/api/controllers/public/users.js +3 -23
  164. package/dist/environment.js +5 -1
  165. package/dist/integrations/postgres.js +36 -16
  166. package/dist/package.json +5 -5
  167. package/dist/tsconfig.build.tsbuildinfo +1 -1
  168. package/dist/utilities/users.js +21 -0
  169. package/package.json +6 -6
  170. package/scripts/load/users.js +97 -0
  171. package/src/api/controllers/application.ts +9 -0
  172. package/src/api/controllers/public/users.ts +3 -24
  173. package/src/environment.js +6 -1
  174. package/src/integrations/postgres.ts +35 -14
  175. package/src/utilities/users.js +21 -0
@@ -11,6 +11,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
11
11
  const { InternalTables } = require("../db/utils");
12
12
  const { getGlobalUser } = require("../utilities/global");
13
13
  const { getAppDB } = require("@budibase/backend-core/context");
14
+ const { getProdAppID } = require("@budibase/backend-core/db");
14
15
  exports.getFullUser = (ctx, userId) => __awaiter(void 0, void 0, void 0, function* () {
15
16
  const global = yield getGlobalUser(userId);
16
17
  let metadata;
@@ -28,3 +29,23 @@ exports.getFullUser = (ctx, userId) => __awaiter(void 0, void 0, void 0, functio
28
29
  // make sure the ID is always a local ID, not a global one
29
30
  _id: userId });
30
31
  });
32
+ exports.publicApiUserFix = ctx => {
33
+ if (!ctx.request.body) {
34
+ return ctx;
35
+ }
36
+ if (!ctx.request.body._id && ctx.params.userId) {
37
+ ctx.request.body._id = ctx.params.userId;
38
+ }
39
+ if (!ctx.request.body.roles) {
40
+ ctx.request.body.roles = {};
41
+ }
42
+ else {
43
+ const newRoles = {};
44
+ for (let [appId, role] of Object.entries(ctx.request.body.roles)) {
45
+ // @ts-ignore
46
+ newRoles[getProdAppID(appId)] = role;
47
+ }
48
+ ctx.request.body.roles = newRoles;
49
+ }
50
+ return ctx;
51
+ };
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.167",
4
+ "version": "1.0.170",
5
5
  "description": "Budibase Web Server",
6
6
  "main": "src/index.ts",
7
7
  "repository": {
@@ -69,10 +69,10 @@
69
69
  "license": "GPL-3.0",
70
70
  "dependencies": {
71
71
  "@apidevtools/swagger-parser": "^10.0.3",
72
- "@budibase/backend-core": "^1.0.167",
73
- "@budibase/client": "^1.0.167",
74
- "@budibase/pro": "1.0.166",
75
- "@budibase/string-templates": "^1.0.167",
72
+ "@budibase/backend-core": "^1.0.170",
73
+ "@budibase/client": "^1.0.170",
74
+ "@budibase/pro": "1.0.169",
75
+ "@budibase/string-templates": "^1.0.170",
76
76
  "@bull-board/api": "^3.7.0",
77
77
  "@bull-board/koa": "^3.7.0",
78
78
  "@elastic/elasticsearch": "7.10.0",
@@ -183,5 +183,5 @@
183
183
  "optionalDependencies": {
184
184
  "oracledb": "^5.3.0"
185
185
  },
186
- "gitHead": "de26757649b77235b1ce62d31b9d0d34e10112b1"
186
+ "gitHead": "8f71291cf5d14ad1f06793a475157866ce8d585b"
187
187
  }
@@ -0,0 +1,97 @@
1
+ // get the JWT secret etc
2
+ require("../../src/environment")
3
+ require("@budibase/backend-core").init()
4
+ const {
5
+ getProdAppID,
6
+ generateGlobalUserID,
7
+ } = require("@budibase/backend-core/db")
8
+ const { doInTenant, getGlobalDB } = require("@budibase/backend-core/tenancy")
9
+ const { internalSaveUser } = require("@budibase/backend-core/utils")
10
+ const { publicApiUserFix } = require("../../src/utilities/users")
11
+ const { hash } = require("@budibase/backend-core/utils")
12
+
13
+ const USER_LOAD_NUMBER = 10000
14
+ const BATCH_SIZE = 200
15
+ const PASSWORD = "test"
16
+ const TENANT_ID = "default"
17
+
18
+ const APP_ID = process.argv[2]
19
+
20
+ const words = [
21
+ "test",
22
+ "testing",
23
+ "budi",
24
+ "mail",
25
+ "age",
26
+ "risk",
27
+ "load",
28
+ "uno",
29
+ "arm",
30
+ "leg",
31
+ "pen",
32
+ "glass",
33
+ "box",
34
+ "chicken",
35
+ "bottle",
36
+ ]
37
+
38
+ if (!APP_ID) {
39
+ console.error("Must supply app ID as first CLI option!")
40
+ process.exit(-1)
41
+ }
42
+
43
+ const WORD_1 = words[Math.floor(Math.random() * words.length)]
44
+ const WORD_2 = words[Math.floor(Math.random() * words.length)]
45
+ let HASHED_PASSWORD
46
+
47
+ function generateUser(count) {
48
+ return {
49
+ _id: generateGlobalUserID(),
50
+ password: HASHED_PASSWORD,
51
+ email: `${WORD_1}${count}@${WORD_2}.com`,
52
+ roles: {
53
+ [getProdAppID(APP_ID)]: "BASIC",
54
+ },
55
+ status: "active",
56
+ forceResetPassword: false,
57
+ firstName: "John",
58
+ lastName: "Smith",
59
+ }
60
+ }
61
+
62
+ async function run() {
63
+ HASHED_PASSWORD = await hash(PASSWORD)
64
+ return doInTenant(TENANT_ID, async () => {
65
+ const db = getGlobalDB()
66
+ for (let i = 0; i < USER_LOAD_NUMBER; i += BATCH_SIZE) {
67
+ let userSavePromises = []
68
+ for (let j = 0; j < BATCH_SIZE; j++) {
69
+ // like the public API
70
+ const ctx = publicApiUserFix({
71
+ request: {
72
+ body: generateUser(i + j),
73
+ },
74
+ })
75
+ userSavePromises.push(
76
+ internalSaveUser(ctx.request.body, TENANT_ID, {
77
+ hashPassword: false,
78
+ requirePassword: true,
79
+ bulkCreate: true,
80
+ })
81
+ )
82
+ }
83
+ const users = await Promise.all(userSavePromises)
84
+ await db.bulkDocs(users)
85
+ console.log(`${i + BATCH_SIZE} users have been created.`)
86
+ }
87
+ })
88
+ }
89
+
90
+ run()
91
+ .then(() => {
92
+ console.log(`Generated ${USER_LOAD_NUMBER} users!`)
93
+ })
94
+ .catch(err => {
95
+ console.error("Failed for reason: ", err)
96
+ process.exit(-1)
97
+ })
@@ -439,6 +439,15 @@ export const destroy = async (ctx: any) => {
439
439
  }
440
440
 
441
441
  export const sync = async (ctx: any, next: any) => {
442
+ if (env.DISABLE_AUTO_PROD_APP_SYNC) {
443
+ ctx.status = 200
444
+ ctx.body = {
445
+ message:
446
+ "App sync disabled. You can reenable with the DISABLE_AUTO_PROD_APP_SYNC environment variable.",
447
+ }
448
+ return next()
449
+ }
450
+
442
451
  const appId = ctx.params.appId
443
452
  if (!isDevAppID(appId)) {
444
453
  ctx.throw(400, "This action cannot be performed for production apps")
@@ -4,30 +4,9 @@ import {
4
4
  readGlobalUser,
5
5
  saveGlobalUser,
6
6
  } from "../../../utilities/workerRequests"
7
+ import { publicApiUserFix } from "../../../utilities/users"
7
8
  import { search as stringSearch } from "./utils"
8
9
 
9
- const { getProdAppID } = require("@budibase/backend-core/db")
10
-
11
- function fixUser(ctx: any) {
12
- if (!ctx.request.body) {
13
- return ctx
14
- }
15
- if (!ctx.request.body._id && ctx.params.userId) {
16
- ctx.request.body._id = ctx.params.userId
17
- }
18
- if (!ctx.request.body.roles) {
19
- ctx.request.body.roles = {}
20
- } else {
21
- const newRoles: { [key: string]: string } = {}
22
- for (let [appId, role] of Object.entries(ctx.request.body.roles)) {
23
- // @ts-ignore
24
- newRoles[getProdAppID(appId)] = role
25
- }
26
- ctx.request.body.roles = newRoles
27
- }
28
- return ctx
29
- }
30
-
31
10
  function getUser(ctx: any, userId?: string) {
32
11
  if (userId) {
33
12
  ctx.params = { userId }
@@ -45,7 +24,7 @@ export async function search(ctx: any, next: any) {
45
24
  }
46
25
 
47
26
  export async function create(ctx: any, next: any) {
48
- const response = await saveGlobalUser(fixUser(ctx))
27
+ const response = await saveGlobalUser(publicApiUserFix(ctx))
49
28
  ctx.body = await getUser(ctx, response._id)
50
29
  await next()
51
30
  }
@@ -61,7 +40,7 @@ export async function update(ctx: any, next: any) {
61
40
  ...ctx.request.body,
62
41
  _rev: user._rev,
63
42
  }
64
- const response = await saveGlobalUser(fixUser(ctx))
43
+ const response = await saveGlobalUser(publicApiUserFix(ctx))
65
44
  ctx.body = await getUser(ctx, response._id)
66
45
  await next()
67
46
  }
@@ -1,3 +1,5 @@
1
+ const { join } = require("path")
2
+
1
3
  function isTest() {
2
4
  return (
3
5
  process.env.NODE_ENV === "jest" ||
@@ -20,7 +22,9 @@ function isCypress() {
20
22
 
21
23
  let LOADED = false
22
24
  if (!LOADED && isDev() && !isTest()) {
23
- require("dotenv").config()
25
+ require("dotenv").config({
26
+ path: join(__dirname, "..", ".env"),
27
+ })
24
28
  LOADED = true
25
29
  }
26
30
 
@@ -57,6 +61,7 @@ module.exports = {
57
61
  JEST_WORKER_ID: process.env.JEST_WORKER_ID,
58
62
  BUDIBASE_ENVIRONMENT: process.env.BUDIBASE_ENVIRONMENT,
59
63
  DISABLE_ACCOUNT_PORTAL: process.env.DISABLE_ACCOUNT_PORTAL,
64
+ DISABLE_AUTO_PROD_APP_SYNC: process.env.DISABLE_AUTO_PROD_APP_SYNC,
60
65
  // minor
61
66
  SALT_ROUNDS: process.env.SALT_ROUNDS,
62
67
  LOGGER: process.env.LOGGER,
@@ -136,7 +136,7 @@ module PostgresModule {
136
136
  : undefined,
137
137
  }
138
138
  this.client = new Client(newConfig)
139
- this.setSchema()
139
+ this.open = false
140
140
  }
141
141
 
142
142
  getBindingIdentifier(): string {
@@ -147,7 +147,34 @@ module PostgresModule {
147
147
  return parts.join(" || ")
148
148
  }
149
149
 
150
+ async openConnection() {
151
+ await this.client.connect()
152
+ if (!this.config.schema) {
153
+ this.config.schema = "public"
154
+ }
155
+ this.client.query(`SET search_path TO ${this.config.schema}`)
156
+ this.COLUMNS_SQL = `select * from information_schema.columns where table_schema = '${this.config.schema}'`
157
+ this.open = true
158
+ }
159
+
160
+ closeConnection() {
161
+ const pg = this
162
+ return new Promise<void>((resolve, reject) => {
163
+ this.client.end((err: any) => {
164
+ pg.open = false
165
+ if (err) {
166
+ reject(err)
167
+ } else {
168
+ resolve()
169
+ }
170
+ })
171
+ })
172
+ }
173
+
150
174
  async internalQuery(query: SqlQuery, close: boolean = true) {
175
+ if (!this.open) {
176
+ await this.openConnection()
177
+ }
151
178
  const client = this.client
152
179
  this.index = 1
153
180
  // need to handle a specific issue with json data types in postgres,
@@ -164,21 +191,14 @@ module PostgresModule {
164
191
  try {
165
192
  return await client.query(query.sql, query.bindings || [])
166
193
  } catch (err) {
167
- await this.client.end()
194
+ await this.closeConnection()
168
195
  // @ts-ignore
169
196
  throw new Error(err)
170
197
  } finally {
171
- if (close) await this.client.end()
172
- }
173
- }
174
-
175
- async setSchema() {
176
- await this.client.connect()
177
- if (!this.config.schema) {
178
- this.config.schema = "public"
198
+ if (close) {
199
+ await this.closeConnection()
200
+ }
179
201
  }
180
- this.client.query(`SET search_path TO ${this.config.schema}`)
181
- this.COLUMNS_SQL = `select * from information_schema.columns where table_schema = '${this.config.schema}'`
182
202
  }
183
203
 
184
204
  /**
@@ -188,6 +208,7 @@ module PostgresModule {
188
208
  */
189
209
  async buildSchema(datasourceId: string, entities: Record<string, Table>) {
190
210
  let tableKeys: { [key: string]: string[] } = {}
211
+ await this.openConnection()
191
212
  try {
192
213
  const primaryKeysResponse = await this.client.query(
193
214
  this.PRIMARY_KEYS_SQL
@@ -251,7 +272,7 @@ module PostgresModule {
251
272
  // @ts-ignore
252
273
  throw new Error(err)
253
274
  } finally {
254
- await this.client.end()
275
+ await this.closeConnection()
255
276
  }
256
277
  }
257
278
 
@@ -283,7 +304,7 @@ module PostgresModule {
283
304
  for (let query of input) {
284
305
  responses.push(await this.internalQuery(query, false))
285
306
  }
286
- await this.client.end()
307
+ await this.closeConnection()
287
308
  return responses
288
309
  } else {
289
310
  const response = await this.internalQuery(input)
@@ -1,6 +1,7 @@
1
1
  const { InternalTables } = require("../db/utils")
2
2
  const { getGlobalUser } = require("../utilities/global")
3
3
  const { getAppDB } = require("@budibase/backend-core/context")
4
+ const { getProdAppID } = require("@budibase/backend-core/db")
4
5
 
5
6
  exports.getFullUser = async (ctx, userId) => {
6
7
  const global = await getGlobalUser(userId)
@@ -22,3 +23,23 @@ exports.getFullUser = async (ctx, userId) => {
22
23
  _id: userId,
23
24
  }
24
25
  }
26
+
27
+ exports.publicApiUserFix = ctx => {
28
+ if (!ctx.request.body) {
29
+ return ctx
30
+ }
31
+ if (!ctx.request.body._id && ctx.params.userId) {
32
+ ctx.request.body._id = ctx.params.userId
33
+ }
34
+ if (!ctx.request.body.roles) {
35
+ ctx.request.body.roles = {}
36
+ } else {
37
+ const newRoles = {}
38
+ for (let [appId, role] of Object.entries(ctx.request.body.roles)) {
39
+ // @ts-ignore
40
+ newRoles[getProdAppID(appId)] = role
41
+ }
42
+ ctx.request.body.roles = newRoles
43
+ }
44
+ return ctx
45
+ }