@budibase/server 2.7.21-alpha.3 → 2.7.23

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.
@@ -20,7 +20,7 @@ import Sql from "./base/sql"
20
20
  import { PostgresColumn } from "./base/types"
21
21
  import { escapeDangerousCharacters } from "../utilities"
22
22
 
23
- import { Client, ClientConfig, types } from "pg"
23
+ import { Client, types } from "pg"
24
24
 
25
25
  // Return "date" and "timestamp" types as plain strings.
26
26
  // This lets us reference the original stored timezone.
@@ -42,8 +42,6 @@ interface PostgresConfig {
42
42
  schema: string
43
43
  ssl?: boolean
44
44
  ca?: string
45
- clientKey?: string
46
- clientCert?: string
47
45
  rejectUnauthorized?: boolean
48
46
  }
49
47
 
@@ -100,19 +98,6 @@ const SCHEMA: Integration = {
100
98
  required: false,
101
99
  },
102
100
  ca: {
103
- display: "Server CA",
104
- type: DatasourceFieldType.LONGFORM,
105
- default: false,
106
- required: false,
107
- },
108
- clientKey: {
109
- display: "Client key",
110
- type: DatasourceFieldType.LONGFORM,
111
- default: false,
112
- required: false,
113
- },
114
- clientCert: {
115
- display: "Client cert",
116
101
  type: DatasourceFieldType.LONGFORM,
117
102
  default: false,
118
103
  required: false,
@@ -159,14 +144,12 @@ class PostgresIntegration extends Sql implements DatasourcePlus {
159
144
  super(SqlClient.POSTGRES)
160
145
  this.config = config
161
146
 
162
- let newConfig: ClientConfig = {
147
+ let newConfig = {
163
148
  ...this.config,
164
149
  ssl: this.config.ssl
165
150
  ? {
166
151
  rejectUnauthorized: this.config.rejectUnauthorized,
167
152
  ca: this.config.ca,
168
- key: this.config.clientKey,
169
- cert: this.config.clientCert,
170
153
  }
171
154
  : undefined,
172
155
  }
@@ -339,8 +322,7 @@ class PostgresIntegration extends Sql implements DatasourcePlus {
339
322
  await this.openConnection()
340
323
  const columnsResponse: { rows: PostgresColumn[] } =
341
324
  await this.client.query(this.COLUMNS_SQL)
342
- const names = columnsResponse.rows.map(row => row.table_name)
343
- return [...new Set(names)]
325
+ return columnsResponse.rows.map(row => row.table_name)
344
326
  } finally {
345
327
  await this.closeConnection()
346
328
  }
@@ -103,7 +103,7 @@ export default async (ctx: UserCtx, next: any) => {
103
103
  userId,
104
104
  globalId,
105
105
  roleId,
106
- role: await roles.getRole(roleId, { defaultPublic: true }),
106
+ role: await roles.getRole(roleId),
107
107
  }
108
108
  }
109
109
 
@@ -1,4 +1,4 @@
1
- import { db as dbCore, encryption, objectStore } from "@budibase/backend-core"
1
+ import { db as dbCore, objectStore } from "@budibase/backend-core"
2
2
  import { budibaseTempDir } from "../../../utilities/budibaseDir"
3
3
  import { streamFile, createTempFolder } from "../../../utilities/fileSystem"
4
4
  import { ObjectStoreBuckets } from "../../../constants"
@@ -18,8 +18,7 @@ import { join } from "path"
18
18
  import env from "../../../environment"
19
19
 
20
20
  const uuid = require("uuid/v4")
21
- import tar from "tar"
22
-
21
+ const tar = require("tar")
23
22
  const MemoryStream = require("memorystream")
24
23
 
25
24
  interface DBDumpOpts {
@@ -31,18 +30,16 @@ interface ExportOpts extends DBDumpOpts {
31
30
  tar?: boolean
32
31
  excludeRows?: boolean
33
32
  excludeLogs?: boolean
34
- encryptPassword?: string
35
33
  }
36
34
 
37
35
  function tarFilesToTmp(tmpDir: string, files: string[]) {
38
- const fileName = `${uuid()}.tar.gz`
39
- const exportFile = join(budibaseTempDir(), fileName)
36
+ const exportFile = join(budibaseTempDir(), `${uuid()}.tar.gz`)
40
37
  tar.create(
41
38
  {
42
39
  sync: true,
43
40
  gzip: true,
44
41
  file: exportFile,
45
- noDirRecurse: false,
42
+ recursive: true,
46
43
  cwd: tmpDir,
47
44
  },
48
45
  files
@@ -127,7 +124,6 @@ export async function exportApp(appId: string, config?: ExportOpts) {
127
124
  )
128
125
  }
129
126
  }
130
-
131
127
  const downloadedPath = join(tmpPath, appPath)
132
128
  if (fs.existsSync(downloadedPath)) {
133
129
  const allFiles = fs.readdirSync(downloadedPath)
@@ -145,27 +141,12 @@ export async function exportApp(appId: string, config?: ExportOpts) {
145
141
  filter: defineFilter(config?.excludeRows, config?.excludeLogs),
146
142
  exportPath: dbPath,
147
143
  })
148
-
149
- if (config?.encryptPassword) {
150
- for (let file of fs.readdirSync(tmpPath)) {
151
- const path = join(tmpPath, file)
152
-
153
- await encryption.encryptFile(
154
- { dir: tmpPath, filename: file },
155
- config.encryptPassword
156
- )
157
-
158
- fs.rmSync(path)
159
- }
160
- }
161
-
162
144
  // if tar requested, return where the tarball is
163
145
  if (config?.tar) {
164
146
  // now the tmpPath contains both the DB export and attachments, tar this
165
147
  const tarPath = tarFilesToTmp(tmpPath, fs.readdirSync(tmpPath))
166
148
  // cleanup the tmp export files as tarball returned
167
149
  fs.rmSync(tmpPath, { recursive: true, force: true })
168
-
169
150
  return tarPath
170
151
  }
171
152
  // tar not requested, turn the directory where export is
@@ -180,20 +161,11 @@ export async function exportApp(appId: string, config?: ExportOpts) {
180
161
  * @param {boolean} excludeRows Flag to state whether the export should include data.
181
162
  * @returns {*} a readable stream of the backup which is written in real time
182
163
  */
183
- export async function streamExportApp({
184
- appId,
185
- excludeRows,
186
- encryptPassword,
187
- }: {
188
- appId: string
189
- excludeRows: boolean
190
- encryptPassword?: string
191
- }) {
164
+ export async function streamExportApp(appId: string, excludeRows: boolean) {
192
165
  const tmpPath = await exportApp(appId, {
193
166
  excludeRows,
194
167
  excludeLogs: true,
195
168
  tar: true,
196
- encryptPassword,
197
169
  })
198
170
  return streamFile(tmpPath)
199
171
  }
@@ -1,4 +1,4 @@
1
- import { db as dbCore, encryption, objectStore } from "@budibase/backend-core"
1
+ import { db as dbCore, objectStore } from "@budibase/backend-core"
2
2
  import { Database, Row } from "@budibase/types"
3
3
  import { getAutomationParams, TABLE_ROW_PREFIX } from "../../../db/utils"
4
4
  import { budibaseTempDir } from "../../../utilities/budibaseDir"
@@ -20,7 +20,6 @@ type TemplateType = {
20
20
  file?: {
21
21
  type: string
22
22
  path: string
23
- password?: string
24
23
  }
25
24
  key?: string
26
25
  }
@@ -124,22 +123,6 @@ export function untarFile(file: { path: string }) {
124
123
  return tmpPath
125
124
  }
126
125
 
127
- async function decryptFiles(path: string, password: string) {
128
- try {
129
- for (let file of fs.readdirSync(path)) {
130
- const inputPath = join(path, file)
131
- const outputPath = inputPath.replace(/\.enc$/, "")
132
- await encryption.decryptFile(inputPath, outputPath, password)
133
- fs.rmSync(inputPath)
134
- }
135
- } catch (err: any) {
136
- if (err.message === "incorrect header check") {
137
- throw new Error("File cannot be imported")
138
- }
139
- throw err
140
- }
141
- }
142
-
143
126
  export function getGlobalDBFile(tmpPath: string) {
144
127
  return fs.readFileSync(join(tmpPath, GLOBAL_DB_EXPORT_FILE), "utf8")
145
128
  }
@@ -160,9 +143,6 @@ export async function importApp(
160
143
  template.file && fs.lstatSync(template.file.path).isDirectory()
161
144
  if (template.file && (isTar || isDirectory)) {
162
145
  const tmpPath = isTar ? untarFile(template.file) : template.file.path
163
- if (isTar && template.file.password) {
164
- await decryptFiles(tmpPath, template.file.password)
165
- }
166
146
  const contents = fs.readdirSync(tmpPath)
167
147
  // have to handle object import
168
148
  if (contents.length) {
@@ -164,6 +164,5 @@ export function mergeConfigs(update: Datasource, old: Datasource) {
164
164
  delete update.config[key]
165
165
  }
166
166
  }
167
-
168
167
  return update
169
168
  }
@@ -9,7 +9,7 @@ import {
9
9
  env as coreEnv,
10
10
  } from "@budibase/backend-core"
11
11
  import { updateAppRole } from "./global"
12
- import { BBContext, User, EmailInvite } from "@budibase/types"
12
+ import { BBContext, User } from "@budibase/types"
13
13
 
14
14
  export function request(ctx?: BBContext, request?: any) {
15
15
  if (!request.headers) {
@@ -65,25 +65,15 @@ async function checkResponse(
65
65
  }
66
66
 
67
67
  // have to pass in the tenant ID as this could be coming from an automation
68
- export async function sendSmtpEmail({
69
- to,
70
- from,
71
- subject,
72
- contents,
73
- cc,
74
- bcc,
75
- automation,
76
- invite,
77
- }: {
78
- to: string
79
- from: string
80
- subject: string
81
- contents: string
82
- cc: string
83
- bcc: string
68
+ export async function sendSmtpEmail(
69
+ to: string,
70
+ from: string,
71
+ subject: string,
72
+ contents: string,
73
+ cc: string,
74
+ bcc: string,
84
75
  automation: boolean
85
- invite?: EmailInvite
86
- }) {
76
+ ) {
87
77
  // tenant ID will be set in header
88
78
  const response = await fetch(
89
79
  checkSlashesInUrl(env.WORKER_URL + `/api/global/email/send`),
@@ -98,7 +88,6 @@ export async function sendSmtpEmail({
98
88
  bcc,
99
89
  purpose: "custom",
100
90
  automation,
101
- invite,
102
91
  },
103
92
  })
104
93
  )
@@ -1,74 +0,0 @@
1
- import * as workerRequests from "../../utilities/workerRequests"
2
-
3
- jest.mock("../../utilities/workerRequests", () => ({
4
- sendSmtpEmail: jest.fn(),
5
- }))
6
-
7
- function generateResponse(to: string, from: string) {
8
- return {
9
- success: true,
10
- response: {
11
- accepted: [to],
12
- envelope: {
13
- from: from,
14
- to: [to],
15
- },
16
- message: `Email sent to ${to}.`,
17
- },
18
- }
19
- }
20
-
21
- const setup = require("./utilities")
22
-
23
- describe("test the outgoing webhook action", () => {
24
- let inputs
25
- let config = setup.getConfig()
26
- beforeAll(async () => {
27
- await config.init()
28
- })
29
-
30
- afterAll(setup.afterAll)
31
-
32
- it("should be able to run the action", async () => {
33
- jest
34
- .spyOn(workerRequests, "sendSmtpEmail")
35
- .mockImplementationOnce(async () =>
36
- generateResponse("user1@test.com", "admin@test.com")
37
- )
38
- const invite = {
39
- startTime: new Date(),
40
- endTime: new Date(),
41
- summary: "summary",
42
- location: "location",
43
- url: "url",
44
- }
45
- inputs = {
46
- to: "user1@test.com",
47
- from: "admin@test.com",
48
- subject: "hello",
49
- contents: "testing",
50
- cc: "cc",
51
- bcc: "bcc",
52
- addInvite: true,
53
- ...invite,
54
- }
55
- let resp = generateResponse(inputs.to, inputs.from)
56
- const res = await setup.runStep(
57
- setup.actions.SEND_EMAIL_SMTP.stepId,
58
- inputs
59
- )
60
- expect(res.response).toEqual(resp)
61
- expect(res.success).toEqual(true)
62
- expect(workerRequests.sendSmtpEmail).toHaveBeenCalledTimes(1)
63
- expect(workerRequests.sendSmtpEmail).toHaveBeenCalledWith({
64
- to: "user1@test.com",
65
- from: "admin@test.com",
66
- subject: "hello",
67
- contents: "testing",
68
- cc: "cc",
69
- bcc: "bcc",
70
- invite,
71
- automation: true,
72
- })
73
- })
74
- })