@budibase/server 2.0.34-alpha.5 → 2.0.34-alpha.7
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.
- package/__mocks__/node-fetch.ts +12 -2
- package/builder/assets/{index.33bdfd8f.js → index.ffeaa56c.js} +1 -1
- package/builder/index.html +1 -1
- package/coverage/clover.xml +426 -496
- package/coverage/coverage-final.json +47 -49
- package/coverage/lcov-report/api/controllers/apikeys.js.html +6 -6
- package/coverage/lcov-report/api/controllers/automation.js.html +1 -1
- package/coverage/lcov-report/api/controllers/cloud.js.html +13 -13
- package/coverage/lcov-report/api/controllers/datasource.js.html +1 -1
- package/coverage/lcov-report/api/controllers/dev.js.html +20 -20
- package/coverage/lcov-report/api/controllers/index.html +9 -24
- package/coverage/lcov-report/api/controllers/integration.js.html +4 -4
- package/coverage/lcov-report/api/controllers/layout.js.html +1 -1
- package/coverage/lcov-report/api/controllers/metadata.js.html +9 -9
- package/coverage/lcov-report/api/controllers/migrations.js.html +4 -4
- package/coverage/lcov-report/api/controllers/permission.js.html +1 -1
- package/coverage/lcov-report/api/controllers/query/index.html +1 -1
- package/coverage/lcov-report/api/controllers/query/validation.js.html +4 -4
- package/coverage/lcov-report/api/controllers/role.js.html +1 -1
- package/coverage/lcov-report/api/controllers/routing.js.html +9 -9
- package/coverage/lcov-report/api/controllers/row/external.js.html +1 -1
- package/coverage/lcov-report/api/controllers/row/index.html +1 -1
- package/coverage/lcov-report/api/controllers/row/internal.js.html +1 -1
- package/coverage/lcov-report/api/controllers/row/internalSearch.js.html +1 -1
- package/coverage/lcov-report/api/controllers/row/staticFormula.js.html +1 -1
- package/coverage/lcov-report/api/controllers/row/utils.js.html +1 -1
- package/coverage/lcov-report/api/controllers/script.js.html +1 -1
- package/coverage/lcov-report/api/controllers/table/bulkFormula.js.html +1 -1
- package/coverage/lcov-report/api/controllers/table/external.js.html +1 -1
- package/coverage/lcov-report/api/controllers/table/index.html +1 -1
- package/coverage/lcov-report/api/controllers/table/index.js.html +1 -1
- package/coverage/lcov-report/api/controllers/templates.js.html +6 -6
- package/coverage/lcov-report/api/controllers/user.js.html +1 -1
- package/coverage/lcov-report/api/controllers/view/exporters.js.html +1 -1
- package/coverage/lcov-report/api/controllers/view/index.html +1 -1
- package/coverage/lcov-report/api/controllers/view/index.js.html +1 -1
- package/coverage/lcov-report/api/controllers/view/utils.js.html +1 -1
- package/coverage/lcov-report/api/controllers/view/viewBuilder.js.html +1 -1
- package/coverage/lcov-report/api/index.html +1 -1
- package/coverage/lcov-report/api/index.js.html +26 -26
- package/coverage/lcov-report/api/routes/analytics.js.html +7 -7
- package/coverage/lcov-report/api/routes/apikeys.js.html +8 -8
- package/coverage/lcov-report/api/routes/automation.js.html +11 -11
- package/coverage/lcov-report/api/routes/cloud.js.html +8 -8
- package/coverage/lcov-report/api/routes/component.js.html +8 -8
- package/coverage/lcov-report/api/routes/datasource.js.html +9 -9
- package/coverage/lcov-report/api/routes/deploy.js.html +8 -8
- package/coverage/lcov-report/api/routes/dev.js.html +13 -13
- package/coverage/lcov-report/api/routes/index.html +5 -20
- package/coverage/lcov-report/api/routes/integration.js.html +8 -8
- package/coverage/lcov-report/api/routes/layout.js.html +8 -8
- package/coverage/lcov-report/api/routes/metadata.js.html +9 -9
- package/coverage/lcov-report/api/routes/migrations.js.html +7 -7
- package/coverage/lcov-report/api/routes/permission.js.html +9 -9
- package/coverage/lcov-report/api/routes/query.js.html +10 -10
- package/coverage/lcov-report/api/routes/role.js.html +9 -9
- package/coverage/lcov-report/api/routes/routing.js.html +8 -8
- package/coverage/lcov-report/api/routes/screen.js.html +9 -9
- package/coverage/lcov-report/api/routes/script.js.html +1 -1
- package/coverage/lcov-report/api/routes/table.js.html +10 -10
- package/coverage/lcov-report/api/routes/templates.js.html +8 -8
- package/coverage/lcov-report/api/routes/user.js.html +8 -8
- package/coverage/lcov-report/api/routes/utils/index.html +1 -1
- package/coverage/lcov-report/api/routes/utils/validators.js.html +45 -45
- package/coverage/lcov-report/api/routes/view.js.html +10 -10
- package/coverage/lcov-report/automations/actions.js.html +1 -1
- package/coverage/lcov-report/automations/automationUtils.js.html +1 -1
- package/coverage/lcov-report/automations/bullboard.js.html +25 -10
- package/coverage/lcov-report/automations/index.html +16 -16
- package/coverage/lcov-report/automations/index.js.html +4 -4
- package/coverage/lcov-report/automations/steps/bash.js.html +1 -1
- package/coverage/lcov-report/automations/steps/delay.js.html +1 -1
- package/coverage/lcov-report/automations/steps/discord.js.html +1 -1
- package/coverage/lcov-report/automations/steps/executeQuery.js.html +1 -1
- package/coverage/lcov-report/automations/steps/executeScript.js.html +1 -1
- package/coverage/lcov-report/automations/steps/filter.js.html +1 -1
- package/coverage/lcov-report/automations/steps/index.html +1 -1
- package/coverage/lcov-report/automations/steps/integromat.js.html +1 -1
- package/coverage/lcov-report/automations/steps/loop.js.html +1 -1
- package/coverage/lcov-report/automations/steps/outgoingWebhook.js.html +1 -1
- package/coverage/lcov-report/automations/steps/queryRows.js.html +1 -1
- package/coverage/lcov-report/automations/steps/sendSmtpEmail.js.html +1 -1
- package/coverage/lcov-report/automations/steps/serverLog.js.html +1 -1
- package/coverage/lcov-report/automations/steps/slack.js.html +1 -1
- package/coverage/lcov-report/automations/steps/updateRow.js.html +1 -1
- package/coverage/lcov-report/automations/steps/utils.js.html +1 -1
- package/coverage/lcov-report/automations/steps/zapier.js.html +1 -1
- package/coverage/lcov-report/automations/triggerInfo/app.js.html +1 -1
- package/coverage/lcov-report/automations/triggerInfo/cron.js.html +1 -1
- package/coverage/lcov-report/automations/triggerInfo/index.html +1 -1
- package/coverage/lcov-report/automations/triggerInfo/index.js.html +1 -1
- package/coverage/lcov-report/automations/triggerInfo/rowDeleted.js.html +1 -1
- package/coverage/lcov-report/automations/triggerInfo/rowSaved.js.html +1 -1
- package/coverage/lcov-report/automations/triggerInfo/rowUpdated.js.html +1 -1
- package/coverage/lcov-report/automations/triggerInfo/webhook.js.html +1 -1
- package/coverage/lcov-report/automations/triggers.js.html +23 -23
- package/coverage/lcov-report/constants/index.html +5 -5
- package/coverage/lcov-report/constants/index.js.html +4 -16
- package/coverage/lcov-report/constants/layouts.js.html +1 -1
- package/coverage/lcov-report/constants/screens.js.html +1 -1
- package/coverage/lcov-report/db/inMemoryView.js.html +1 -1
- package/coverage/lcov-report/db/index.html +1 -1
- package/coverage/lcov-report/db/index.js.html +1 -1
- package/coverage/lcov-report/db/linkedRows/LinkController.js.html +1 -1
- package/coverage/lcov-report/db/linkedRows/index.html +1 -1
- package/coverage/lcov-report/db/linkedRows/index.js.html +1 -1
- package/coverage/lcov-report/db/linkedRows/linkUtils.js.html +1 -1
- package/coverage/lcov-report/db/newid.js.html +1 -1
- package/coverage/lcov-report/db/utils.js.html +2 -2
- package/coverage/lcov-report/events/AutomationEmitter.js.html +1 -1
- package/coverage/lcov-report/events/index.html +1 -1
- package/coverage/lcov-report/events/index.js.html +2 -2
- package/coverage/lcov-report/events/utils.js.html +1 -1
- package/coverage/lcov-report/index.html +45 -45
- package/coverage/lcov-report/integrations/tests/TestConfiguration.js.html +1 -1
- package/coverage/lcov-report/integrations/tests/index.html +1 -1
- package/coverage/lcov-report/middleware/appInfo.js.html +5 -5
- package/coverage/lcov-report/middleware/builder.js.html +9 -9
- package/coverage/lcov-report/middleware/currentapp.js.html +14 -14
- package/coverage/lcov-report/middleware/index.html +1 -1
- package/coverage/lcov-report/middleware/joi-validator.js.html +1 -1
- package/coverage/lcov-report/middleware/publicApi.js.html +5 -5
- package/coverage/lcov-report/middleware/resourceId.js.html +22 -22
- package/coverage/lcov-report/middleware/selfhost.js.html +1 -1
- package/coverage/lcov-report/middleware/utils.js.html +3 -3
- package/coverage/lcov-report/utilities/budibaseDir.js.html +1 -1
- package/coverage/lcov-report/utilities/centralPath.js.html +1 -1
- package/coverage/lcov-report/utilities/csvParser.js.html +1 -1
- package/coverage/lcov-report/utilities/global.js.html +1 -1
- package/coverage/lcov-report/utilities/index.html +20 -20
- package/coverage/lcov-report/utilities/index.js.html +2 -2
- package/coverage/lcov-report/utilities/plugins.js.html +1 -1
- package/coverage/lcov-report/utilities/queue/inMemoryQueue.js.html +1 -1
- package/coverage/lcov-report/utilities/queue/index.html +1 -1
- package/coverage/lcov-report/utilities/routing/index.html +1 -1
- package/coverage/lcov-report/utilities/routing/index.js.html +6 -6
- package/coverage/lcov-report/utilities/rowProcessor/index.html +1 -1
- package/coverage/lcov-report/utilities/rowProcessor/index.js.html +1 -1
- package/coverage/lcov-report/utilities/rowProcessor/utils.js.html +1 -1
- package/coverage/lcov-report/utilities/scriptRunner.js.html +1 -1
- package/coverage/lcov-report/utilities/security.js.html +1 -1
- package/coverage/lcov-report/utilities/statusCodes.js.html +1 -1
- package/coverage/lcov-report/utilities/usageQuota/index.html +1 -1
- package/coverage/lcov-report/utilities/usageQuota/rows.js.html +1 -1
- package/coverage/lcov-report/utilities/usageQuota/usageQuoteReset.js.html +1 -1
- package/coverage/lcov-report/utilities/users.js.html +1 -1
- package/coverage/lcov-report/utilities/workerRequests.js.html +46 -46
- package/coverage/lcov.info +492 -596
- package/dist/api/controllers/webhook.js +88 -89
- package/dist/api/routes/utils/validators.js +2 -2
- package/dist/api/routes/webhook.js +39 -11
- package/dist/app.js +2 -84
- package/dist/automations/bullboard.js +7 -2
- package/dist/automations/utils.js +5 -37
- package/dist/constants/index.js +0 -3
- package/dist/package.json +6 -6
- package/dist/sdk/app/automations/index.js +29 -0
- package/dist/sdk/app/automations/webhook.js +54 -0
- package/dist/sdk/app/backups/imports.js +24 -0
- package/dist/sdk/index.js +2 -0
- package/dist/startup.js +152 -0
- package/dist/tests/utilities/TestConfiguration.js +8 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +7 -7
- package/src/api/controllers/{webhook.js → webhook.ts} +33 -48
- package/src/api/routes/utils/validators.js +2 -2
- package/src/api/routes/{webhook.js → webhook.ts} +7 -6
- package/src/app.ts +3 -108
- package/src/automations/bullboard.js +6 -1
- package/src/automations/utils.ts +12 -20
- package/src/constants/index.js +0 -4
- package/src/definitions/automations.ts +1 -6
- package/src/migrations/functions/tests/syncQuotas.spec.js +1 -3
- package/src/migrations/functions/tests/userEmailViewCasing.spec.js +6 -4
- package/src/sdk/app/automations/index.ts +5 -0
- package/src/sdk/app/automations/webhook.ts +43 -0
- package/src/sdk/app/backups/imports.ts +39 -5
- package/src/sdk/index.ts +2 -0
- package/src/startup.ts +138 -0
- package/src/tests/utilities/TestConfiguration.js +7 -0
- package/coverage/lcov-report/api/controllers/webhook.js.html +0 -424
- package/coverage/lcov-report/api/routes/webhook.js.html +0 -163
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@budibase/server",
|
|
3
3
|
"email": "hi@budibase.com",
|
|
4
|
-
"version": "2.0.34-alpha.
|
|
4
|
+
"version": "2.0.34-alpha.7",
|
|
5
5
|
"description": "Budibase Web Server",
|
|
6
6
|
"main": "src/index.ts",
|
|
7
7
|
"repository": {
|
|
@@ -77,11 +77,11 @@
|
|
|
77
77
|
"license": "GPL-3.0",
|
|
78
78
|
"dependencies": {
|
|
79
79
|
"@apidevtools/swagger-parser": "10.0.3",
|
|
80
|
-
"@budibase/backend-core": "2.0.34-alpha.
|
|
81
|
-
"@budibase/client": "2.0.34-alpha.
|
|
82
|
-
"@budibase/pro": "2.0.34-alpha.
|
|
83
|
-
"@budibase/string-templates": "2.0.34-alpha.
|
|
84
|
-
"@budibase/types": "2.0.34-alpha.
|
|
80
|
+
"@budibase/backend-core": "2.0.34-alpha.7",
|
|
81
|
+
"@budibase/client": "2.0.34-alpha.7",
|
|
82
|
+
"@budibase/pro": "2.0.34-alpha.6",
|
|
83
|
+
"@budibase/string-templates": "2.0.34-alpha.7",
|
|
84
|
+
"@budibase/types": "2.0.34-alpha.7",
|
|
85
85
|
"@bull-board/api": "3.7.0",
|
|
86
86
|
"@bull-board/koa": "3.9.4",
|
|
87
87
|
"@elastic/elasticsearch": "7.10.0",
|
|
@@ -199,5 +199,5 @@
|
|
|
199
199
|
"optionalDependencies": {
|
|
200
200
|
"oracledb": "5.3.0"
|
|
201
201
|
},
|
|
202
|
-
"gitHead": "
|
|
202
|
+
"gitHead": "899da8117bff87550e52d246e54c00bfe88bd56e"
|
|
203
203
|
}
|
|
@@ -1,66 +1,51 @@
|
|
|
1
|
-
|
|
1
|
+
import { getWebhookParams } from "../../db/utils"
|
|
2
|
+
import triggers from "../../automations/triggers"
|
|
3
|
+
import { db as dbCore, context } from "@budibase/backend-core"
|
|
4
|
+
import {
|
|
5
|
+
Webhook,
|
|
6
|
+
WebhookActionType,
|
|
7
|
+
BBContext,
|
|
8
|
+
Automation,
|
|
9
|
+
} from "@budibase/types"
|
|
10
|
+
import sdk from "../../sdk"
|
|
2
11
|
const toJsonSchema = require("to-json-schema")
|
|
3
12
|
const validate = require("jsonschema").validate
|
|
4
|
-
const { WebhookType } = require("../../constants")
|
|
5
|
-
const triggers = require("../../automations/triggers")
|
|
6
|
-
const { getProdAppID } = require("@budibase/backend-core/db")
|
|
7
|
-
const { getAppDB, updateAppId } = require("@budibase/backend-core/context")
|
|
8
13
|
|
|
9
14
|
const AUTOMATION_DESCRIPTION = "Generated from Webhook Schema"
|
|
10
15
|
|
|
11
|
-
function
|
|
12
|
-
|
|
13
|
-
this.name = name
|
|
14
|
-
this.action = {
|
|
15
|
-
type,
|
|
16
|
-
target,
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
exports.Webhook = Webhook
|
|
21
|
-
|
|
22
|
-
exports.fetch = async ctx => {
|
|
23
|
-
const db = getAppDB()
|
|
16
|
+
export async function fetch(ctx: BBContext) {
|
|
17
|
+
const db = context.getAppDB()
|
|
24
18
|
const response = await db.allDocs(
|
|
25
19
|
getWebhookParams(null, {
|
|
26
20
|
include_docs: true,
|
|
27
21
|
})
|
|
28
22
|
)
|
|
29
|
-
ctx.body = response.rows.map(row => row.doc)
|
|
23
|
+
ctx.body = response.rows.map((row: any) => row.doc)
|
|
30
24
|
}
|
|
31
25
|
|
|
32
|
-
|
|
33
|
-
const
|
|
34
|
-
const webhook = ctx.request.body
|
|
35
|
-
webhook.appId = ctx.appId
|
|
36
|
-
|
|
37
|
-
// check that the webhook exists
|
|
38
|
-
if (webhook._id) {
|
|
39
|
-
await db.get(webhook._id)
|
|
40
|
-
} else {
|
|
41
|
-
webhook._id = generateWebhookID()
|
|
42
|
-
}
|
|
43
|
-
const response = await db.put(webhook)
|
|
44
|
-
webhook._rev = response.rev
|
|
26
|
+
export async function save(ctx: BBContext) {
|
|
27
|
+
const webhook = await sdk.automations.webhook.save(ctx.request.body)
|
|
45
28
|
ctx.body = {
|
|
46
29
|
message: "Webhook created successfully",
|
|
47
30
|
webhook,
|
|
48
31
|
}
|
|
49
32
|
}
|
|
50
33
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
34
|
+
export async function destroy(ctx: BBContext) {
|
|
35
|
+
ctx.body = await sdk.automations.webhook.destroy(
|
|
36
|
+
ctx.params.id,
|
|
37
|
+
ctx.params.rev
|
|
38
|
+
)
|
|
54
39
|
}
|
|
55
40
|
|
|
56
|
-
|
|
57
|
-
await updateAppId(ctx.params.instance)
|
|
58
|
-
const db = getAppDB()
|
|
59
|
-
const webhook = await db.get(ctx.params.id)
|
|
41
|
+
export async function buildSchema(ctx: BBContext) {
|
|
42
|
+
await context.updateAppId(ctx.params.instance)
|
|
43
|
+
const db = context.getAppDB()
|
|
44
|
+
const webhook = (await db.get(ctx.params.id)) as Webhook
|
|
60
45
|
webhook.bodySchema = toJsonSchema(ctx.request.body)
|
|
61
46
|
// update the automation outputs
|
|
62
|
-
if (webhook.action.type ===
|
|
63
|
-
let automation = await db.get(webhook.action.target)
|
|
47
|
+
if (webhook.action.type === WebhookActionType.AUTOMATION) {
|
|
48
|
+
let automation = (await db.get(webhook.action.target)) as Automation
|
|
64
49
|
const autoOutputs = automation.definition.trigger.schema.outputs
|
|
65
50
|
let properties = webhook.bodySchema.properties
|
|
66
51
|
// reset webhook outputs
|
|
@@ -78,18 +63,18 @@ exports.buildSchema = async ctx => {
|
|
|
78
63
|
ctx.body = await db.put(webhook)
|
|
79
64
|
}
|
|
80
65
|
|
|
81
|
-
|
|
82
|
-
const prodAppId = getProdAppID(ctx.params.instance)
|
|
83
|
-
await updateAppId(prodAppId)
|
|
66
|
+
export async function trigger(ctx: BBContext) {
|
|
67
|
+
const prodAppId = dbCore.getProdAppID(ctx.params.instance)
|
|
68
|
+
await context.updateAppId(prodAppId)
|
|
84
69
|
try {
|
|
85
|
-
const db = getAppDB()
|
|
86
|
-
const webhook = await db.get(ctx.params.id)
|
|
70
|
+
const db = context.getAppDB()
|
|
71
|
+
const webhook = (await db.get(ctx.params.id)) as Webhook
|
|
87
72
|
// validate against the schema
|
|
88
73
|
if (webhook.bodySchema) {
|
|
89
74
|
validate(ctx.request.body, webhook.bodySchema)
|
|
90
75
|
}
|
|
91
76
|
const target = await db.get(webhook.action.target)
|
|
92
|
-
if (webhook.action.type ===
|
|
77
|
+
if (webhook.action.type === WebhookActionType.AUTOMATION) {
|
|
93
78
|
// trigger with both the pure request and then expand it
|
|
94
79
|
// incase the user has produced a schema to bind to
|
|
95
80
|
await triggers.externalTrigger(target, {
|
|
@@ -102,7 +87,7 @@ exports.trigger = async ctx => {
|
|
|
102
87
|
ctx.body = {
|
|
103
88
|
message: "Webhook trigger fired successfully",
|
|
104
89
|
}
|
|
105
|
-
} catch (err) {
|
|
90
|
+
} catch (err: any) {
|
|
106
91
|
if (err.status === 404) {
|
|
107
92
|
ctx.status = 200
|
|
108
93
|
ctx.body = {
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
const { joiValidator } = require("@budibase/backend-core/auth")
|
|
2
2
|
const { DataSourceOperation } = require("../../../constants")
|
|
3
|
-
const { WebhookType } = require("../../../constants")
|
|
4
3
|
const {
|
|
5
4
|
BUILTIN_PERMISSION_IDS,
|
|
6
5
|
PermissionLevels,
|
|
7
6
|
} = require("@budibase/backend-core/permissions")
|
|
7
|
+
const { WebhookActionType } = require("@budibase/types")
|
|
8
8
|
const Joi = require("joi")
|
|
9
9
|
|
|
10
10
|
const OPTIONAL_STRING = Joi.string().optional().allow(null).allow("")
|
|
@@ -126,7 +126,7 @@ exports.webhookValidator = () => {
|
|
|
126
126
|
name: Joi.string().required(),
|
|
127
127
|
bodySchema: Joi.object().optional(),
|
|
128
128
|
action: Joi.object({
|
|
129
|
-
type: Joi.string().required().valid(
|
|
129
|
+
type: Joi.string().required().valid(WebhookActionType.AUTOMATION),
|
|
130
130
|
target: Joi.string().required(),
|
|
131
131
|
}).required(),
|
|
132
132
|
}).unknown(true))
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
import Router from "@koa/router"
|
|
2
|
+
import * as controller from "../controllers/webhook"
|
|
3
|
+
import authorized from "../../middleware/authorized"
|
|
4
|
+
import { permissions } from "@budibase/backend-core"
|
|
5
|
+
import { webhookValidator } from "./utils/validators"
|
|
6
6
|
|
|
7
|
+
const BUILDER = permissions.BUILDER
|
|
7
8
|
const router = new Router()
|
|
8
9
|
|
|
9
10
|
router
|
|
@@ -23,4 +24,4 @@ router
|
|
|
23
24
|
// this shouldn't have authorisation, right now its always public
|
|
24
25
|
.post("/api/webhooks/trigger/:instance/:id", controller.trigger)
|
|
25
26
|
|
|
26
|
-
|
|
27
|
+
export default router
|
package/src/app.ts
CHANGED
|
@@ -15,30 +15,16 @@ db.init()
|
|
|
15
15
|
const Koa = require("koa")
|
|
16
16
|
const destroyable = require("server-destroy")
|
|
17
17
|
const koaBody = require("koa-body")
|
|
18
|
-
const pino = require("koa-pino-logger")
|
|
19
18
|
const http = require("http")
|
|
20
19
|
const api = require("./api")
|
|
21
|
-
const eventEmitter = require("./events")
|
|
22
20
|
const automations = require("./automations/index")
|
|
23
21
|
const Sentry = require("@sentry/node")
|
|
24
|
-
const fileSystem = require("./utilities/fileSystem")
|
|
25
|
-
const bullboard = require("./automations/bullboard")
|
|
26
22
|
const { logAlert } = require("@budibase/backend-core/logging")
|
|
27
|
-
const { pinoSettings } = require("@budibase/backend-core")
|
|
28
23
|
const { Thread } = require("./threads")
|
|
29
|
-
const fs = require("fs")
|
|
30
24
|
import redis from "./utilities/redis"
|
|
31
|
-
import
|
|
32
|
-
import { events, installation, tenancy } from "@budibase/backend-core"
|
|
33
|
-
import {
|
|
34
|
-
createAdminUser,
|
|
35
|
-
generateApiKey,
|
|
36
|
-
getChecklist,
|
|
37
|
-
} from "./utilities/workerRequests"
|
|
38
|
-
import { watch } from "./watch"
|
|
25
|
+
import { events } from "@budibase/backend-core"
|
|
39
26
|
import { initialise as initialiseWebsockets } from "./websocket"
|
|
40
|
-
import
|
|
41
|
-
import * as pro from "@budibase/pro"
|
|
27
|
+
import { startup } from "./startup"
|
|
42
28
|
|
|
43
29
|
const app = new Koa()
|
|
44
30
|
|
|
@@ -54,19 +40,6 @@ app.use(
|
|
|
54
40
|
})
|
|
55
41
|
)
|
|
56
42
|
|
|
57
|
-
app.use(pino(pinoSettings()))
|
|
58
|
-
|
|
59
|
-
if (!env.isTest()) {
|
|
60
|
-
const plugin = bullboard.init()
|
|
61
|
-
app.use(plugin)
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
app.context.eventEmitter = eventEmitter
|
|
65
|
-
app.context.auth = {}
|
|
66
|
-
|
|
67
|
-
// api routes
|
|
68
|
-
app.use(api.router.routes())
|
|
69
|
-
|
|
70
43
|
if (env.isProd()) {
|
|
71
44
|
env._set("NODE_ENV", "production")
|
|
72
45
|
Sentry.init()
|
|
@@ -104,86 +77,8 @@ server.on("close", async () => {
|
|
|
104
77
|
}
|
|
105
78
|
})
|
|
106
79
|
|
|
107
|
-
const initPro = async () => {
|
|
108
|
-
await pro.init({
|
|
109
|
-
backups: {
|
|
110
|
-
processing: {
|
|
111
|
-
exportAppFn: sdk.backups.exportApp,
|
|
112
|
-
importAppFn: sdk.backups.importApp,
|
|
113
|
-
statsFn: sdk.backups.calculateBackupStats,
|
|
114
|
-
},
|
|
115
|
-
},
|
|
116
|
-
})
|
|
117
|
-
}
|
|
118
|
-
|
|
119
80
|
module.exports = server.listen(env.PORT || 0, async () => {
|
|
120
|
-
|
|
121
|
-
env._set("PORT", server.address().port)
|
|
122
|
-
eventEmitter.emitPort(env.PORT)
|
|
123
|
-
fileSystem.init()
|
|
124
|
-
await redis.init()
|
|
125
|
-
|
|
126
|
-
// run migrations on startup if not done via http
|
|
127
|
-
// not recommended in a clustered environment
|
|
128
|
-
if (!env.HTTP_MIGRATIONS && !env.isTest()) {
|
|
129
|
-
try {
|
|
130
|
-
await migrations.migrate()
|
|
131
|
-
} catch (e) {
|
|
132
|
-
logAlert("Error performing migrations. Exiting.", e)
|
|
133
|
-
shutdown()
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
// check and create admin user if required
|
|
138
|
-
if (
|
|
139
|
-
env.SELF_HOSTED &&
|
|
140
|
-
!env.MULTI_TENANCY &&
|
|
141
|
-
env.BB_ADMIN_USER_EMAIL &&
|
|
142
|
-
env.BB_ADMIN_USER_PASSWORD
|
|
143
|
-
) {
|
|
144
|
-
const checklist = await getChecklist()
|
|
145
|
-
if (!checklist?.adminUser?.checked) {
|
|
146
|
-
try {
|
|
147
|
-
const tenantId = tenancy.getTenantId()
|
|
148
|
-
const user = await createAdminUser(
|
|
149
|
-
env.BB_ADMIN_USER_EMAIL,
|
|
150
|
-
env.BB_ADMIN_USER_PASSWORD,
|
|
151
|
-
tenantId
|
|
152
|
-
)
|
|
153
|
-
// Need to set up an API key for automated integration tests
|
|
154
|
-
if (env.isTest()) {
|
|
155
|
-
await generateApiKey(user._id)
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
console.log(
|
|
159
|
-
"Admin account automatically created for",
|
|
160
|
-
env.BB_ADMIN_USER_EMAIL
|
|
161
|
-
)
|
|
162
|
-
} catch (e) {
|
|
163
|
-
logAlert("Error creating initial admin user. Exiting.", e)
|
|
164
|
-
shutdown()
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
// monitor plugin directory if required
|
|
170
|
-
if (
|
|
171
|
-
env.SELF_HOSTED &&
|
|
172
|
-
!env.MULTI_TENANCY &&
|
|
173
|
-
env.PLUGINS_DIR &&
|
|
174
|
-
fs.existsSync(env.PLUGINS_DIR)
|
|
175
|
-
) {
|
|
176
|
-
watch()
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
// check for version updates
|
|
180
|
-
await installation.checkInstallVersion()
|
|
181
|
-
|
|
182
|
-
// done last - these will never complete
|
|
183
|
-
let promises = []
|
|
184
|
-
promises.push(automations.init())
|
|
185
|
-
promises.push(initPro())
|
|
186
|
-
await Promise.all(promises)
|
|
81
|
+
await startup(app, server)
|
|
187
82
|
})
|
|
188
83
|
|
|
189
84
|
const shutdown = () => {
|
|
@@ -3,6 +3,7 @@ const { BullAdapter } = require("@bull-board/api/bullAdapter")
|
|
|
3
3
|
const { KoaAdapter } = require("@bull-board/koa")
|
|
4
4
|
const { queue } = require("@budibase/backend-core")
|
|
5
5
|
const automation = require("../threads/automation")
|
|
6
|
+
const { backups } = require("@budibase/pro")
|
|
6
7
|
|
|
7
8
|
let automationQueue = queue.createQueue(
|
|
8
9
|
queue.JobQueue.AUTOMATION,
|
|
@@ -11,9 +12,13 @@ let automationQueue = queue.createQueue(
|
|
|
11
12
|
|
|
12
13
|
const PATH_PREFIX = "/bulladmin"
|
|
13
14
|
|
|
14
|
-
exports.init = () => {
|
|
15
|
+
exports.init = async () => {
|
|
15
16
|
// Set up queues for bull board admin
|
|
17
|
+
const backupQueue = await backups.getBackupQueue()
|
|
16
18
|
const queues = [automationQueue]
|
|
19
|
+
if (backupQueue) {
|
|
20
|
+
queues.push(backupQueue)
|
|
21
|
+
}
|
|
17
22
|
const adapters = []
|
|
18
23
|
const serverAdapter = new KoaAdapter()
|
|
19
24
|
for (let queue of queues) {
|
package/src/automations/utils.ts
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import { Thread, ThreadType } from "../threads"
|
|
2
2
|
import { definitions } from "./triggerInfo"
|
|
3
|
-
import * as webhooks from "../api/controllers/webhook"
|
|
4
3
|
import { automationQueue } from "./bullboard"
|
|
5
4
|
import newid from "../db/newid"
|
|
6
5
|
import { updateEntityMetadata } from "../utilities"
|
|
7
|
-
import { MetadataTypes
|
|
6
|
+
import { MetadataTypes } from "../constants"
|
|
8
7
|
import { getProdAppID, doWithDB } from "@budibase/backend-core/db"
|
|
9
8
|
import { getAutomationMetadataParams } from "../db/utils"
|
|
10
9
|
import { cloneDeep } from "lodash/fp"
|
|
@@ -15,7 +14,8 @@ import {
|
|
|
15
14
|
} from "@budibase/backend-core/context"
|
|
16
15
|
import { context } from "@budibase/backend-core"
|
|
17
16
|
import { quotas } from "@budibase/pro"
|
|
18
|
-
import { Automation } from "@budibase/types"
|
|
17
|
+
import { Automation, WebhookActionType } from "@budibase/types"
|
|
18
|
+
import sdk from "../sdk"
|
|
19
19
|
|
|
20
20
|
const REBOOT_CRON = "@reboot"
|
|
21
21
|
const WH_STEP_ID = definitions.WEBHOOK.stepId
|
|
@@ -197,16 +197,12 @@ export async function checkForWebhooks({ oldAuto, newAuto }: any) {
|
|
|
197
197
|
let db = getAppDB()
|
|
198
198
|
// need to get the webhook to get the rev
|
|
199
199
|
const webhook = await db.get(oldTrigger.webhookId)
|
|
200
|
-
const ctx = {
|
|
201
|
-
appId,
|
|
202
|
-
params: { id: webhook._id, rev: webhook._rev },
|
|
203
|
-
}
|
|
204
200
|
// might be updating - reset the inputs to remove the URLs
|
|
205
201
|
if (newTrigger) {
|
|
206
202
|
delete newTrigger.webhookId
|
|
207
203
|
newTrigger.inputs = {}
|
|
208
204
|
}
|
|
209
|
-
await
|
|
205
|
+
await sdk.automations.webhook.destroy(webhook._id, webhook._rev)
|
|
210
206
|
} catch (err) {
|
|
211
207
|
// don't worry about not being able to delete, if it doesn't exist all good
|
|
212
208
|
}
|
|
@@ -216,18 +212,14 @@ export async function checkForWebhooks({ oldAuto, newAuto }: any) {
|
|
|
216
212
|
(!isWebhookTrigger(oldAuto) || triggerChanged) &&
|
|
217
213
|
isWebhookTrigger(newAuto)
|
|
218
214
|
) {
|
|
219
|
-
const
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
},
|
|
228
|
-
}
|
|
229
|
-
await webhooks.save(ctx)
|
|
230
|
-
const id = ctx.body.webhook._id
|
|
215
|
+
const webhook = await sdk.automations.webhook.save(
|
|
216
|
+
sdk.automations.webhook.newDoc(
|
|
217
|
+
"Automation webhook",
|
|
218
|
+
WebhookActionType.AUTOMATION,
|
|
219
|
+
newAuto._id
|
|
220
|
+
)
|
|
221
|
+
)
|
|
222
|
+
const id = webhook._id
|
|
231
223
|
newTrigger.webhookId = id
|
|
232
224
|
// the app ID has to be development for this endpoint
|
|
233
225
|
// it can only be used when building the app
|
package/src/constants/index.js
CHANGED
|
@@ -196,10 +196,6 @@ exports.BuildSchemaErrors = {
|
|
|
196
196
|
INVALID_COLUMN: "invalid_column",
|
|
197
197
|
}
|
|
198
198
|
|
|
199
|
-
exports.WebhookType = {
|
|
200
|
-
AUTOMATION: "automation",
|
|
201
|
-
}
|
|
202
|
-
|
|
203
199
|
exports.AutomationErrors = {
|
|
204
200
|
INCORRECT_TYPE: "INCORRECT_TYPE",
|
|
205
201
|
MAX_ITERATIONS: "MAX_ITERATIONS_REACHED",
|
|
@@ -1,13 +1,11 @@
|
|
|
1
|
-
const TestConfig = require("../../../tests/utilities/TestConfiguration")
|
|
2
|
-
|
|
3
1
|
const syncApps = jest.fn()
|
|
4
2
|
const syncRows = jest.fn()
|
|
5
3
|
const syncPlugins = jest.fn()
|
|
6
|
-
|
|
7
4
|
jest.mock("../usageQuotas/syncApps", () => ({ run: syncApps }) )
|
|
8
5
|
jest.mock("../usageQuotas/syncRows", () => ({ run: syncRows }) )
|
|
9
6
|
jest.mock("../usageQuotas/syncPlugins", () => ({ run: syncPlugins }) )
|
|
10
7
|
|
|
8
|
+
const TestConfig = require("../../../tests/utilities/TestConfiguration")
|
|
11
9
|
const migration = require("../syncQuotas")
|
|
12
10
|
|
|
13
11
|
describe("run", () => {
|
|
@@ -1,11 +1,13 @@
|
|
|
1
|
+
jest.mock("@budibase/backend-core/db", () => ({
|
|
2
|
+
...jest.requireActual("@budibase/backend-core/db"),
|
|
3
|
+
createNewUserEmailView: jest.fn(),
|
|
4
|
+
}))
|
|
5
|
+
const coreDb = require("@budibase/backend-core/db")
|
|
1
6
|
const TestConfig = require("../../../tests/utilities/TestConfiguration")
|
|
2
7
|
const { TENANT_ID } = require("../../../tests/utilities/structures")
|
|
3
8
|
const { getGlobalDB, doInTenant } = require("@budibase/backend-core/tenancy")
|
|
4
9
|
|
|
5
10
|
// mock email view creation
|
|
6
|
-
const coreDb = require("@budibase/backend-core/db")
|
|
7
|
-
const createNewUserEmailView = jest.fn()
|
|
8
|
-
coreDb.createNewUserEmailView = createNewUserEmailView
|
|
9
11
|
|
|
10
12
|
const migration = require("../userEmailViewCasing")
|
|
11
13
|
|
|
@@ -22,7 +24,7 @@ describe("run", () => {
|
|
|
22
24
|
await doInTenant(TENANT_ID, async () => {
|
|
23
25
|
const globalDb = getGlobalDB()
|
|
24
26
|
await migration.run(globalDb)
|
|
25
|
-
expect(createNewUserEmailView).toHaveBeenCalledTimes(1)
|
|
27
|
+
expect(coreDb.createNewUserEmailView).toHaveBeenCalledTimes(1)
|
|
26
28
|
})
|
|
27
29
|
})
|
|
28
30
|
})
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { Webhook, WebhookActionType } from "@budibase/types"
|
|
2
|
+
import { db as dbCore, context } from "@budibase/backend-core"
|
|
3
|
+
import { generateWebhookID } from "../../../db/utils"
|
|
4
|
+
|
|
5
|
+
function isWebhookID(id: string) {
|
|
6
|
+
return id.startsWith(dbCore.DocumentType.WEBHOOK)
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function newDoc(
|
|
10
|
+
name: string,
|
|
11
|
+
type: WebhookActionType,
|
|
12
|
+
target: string
|
|
13
|
+
): Webhook {
|
|
14
|
+
return {
|
|
15
|
+
live: true,
|
|
16
|
+
name,
|
|
17
|
+
action: {
|
|
18
|
+
type,
|
|
19
|
+
target,
|
|
20
|
+
},
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export async function save(webhook: Webhook) {
|
|
25
|
+
const db = context.getAppDB()
|
|
26
|
+
// check that the webhook exists
|
|
27
|
+
if (webhook._id && isWebhookID(webhook._id)) {
|
|
28
|
+
await db.get(webhook._id)
|
|
29
|
+
} else {
|
|
30
|
+
webhook._id = generateWebhookID()
|
|
31
|
+
}
|
|
32
|
+
const response = await db.put(webhook)
|
|
33
|
+
webhook._rev = response.rev
|
|
34
|
+
return webhook
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export async function destroy(id: string, rev: string) {
|
|
38
|
+
const db = context.getAppDB()
|
|
39
|
+
if (!id || !isWebhookID(id)) {
|
|
40
|
+
throw new Error("Provided webhook ID is not valid.")
|
|
41
|
+
}
|
|
42
|
+
return await db.remove(id, rev)
|
|
43
|
+
}
|
|
@@ -1,20 +1,25 @@
|
|
|
1
1
|
import { db as dbCore } from "@budibase/backend-core"
|
|
2
|
-
import { TABLE_ROW_PREFIX } from "../../../db/utils"
|
|
2
|
+
import { getAutomationParams, TABLE_ROW_PREFIX } from "../../../db/utils"
|
|
3
3
|
import { budibaseTempDir } from "../../../utilities/budibaseDir"
|
|
4
4
|
import { DB_EXPORT_FILE, GLOBAL_DB_EXPORT_FILE } from "./constants"
|
|
5
5
|
import {
|
|
6
|
-
uploadDirectory,
|
|
7
6
|
upload,
|
|
7
|
+
uploadDirectory,
|
|
8
8
|
} from "../../../utilities/fileSystem/utilities"
|
|
9
9
|
import { downloadTemplate } from "../../../utilities/fileSystem"
|
|
10
|
-
import {
|
|
10
|
+
import { FieldTypes, ObjectStoreBuckets } from "../../../constants"
|
|
11
11
|
import { join } from "path"
|
|
12
12
|
import fs from "fs"
|
|
13
13
|
import sdk from "../../"
|
|
14
|
-
import {
|
|
14
|
+
import {
|
|
15
|
+
Automation,
|
|
16
|
+
AutomationTriggerStepId,
|
|
17
|
+
CouchFindOptions,
|
|
18
|
+
RowAttachment,
|
|
19
|
+
} from "@budibase/types"
|
|
20
|
+
import PouchDB from "pouchdb"
|
|
15
21
|
const uuid = require("uuid/v4")
|
|
16
22
|
const tar = require("tar")
|
|
17
|
-
import PouchDB from "pouchdb"
|
|
18
23
|
|
|
19
24
|
type TemplateType = {
|
|
20
25
|
file?: {
|
|
@@ -81,6 +86,34 @@ async function updateAttachmentColumns(
|
|
|
81
86
|
}
|
|
82
87
|
}
|
|
83
88
|
|
|
89
|
+
async function updateAutomations(prodAppId: string, db: PouchDB.Database) {
|
|
90
|
+
const automations = (
|
|
91
|
+
await db.allDocs(
|
|
92
|
+
getAutomationParams(null, {
|
|
93
|
+
include_docs: true,
|
|
94
|
+
})
|
|
95
|
+
)
|
|
96
|
+
).rows.map(row => row.doc) as Automation[]
|
|
97
|
+
const devAppId = dbCore.getDevAppID(prodAppId)
|
|
98
|
+
let toSave: Automation[] = []
|
|
99
|
+
for (let automation of automations) {
|
|
100
|
+
const oldDevAppId = automation.appId,
|
|
101
|
+
oldProdAppId = dbCore.getProdAppID(automation.appId)
|
|
102
|
+
if (
|
|
103
|
+
automation.definition.trigger.stepId === AutomationTriggerStepId.WEBHOOK
|
|
104
|
+
) {
|
|
105
|
+
const old = automation.definition.trigger.inputs
|
|
106
|
+
automation.definition.trigger.inputs = {
|
|
107
|
+
schemaUrl: old.schemaUrl.replace(oldDevAppId, devAppId),
|
|
108
|
+
triggerUrl: old.triggerUrl.replace(oldProdAppId, prodAppId),
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
automation.appId = devAppId
|
|
112
|
+
toSave.push(automation)
|
|
113
|
+
}
|
|
114
|
+
await db.bulkDocs(toSave)
|
|
115
|
+
}
|
|
116
|
+
|
|
84
117
|
/**
|
|
85
118
|
* This function manages temporary template files which are stored by Koa.
|
|
86
119
|
* @param {Object} template The template object retrieved from the Koa context object.
|
|
@@ -165,5 +198,6 @@ export async function importApp(
|
|
|
165
198
|
throw "Error loading database dump from template."
|
|
166
199
|
}
|
|
167
200
|
await updateAttachmentColumns(prodAppId, db)
|
|
201
|
+
await updateAutomations(prodAppId, db)
|
|
168
202
|
return ok
|
|
169
203
|
}
|
package/src/sdk/index.ts
CHANGED