@budibase/worker 2.1.22-alpha.6 → 2.1.22-alpha.8

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 (123) hide show
  1. package/coverage/clover.xml +326 -305
  2. package/coverage/coverage-final.json +13 -13
  3. package/coverage/lcov-report/index.html +34 -34
  4. package/coverage/lcov-report/src/api/controllers/global/auth.ts.html +50 -38
  5. package/coverage/lcov-report/src/api/controllers/global/configs.js.html +18 -18
  6. package/coverage/lcov-report/src/api/controllers/global/email.js.html +1 -1
  7. package/coverage/lcov-report/src/api/controllers/global/index.html +10 -10
  8. package/coverage/lcov-report/src/api/controllers/global/license.ts.html +1 -1
  9. package/coverage/lcov-report/src/api/controllers/global/roles.js.html +1 -1
  10. package/coverage/lcov-report/src/api/controllers/global/self.ts.html +3 -3
  11. package/coverage/lcov-report/src/api/controllers/global/templates.ts.html +1 -1
  12. package/coverage/lcov-report/src/api/controllers/global/users.ts.html +1 -1
  13. package/coverage/lcov-report/src/api/controllers/global/workspaces.js.html +1 -1
  14. package/coverage/lcov-report/src/api/controllers/system/accounts.ts.html +1 -1
  15. package/coverage/lcov-report/src/api/controllers/system/environment.ts.html +1 -1
  16. package/coverage/lcov-report/src/api/controllers/system/index.html +1 -1
  17. package/coverage/lcov-report/src/api/controllers/system/migrations.ts.html +1 -1
  18. package/coverage/lcov-report/src/api/controllers/system/restore.ts.html +1 -1
  19. package/coverage/lcov-report/src/api/controllers/system/status.ts.html +1 -1
  20. package/coverage/lcov-report/src/api/controllers/system/tenants.ts.html +1 -1
  21. package/coverage/lcov-report/src/api/index.html +1 -1
  22. package/coverage/lcov-report/src/api/index.ts.html +1 -1
  23. package/coverage/lcov-report/src/api/routes/global/auth.js.html +1 -1
  24. package/coverage/lcov-report/src/api/routes/global/configs.js.html +10 -10
  25. package/coverage/lcov-report/src/api/routes/global/email.js.html +1 -1
  26. package/coverage/lcov-report/src/api/routes/global/index.html +1 -1
  27. package/coverage/lcov-report/src/api/routes/global/license.ts.html +1 -1
  28. package/coverage/lcov-report/src/api/routes/global/roles.js.html +1 -1
  29. package/coverage/lcov-report/src/api/routes/global/self.ts.html +1 -1
  30. package/coverage/lcov-report/src/api/routes/global/templates.ts.html +3 -3
  31. package/coverage/lcov-report/src/api/routes/global/users.js.html +1 -1
  32. package/coverage/lcov-report/src/api/routes/global/workspaces.js.html +1 -1
  33. package/coverage/lcov-report/src/api/routes/index.html +1 -1
  34. package/coverage/lcov-report/src/api/routes/index.ts.html +1 -1
  35. package/coverage/lcov-report/src/api/routes/system/accounts.ts.html +1 -1
  36. package/coverage/lcov-report/src/api/routes/system/environment.ts.html +1 -1
  37. package/coverage/lcov-report/src/api/routes/system/index.html +1 -1
  38. package/coverage/lcov-report/src/api/routes/system/migrations.ts.html +1 -1
  39. package/coverage/lcov-report/src/api/routes/system/restore.ts.html +1 -1
  40. package/coverage/lcov-report/src/api/routes/system/status.ts.html +1 -1
  41. package/coverage/lcov-report/src/api/routes/system/tenants.ts.html +1 -1
  42. package/coverage/lcov-report/src/api/routes/validation/index.html +1 -1
  43. package/coverage/lcov-report/src/api/routes/validation/index.ts.html +1 -1
  44. package/coverage/lcov-report/src/api/routes/validation/users.ts.html +1 -1
  45. package/coverage/lcov-report/src/constants/index.html +10 -10
  46. package/coverage/lcov-report/src/constants/{index.js.html → index.ts.html} +92 -113
  47. package/coverage/lcov-report/src/constants/templates/index.html +1 -1
  48. package/coverage/lcov-report/src/constants/templates/index.js.html +3 -3
  49. package/coverage/lcov-report/src/db/index.html +1 -1
  50. package/coverage/lcov-report/src/db/index.ts.html +1 -1
  51. package/coverage/lcov-report/src/environment.ts.html +1 -1
  52. package/coverage/lcov-report/src/index.html +1 -1
  53. package/coverage/lcov-report/src/index.ts.html +1 -1
  54. package/coverage/lcov-report/src/middleware/cloudRestricted.js.html +3 -3
  55. package/coverage/lcov-report/src/middleware/index.html +1 -1
  56. package/coverage/lcov-report/src/migrations/functions/globalInfoSyncUsers.ts.html +1 -1
  57. package/coverage/lcov-report/src/migrations/functions/index.html +1 -1
  58. package/coverage/lcov-report/src/migrations/index.html +1 -1
  59. package/coverage/lcov-report/src/migrations/index.ts.html +1 -1
  60. package/coverage/lcov-report/src/sdk/accounts/accounts.ts.html +1 -1
  61. package/coverage/lcov-report/src/sdk/accounts/index.html +1 -1
  62. package/coverage/lcov-report/src/sdk/accounts/index.ts.html +1 -1
  63. package/coverage/lcov-report/src/sdk/index.html +1 -1
  64. package/coverage/lcov-report/src/sdk/index.ts.html +1 -1
  65. package/coverage/lcov-report/src/sdk/users/events.ts.html +1 -1
  66. package/coverage/lcov-report/src/sdk/users/index.html +1 -1
  67. package/coverage/lcov-report/src/sdk/users/index.ts.html +1 -1
  68. package/coverage/lcov-report/src/sdk/users/users.ts.html +1 -1
  69. package/coverage/lcov-report/src/tests/TestConfiguration.ts.html +31 -22
  70. package/coverage/lcov-report/src/tests/api/accounts.ts.html +1 -1
  71. package/coverage/lcov-report/src/tests/api/auth.ts.html +1 -1
  72. package/coverage/lcov-report/src/tests/api/base.ts.html +1 -1
  73. package/coverage/lcov-report/src/tests/api/configs.ts.html +1 -1
  74. package/coverage/lcov-report/src/tests/api/email.ts.html +1 -1
  75. package/coverage/lcov-report/src/tests/api/environment.ts.html +1 -1
  76. package/coverage/lcov-report/src/tests/api/index.html +1 -1
  77. package/coverage/lcov-report/src/tests/api/index.ts.html +1 -1
  78. package/coverage/lcov-report/src/tests/api/migrations.ts.html +1 -1
  79. package/coverage/lcov-report/src/tests/api/restore.ts.html +1 -1
  80. package/coverage/lcov-report/src/tests/api/self.ts.html +1 -1
  81. package/coverage/lcov-report/src/tests/api/status.ts.html +1 -1
  82. package/coverage/lcov-report/src/tests/api/tenants.ts.html +1 -1
  83. package/coverage/lcov-report/src/tests/api/users.ts.html +1 -1
  84. package/coverage/lcov-report/src/tests/controllers.js.html +1 -1
  85. package/coverage/lcov-report/src/tests/index.html +15 -15
  86. package/coverage/lcov-report/src/tests/index.ts.html +1 -1
  87. package/coverage/lcov-report/src/tests/mocks/email.js.html +1 -1
  88. package/coverage/lcov-report/src/tests/mocks/index.html +1 -1
  89. package/coverage/lcov-report/src/tests/mocks/index.ts.html +1 -1
  90. package/coverage/lcov-report/src/tests/structures/configs.js.html +7 -7
  91. package/coverage/lcov-report/src/tests/structures/groups.ts.html +1 -1
  92. package/coverage/lcov-report/src/tests/structures/index.html +1 -1
  93. package/coverage/lcov-report/src/tests/structures/index.ts.html +1 -1
  94. package/coverage/lcov-report/src/tests/structures/users.ts.html +1 -1
  95. package/coverage/lcov-report/src/utilities/appService.js.html +4 -4
  96. package/coverage/lcov-report/src/utilities/{email.js.html → email.ts.html} +160 -61
  97. package/coverage/lcov-report/src/utilities/fileSystem.js.html +1 -1
  98. package/coverage/lcov-report/src/utilities/index.html +23 -23
  99. package/coverage/lcov-report/src/utilities/index.js.html +1 -1
  100. package/coverage/lcov-report/src/utilities/{redis.js.html → redis.ts.html} +53 -38
  101. package/coverage/lcov-report/src/utilities/{templates.js.html → templates.ts.html} +38 -38
  102. package/coverage/lcov-report/src/utilities/users.js.html +1 -1
  103. package/coverage/lcov.info +593 -529
  104. package/jest.config.ts +1 -0
  105. package/package.json +6 -6
  106. package/src/api/controllers/global/auth.ts +34 -30
  107. package/src/api/controllers/global/configs.js +17 -17
  108. package/src/api/controllers/global/self.ts +2 -2
  109. package/src/api/routes/global/configs.js +9 -9
  110. package/src/api/routes/global/templates.ts +2 -2
  111. package/src/api/routes/global/tests/configs.spec.ts +29 -29
  112. package/src/constants/{index.js → index.ts} +57 -64
  113. package/src/constants/templates/index.js +2 -2
  114. package/src/middleware/cloudRestricted.js +2 -2
  115. package/src/middleware/tests/tenancy.spec.ts +7 -7
  116. package/src/tests/TestConfiguration.ts +15 -12
  117. package/src/tests/structures/configs.js +6 -6
  118. package/src/utilities/appService.js +3 -3
  119. package/src/utilities/{email.js → email.ts} +78 -45
  120. package/src/utilities/{redis.js → redis.ts} +29 -24
  121. package/src/utilities/templates.ts +49 -0
  122. package/tsconfig.build.json +3 -3
  123. package/src/utilities/templates.js +0 -49
@@ -1,97 +1,97 @@
1
- const { Configs } = require("@budibase/backend-core/constants")
1
+ import { constants } from "@budibase/backend-core"
2
2
 
3
- exports.LOGO_URL =
3
+ export const LOGO_URL =
4
4
  "https://d33wubrfki0l68.cloudfront.net/aac32159d7207b5085e74a7ef67afbb7027786c5/2b1fd/img/logo/bb-emblem.svg"
5
5
 
6
- exports.UserStatus = {
7
- ACTIVE: "active",
8
- INACTIVE: "inactive",
6
+ export enum UserStatus {
7
+ ACTIVE = "active",
8
+ INACTIVE = "inactive",
9
9
  }
10
10
 
11
- exports.Configs = Configs
11
+ export const Config = constants.Config
12
12
 
13
- exports.ConfigUploads = {
14
- LOGO: "logo",
15
- OIDC_LOGO: "oidc_logo",
13
+ export enum ConfigUpload {
14
+ LOGO = "logo",
15
+ OIDC_LOGO = "oidc_logo",
16
16
  }
17
17
 
18
- const TemplateTypes = {
19
- EMAIL: "email",
18
+ export enum TemplateType {
19
+ EMAIL = "email",
20
20
  }
21
21
 
22
- const EmailTemplatePurpose = {
23
- BASE: "base",
24
- PASSWORD_RECOVERY: "password_recovery",
25
- INVITATION: "invitation",
26
- WELCOME: "welcome",
27
- CUSTOM: "custom",
22
+ export enum EmailTemplatePurpose {
23
+ BASE = "base",
24
+ PASSWORD_RECOVERY = "password_recovery",
25
+ INVITATION = "invitation",
26
+ WELCOME = "welcome",
27
+ CUSTOM = "custom",
28
28
  }
29
29
 
30
- const InternalTemplateBindings = {
31
- PLATFORM_URL: "platformUrl",
32
- COMPANY: "company",
33
- LOGO_URL: "logoUrl",
34
- EMAIL: "email",
35
- USER: "user",
36
- REQUEST: "request",
37
- DOCS_URL: "docsUrl",
38
- LOGIN_URL: "loginUrl",
39
- CURRENT_YEAR: "currentYear",
40
- CURRENT_DATE: "currentDate",
41
- BODY: "body",
42
- STYLES: "styles",
43
- RESET_URL: "resetUrl",
44
- RESET_CODE: "resetCode",
45
- INVITE_URL: "inviteUrl",
46
- INVITE_CODE: "inviteUrl",
47
- CONTENTS: "contents",
30
+ export enum InternalTemplateBinding {
31
+ PLATFORM_URL = "platformUrl",
32
+ COMPANY = "company",
33
+ LOGO_URL = "logoUrl",
34
+ EMAIL = "email",
35
+ USER = "user",
36
+ REQUEST = "request",
37
+ DOCS_URL = "docsUrl",
38
+ LOGIN_URL = "loginUrl",
39
+ CURRENT_YEAR = "currentYear",
40
+ CURRENT_DATE = "currentDate",
41
+ BODY = "body",
42
+ STYLES = "styles",
43
+ RESET_URL = "resetUrl",
44
+ RESET_CODE = "resetCode",
45
+ INVITE_URL = "inviteUrl",
46
+ INVITE_CODE = "inviteUrl",
47
+ CONTENTS = "contents",
48
48
  }
49
49
 
50
- const TemplateBindings = {
50
+ export const TemplateBindings = {
51
51
  PLATFORM_URL: {
52
- name: InternalTemplateBindings.PLATFORM_URL,
52
+ name: InternalTemplateBinding.PLATFORM_URL,
53
53
  description: "The URL used to access the budibase platform",
54
54
  },
55
55
  COMPANY: {
56
- name: InternalTemplateBindings.COMPANY,
56
+ name: InternalTemplateBinding.COMPANY,
57
57
  description: "The name of your organization",
58
58
  },
59
59
  LOGO_URL: {
60
- name: InternalTemplateBindings.LOGO_URL,
60
+ name: InternalTemplateBinding.LOGO_URL,
61
61
  description: "The URL of your organizations logo.",
62
62
  },
63
63
  EMAIL: {
64
- name: InternalTemplateBindings.EMAIL,
64
+ name: InternalTemplateBinding.EMAIL,
65
65
  description: "The recipients email address.",
66
66
  },
67
67
  USER: {
68
- name: InternalTemplateBindings.USER,
68
+ name: InternalTemplateBinding.USER,
69
69
  description: "The recipients user object.",
70
70
  },
71
71
  REQUEST: {
72
- name: InternalTemplateBindings.REQUEST,
72
+ name: InternalTemplateBinding.REQUEST,
73
73
  description: "Additional request metadata.",
74
74
  },
75
75
  DOCS_URL: {
76
- name: InternalTemplateBindings.DOCS_URL,
76
+ name: InternalTemplateBinding.DOCS_URL,
77
77
  description: "Organization documentation URL.",
78
78
  },
79
79
  LOGIN_URL: {
80
- name: InternalTemplateBindings.LOGIN_URL,
80
+ name: InternalTemplateBinding.LOGIN_URL,
81
81
  description: "The URL used to log into the organization budibase instance.",
82
82
  },
83
83
  CURRENT_YEAR: {
84
- name: InternalTemplateBindings.CURRENT_YEAR,
84
+ name: InternalTemplateBinding.CURRENT_YEAR,
85
85
  description: "The current year.",
86
86
  },
87
87
  CURRENT_DATE: {
88
- name: InternalTemplateBindings.CURRENT_DATE,
88
+ name: InternalTemplateBinding.CURRENT_DATE,
89
89
  description: "The current date.",
90
90
  },
91
91
  }
92
92
 
93
- const TemplateMetadata = {
94
- [TemplateTypes.EMAIL]: [
93
+ export const TemplateMetadata = {
94
+ [TemplateType.EMAIL]: [
95
95
  {
96
96
  name: "Base format",
97
97
  description:
@@ -100,11 +100,11 @@ const TemplateMetadata = {
100
100
  purpose: EmailTemplatePurpose.BASE,
101
101
  bindings: [
102
102
  {
103
- name: InternalTemplateBindings.BODY,
103
+ name: InternalTemplateBinding.BODY,
104
104
  description: "The main body of another email template.",
105
105
  },
106
106
  {
107
- name: InternalTemplateBindings.STYLES,
107
+ name: InternalTemplateBinding.STYLES,
108
108
  description: "The contents of the Styling email template.",
109
109
  },
110
110
  ],
@@ -117,12 +117,12 @@ const TemplateMetadata = {
117
117
  purpose: EmailTemplatePurpose.PASSWORD_RECOVERY,
118
118
  bindings: [
119
119
  {
120
- name: InternalTemplateBindings.RESET_URL,
120
+ name: InternalTemplateBinding.RESET_URL,
121
121
  description:
122
122
  "The URL the recipient must click to reset their password.",
123
123
  },
124
124
  {
125
- name: InternalTemplateBindings.RESET_CODE,
125
+ name: InternalTemplateBinding.RESET_CODE,
126
126
  description:
127
127
  "The temporary password reset code used in the recipients password reset URL.",
128
128
  },
@@ -144,12 +144,12 @@ const TemplateMetadata = {
144
144
  purpose: EmailTemplatePurpose.INVITATION,
145
145
  bindings: [
146
146
  {
147
- name: InternalTemplateBindings.INVITE_URL,
147
+ name: InternalTemplateBinding.INVITE_URL,
148
148
  description:
149
149
  "The URL the recipient must click to accept the invitation and activate their account.",
150
150
  },
151
151
  {
152
- name: InternalTemplateBindings.INVITE_CODE,
152
+ name: InternalTemplateBinding.INVITE_CODE,
153
153
  description:
154
154
  "The temporary invite code used in the recipients invitation URL.",
155
155
  },
@@ -163,7 +163,7 @@ const TemplateMetadata = {
163
163
  purpose: EmailTemplatePurpose.CUSTOM,
164
164
  bindings: [
165
165
  {
166
- name: InternalTemplateBindings.CONTENTS,
166
+ name: InternalTemplateBinding.CONTENTS,
167
167
  description: "Custom content body.",
168
168
  },
169
169
  ],
@@ -172,12 +172,5 @@ const TemplateMetadata = {
172
172
  }
173
173
 
174
174
  // all purpose combined
175
- exports.TemplatePurpose = {
176
- ...EmailTemplatePurpose,
177
- }
178
- exports.TemplateTypes = TemplateTypes
179
- exports.EmailTemplatePurpose = EmailTemplatePurpose
180
- exports.TemplateMetadata = TemplateMetadata
181
- exports.TemplateBindings = TemplateBindings
182
- exports.InternalTemplateBindings = InternalTemplateBindings
183
- exports.GLOBAL_OWNER = "global"
175
+ export { EmailTemplatePurpose as TemplatePurpose }
176
+ export const GLOBAL_OWNER = "global"
@@ -1,7 +1,7 @@
1
1
  const { readStaticFile } = require("../../utilities/fileSystem")
2
2
  const {
3
3
  EmailTemplatePurpose,
4
- TemplateTypes,
4
+ TemplateType,
5
5
  TemplatePurpose,
6
6
  GLOBAL_OWNER,
7
7
  } = require("../index")
@@ -26,7 +26,7 @@ exports.EmailTemplates = {
26
26
  exports.addBaseTemplates = (templates, type = null) => {
27
27
  let purposeList
28
28
  switch (type) {
29
- case TemplateTypes.EMAIL:
29
+ case TemplateType.EMAIL:
30
30
  purposeList = Object.values(EmailTemplatePurpose)
31
31
  break
32
32
  default:
@@ -1,5 +1,5 @@
1
1
  const env = require("../environment")
2
- const { Headers } = require("@budibase/backend-core/constants")
2
+ const { Header } = require("@budibase/backend-core/constants")
3
3
 
4
4
  /**
5
5
  * This is a restricted endpoint in the cloud.
@@ -7,7 +7,7 @@ const { Headers } = require("@budibase/backend-core/constants")
7
7
  */
8
8
  module.exports = async (ctx, next) => {
9
9
  if (!env.SELF_HOSTED && !env.DISABLE_ACCOUNT_PORTAL) {
10
- const apiKey = ctx.request.headers[Headers.API_KEY]
10
+ const apiKey = ctx.request.headers[Header.API_KEY]
11
11
  if (apiKey !== env.INTERNAL_API_KEY) {
12
12
  ctx.throw(403, "Unauthorized")
13
13
  }
@@ -20,18 +20,18 @@ describe("tenancy middleware", () => {
20
20
  const user = await config.createTenant()
21
21
  await config.createSession(user)
22
22
  const res = await config.api.self.getSelf(user)
23
- expect(res.headers[constants.Headers.TENANT_ID]).toBe(user.tenantId)
23
+ expect(res.headers[constants.Header.TENANT_ID]).toBe(user.tenantId)
24
24
  })
25
25
 
26
26
  it("should get tenant id from header", async () => {
27
27
  const tenantId = structures.uuid()
28
28
  const headers = {
29
- [constants.Headers.TENANT_ID]: tenantId,
29
+ [constants.Header.TENANT_ID]: tenantId,
30
30
  }
31
31
  const res = await config.request
32
32
  .get(`/api/global/configs/checklist`)
33
33
  .set(headers)
34
- expect(res.headers[constants.Headers.TENANT_ID]).toBe(tenantId)
34
+ expect(res.headers[constants.Header.TENANT_ID]).toBe(tenantId)
35
35
  })
36
36
 
37
37
  it("should get tenant id from query param", async () => {
@@ -39,7 +39,7 @@ describe("tenancy middleware", () => {
39
39
  const res = await config.request.get(
40
40
  `/api/global/configs/checklist?tenantId=${tenantId}`
41
41
  )
42
- expect(res.headers[constants.Headers.TENANT_ID]).toBe(tenantId)
42
+ expect(res.headers[constants.Header.TENANT_ID]).toBe(tenantId)
43
43
  })
44
44
 
45
45
  it("should get tenant id from subdomain", async () => {
@@ -50,7 +50,7 @@ describe("tenancy middleware", () => {
50
50
  const res = await config.request
51
51
  .get(`/api/global/configs/checklist`)
52
52
  .set(headers)
53
- expect(res.headers[constants.Headers.TENANT_ID]).toBe(tenantId)
53
+ expect(res.headers[constants.Header.TENANT_ID]).toBe(tenantId)
54
54
  })
55
55
 
56
56
  it("should get tenant id from path variable", async () => {
@@ -61,13 +61,13 @@ describe("tenancy middleware", () => {
61
61
  username: user.email,
62
62
  password: user.password,
63
63
  })
64
- expect(res.headers[constants.Headers.TENANT_ID]).toBe(user.tenantId)
64
+ expect(res.headers[constants.Header.TENANT_ID]).toBe(user.tenantId)
65
65
  })
66
66
 
67
67
  it("should throw when no tenant id is found", async () => {
68
68
  const res = await config.request.get(`/api/global/configs/checklist`)
69
69
  expect(res.status).toBe(403)
70
70
  expect(res.text).toBe("Tenant id not set")
71
- expect(res.headers[constants.Headers.TENANT_ID]).toBe(undefined)
71
+ expect(res.headers[constants.Header.TENANT_ID]).toBe(undefined)
72
72
  })
73
73
  })
@@ -4,12 +4,10 @@ dbConfig.init()
4
4
  import env from "../environment"
5
5
  import controllers from "./controllers"
6
6
  const supertest = require("supertest")
7
- import { Configs } from "../constants"
7
+ import { Config } from "../constants"
8
8
  import {
9
9
  users,
10
10
  tenancy,
11
- Cookies,
12
- Headers,
13
11
  sessions,
14
12
  auth,
15
13
  constants,
@@ -131,7 +129,7 @@ class TestConfiguration {
131
129
  const userRes = await this.api.users.getUser(res.userId, {
132
130
  headers: {
133
131
  ...this.internalAPIHeaders(),
134
- [constants.Headers.TENANT_ID]: res.tenantId,
132
+ [constants.Header.TENANT_ID]: res.tenantId,
135
133
  },
136
134
  })
137
135
 
@@ -188,8 +186,8 @@ class TestConfiguration {
188
186
  const authCookie = auth.jwt.sign(authToken, env.JWT_SECRET)
189
187
  return {
190
188
  Accept: "application/json",
191
- ...this.cookieHeader([`${Cookies.Auth}=${authCookie}`]),
192
- [Headers.CSRF_TOKEN]: CSRF_TOKEN,
189
+ ...this.cookieHeader([`${constants.Cookie.Auth}=${authCookie}`]),
190
+ [constants.Header.CSRF_TOKEN]: CSRF_TOKEN,
193
191
  }
194
192
  }
195
193
 
@@ -205,7 +203,7 @@ class TestConfiguration {
205
203
  }
206
204
 
207
205
  internalAPIHeaders() {
208
- return { [constants.Headers.API_KEY]: env.INTERNAL_API_KEY }
206
+ return { [constants.Header.API_KEY]: env.INTERNAL_API_KEY }
209
207
  }
210
208
 
211
209
  adminOnlyResponse = () => {
@@ -274,7 +272,7 @@ class TestConfiguration {
274
272
  // CONFIGS - SETTINGS
275
273
 
276
274
  async saveSettingsConfig() {
277
- await this.deleteConfig(Configs.SETTINGS)
275
+ await this.deleteConfig(Config.SETTINGS)
278
276
  await this._req(
279
277
  structures.configs.settings(),
280
278
  null,
@@ -285,14 +283,19 @@ class TestConfiguration {
285
283
  // CONFIGS - GOOGLE
286
284
 
287
285
  async saveGoogleConfig() {
288
- await this.deleteConfig(Configs.GOOGLE)
286
+ await this.deleteConfig(Config.GOOGLE)
289
287
  await this._req(structures.configs.google(), null, controllers.config.save)
290
288
  }
291
289
 
292
290
  // CONFIGS - OIDC
293
291
 
292
+ getOIDConfigCookie(configId: string) {
293
+ const token = auth.jwt.sign(configId, env.JWT_SECRET)
294
+ return this.cookieHeader([[`${constants.Cookie.OIDC_CONFIG}=${token}`]])
295
+ }
296
+
294
297
  async saveOIDCConfig() {
295
- await this.deleteConfig(Configs.OIDC)
298
+ await this.deleteConfig(Config.OIDC)
296
299
  const config = structures.configs.oidc()
297
300
 
298
301
  await this._req(config, null, controllers.config.save)
@@ -302,12 +305,12 @@ class TestConfiguration {
302
305
  // CONFIGS - SMTP
303
306
 
304
307
  async saveSmtpConfig() {
305
- await this.deleteConfig(Configs.SMTP)
308
+ await this.deleteConfig(Config.SMTP)
306
309
  await this._req(structures.configs.smtp(), null, controllers.config.save)
307
310
  }
308
311
 
309
312
  async saveEtherealSmtpConfig() {
310
- await this.deleteConfig(Configs.SMTP)
313
+ await this.deleteConfig(Config.SMTP)
311
314
  await this._req(
312
315
  structures.configs.smtpEthereal(),
313
316
  null,
@@ -1,9 +1,9 @@
1
- const { Configs } = require("../../constants")
1
+ const { Config } = require("../../constants")
2
2
  const { utils } = require("@budibase/backend-core")
3
3
 
4
4
  exports.oidc = conf => {
5
5
  return {
6
- type: Configs.OIDC,
6
+ type: Config.OIDC,
7
7
  config: {
8
8
  configs: [
9
9
  {
@@ -23,7 +23,7 @@ exports.oidc = conf => {
23
23
 
24
24
  exports.google = conf => {
25
25
  return {
26
- type: Configs.GOOGLE,
26
+ type: Config.GOOGLE,
27
27
  config: {
28
28
  clientID: "clientId",
29
29
  clientSecret: "clientSecret",
@@ -35,7 +35,7 @@ exports.google = conf => {
35
35
 
36
36
  exports.smtp = conf => {
37
37
  return {
38
- type: Configs.SMTP,
38
+ type: Config.SMTP,
39
39
  config: {
40
40
  port: 12345,
41
41
  host: "smtptesthost.com",
@@ -49,7 +49,7 @@ exports.smtp = conf => {
49
49
 
50
50
  exports.smtpEthereal = () => {
51
51
  return {
52
- type: Configs.SMTP,
52
+ type: Config.SMTP,
53
53
  config: {
54
54
  port: 587,
55
55
  host: "smtp.ethereal.email",
@@ -65,7 +65,7 @@ exports.smtpEthereal = () => {
65
65
 
66
66
  exports.settings = conf => {
67
67
  return {
68
- type: Configs.SETTINGS,
68
+ type: Config.SETTINGS,
69
69
  config: {
70
70
  platformUrl: "http://localhost:10000",
71
71
  logoUrl: "",
@@ -1,5 +1,5 @@
1
1
  const fetch = require("node-fetch")
2
- const { Headers } = require("@budibase/backend-core/constants")
2
+ const { Header } = require("@budibase/backend-core/constants")
3
3
  const { getTenantId, isTenantIdSet } = require("@budibase/backend-core/tenancy")
4
4
  const { checkSlashesInUrl } = require("../utilities")
5
5
  const env = require("../environment")
@@ -9,9 +9,9 @@ async function makeAppRequest(url, method, body) {
9
9
  return
10
10
  }
11
11
  const request = { headers: {} }
12
- request.headers[Headers.API_KEY] = env.INTERNAL_API_KEY
12
+ request.headers[Header.API_KEY] = env.INTERNAL_API_KEY
13
13
  if (isTenantIdSet()) {
14
- request.headers[Headers.TENANT_ID] = getTenantId()
14
+ request.headers[Header.TENANT_ID] = getTenantId()
15
15
  }
16
16
  if (body) {
17
17
  request.headers["Content-Type"] = "application/json"
@@ -1,15 +1,33 @@
1
+ import env from "../environment"
2
+ import { EmailTemplatePurpose, TemplateType, Config } from "../constants"
3
+ import { getTemplateByPurpose } from "../constants/templates"
4
+ import { getSettingsTemplateContext } from "./templates"
5
+ import { processString } from "@budibase/string-templates"
6
+ import { getResetPasswordCode, getInviteCode } from "./redis"
7
+ import { User, Database } from "@budibase/types"
8
+ import { tenancy, db as dbCore } from "@budibase/backend-core"
1
9
  const nodemailer = require("nodemailer")
2
- const env = require("../environment")
3
- const { getScopedConfig } = require("@budibase/backend-core/db")
4
- const { EmailTemplatePurpose, TemplateTypes, Configs } = require("../constants")
5
- const { getTemplateByPurpose } = require("../constants/templates")
6
- const { getSettingsTemplateContext } = require("./templates")
7
- const { processString } = require("@budibase/string-templates")
8
- const { getResetPasswordCode, getInviteCode } = require("../utilities/redis")
9
- const { getGlobalDB } = require("@budibase/backend-core/tenancy")
10
+
11
+ type SendEmailOpts = {
12
+ // workspaceId If finer grain controls being used then this will lookup config for workspace.
13
+ workspaceId?: string
14
+ // user If sending to an existing user the object can be provided, this is used in the context.
15
+ user: User
16
+ // from If sending from an address that is not what is configured in the SMTP config.
17
+ from?: string
18
+ // contents If sending a custom email then can supply contents which will be added to it.
19
+ contents?: string
20
+ // subject A custom subject can be specified if the config one is not desired.
21
+ subject?: string
22
+ // info Pass in a structure of information to be stored alongside the invitation.
23
+ info?: any
24
+ cc?: boolean
25
+ bcc?: boolean
26
+ automation?: boolean
27
+ }
10
28
 
11
29
  const TEST_MODE = false
12
- const TYPE = TemplateTypes.EMAIL
30
+ const TYPE = TemplateType.EMAIL
13
31
 
14
32
  const FULL_EMAIL_PURPOSES = [
15
33
  EmailTemplatePurpose.INVITATION,
@@ -18,8 +36,8 @@ const FULL_EMAIL_PURPOSES = [
18
36
  EmailTemplatePurpose.CUSTOM,
19
37
  ]
20
38
 
21
- function createSMTPTransport(config) {
22
- let options
39
+ function createSMTPTransport(config: any) {
40
+ let options: any
23
41
  let secure = config.secure
24
42
  // default it if not specified
25
43
  if (secure == null) {
@@ -52,10 +70,15 @@ function createSMTPTransport(config) {
52
70
  return nodemailer.createTransport(options)
53
71
  }
54
72
 
55
- async function getLinkCode(purpose, email, user, info = null) {
73
+ async function getLinkCode(
74
+ purpose: EmailTemplatePurpose,
75
+ email: string,
76
+ user: User,
77
+ info: any = null
78
+ ) {
56
79
  switch (purpose) {
57
80
  case EmailTemplatePurpose.PASSWORD_RECOVERY:
58
- return getResetPasswordCode(user._id, info)
81
+ return getResetPasswordCode(user._id!, info)
59
82
  case EmailTemplatePurpose.INVITATION:
60
83
  return getInviteCode(email, info)
61
84
  default:
@@ -72,7 +95,12 @@ async function getLinkCode(purpose, email, user, info = null) {
72
95
  * @param {string|null} contents if using a custom template can supply contents for context.
73
96
  * @return {Promise<string>} returns the built email HTML if all provided parameters were valid.
74
97
  */
75
- async function buildEmail(purpose, email, context, { user, contents } = {}) {
98
+ async function buildEmail(
99
+ purpose: EmailTemplatePurpose,
100
+ email: string,
101
+ context: any,
102
+ { user, contents }: any = {}
103
+ ) {
76
104
  // this isn't a full email
77
105
  if (FULL_EMAIL_PURPOSES.indexOf(purpose) === -1) {
78
106
  throw `Unable to build an email of type ${purpose}`
@@ -113,15 +141,19 @@ async function buildEmail(purpose, email, context, { user, contents } = {}) {
113
141
  * @param {boolean|null} automation Whether or not the configuration is being fetched for an email automation.
114
142
  * @return {Promise<object|null>} returns the SMTP configuration if it exists
115
143
  */
116
- async function getSmtpConfiguration(db, workspaceId = null, automation) {
117
- const params = {
118
- type: Configs.SMTP,
144
+ async function getSmtpConfiguration(
145
+ db: Database,
146
+ workspaceId?: string,
147
+ automation?: boolean
148
+ ) {
149
+ const params: any = {
150
+ type: Config.SMTP,
119
151
  }
120
152
  if (workspaceId) {
121
153
  params.workspace = workspaceId
122
154
  }
123
155
 
124
- const customConfig = await getScopedConfig(db, params)
156
+ const customConfig = await dbCore.getScopedConfig(db, params)
125
157
 
126
158
  if (customConfig) {
127
159
  return customConfig
@@ -146,12 +178,12 @@ async function getSmtpConfiguration(db, workspaceId = null, automation) {
146
178
  * Checks if a SMTP config exists based on passed in parameters.
147
179
  * @return {Promise<boolean>} returns true if there is a configuration that can be used.
148
180
  */
149
- exports.isEmailConfigured = async (workspaceId = null) => {
181
+ export async function isEmailConfigured(workspaceId?: string) {
150
182
  // when "testing" or smtp fallback is enabled simply return true
151
183
  if (TEST_MODE || env.SMTP_FALLBACK_ENABLED) {
152
184
  return true
153
185
  }
154
- const db = getGlobalDB()
186
+ const db = tenancy.getGlobalDB()
155
187
  const config = await getSmtpConfiguration(db, workspaceId)
156
188
  return config != null
157
189
  }
@@ -161,48 +193,49 @@ exports.isEmailConfigured = async (workspaceId = null) => {
161
193
  * send an email using it.
162
194
  * @param {string} email The email address to send to.
163
195
  * @param {string} purpose The purpose of the email being sent (e.g. reset password).
164
- * @param {string|undefined} workspaceId If finer grain controls being used then this will lookup config for workspace.
165
- * @param {object|undefined} user If sending to an existing user the object can be provided, this is used in the context.
166
- * @param {string|undefined} from If sending from an address that is not what is configured in the SMTP config.
167
- * @param {string|undefined} contents If sending a custom email then can supply contents which will be added to it.
168
- * @param {string|undefined} subject A custom subject can be specified if the config one is not desired.
169
- * @param {object|undefined} info Pass in a structure of information to be stored alongside the invitation.
170
- * @param {boolean|undefined} disableFallback Prevent email being sent from SMTP fallback to avoid spam.
196
+ * @param {object} opts The options for sending the email.
171
197
  * @return {Promise<object>} returns details about the attempt to send email, e.g. if it is successful; based on
172
198
  * nodemailer response.
173
199
  */
174
- exports.sendEmail = async (
175
- email,
176
- purpose,
177
- { workspaceId, user, from, contents, subject, info, cc, bcc, automation } = {}
178
- ) => {
179
- const db = getGlobalDB()
180
- let config = (await getSmtpConfiguration(db, workspaceId, automation)) || {}
200
+ export async function sendEmail(
201
+ email: string,
202
+ purpose: EmailTemplatePurpose,
203
+ opts: SendEmailOpts
204
+ ) {
205
+ const db = tenancy.getGlobalDB()
206
+ let config =
207
+ (await getSmtpConfiguration(db, opts?.workspaceId, opts?.automation)) || {}
181
208
  if (Object.keys(config).length === 0 && !TEST_MODE) {
182
209
  throw "Unable to find SMTP configuration."
183
210
  }
184
211
  const transport = createSMTPTransport(config)
185
212
  // if there is a link code needed this will retrieve it
186
- const code = await getLinkCode(purpose, email, user, info)
187
- const context = await getSettingsTemplateContext(purpose, code)
213
+ const code = await getLinkCode(purpose, email, opts.user, opts?.info)
214
+ let context
215
+ if (code) {
216
+ context = await getSettingsTemplateContext(purpose, code)
217
+ }
188
218
 
189
- let message = {
190
- from: from || config.from,
219
+ let message: any = {
220
+ from: opts?.from || config.from,
191
221
  html: await buildEmail(purpose, email, context, {
192
- user,
193
- contents,
222
+ user: opts?.user,
223
+ contents: opts?.contents,
194
224
  }),
195
225
  }
196
226
 
197
227
  message = {
198
228
  ...message,
199
229
  to: email,
200
- cc: cc,
201
- bcc: bcc,
230
+ cc: opts?.cc,
231
+ bcc: opts?.bcc,
202
232
  }
203
233
 
204
- if (subject || config.subject) {
205
- message.subject = await processString(subject || config.subject, context)
234
+ if (opts?.subject || config.subject) {
235
+ message.subject = await processString(
236
+ opts?.subject || config.subject,
237
+ context
238
+ )
206
239
  }
207
240
  const response = await transport.sendMail(message)
208
241
  if (TEST_MODE) {
@@ -216,7 +249,7 @@ exports.sendEmail = async (
216
249
  * @param {object} config an SMTP configuration - this is based on the nodemailer API.
217
250
  * @return {Promise<boolean>} returns true if the configuration is valid.
218
251
  */
219
- exports.verifyConfig = async config => {
252
+ export async function verifyConfig(config: any) {
220
253
  const transport = createSMTPTransport(config)
221
254
  await transport.verify()
222
255
  }