@budibase/backend-core 2.9.40-alpha.6 → 2.10.1

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 (252) hide show
  1. package/dist/index.js +5 -4
  2. package/dist/index.js.map +2 -2
  3. package/dist/index.js.meta.json +1 -1
  4. package/dist/package.json +6 -6
  5. package/dist/src/cache/appMetadata.js +1 -1
  6. package/dist/src/cache/appMetadata.js.map +1 -1
  7. package/dist/src/constants/misc.d.ts +0 -2
  8. package/dist/src/constants/misc.js +0 -2
  9. package/dist/src/constants/misc.js.map +1 -1
  10. package/dist/src/environment.js +5 -4
  11. package/dist/src/environment.js.map +1 -1
  12. package/dist/src/logging/system.d.ts +1 -1
  13. package/dist/src/timers/timers.d.ts +1 -1
  14. package/package.json +6 -6
  15. package/src/accounts/accounts.ts +82 -0
  16. package/src/accounts/api.ts +59 -0
  17. package/src/accounts/index.ts +1 -0
  18. package/src/auth/auth.ts +208 -0
  19. package/src/auth/index.ts +1 -0
  20. package/src/auth/tests/auth.spec.ts +14 -0
  21. package/src/blacklist/blacklist.ts +54 -0
  22. package/src/blacklist/index.ts +1 -0
  23. package/src/blacklist/tests/blacklist.spec.ts +46 -0
  24. package/src/cache/appMetadata.ts +88 -0
  25. package/src/cache/base/index.ts +92 -0
  26. package/src/cache/generic.ts +30 -0
  27. package/src/cache/index.ts +5 -0
  28. package/src/cache/tests/writethrough.spec.ts +138 -0
  29. package/src/cache/user.ts +83 -0
  30. package/src/cache/writethrough.ts +133 -0
  31. package/src/configs/configs.ts +257 -0
  32. package/src/configs/index.ts +1 -0
  33. package/src/configs/tests/configs.spec.ts +184 -0
  34. package/src/constants/db.ts +63 -0
  35. package/src/constants/index.ts +2 -0
  36. package/src/constants/misc.ts +50 -0
  37. package/src/context/Context.ts +14 -0
  38. package/src/context/identity.ts +58 -0
  39. package/src/context/index.ts +3 -0
  40. package/src/context/mainContext.ts +310 -0
  41. package/src/context/tests/index.spec.ts +147 -0
  42. package/src/context/types.ts +11 -0
  43. package/src/db/Replication.ts +84 -0
  44. package/src/db/constants.ts +10 -0
  45. package/src/db/couch/DatabaseImpl.ts +238 -0
  46. package/src/db/couch/connections.ts +77 -0
  47. package/src/db/couch/index.ts +5 -0
  48. package/src/db/couch/pouchDB.ts +97 -0
  49. package/src/db/couch/pouchDump.ts +0 -0
  50. package/src/db/couch/utils.ts +50 -0
  51. package/src/db/db.ts +43 -0
  52. package/src/db/errors.ts +14 -0
  53. package/src/db/index.ts +12 -0
  54. package/src/db/lucene.ts +750 -0
  55. package/src/db/searchIndexes/index.ts +1 -0
  56. package/src/db/searchIndexes/searchIndexes.ts +62 -0
  57. package/src/db/tests/index.spec.js +25 -0
  58. package/src/db/tests/lucene.spec.ts +368 -0
  59. package/src/db/tests/pouch.spec.js +62 -0
  60. package/src/db/tests/utils.spec.ts +63 -0
  61. package/src/db/utils.ts +207 -0
  62. package/src/db/views.ts +241 -0
  63. package/src/docIds/conversions.ts +59 -0
  64. package/src/docIds/ids.ts +113 -0
  65. package/src/docIds/index.ts +2 -0
  66. package/src/docIds/newid.ts +5 -0
  67. package/src/docIds/params.ts +174 -0
  68. package/src/docUpdates/index.ts +29 -0
  69. package/src/environment.ts +201 -0
  70. package/src/errors/errors.ts +119 -0
  71. package/src/errors/index.ts +1 -0
  72. package/src/events/analytics.ts +6 -0
  73. package/src/events/asyncEvents/index.ts +2 -0
  74. package/src/events/asyncEvents/publisher.ts +12 -0
  75. package/src/events/asyncEvents/queue.ts +22 -0
  76. package/src/events/backfill.ts +183 -0
  77. package/src/events/documentId.ts +56 -0
  78. package/src/events/events.ts +40 -0
  79. package/src/events/identification.ts +310 -0
  80. package/src/events/index.ts +14 -0
  81. package/src/events/processors/AnalyticsProcessor.ts +64 -0
  82. package/src/events/processors/AuditLogsProcessor.ts +93 -0
  83. package/src/events/processors/LoggingProcessor.ts +37 -0
  84. package/src/events/processors/Processors.ts +52 -0
  85. package/src/events/processors/async/DocumentUpdateProcessor.ts +43 -0
  86. package/src/events/processors/index.ts +19 -0
  87. package/src/events/processors/posthog/PosthogProcessor.ts +118 -0
  88. package/src/events/processors/posthog/index.ts +2 -0
  89. package/src/events/processors/posthog/rateLimiting.ts +106 -0
  90. package/src/events/processors/posthog/tests/PosthogProcessor.spec.ts +168 -0
  91. package/src/events/processors/types.ts +1 -0
  92. package/src/events/publishers/account.ts +35 -0
  93. package/src/events/publishers/app.ts +155 -0
  94. package/src/events/publishers/auditLog.ts +26 -0
  95. package/src/events/publishers/auth.ts +73 -0
  96. package/src/events/publishers/automation.ts +110 -0
  97. package/src/events/publishers/backfill.ts +74 -0
  98. package/src/events/publishers/backup.ts +42 -0
  99. package/src/events/publishers/datasource.ts +48 -0
  100. package/src/events/publishers/email.ts +17 -0
  101. package/src/events/publishers/environmentVariable.ts +38 -0
  102. package/src/events/publishers/group.ts +99 -0
  103. package/src/events/publishers/index.ts +24 -0
  104. package/src/events/publishers/installation.ts +38 -0
  105. package/src/events/publishers/layout.ts +26 -0
  106. package/src/events/publishers/license.ts +84 -0
  107. package/src/events/publishers/org.ts +37 -0
  108. package/src/events/publishers/plugin.ts +47 -0
  109. package/src/events/publishers/query.ts +88 -0
  110. package/src/events/publishers/role.ts +62 -0
  111. package/src/events/publishers/rows.ts +29 -0
  112. package/src/events/publishers/screen.ts +36 -0
  113. package/src/events/publishers/serve.ts +43 -0
  114. package/src/events/publishers/table.ts +70 -0
  115. package/src/events/publishers/user.ts +202 -0
  116. package/src/events/publishers/view.ts +107 -0
  117. package/src/features/index.ts +78 -0
  118. package/src/features/installation.ts +17 -0
  119. package/src/features/tests/featureFlags.spec.ts +85 -0
  120. package/src/helpers.ts +9 -0
  121. package/src/index.ts +54 -0
  122. package/src/installation.ts +107 -0
  123. package/src/logging/alerts.ts +26 -0
  124. package/src/logging/correlation/correlation.ts +13 -0
  125. package/src/logging/correlation/index.ts +1 -0
  126. package/src/logging/correlation/middleware.ts +17 -0
  127. package/src/logging/index.ts +4 -0
  128. package/src/logging/pino/logger.ts +232 -0
  129. package/src/logging/pino/middleware.ts +45 -0
  130. package/src/logging/system.ts +81 -0
  131. package/src/logging/tests/system.spec.ts +61 -0
  132. package/src/middleware/adminOnly.ts +9 -0
  133. package/src/middleware/auditLog.ts +6 -0
  134. package/src/middleware/authenticated.ts +193 -0
  135. package/src/middleware/builderOnly.ts +21 -0
  136. package/src/middleware/builderOrAdmin.ts +21 -0
  137. package/src/middleware/csrf.ts +81 -0
  138. package/src/middleware/errorHandling.ts +29 -0
  139. package/src/middleware/index.ts +21 -0
  140. package/src/middleware/internalApi.ts +23 -0
  141. package/src/middleware/joi-validator.ts +45 -0
  142. package/src/middleware/matchers.ts +47 -0
  143. package/src/middleware/passport/datasource/google.ts +95 -0
  144. package/src/middleware/passport/local.ts +54 -0
  145. package/src/middleware/passport/sso/google.ts +77 -0
  146. package/src/middleware/passport/sso/oidc.ts +154 -0
  147. package/src/middleware/passport/sso/sso.ts +165 -0
  148. package/src/middleware/passport/sso/tests/google.spec.ts +67 -0
  149. package/src/middleware/passport/sso/tests/oidc.spec.ts +152 -0
  150. package/src/middleware/passport/sso/tests/sso.spec.ts +197 -0
  151. package/src/middleware/passport/utils.ts +38 -0
  152. package/src/middleware/querystringToBody.ts +28 -0
  153. package/src/middleware/tenancy.ts +36 -0
  154. package/src/middleware/tests/builder.spec.ts +180 -0
  155. package/src/middleware/tests/matchers.spec.ts +134 -0
  156. package/src/migrations/definitions.ts +40 -0
  157. package/src/migrations/index.ts +2 -0
  158. package/src/migrations/migrations.ts +191 -0
  159. package/src/migrations/tests/__snapshots__/migrations.spec.ts.snap +11 -0
  160. package/src/migrations/tests/migrations.spec.ts +64 -0
  161. package/src/objectStore/buckets/app.ts +40 -0
  162. package/src/objectStore/buckets/global.ts +29 -0
  163. package/src/objectStore/buckets/index.ts +3 -0
  164. package/src/objectStore/buckets/plugins.ts +71 -0
  165. package/src/objectStore/buckets/tests/app.spec.ts +171 -0
  166. package/src/objectStore/buckets/tests/global.spec.ts +74 -0
  167. package/src/objectStore/buckets/tests/plugins.spec.ts +111 -0
  168. package/src/objectStore/cloudfront.ts +41 -0
  169. package/src/objectStore/index.ts +3 -0
  170. package/src/objectStore/objectStore.ts +440 -0
  171. package/src/objectStore/utils.ts +27 -0
  172. package/src/platform/index.ts +3 -0
  173. package/src/platform/platformDb.ts +6 -0
  174. package/src/platform/tenants.ts +101 -0
  175. package/src/platform/tests/tenants.spec.ts +26 -0
  176. package/src/platform/users.ts +90 -0
  177. package/src/plugin/index.ts +1 -0
  178. package/src/plugin/tests/validation.spec.ts +83 -0
  179. package/src/plugin/utils.ts +156 -0
  180. package/src/queue/constants.ts +6 -0
  181. package/src/queue/inMemoryQueue.ts +141 -0
  182. package/src/queue/index.ts +2 -0
  183. package/src/queue/listeners.ts +195 -0
  184. package/src/queue/queue.ts +54 -0
  185. package/src/redis/index.ts +6 -0
  186. package/src/redis/init.ts +86 -0
  187. package/src/redis/redis.ts +308 -0
  188. package/src/redis/redlockImpl.ts +139 -0
  189. package/src/redis/utils.ts +117 -0
  190. package/src/security/encryption.ts +179 -0
  191. package/src/security/permissions.ts +158 -0
  192. package/src/security/roles.ts +389 -0
  193. package/src/security/sessions.ts +120 -0
  194. package/src/security/tests/encryption.spec.ts +31 -0
  195. package/src/security/tests/permissions.spec.ts +145 -0
  196. package/src/security/tests/sessions.spec.ts +12 -0
  197. package/src/tenancy/db.ts +6 -0
  198. package/src/tenancy/index.ts +2 -0
  199. package/src/tenancy/tenancy.ts +140 -0
  200. package/src/tenancy/tests/tenancy.spec.ts +184 -0
  201. package/src/timers/index.ts +1 -0
  202. package/src/timers/timers.ts +22 -0
  203. package/src/users/db.ts +484 -0
  204. package/src/users/events.ts +176 -0
  205. package/src/users/index.ts +4 -0
  206. package/src/users/lookup.ts +102 -0
  207. package/src/users/users.ts +276 -0
  208. package/src/users/utils.ts +55 -0
  209. package/src/utils/hashing.ts +14 -0
  210. package/src/utils/index.ts +3 -0
  211. package/src/utils/stringUtils.ts +8 -0
  212. package/src/utils/tests/utils.spec.ts +191 -0
  213. package/src/utils/utils.ts +239 -0
  214. package/tests/core/logging.ts +34 -0
  215. package/tests/core/utilities/index.ts +6 -0
  216. package/tests/core/utilities/jestUtils.ts +30 -0
  217. package/tests/core/utilities/mocks/alerts.ts +3 -0
  218. package/tests/core/utilities/mocks/date.ts +2 -0
  219. package/tests/core/utilities/mocks/events.ts +131 -0
  220. package/tests/core/utilities/mocks/fetch.ts +17 -0
  221. package/tests/core/utilities/mocks/index.ts +10 -0
  222. package/tests/core/utilities/mocks/licenses.ts +115 -0
  223. package/tests/core/utilities/mocks/posthog.ts +7 -0
  224. package/tests/core/utilities/structures/Chance.ts +20 -0
  225. package/tests/core/utilities/structures/accounts.ts +115 -0
  226. package/tests/core/utilities/structures/apps.ts +21 -0
  227. package/tests/core/utilities/structures/common.ts +7 -0
  228. package/tests/core/utilities/structures/db.ts +12 -0
  229. package/tests/core/utilities/structures/documents/index.ts +1 -0
  230. package/tests/core/utilities/structures/documents/platform/index.ts +1 -0
  231. package/tests/core/utilities/structures/documents/platform/installation.ts +12 -0
  232. package/tests/core/utilities/structures/generator.ts +2 -0
  233. package/tests/core/utilities/structures/index.ts +15 -0
  234. package/tests/core/utilities/structures/koa.ts +16 -0
  235. package/tests/core/utilities/structures/licenses.ts +167 -0
  236. package/tests/core/utilities/structures/plugins.ts +19 -0
  237. package/tests/core/utilities/structures/quotas.ts +67 -0
  238. package/tests/core/utilities/structures/scim.ts +80 -0
  239. package/tests/core/utilities/structures/shared.ts +19 -0
  240. package/tests/core/utilities/structures/sso.ts +119 -0
  241. package/tests/core/utilities/structures/tenants.ts +5 -0
  242. package/tests/core/utilities/structures/userGroups.ts +10 -0
  243. package/tests/core/utilities/structures/users.ts +73 -0
  244. package/tests/core/utilities/testContainerUtils.ts +85 -0
  245. package/tests/core/utilities/utils/index.ts +1 -0
  246. package/tests/core/utilities/utils/time.ts +3 -0
  247. package/tests/extra/DBTestConfiguration.ts +36 -0
  248. package/tests/extra/index.ts +2 -0
  249. package/tests/extra/testEnv.ts +95 -0
  250. package/tests/index.ts +1 -0
  251. package/tests/jestEnv.ts +6 -0
  252. package/tests/jestSetup.ts +28 -0
@@ -0,0 +1,257 @@
1
+ import {
2
+ Config,
3
+ ConfigType,
4
+ GoogleConfig,
5
+ GoogleInnerConfig,
6
+ OIDCConfig,
7
+ OIDCInnerConfig,
8
+ OIDCLogosConfig,
9
+ SCIMConfig,
10
+ SCIMInnerConfig,
11
+ SettingsConfig,
12
+ SettingsInnerConfig,
13
+ SMTPConfig,
14
+ SMTPInnerConfig,
15
+ } from "@budibase/types"
16
+ import { DocumentType, SEPARATOR } from "../constants"
17
+ import { CacheKey, TTL, withCache } from "../cache"
18
+ import * as context from "../context"
19
+ import env from "../environment"
20
+ import environment from "../environment"
21
+
22
+ // UTILS
23
+
24
+ /**
25
+ * Generates a new configuration ID.
26
+ * @returns {string} The new configuration ID which the config doc can be stored under.
27
+ */
28
+ export function generateConfigID(type: ConfigType) {
29
+ return `${DocumentType.CONFIG}${SEPARATOR}${type}`
30
+ }
31
+
32
+ export async function getConfig<T extends Config>(
33
+ type: ConfigType
34
+ ): Promise<T | undefined> {
35
+ const db = context.getGlobalDB()
36
+ try {
37
+ // await to catch error
38
+ return (await db.get(generateConfigID(type))) as T
39
+ } catch (e: any) {
40
+ if (e.status === 404) {
41
+ return
42
+ }
43
+ throw e
44
+ }
45
+ }
46
+
47
+ export async function save(
48
+ config: Config
49
+ ): Promise<{ id: string; rev: string }> {
50
+ const db = context.getGlobalDB()
51
+ return db.put(config)
52
+ }
53
+
54
+ // SETTINGS
55
+
56
+ export async function getSettingsConfigDoc(): Promise<SettingsConfig> {
57
+ let config = await getConfig<SettingsConfig>(ConfigType.SETTINGS)
58
+
59
+ if (!config) {
60
+ config = {
61
+ _id: generateConfigID(ConfigType.SETTINGS),
62
+ type: ConfigType.SETTINGS,
63
+ config: {},
64
+ }
65
+ }
66
+
67
+ // overridden fields
68
+ config.config.platformUrl = await getPlatformUrl({
69
+ tenantAware: true,
70
+ config: config.config,
71
+ })
72
+ config.config.analyticsEnabled = await analyticsEnabled({
73
+ config: config.config,
74
+ })
75
+
76
+ return config
77
+ }
78
+
79
+ export async function getSettingsConfig(): Promise<SettingsInnerConfig> {
80
+ return (await getSettingsConfigDoc()).config
81
+ }
82
+
83
+ export async function getPlatformUrl(
84
+ opts: { tenantAware: boolean; config?: SettingsInnerConfig } = {
85
+ tenantAware: true,
86
+ }
87
+ ) {
88
+ let platformUrl = env.PLATFORM_URL || "http://localhost:10000"
89
+
90
+ if (!env.SELF_HOSTED && env.MULTI_TENANCY && opts.tenantAware) {
91
+ // cloud and multi tenant - add the tenant to the default platform url
92
+ const tenantId = context.getTenantId()
93
+ if (!platformUrl.includes("localhost:")) {
94
+ platformUrl = platformUrl.replace("://", `://${tenantId}.`)
95
+ }
96
+ } else if (env.SELF_HOSTED) {
97
+ const config = opts?.config
98
+ ? opts.config
99
+ : // direct to db to prevent infinite loop
100
+ (await getConfig<SettingsConfig>(ConfigType.SETTINGS))?.config
101
+ if (config?.platformUrl) {
102
+ platformUrl = config.platformUrl
103
+ }
104
+ }
105
+
106
+ return platformUrl
107
+ }
108
+
109
+ export const analyticsEnabled = async (opts?: {
110
+ config?: SettingsInnerConfig
111
+ }) => {
112
+ // cloud - always use the environment variable
113
+ if (!env.SELF_HOSTED) {
114
+ return !!env.ENABLE_ANALYTICS
115
+ }
116
+
117
+ // self host - prefer the settings doc
118
+ // use cache as events have high throughput
119
+ const enabledInDB = await withCache(
120
+ CacheKey.ANALYTICS_ENABLED,
121
+ TTL.ONE_DAY,
122
+ async () => {
123
+ const config = opts?.config
124
+ ? opts.config
125
+ : // direct to db to prevent infinite loop
126
+ (await getConfig<SettingsConfig>(ConfigType.SETTINGS))?.config
127
+
128
+ // need to do explicit checks in case the field is not set
129
+ if (config?.analyticsEnabled === false) {
130
+ return false
131
+ } else if (config?.analyticsEnabled === true) {
132
+ return true
133
+ }
134
+ }
135
+ )
136
+
137
+ if (enabledInDB !== undefined) {
138
+ return enabledInDB
139
+ }
140
+
141
+ // fallback to the environment variable
142
+ // explicitly check for 0 or false here, undefined or otherwise is treated as true
143
+ const envEnabled: any = env.ENABLE_ANALYTICS
144
+ if (envEnabled === 0 || envEnabled === false) {
145
+ return false
146
+ } else {
147
+ return true
148
+ }
149
+ }
150
+
151
+ // GOOGLE
152
+
153
+ async function getGoogleConfigDoc(): Promise<GoogleConfig | undefined> {
154
+ return await getConfig<GoogleConfig>(ConfigType.GOOGLE)
155
+ }
156
+
157
+ export async function getGoogleConfig(): Promise<
158
+ GoogleInnerConfig | undefined
159
+ > {
160
+ const config = await getGoogleConfigDoc()
161
+ return config?.config
162
+ }
163
+
164
+ export async function getGoogleDatasourceConfig(): Promise<
165
+ GoogleInnerConfig | undefined
166
+ > {
167
+ if (!env.SELF_HOSTED) {
168
+ // always use the env vars in cloud
169
+ return getDefaultGoogleConfig()
170
+ }
171
+
172
+ // prefer the config in self-host
173
+ let config = await getGoogleConfig()
174
+
175
+ // fallback to env vars
176
+ if (!config || !config.activated) {
177
+ config = getDefaultGoogleConfig()
178
+ }
179
+
180
+ return config
181
+ }
182
+
183
+ export function getDefaultGoogleConfig(): GoogleInnerConfig | undefined {
184
+ if (environment.GOOGLE_CLIENT_ID && environment.GOOGLE_CLIENT_SECRET) {
185
+ return {
186
+ clientID: environment.GOOGLE_CLIENT_ID!,
187
+ clientSecret: environment.GOOGLE_CLIENT_SECRET!,
188
+ activated: true,
189
+ }
190
+ }
191
+ }
192
+
193
+ // OIDC
194
+
195
+ export async function getOIDCLogosDoc(): Promise<OIDCLogosConfig | undefined> {
196
+ return getConfig<OIDCLogosConfig>(ConfigType.OIDC_LOGOS)
197
+ }
198
+
199
+ async function getOIDCConfigDoc(): Promise<OIDCConfig | undefined> {
200
+ return getConfig<OIDCConfig>(ConfigType.OIDC)
201
+ }
202
+
203
+ export async function getOIDCConfig(): Promise<OIDCInnerConfig | undefined> {
204
+ const config = (await getOIDCConfigDoc())?.config
205
+ // default to the 0th config
206
+ return config?.configs && config.configs[0]
207
+ }
208
+
209
+ /**
210
+ * @param configId The config id of the inner config to retrieve
211
+ */
212
+ export async function getOIDCConfigById(
213
+ configId: string
214
+ ): Promise<OIDCInnerConfig | undefined> {
215
+ const config = (await getConfig<OIDCConfig>(ConfigType.OIDC))?.config
216
+ return config && config.configs.filter((c: any) => c.uuid === configId)[0]
217
+ }
218
+
219
+ // SMTP
220
+
221
+ export async function getSMTPConfigDoc(): Promise<SMTPConfig | undefined> {
222
+ return getConfig<SMTPConfig>(ConfigType.SMTP)
223
+ }
224
+
225
+ export async function getSMTPConfig(
226
+ isAutomation?: boolean
227
+ ): Promise<SMTPInnerConfig | undefined> {
228
+ const config = await getSMTPConfigDoc()
229
+ if (config) {
230
+ return config.config
231
+ }
232
+
233
+ // always allow fallback in self host
234
+ // in cloud don't allow for automations
235
+ const allowFallback = env.SELF_HOSTED || !isAutomation
236
+
237
+ // Use an SMTP fallback configuration from env variables
238
+ if (env.SMTP_FALLBACK_ENABLED && allowFallback) {
239
+ return {
240
+ port: env.SMTP_PORT,
241
+ host: env.SMTP_HOST!,
242
+ secure: false,
243
+ from: env.SMTP_FROM_ADDRESS!,
244
+ auth: {
245
+ user: env.SMTP_USER!,
246
+ pass: env.SMTP_PASSWORD!,
247
+ },
248
+ }
249
+ }
250
+ }
251
+
252
+ // SCIM
253
+
254
+ export async function getSCIMConfig(): Promise<SCIMInnerConfig | undefined> {
255
+ const config = await getConfig<SCIMConfig>(ConfigType.SCIM)
256
+ return config?.config
257
+ }
@@ -0,0 +1 @@
1
+ export * from "./configs"
@@ -0,0 +1,184 @@
1
+ import { generator, structures } from "../../../tests"
2
+ import { DBTestConfiguration, testEnv } from "../../../tests/extra"
3
+ import { ConfigType } from "@budibase/types"
4
+ import env from "../../environment"
5
+ import * as configs from "../configs"
6
+
7
+ const DEFAULT_URL = "http://localhost:10000"
8
+ const ENV_URL = "http://env.com"
9
+
10
+ describe("configs", () => {
11
+ const config = new DBTestConfiguration()
12
+
13
+ const setDbPlatformUrl = async (dbUrl: string) => {
14
+ const settingsConfig = {
15
+ _id: configs.generateConfigID(ConfigType.SETTINGS),
16
+ type: ConfigType.SETTINGS,
17
+ config: {
18
+ platformUrl: dbUrl,
19
+ },
20
+ }
21
+ await configs.save(settingsConfig)
22
+ }
23
+
24
+ beforeEach(async () => {
25
+ config.newTenant()
26
+ })
27
+
28
+ describe("getPlatformUrl", () => {
29
+ describe("self host", () => {
30
+ beforeEach(async () => {
31
+ testEnv.selfHosted()
32
+ })
33
+
34
+ it("gets the default url", async () => {
35
+ await config.doInTenant(async () => {
36
+ const url = await configs.getPlatformUrl()
37
+ expect(url).toBe(DEFAULT_URL)
38
+ })
39
+ })
40
+
41
+ it("gets the platform url from the environment", async () => {
42
+ await config.doInTenant(async () => {
43
+ env._set("PLATFORM_URL", ENV_URL)
44
+ const url = await configs.getPlatformUrl()
45
+ expect(url).toBe(ENV_URL)
46
+ })
47
+ })
48
+
49
+ it("gets the platform url from the database", async () => {
50
+ await config.doInTenant(async () => {
51
+ const dbUrl = generator.url()
52
+ await setDbPlatformUrl(dbUrl)
53
+ const url = await configs.getPlatformUrl()
54
+ expect(url).toBe(dbUrl)
55
+ })
56
+ })
57
+ })
58
+
59
+ describe("cloud", () => {
60
+ function getTenantAwareUrl() {
61
+ return `http://${config.tenantId}.env.com`
62
+ }
63
+
64
+ beforeEach(async () => {
65
+ testEnv.cloudHosted()
66
+ testEnv.multiTenant()
67
+
68
+ env._set("PLATFORM_URL", ENV_URL)
69
+ })
70
+
71
+ it("gets the platform url from the environment without tenancy", async () => {
72
+ await config.doInTenant(async () => {
73
+ const url = await configs.getPlatformUrl({ tenantAware: false })
74
+ expect(url).toBe(ENV_URL)
75
+ })
76
+ })
77
+
78
+ it("gets the platform url from the environment with tenancy", async () => {
79
+ await config.doInTenant(async () => {
80
+ const url = await configs.getPlatformUrl()
81
+ expect(url).toBe(getTenantAwareUrl())
82
+ })
83
+ })
84
+
85
+ it("never gets the platform url from the database", async () => {
86
+ await config.doInTenant(async () => {
87
+ await setDbPlatformUrl(generator.url())
88
+ const url = await configs.getPlatformUrl()
89
+ expect(url).toBe(getTenantAwareUrl())
90
+ })
91
+ })
92
+ })
93
+ })
94
+
95
+ describe("getSettingsConfig", () => {
96
+ beforeAll(async () => {
97
+ testEnv.selfHosted()
98
+ env._set("PLATFORM_URL", "")
99
+ })
100
+
101
+ it("returns the platform url with an existing config", async () => {
102
+ await config.doInTenant(async () => {
103
+ const dbUrl = generator.url()
104
+ await setDbPlatformUrl(dbUrl)
105
+ const config = await configs.getSettingsConfig()
106
+ expect(config.platformUrl).toBe(dbUrl)
107
+ })
108
+ })
109
+
110
+ it("returns the platform url without an existing config", async () => {
111
+ await config.doInTenant(async () => {
112
+ const config = await configs.getSettingsConfig()
113
+ expect(config.platformUrl).toBe(DEFAULT_URL)
114
+ })
115
+ })
116
+ })
117
+
118
+ describe("getGoogleDatasourceConfig", () => {
119
+ function setEnvVars() {
120
+ env.GOOGLE_CLIENT_SECRET = "test"
121
+ env.GOOGLE_CLIENT_ID = "test"
122
+ }
123
+
124
+ function unsetEnvVars() {
125
+ env.GOOGLE_CLIENT_SECRET = undefined
126
+ env.GOOGLE_CLIENT_ID = undefined
127
+ }
128
+
129
+ describe("cloud", () => {
130
+ beforeEach(() => {
131
+ testEnv.cloudHosted()
132
+ })
133
+
134
+ it("returns from env vars", async () => {
135
+ await config.doInTenant(async () => {
136
+ setEnvVars()
137
+ const config = await configs.getGoogleDatasourceConfig()
138
+ unsetEnvVars()
139
+
140
+ expect(config).toEqual({
141
+ activated: true,
142
+ clientID: "test",
143
+ clientSecret: "test",
144
+ })
145
+ })
146
+ })
147
+
148
+ it("returns undefined when no env vars are configured", async () => {
149
+ await config.doInTenant(async () => {
150
+ const config = await configs.getGoogleDatasourceConfig()
151
+ expect(config).toBeUndefined()
152
+ })
153
+ })
154
+ })
155
+
156
+ describe("self host", () => {
157
+ beforeEach(() => {
158
+ testEnv.selfHosted()
159
+ })
160
+
161
+ it("returns from config", async () => {
162
+ await config.doInTenant(async () => {
163
+ const googleDoc = structures.sso.googleConfigDoc()
164
+ await configs.save(googleDoc)
165
+ const config = await configs.getGoogleDatasourceConfig()
166
+ expect(config).toEqual(googleDoc.config)
167
+ })
168
+ })
169
+
170
+ it("falls back to env vars when config is disabled", async () => {
171
+ await config.doInTenant(async () => {
172
+ setEnvVars()
173
+ const config = await configs.getGoogleDatasourceConfig()
174
+ unsetEnvVars()
175
+ expect(config).toEqual({
176
+ activated: true,
177
+ clientID: "test",
178
+ clientSecret: "test",
179
+ })
180
+ })
181
+ })
182
+ })
183
+ })
184
+ })
@@ -0,0 +1,63 @@
1
+ import { prefixed, DocumentType } from "@budibase/types"
2
+ export { SEPARATOR, UNICODE_MAX, DocumentType } from "@budibase/types"
3
+
4
+ /**
5
+ * Can be used to create a few different forms of querying a view.
6
+ */
7
+ export enum AutomationViewMode {
8
+ ALL = "all",
9
+ AUTOMATION = "automation",
10
+ STATUS = "status",
11
+ }
12
+
13
+ export enum ViewName {
14
+ USER_BY_APP = "by_app",
15
+ USER_BY_EMAIL = "by_email2",
16
+ BY_API_KEY = "by_api_key",
17
+ LINK = "by_link",
18
+ ROUTING = "screen_routes",
19
+ AUTOMATION_LOGS = "automation_logs",
20
+ ACCOUNT_BY_EMAIL = "account_by_email",
21
+ PLATFORM_USERS_LOWERCASE = "platform_users_lowercase",
22
+ USER_BY_GROUP = "user_by_group",
23
+ APP_BACKUP_BY_TRIGGER = "by_trigger",
24
+ }
25
+
26
+ export const DeprecatedViews = {
27
+ [ViewName.USER_BY_EMAIL]: [
28
+ // removed due to inaccuracy in view doc filter logic
29
+ "by_email",
30
+ ],
31
+ }
32
+
33
+ export enum InternalTable {
34
+ USER_METADATA = "ta_users",
35
+ }
36
+
37
+ export const StaticDatabases = {
38
+ GLOBAL: {
39
+ name: "global-db",
40
+ docs: {
41
+ apiKeys: "apikeys",
42
+ usageQuota: "usage_quota",
43
+ licenseInfo: "license_info",
44
+ environmentVariables: "environmentvariables",
45
+ },
46
+ },
47
+ // contains information about tenancy and so on
48
+ PLATFORM_INFO: {
49
+ name: "global-info",
50
+ docs: {
51
+ tenants: "tenants",
52
+ install: "install",
53
+ },
54
+ },
55
+ AUDIT_LOGS: {
56
+ name: "audit-logs",
57
+ },
58
+ }
59
+
60
+ export const APP_PREFIX = prefixed(DocumentType.APP)
61
+ export const APP_DEV = prefixed(DocumentType.APP_DEV)
62
+ export const APP_DEV_PREFIX = APP_DEV
63
+ export const BUDIBASE_DATASOURCE_TYPE = "budibase"
@@ -0,0 +1,2 @@
1
+ export * from "./db"
2
+ export * from "./misc"
@@ -0,0 +1,50 @@
1
+ export enum UserStatus {
2
+ ACTIVE = "active",
3
+ INACTIVE = "inactive",
4
+ }
5
+
6
+ export enum Cookie {
7
+ Auth = "budibase:auth",
8
+ Init = "budibase:init",
9
+ ACCOUNT_RETURN_URL = "budibase:account:returnurl",
10
+ DatasourceAuth = "budibase:datasourceauth",
11
+ OIDC_CONFIG = "budibase:oidc:config",
12
+ }
13
+
14
+ export enum Header {
15
+ API_KEY = "x-budibase-api-key",
16
+ LICENSE_KEY = "x-budibase-license-key",
17
+ API_VER = "x-budibase-api-version",
18
+ APP_ID = "x-budibase-app-id",
19
+ SESSION_ID = "x-budibase-session-id",
20
+ TYPE = "x-budibase-type",
21
+ PREVIEW_ROLE = "x-budibase-role",
22
+ TENANT_ID = "x-budibase-tenant-id",
23
+ VERIFICATION_CODE = "x-budibase-verification-code",
24
+ RETURN_VERIFICATION_CODE = "x-budibase-return-verification-code",
25
+ TOKEN = "x-budibase-token",
26
+ CSRF_TOKEN = "x-csrf-token",
27
+ CORRELATION_ID = "x-budibase-correlation-id",
28
+ AUTHORIZATION = "authorization",
29
+ }
30
+
31
+ export enum GlobalRole {
32
+ OWNER = "owner",
33
+ ADMIN = "admin",
34
+ BUILDER = "builder",
35
+ WORKSPACE_MANAGER = "workspace_manager",
36
+ }
37
+
38
+ export enum Config {
39
+ SETTINGS = "settings",
40
+ ACCOUNT = "account",
41
+ SMTP = "smtp",
42
+ GOOGLE = "google",
43
+ OIDC = "oidc",
44
+ OIDC_LOGOS = "logos_oidc",
45
+ SCIM = "scim",
46
+ }
47
+
48
+ export const MIN_VALID_DATE = new Date(-2147483647000)
49
+ export const MAX_VALID_DATE = new Date(2147483647000)
50
+ export const DEFAULT_TENANT_ID = "default"
@@ -0,0 +1,14 @@
1
+ import { AsyncLocalStorage } from "async_hooks"
2
+ import { ContextMap } from "./types"
3
+
4
+ export default class Context {
5
+ static storage = new AsyncLocalStorage<ContextMap>()
6
+
7
+ static run(context: ContextMap, func: any) {
8
+ return Context.storage.run(context, () => func())
9
+ }
10
+
11
+ static get(): ContextMap {
12
+ return Context.storage.getStore() as ContextMap
13
+ }
14
+ }
@@ -0,0 +1,58 @@
1
+ import {
2
+ IdentityContext,
3
+ IdentityType,
4
+ User,
5
+ isCloudAccount,
6
+ Account,
7
+ AccountUserContext,
8
+ UserContext,
9
+ Ctx,
10
+ } from "@budibase/types"
11
+ import * as context from "."
12
+
13
+ export function getIdentity(): IdentityContext | undefined {
14
+ return context.getIdentity()
15
+ }
16
+
17
+ export function doInIdentityContext(identity: IdentityContext, task: any) {
18
+ return context.doInIdentityContext(identity, task)
19
+ }
20
+
21
+ // used in server/worker
22
+ export function doInUserContext(user: User, ctx: Ctx, task: any) {
23
+ const userContext: UserContext = {
24
+ ...user,
25
+ _id: user._id as string,
26
+ type: IdentityType.USER,
27
+ hostInfo: {
28
+ ipAddress: ctx.request.ip,
29
+ // filled in by koa-useragent package
30
+ userAgent: ctx.userAgent._agent.source,
31
+ },
32
+ }
33
+ return doInIdentityContext(userContext, task)
34
+ }
35
+
36
+ // used in account portal
37
+ export function doInAccountContext(account: Account, task: any) {
38
+ const _id = getAccountUserId(account)
39
+ const tenantId = account.tenantId
40
+ const accountContext: AccountUserContext = {
41
+ _id,
42
+ type: IdentityType.USER,
43
+ tenantId,
44
+ account,
45
+ }
46
+ return doInIdentityContext(accountContext, task)
47
+ }
48
+
49
+ export function getAccountUserId(account: Account) {
50
+ let userId: string
51
+ if (isCloudAccount(account)) {
52
+ userId = account.budibaseUserId
53
+ } else {
54
+ // use account id as user id for self-hosting
55
+ userId = account.accountId
56
+ }
57
+ return userId
58
+ }
@@ -0,0 +1,3 @@
1
+ export { DEFAULT_TENANT_ID } from "../constants"
2
+ export * as identity from "./identity"
3
+ export * from "./mainContext"