@budibase/server 2.5.6-alpha.1 → 2.5.6-alpha.10
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/builder/assets/{index.1fe52b59.js → index.5c1a6913.js} +361 -361
- package/builder/assets/index.c0265b74.css +6 -0
- package/builder/index.html +2 -2
- package/dist/api/controllers/automation.js +13 -7
- package/dist/api/controllers/plugin/index.js +6 -37
- package/dist/api/controllers/table/utils.js +2 -1
- package/dist/api/controllers/user.js +1 -83
- package/dist/api/routes/user.js +0 -1
- package/dist/app.js +2 -2
- package/dist/automations/actions.js +32 -6
- package/dist/automations/index.js +3 -2
- package/dist/automations/steps/bash.js +6 -6
- package/dist/automations/steps/createRow.js +11 -11
- package/dist/automations/steps/delay.js +3 -3
- package/dist/automations/steps/deleteRow.js +8 -8
- package/dist/automations/steps/discord.js +8 -8
- package/dist/automations/steps/executeQuery.js +9 -9
- package/dist/automations/steps/executeScript.js +6 -6
- package/dist/automations/steps/filter.js +6 -6
- package/dist/automations/steps/integromat.js +10 -10
- package/dist/automations/steps/loop.js +9 -9
- package/dist/automations/steps/outgoingWebhook.js +10 -10
- package/dist/automations/steps/queryRows.js +14 -14
- package/dist/automations/steps/sendSmtpEmail.js +9 -9
- package/dist/automations/steps/serverLog.js +4 -4
- package/dist/automations/steps/slack.js +6 -6
- package/dist/automations/steps/updateRow.js +11 -11
- package/dist/automations/steps/zapier.js +9 -9
- package/dist/automations/triggerInfo/app.js +5 -5
- package/dist/automations/triggerInfo/cron.js +4 -4
- package/dist/automations/triggerInfo/rowDeleted.js +5 -5
- package/dist/automations/triggerInfo/rowSaved.js +7 -7
- package/dist/automations/triggerInfo/rowUpdated.js +7 -7
- package/dist/automations/triggerInfo/webhook.js +6 -6
- package/dist/events/docUpdates/index.js +17 -0
- package/dist/events/docUpdates/processors.js +18 -0
- package/dist/events/docUpdates/syncUsers.js +49 -0
- package/dist/events/index.js +3 -0
- package/dist/integrations/index.js +3 -3
- package/dist/package.json +9 -8
- package/dist/sdk/app/applications/sync.js +117 -23
- package/dist/sdk/index.js +2 -0
- package/dist/sdk/plugins/index.js +27 -0
- package/dist/sdk/plugins/plugins.js +53 -0
- package/dist/sdk/users/utils.js +21 -4
- package/dist/startup.js +2 -1
- package/dist/threads/automation.js +2 -2
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/dist/utilities/fileSystem/plugin.js +33 -23
- package/dist/utilities/global.js +17 -12
- package/dist/watch.js +2 -2
- package/dist/websockets/client.js +14 -0
- package/dist/websockets/grid.js +60 -0
- package/dist/websockets/index.js +17 -0
- package/dist/websockets/websocket.js +78 -0
- package/jest.config.ts +3 -3
- package/nodemon.json +7 -3
- package/package.json +10 -9
- package/src/api/controllers/automation.ts +12 -6
- package/src/api/controllers/plugin/index.ts +8 -45
- package/src/api/controllers/row/internal.ts +9 -10
- package/src/api/controllers/row/utils.ts +2 -2
- package/src/api/controllers/table/utils.ts +2 -1
- package/src/api/controllers/user.ts +10 -96
- package/src/api/routes/tests/automation.spec.js +2 -2
- package/src/api/routes/tests/user.spec.js +0 -37
- package/src/api/routes/user.ts +0 -5
- package/src/app.ts +2 -2
- package/src/automations/actions.ts +56 -24
- package/src/automations/index.ts +1 -1
- package/src/automations/steps/bash.ts +10 -7
- package/src/automations/steps/createRow.ts +15 -12
- package/src/automations/steps/delay.ts +6 -4
- package/src/automations/steps/deleteRow.ts +12 -9
- package/src/automations/steps/discord.ts +10 -8
- package/src/automations/steps/executeQuery.ts +13 -10
- package/src/automations/steps/executeScript.ts +10 -7
- package/src/automations/steps/filter.ts +8 -6
- package/src/automations/steps/integromat.ts +12 -10
- package/src/automations/steps/loop.ts +16 -10
- package/src/automations/steps/outgoingWebhook.ts +14 -11
- package/src/automations/steps/queryRows.ts +18 -15
- package/src/automations/steps/sendSmtpEmail.ts +11 -9
- package/src/automations/steps/serverLog.ts +6 -4
- package/src/automations/steps/slack.ts +8 -6
- package/src/automations/steps/updateRow.ts +15 -12
- package/src/automations/steps/zapier.ts +11 -9
- package/src/automations/tests/utilities/index.ts +2 -2
- package/src/automations/triggerInfo/app.ts +8 -5
- package/src/automations/triggerInfo/cron.ts +7 -4
- package/src/automations/triggerInfo/rowDeleted.ts +8 -5
- package/src/automations/triggerInfo/rowSaved.ts +10 -7
- package/src/automations/triggerInfo/rowUpdated.ts +10 -7
- package/src/automations/triggerInfo/webhook.ts +9 -6
- package/src/events/docUpdates/index.ts +1 -0
- package/src/events/docUpdates/processors.ts +14 -0
- package/src/events/docUpdates/syncUsers.ts +35 -0
- package/src/events/index.ts +1 -0
- package/src/integrations/index.ts +3 -3
- package/src/sdk/app/applications/sync.ts +129 -22
- package/src/sdk/app/applications/tests/sync.spec.ts +137 -0
- package/src/sdk/index.ts +2 -0
- package/src/sdk/plugins/index.ts +5 -0
- package/src/sdk/plugins/plugins.ts +41 -0
- package/src/sdk/users/tests/utils.spec.ts +1 -32
- package/src/sdk/users/utils.ts +23 -5
- package/src/startup.ts +2 -1
- package/src/tests/utilities/TestConfiguration.ts +28 -0
- package/src/tests/utilities/structures.ts +25 -17
- package/src/threads/automation.ts +2 -2
- package/src/utilities/fileSystem/plugin.ts +13 -4
- package/src/utilities/global.ts +21 -16
- package/src/watch.ts +2 -2
- package/src/websockets/client.ts +11 -0
- package/src/websockets/grid.ts +55 -0
- package/src/websockets/index.ts +14 -0
- package/src/websockets/websocket.ts +83 -0
- package/tsconfig.json +1 -7
- package/builder/assets/index.841e62d8.css +0 -6
- package/dist/websocket.js +0 -22
- package/src/websocket.ts +0 -26
|
@@ -4,12 +4,14 @@ import {
|
|
|
4
4
|
AutomationActionStepId,
|
|
5
5
|
AutomationStepSchema,
|
|
6
6
|
AutomationStepInput,
|
|
7
|
+
AutomationStepType,
|
|
8
|
+
AutomationIOType,
|
|
7
9
|
} from "@budibase/types"
|
|
8
10
|
|
|
9
11
|
export const definition: AutomationStepSchema = {
|
|
10
12
|
name: "Zapier Webhook",
|
|
11
13
|
stepId: AutomationActionStepId.zapier,
|
|
12
|
-
type:
|
|
14
|
+
type: AutomationStepType.ACTION,
|
|
13
15
|
internal: false,
|
|
14
16
|
description: "Trigger a Zapier Zap via webhooks",
|
|
15
17
|
tagline: "Trigger a Zapier Zap",
|
|
@@ -19,27 +21,27 @@ export const definition: AutomationStepSchema = {
|
|
|
19
21
|
inputs: {
|
|
20
22
|
properties: {
|
|
21
23
|
url: {
|
|
22
|
-
type:
|
|
24
|
+
type: AutomationIOType.STRING,
|
|
23
25
|
title: "Webhook URL",
|
|
24
26
|
},
|
|
25
27
|
value1: {
|
|
26
|
-
type:
|
|
28
|
+
type: AutomationIOType.STRING,
|
|
27
29
|
title: "Payload Value 1",
|
|
28
30
|
},
|
|
29
31
|
value2: {
|
|
30
|
-
type:
|
|
32
|
+
type: AutomationIOType.STRING,
|
|
31
33
|
title: "Payload Value 2",
|
|
32
34
|
},
|
|
33
35
|
value3: {
|
|
34
|
-
type:
|
|
36
|
+
type: AutomationIOType.STRING,
|
|
35
37
|
title: "Payload Value 3",
|
|
36
38
|
},
|
|
37
39
|
value4: {
|
|
38
|
-
type:
|
|
40
|
+
type: AutomationIOType.STRING,
|
|
39
41
|
title: "Payload Value 4",
|
|
40
42
|
},
|
|
41
43
|
value5: {
|
|
42
|
-
type:
|
|
44
|
+
type: AutomationIOType.STRING,
|
|
43
45
|
title: "Payload Value 5",
|
|
44
46
|
},
|
|
45
47
|
},
|
|
@@ -48,11 +50,11 @@ export const definition: AutomationStepSchema = {
|
|
|
48
50
|
outputs: {
|
|
49
51
|
properties: {
|
|
50
52
|
httpStatus: {
|
|
51
|
-
type:
|
|
53
|
+
type: AutomationIOType.NUMBER,
|
|
52
54
|
description: "The HTTP status code of the request",
|
|
53
55
|
},
|
|
54
56
|
response: {
|
|
55
|
-
type:
|
|
57
|
+
type: AutomationIOType.STRING,
|
|
56
58
|
description: "The response from Zapier",
|
|
57
59
|
},
|
|
58
60
|
},
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import TestConfig from "../../../tests/utilities/TestConfiguration"
|
|
2
2
|
import { context } from "@budibase/backend-core"
|
|
3
|
-
import {
|
|
3
|
+
import { BUILTIN_ACTION_DEFINITIONS, getAction } from "../../actions"
|
|
4
4
|
import emitter from "../../../events/index"
|
|
5
5
|
import env from "../../../environment"
|
|
6
6
|
|
|
@@ -57,4 +57,4 @@ export async function runStep(stepId: string, inputs: any, stepContext?: any) {
|
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
export const apiKey = "test"
|
|
60
|
-
export const actions =
|
|
60
|
+
export const actions = BUILTIN_ACTION_DEFINITIONS
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
|
+
AutomationCustomIOType,
|
|
3
|
+
AutomationIOType,
|
|
4
|
+
AutomationStepType,
|
|
2
5
|
AutomationTriggerSchema,
|
|
3
6
|
AutomationTriggerStepId,
|
|
4
7
|
} from "@budibase/types"
|
|
@@ -15,8 +18,8 @@ export const definition: AutomationTriggerSchema = {
|
|
|
15
18
|
inputs: {
|
|
16
19
|
properties: {
|
|
17
20
|
fields: {
|
|
18
|
-
type:
|
|
19
|
-
customType:
|
|
21
|
+
type: AutomationIOType.OBJECT,
|
|
22
|
+
customType: AutomationCustomIOType.TRIGGER_SCHEMA,
|
|
20
23
|
title: "Fields",
|
|
21
24
|
},
|
|
22
25
|
},
|
|
@@ -25,13 +28,13 @@ export const definition: AutomationTriggerSchema = {
|
|
|
25
28
|
outputs: {
|
|
26
29
|
properties: {
|
|
27
30
|
fields: {
|
|
28
|
-
type:
|
|
31
|
+
type: AutomationIOType.OBJECT,
|
|
29
32
|
description: "Fields submitted from the app frontend",
|
|
30
|
-
customType:
|
|
33
|
+
customType: AutomationCustomIOType.TRIGGER_SCHEMA,
|
|
31
34
|
},
|
|
32
35
|
},
|
|
33
36
|
required: ["fields"],
|
|
34
37
|
},
|
|
35
38
|
},
|
|
36
|
-
type:
|
|
39
|
+
type: AutomationStepType.TRIGGER,
|
|
37
40
|
}
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
|
+
AutomationCustomIOType,
|
|
3
|
+
AutomationIOType,
|
|
4
|
+
AutomationStepType,
|
|
2
5
|
AutomationTriggerSchema,
|
|
3
6
|
AutomationTriggerStepId,
|
|
4
7
|
} from "@budibase/types"
|
|
@@ -15,8 +18,8 @@ export const definition: AutomationTriggerSchema = {
|
|
|
15
18
|
inputs: {
|
|
16
19
|
properties: {
|
|
17
20
|
cron: {
|
|
18
|
-
type:
|
|
19
|
-
customType:
|
|
21
|
+
type: AutomationIOType.STRING,
|
|
22
|
+
customType: AutomationCustomIOType.CRON,
|
|
20
23
|
title: "Expression",
|
|
21
24
|
},
|
|
22
25
|
},
|
|
@@ -25,12 +28,12 @@ export const definition: AutomationTriggerSchema = {
|
|
|
25
28
|
outputs: {
|
|
26
29
|
properties: {
|
|
27
30
|
timestamp: {
|
|
28
|
-
type:
|
|
31
|
+
type: AutomationIOType.NUMBER,
|
|
29
32
|
description: "Timestamp the cron was executed",
|
|
30
33
|
},
|
|
31
34
|
},
|
|
32
35
|
required: ["timestamp"],
|
|
33
36
|
},
|
|
34
37
|
},
|
|
35
|
-
type:
|
|
38
|
+
type: AutomationStepType.TRIGGER,
|
|
36
39
|
}
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
|
+
AutomationCustomIOType,
|
|
3
|
+
AutomationIOType,
|
|
4
|
+
AutomationStepType,
|
|
2
5
|
AutomationTriggerSchema,
|
|
3
6
|
AutomationTriggerStepId,
|
|
4
7
|
} from "@budibase/types"
|
|
@@ -15,8 +18,8 @@ export const definition: AutomationTriggerSchema = {
|
|
|
15
18
|
inputs: {
|
|
16
19
|
properties: {
|
|
17
20
|
tableId: {
|
|
18
|
-
type:
|
|
19
|
-
customType:
|
|
21
|
+
type: AutomationIOType.STRING,
|
|
22
|
+
customType: AutomationCustomIOType.TABLE,
|
|
20
23
|
title: "Table",
|
|
21
24
|
},
|
|
22
25
|
},
|
|
@@ -25,13 +28,13 @@ export const definition: AutomationTriggerSchema = {
|
|
|
25
28
|
outputs: {
|
|
26
29
|
properties: {
|
|
27
30
|
row: {
|
|
28
|
-
type:
|
|
29
|
-
customType:
|
|
31
|
+
type: AutomationIOType.OBJECT,
|
|
32
|
+
customType: AutomationCustomIOType.ROW,
|
|
30
33
|
description: "The row that was deleted",
|
|
31
34
|
},
|
|
32
35
|
},
|
|
33
36
|
required: ["row"],
|
|
34
37
|
},
|
|
35
38
|
},
|
|
36
|
-
type:
|
|
39
|
+
type: AutomationStepType.TRIGGER,
|
|
37
40
|
}
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
|
+
AutomationCustomIOType,
|
|
3
|
+
AutomationIOType,
|
|
4
|
+
AutomationStepType,
|
|
2
5
|
AutomationTriggerSchema,
|
|
3
6
|
AutomationTriggerStepId,
|
|
4
7
|
} from "@budibase/types"
|
|
@@ -15,8 +18,8 @@ export const definition: AutomationTriggerSchema = {
|
|
|
15
18
|
inputs: {
|
|
16
19
|
properties: {
|
|
17
20
|
tableId: {
|
|
18
|
-
type:
|
|
19
|
-
customType:
|
|
21
|
+
type: AutomationIOType.STRING,
|
|
22
|
+
customType: AutomationCustomIOType.TABLE,
|
|
20
23
|
title: "Table",
|
|
21
24
|
},
|
|
22
25
|
},
|
|
@@ -25,21 +28,21 @@ export const definition: AutomationTriggerSchema = {
|
|
|
25
28
|
outputs: {
|
|
26
29
|
properties: {
|
|
27
30
|
row: {
|
|
28
|
-
type:
|
|
29
|
-
customType:
|
|
31
|
+
type: AutomationIOType.OBJECT,
|
|
32
|
+
customType: AutomationCustomIOType.ROW,
|
|
30
33
|
description: "The new row that was created",
|
|
31
34
|
},
|
|
32
35
|
id: {
|
|
33
|
-
type:
|
|
36
|
+
type: AutomationIOType.STRING,
|
|
34
37
|
description: "Row ID - can be used for updating",
|
|
35
38
|
},
|
|
36
39
|
revision: {
|
|
37
|
-
type:
|
|
40
|
+
type: AutomationIOType.STRING,
|
|
38
41
|
description: "Revision of row",
|
|
39
42
|
},
|
|
40
43
|
},
|
|
41
44
|
required: ["row", "id"],
|
|
42
45
|
},
|
|
43
46
|
},
|
|
44
|
-
type:
|
|
47
|
+
type: AutomationStepType.TRIGGER,
|
|
45
48
|
}
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
|
+
AutomationCustomIOType,
|
|
3
|
+
AutomationIOType,
|
|
4
|
+
AutomationStepType,
|
|
2
5
|
AutomationTriggerSchema,
|
|
3
6
|
AutomationTriggerStepId,
|
|
4
7
|
} from "@budibase/types"
|
|
@@ -15,8 +18,8 @@ export const definition: AutomationTriggerSchema = {
|
|
|
15
18
|
inputs: {
|
|
16
19
|
properties: {
|
|
17
20
|
tableId: {
|
|
18
|
-
type:
|
|
19
|
-
customType:
|
|
21
|
+
type: AutomationIOType.STRING,
|
|
22
|
+
customType: AutomationCustomIOType.TABLE,
|
|
20
23
|
title: "Table",
|
|
21
24
|
},
|
|
22
25
|
},
|
|
@@ -25,21 +28,21 @@ export const definition: AutomationTriggerSchema = {
|
|
|
25
28
|
outputs: {
|
|
26
29
|
properties: {
|
|
27
30
|
row: {
|
|
28
|
-
type:
|
|
29
|
-
customType:
|
|
31
|
+
type: AutomationIOType.OBJECT,
|
|
32
|
+
customType: AutomationCustomIOType.ROW,
|
|
30
33
|
description: "The row that was updated",
|
|
31
34
|
},
|
|
32
35
|
id: {
|
|
33
|
-
type:
|
|
36
|
+
type: AutomationIOType.STRING,
|
|
34
37
|
description: "Row ID - can be used for updating",
|
|
35
38
|
},
|
|
36
39
|
revision: {
|
|
37
|
-
type:
|
|
40
|
+
type: AutomationIOType.STRING,
|
|
38
41
|
description: "Revision of row",
|
|
39
42
|
},
|
|
40
43
|
},
|
|
41
44
|
required: ["row", "id"],
|
|
42
45
|
},
|
|
43
46
|
},
|
|
44
|
-
type:
|
|
47
|
+
type: AutomationStepType.TRIGGER,
|
|
45
48
|
}
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
|
+
AutomationCustomIOType,
|
|
3
|
+
AutomationIOType,
|
|
4
|
+
AutomationStepType,
|
|
2
5
|
AutomationTriggerSchema,
|
|
3
6
|
AutomationTriggerStepId,
|
|
4
7
|
} from "@budibase/types"
|
|
@@ -15,13 +18,13 @@ export const definition: AutomationTriggerSchema = {
|
|
|
15
18
|
inputs: {
|
|
16
19
|
properties: {
|
|
17
20
|
schemaUrl: {
|
|
18
|
-
type:
|
|
19
|
-
customType:
|
|
21
|
+
type: AutomationIOType.STRING,
|
|
22
|
+
customType: AutomationCustomIOType.WEBHOOK_URL,
|
|
20
23
|
title: "Schema URL",
|
|
21
24
|
},
|
|
22
25
|
triggerUrl: {
|
|
23
|
-
type:
|
|
24
|
-
customType:
|
|
26
|
+
type: AutomationIOType.STRING,
|
|
27
|
+
customType: AutomationCustomIOType.WEBHOOK_URL,
|
|
25
28
|
title: "Trigger URL",
|
|
26
29
|
},
|
|
27
30
|
},
|
|
@@ -30,12 +33,12 @@ export const definition: AutomationTriggerSchema = {
|
|
|
30
33
|
outputs: {
|
|
31
34
|
properties: {
|
|
32
35
|
body: {
|
|
33
|
-
type:
|
|
36
|
+
type: AutomationIOType.OBJECT,
|
|
34
37
|
description: "Body of the request which hit the webhook",
|
|
35
38
|
},
|
|
36
39
|
},
|
|
37
40
|
required: ["body"],
|
|
38
41
|
},
|
|
39
42
|
},
|
|
40
|
-
type:
|
|
43
|
+
type: AutomationStepType.TRIGGER,
|
|
41
44
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./processors"
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import userGroupProcessor from "./syncUsers"
|
|
2
|
+
import { docUpdates } from "@budibase/backend-core"
|
|
3
|
+
|
|
4
|
+
export type UpdateCallback = (docId: string) => void
|
|
5
|
+
let started = false
|
|
6
|
+
|
|
7
|
+
export function init(updateCb?: UpdateCallback) {
|
|
8
|
+
if (started) {
|
|
9
|
+
return
|
|
10
|
+
}
|
|
11
|
+
const processors = [userGroupProcessor(updateCb)]
|
|
12
|
+
docUpdates.init(processors)
|
|
13
|
+
started = true
|
|
14
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { constants, logging } from "@budibase/backend-core"
|
|
2
|
+
import { sdk as proSdk } from "@budibase/pro"
|
|
3
|
+
import { DocUpdateEvent, UserGroupSyncEvents } from "@budibase/types"
|
|
4
|
+
import { syncUsersToAllApps } from "../../sdk/app/applications/sync"
|
|
5
|
+
import { UpdateCallback } from "./processors"
|
|
6
|
+
|
|
7
|
+
export default function process(updateCb?: UpdateCallback) {
|
|
8
|
+
const processor = async (update: DocUpdateEvent) => {
|
|
9
|
+
try {
|
|
10
|
+
const docId = update.id
|
|
11
|
+
const isGroup = docId.startsWith(constants.DocumentType.GROUP)
|
|
12
|
+
let userIds: string[]
|
|
13
|
+
if (isGroup) {
|
|
14
|
+
const group = await proSdk.groups.get(docId)
|
|
15
|
+
userIds = group.users?.map(user => user._id) || []
|
|
16
|
+
} else {
|
|
17
|
+
userIds = [docId]
|
|
18
|
+
}
|
|
19
|
+
if (userIds.length > 0) {
|
|
20
|
+
await syncUsersToAllApps(userIds)
|
|
21
|
+
}
|
|
22
|
+
if (updateCb) {
|
|
23
|
+
updateCb(docId)
|
|
24
|
+
}
|
|
25
|
+
} catch (err: any) {
|
|
26
|
+
// if something not found - no changes to perform
|
|
27
|
+
if (err?.status === 404) {
|
|
28
|
+
return
|
|
29
|
+
} else {
|
|
30
|
+
logging.logAlert("Failed to perform user/group app sync", err)
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return { events: UserGroupSyncEvents, processor }
|
|
35
|
+
}
|
package/src/events/index.ts
CHANGED
|
@@ -14,11 +14,11 @@ import firebase from "./firebase"
|
|
|
14
14
|
import redis from "./redis"
|
|
15
15
|
import snowflake from "./snowflake"
|
|
16
16
|
import oracle from "./oracle"
|
|
17
|
-
import { getPlugins } from "../api/controllers/plugin"
|
|
18
17
|
import { SourceName, Integration, PluginType } from "@budibase/types"
|
|
19
18
|
import { getDatasourcePlugin } from "../utilities/fileSystem"
|
|
20
19
|
import env from "../environment"
|
|
21
20
|
import { cloneDeep } from "lodash"
|
|
21
|
+
import sdk from "../sdk"
|
|
22
22
|
|
|
23
23
|
const DEFINITIONS: { [key: string]: Integration } = {
|
|
24
24
|
[SourceName.POSTGRES]: postgres.schema,
|
|
@@ -79,7 +79,7 @@ export async function getDefinition(source: SourceName): Promise<Integration> {
|
|
|
79
79
|
export async function getDefinitions() {
|
|
80
80
|
const pluginSchemas: { [key: string]: Integration } = {}
|
|
81
81
|
if (env.SELF_HOSTED) {
|
|
82
|
-
const plugins = await
|
|
82
|
+
const plugins = await sdk.plugins.fetch(PluginType.DATASOURCE)
|
|
83
83
|
// extract the actual schema from each custom
|
|
84
84
|
for (let plugin of plugins) {
|
|
85
85
|
const sourceId = plugin.name
|
|
@@ -103,7 +103,7 @@ export async function getIntegration(integration: string) {
|
|
|
103
103
|
return INTEGRATIONS[integration]
|
|
104
104
|
}
|
|
105
105
|
if (env.SELF_HOSTED) {
|
|
106
|
-
const plugins = await
|
|
106
|
+
const plugins = await sdk.plugins.fetch(PluginType.DATASOURCE)
|
|
107
107
|
for (let plugin of plugins) {
|
|
108
108
|
if (plugin.name === integration) {
|
|
109
109
|
// need to use commonJS require due to its dynamic runtime nature
|
|
@@ -1,6 +1,117 @@
|
|
|
1
1
|
import env from "../../../environment"
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
db as dbCore,
|
|
4
|
+
context,
|
|
5
|
+
docUpdates,
|
|
6
|
+
constants,
|
|
7
|
+
logging,
|
|
8
|
+
roles,
|
|
9
|
+
} from "@budibase/backend-core"
|
|
10
|
+
import { User, ContextUser, UserGroup } from "@budibase/types"
|
|
11
|
+
import { sdk as proSdk } from "@budibase/pro"
|
|
3
12
|
import sdk from "../../"
|
|
13
|
+
import { getGlobalUsers, processUser } from "../../../utilities/global"
|
|
14
|
+
import { generateUserMetadataID, InternalTables } from "../../../db/utils"
|
|
15
|
+
|
|
16
|
+
type DeletedUser = { _id: string; deleted: boolean }
|
|
17
|
+
|
|
18
|
+
async function syncUsersToApp(
|
|
19
|
+
appId: string,
|
|
20
|
+
users: (User | DeletedUser)[],
|
|
21
|
+
groups: UserGroup[]
|
|
22
|
+
) {
|
|
23
|
+
if (!(await dbCore.dbExists(appId))) {
|
|
24
|
+
return
|
|
25
|
+
}
|
|
26
|
+
await context.doInAppContext(appId, async () => {
|
|
27
|
+
const db = context.getAppDB()
|
|
28
|
+
for (let user of users) {
|
|
29
|
+
let ctxUser = user as ContextUser
|
|
30
|
+
let deletedUser = false
|
|
31
|
+
const metadataId = generateUserMetadataID(user._id!)
|
|
32
|
+
if ((user as DeletedUser).deleted) {
|
|
33
|
+
deletedUser = true
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// make sure role is correct
|
|
37
|
+
if (!deletedUser) {
|
|
38
|
+
ctxUser = await processUser(ctxUser, { appId, groups })
|
|
39
|
+
}
|
|
40
|
+
let roleId = ctxUser.roleId
|
|
41
|
+
if (roleId === roles.BUILTIN_ROLE_IDS.PUBLIC) {
|
|
42
|
+
roleId = undefined
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
let metadata
|
|
46
|
+
try {
|
|
47
|
+
metadata = await db.get(metadataId)
|
|
48
|
+
} catch (err: any) {
|
|
49
|
+
if (err.status !== 404) {
|
|
50
|
+
throw err
|
|
51
|
+
}
|
|
52
|
+
// no metadata and user is to be deleted, can skip
|
|
53
|
+
// no role - user isn't in app anyway
|
|
54
|
+
if (!roleId) {
|
|
55
|
+
continue
|
|
56
|
+
} else if (!deletedUser) {
|
|
57
|
+
// doesn't exist yet, creating it
|
|
58
|
+
metadata = {
|
|
59
|
+
tableId: InternalTables.USER_METADATA,
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// the user doesn't exist, or doesn't have a role anymore
|
|
65
|
+
// get rid of their metadata
|
|
66
|
+
if (deletedUser || !roleId) {
|
|
67
|
+
await db.remove(metadata)
|
|
68
|
+
continue
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// assign the roleId for the metadata doc
|
|
72
|
+
if (roleId) {
|
|
73
|
+
metadata.roleId = roleId
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
let combined = sdk.users.combineMetadataAndUser(ctxUser, metadata)
|
|
77
|
+
// if no combined returned, there are no updates to make
|
|
78
|
+
if (combined) {
|
|
79
|
+
await db.put(combined)
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
})
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export async function syncUsersToAllApps(userIds: string[]) {
|
|
86
|
+
// list of users, if one has been deleted it will be undefined in array
|
|
87
|
+
const users = (await getGlobalUsers(userIds, {
|
|
88
|
+
noProcessing: true,
|
|
89
|
+
})) as User[]
|
|
90
|
+
const groups = await proSdk.groups.fetch()
|
|
91
|
+
const finalUsers: (User | DeletedUser)[] = []
|
|
92
|
+
for (let userId of userIds) {
|
|
93
|
+
const user = users.find(user => user._id === userId)
|
|
94
|
+
if (!user) {
|
|
95
|
+
finalUsers.push({ _id: userId, deleted: true })
|
|
96
|
+
} else {
|
|
97
|
+
finalUsers.push(user)
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
const devAppIds = await dbCore.getDevAppIDs()
|
|
101
|
+
let promises = []
|
|
102
|
+
for (let devAppId of devAppIds) {
|
|
103
|
+
const prodAppId = dbCore.getProdAppID(devAppId)
|
|
104
|
+
for (let appId of [prodAppId, devAppId]) {
|
|
105
|
+
promises.push(syncUsersToApp(appId, finalUsers, groups))
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
const resp = await Promise.allSettled(promises)
|
|
109
|
+
const failed = resp.filter(promise => promise.status === "rejected")
|
|
110
|
+
if (failed.length > 0) {
|
|
111
|
+
const reasons = failed.map(fail => (fail as PromiseRejectedResult).reason)
|
|
112
|
+
logging.logAlert("Failed to sync users to apps", reasons)
|
|
113
|
+
}
|
|
114
|
+
}
|
|
4
115
|
|
|
5
116
|
export async function syncApp(
|
|
6
117
|
appId: string,
|
|
@@ -23,32 +134,28 @@ export async function syncApp(
|
|
|
23
134
|
// specific case, want to make sure setup is skipped
|
|
24
135
|
const prodDb = context.getProdAppDB({ skip_setup: true })
|
|
25
136
|
const exists = await prodDb.exists()
|
|
26
|
-
if (!exists) {
|
|
27
|
-
// the database doesn't exist. Don't replicate
|
|
28
|
-
return {
|
|
29
|
-
message: "App sync not required, app not deployed.",
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
137
|
|
|
33
|
-
const replication = new dbCore.Replication({
|
|
34
|
-
source: prodAppId,
|
|
35
|
-
target: appId,
|
|
36
|
-
})
|
|
37
138
|
let error
|
|
38
|
-
|
|
39
|
-
const
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
139
|
+
if (exists) {
|
|
140
|
+
const replication = new dbCore.Replication({
|
|
141
|
+
source: prodAppId,
|
|
142
|
+
target: appId,
|
|
143
|
+
})
|
|
144
|
+
try {
|
|
145
|
+
const replOpts = replication.appReplicateOpts()
|
|
146
|
+
if (opts?.automationOnly) {
|
|
147
|
+
replOpts.filter = (doc: any) =>
|
|
148
|
+
doc._id.startsWith(dbCore.DocumentType.AUTOMATION)
|
|
149
|
+
}
|
|
150
|
+
await replication.replicate(replOpts)
|
|
151
|
+
} catch (err) {
|
|
152
|
+
error = err
|
|
153
|
+
} finally {
|
|
154
|
+
await replication.close()
|
|
43
155
|
}
|
|
44
|
-
await replication.replicate(replOpts)
|
|
45
|
-
} catch (err) {
|
|
46
|
-
error = err
|
|
47
|
-
} finally {
|
|
48
|
-
await replication.close()
|
|
49
156
|
}
|
|
50
157
|
|
|
51
|
-
// sync the users
|
|
158
|
+
// sync the users - kept for safe keeping
|
|
52
159
|
await sdk.users.syncGlobalUsers()
|
|
53
160
|
|
|
54
161
|
if (error) {
|