pass user through to automation context
This commit is contained in:
parent
2adc666a78
commit
a26b64bb03
|
@ -13,6 +13,7 @@ import {
|
|||
UserCtx,
|
||||
DeleteAutomationResponse,
|
||||
FetchAutomationResponse,
|
||||
User,
|
||||
} from "@budibase/types"
|
||||
import { getActionDefinitions as actionDefs } from "../../automations/actions"
|
||||
import sdk from "../../sdk"
|
||||
|
@ -159,6 +160,7 @@ export async function trigger(ctx: UserCtx) {
|
|||
automation,
|
||||
{
|
||||
fields: ctx.request.body.fields,
|
||||
user: ctx.user as User,
|
||||
timeout:
|
||||
ctx.request.body.timeout * 1000 || env.AUTOMATION_THREAD_TIMEOUT,
|
||||
},
|
||||
|
@ -183,6 +185,7 @@ export async function trigger(ctx: UserCtx) {
|
|||
await triggers.externalTrigger(automation, {
|
||||
...ctx.request.body,
|
||||
appId: ctx.appId,
|
||||
user: ctx.user as User,
|
||||
})
|
||||
ctx.body = {
|
||||
message: `Automation ${automation._id} has been triggered.`,
|
||||
|
@ -212,6 +215,7 @@ export async function test(ctx: UserCtx) {
|
|||
{
|
||||
...testInput,
|
||||
appId: ctx.appId,
|
||||
user: ctx.user,
|
||||
},
|
||||
{ getResponses: true }
|
||||
)
|
||||
|
|
|
@ -65,7 +65,14 @@ export async function patch(
|
|||
}
|
||||
ctx.status = 200
|
||||
ctx.eventEmitter &&
|
||||
ctx.eventEmitter.emitRow(`row:update`, appId, row, table, oldRow)
|
||||
ctx.eventEmitter.emitRow(
|
||||
`row:update`,
|
||||
appId,
|
||||
row,
|
||||
table,
|
||||
oldRow,
|
||||
ctx.user
|
||||
)
|
||||
ctx.message = `${table.name} updated successfully.`
|
||||
ctx.body = row
|
||||
gridSocket?.emitRowUpdate(ctx, row)
|
||||
|
@ -96,7 +103,8 @@ export const save = async (ctx: UserCtx<Row, Row>) => {
|
|||
sdk.rows.save(sourceId, ctx.request.body, ctx.user?._id)
|
||||
)
|
||||
ctx.status = 200
|
||||
ctx.eventEmitter && ctx.eventEmitter.emitRow(`row:save`, appId, row, table)
|
||||
ctx.eventEmitter &&
|
||||
ctx.eventEmitter.emitRow(`row:save`, appId, row, table, null, ctx.user)
|
||||
ctx.message = `${table.name} saved successfully`
|
||||
// prefer squashed for response
|
||||
ctx.body = row || squashed
|
||||
|
@ -168,7 +176,8 @@ async function deleteRows(ctx: UserCtx<DeleteRowRequest>) {
|
|||
}
|
||||
|
||||
for (let row of rows) {
|
||||
ctx.eventEmitter && ctx.eventEmitter.emitRow(`row:delete`, appId, row)
|
||||
ctx.eventEmitter &&
|
||||
ctx.eventEmitter.emitRow(`row:delete`, appId, row, null, null, ctx.user)
|
||||
gridSocket?.emitRowDeletion(ctx, row)
|
||||
}
|
||||
|
||||
|
@ -184,7 +193,15 @@ async function deleteRow(ctx: UserCtx<DeleteRowRequest>) {
|
|||
await quotas.removeRow()
|
||||
}
|
||||
|
||||
ctx.eventEmitter && ctx.eventEmitter.emitRow(`row:delete`, appId, resp.row)
|
||||
ctx.eventEmitter &&
|
||||
ctx.eventEmitter.emitRow(
|
||||
`row:delete`,
|
||||
appId,
|
||||
resp.row,
|
||||
null,
|
||||
null,
|
||||
ctx.user
|
||||
)
|
||||
gridSocket?.emitRowDeletion(ctx, resp.row)
|
||||
|
||||
return resp
|
||||
|
|
|
@ -5,6 +5,6 @@ export async function run(ctx: Ctx<RowActionTriggerRequest, void>) {
|
|||
const { tableId, actionId } = ctx.params
|
||||
const { rowId } = ctx.request.body
|
||||
|
||||
await sdk.rowActions.run(tableId, actionId, rowId)
|
||||
await sdk.rowActions.run(tableId, actionId, rowId, ctx.user)
|
||||
ctx.status = 200
|
||||
}
|
||||
|
|
|
@ -482,4 +482,38 @@ describe("Automation Scenarios", () => {
|
|||
}
|
||||
)
|
||||
})
|
||||
|
||||
it("Check user is passed through from row trigger", async () => {
|
||||
const table = await config.createTable()
|
||||
|
||||
const builder = createAutomationBuilder({
|
||||
name: "Test a user is successfully passed from the trigger",
|
||||
})
|
||||
|
||||
const results = await builder
|
||||
.rowUpdated(
|
||||
{ tableId: table._id! },
|
||||
{
|
||||
row: { name: "Test", description: "TEST" },
|
||||
id: "1234",
|
||||
}
|
||||
)
|
||||
.serverLog({ text: "{{ [user].[email] }}" })
|
||||
.run()
|
||||
|
||||
expect(results.steps[0].outputs.message).toContain("example.com")
|
||||
})
|
||||
|
||||
it("Check user is passed through from app trigger", async () => {
|
||||
const builder = createAutomationBuilder({
|
||||
name: "Test a user is successfully passed from the trigger",
|
||||
})
|
||||
|
||||
const results = await builder
|
||||
.appAction({ fields: {} })
|
||||
.serverLog({ text: "{{ [user].[email] }}" })
|
||||
.run()
|
||||
|
||||
expect(results.steps[0].outputs.message).toContain("example.com")
|
||||
})
|
||||
})
|
||||
|
|
|
@ -19,6 +19,7 @@ import {
|
|||
AutomationStoppedReason,
|
||||
AutomationStatus,
|
||||
AutomationRowEvent,
|
||||
User,
|
||||
} from "@budibase/types"
|
||||
import { executeInThread } from "../threads/automation"
|
||||
import { dataFilters, sdk } from "@budibase/shared-core"
|
||||
|
@ -140,9 +141,15 @@ function rowPassesFilters(row: Row, filters: SearchFilters) {
|
|||
|
||||
export async function externalTrigger(
|
||||
automation: Automation,
|
||||
params: { fields: Record<string, any>; timeout?: number; appId?: string },
|
||||
params: {
|
||||
fields: Record<string, any>
|
||||
timeout?: number
|
||||
appId?: string
|
||||
user?: User
|
||||
},
|
||||
{ getResponses }: { getResponses?: boolean } = {}
|
||||
): Promise<any> {
|
||||
console.log("user: " + params.user)
|
||||
if (automation.disabled) {
|
||||
throw new Error("Automation is disabled")
|
||||
}
|
||||
|
@ -189,6 +196,7 @@ export async function externalTrigger(
|
|||
appId: context.getAppId(),
|
||||
automation,
|
||||
}
|
||||
console.log(data)
|
||||
return executeInThread({ data } as AutomationJob)
|
||||
} else {
|
||||
return automationQueue.add(data, JOB_OPTS)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { AutomationResults, LoopStepType } from "@budibase/types"
|
||||
import { AutomationResults, LoopStepType, User } from "@budibase/types"
|
||||
|
||||
export interface LoopInput {
|
||||
option: LoopStepType
|
||||
|
@ -18,5 +18,6 @@ export interface AutomationContext extends AutomationResults {
|
|||
stepsById: Record<string, any>
|
||||
stepsByName: Record<string, any>
|
||||
env?: Record<string, string>
|
||||
user?: User
|
||||
trigger: any
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { EventEmitter } from "events"
|
||||
import { rowEmission, tableEmission } from "./utils"
|
||||
import { Table, Row } from "@budibase/types"
|
||||
import { Table, Row, User } from "@budibase/types"
|
||||
|
||||
/**
|
||||
* keeping event emitter in one central location as it might be used for things other than
|
||||
|
@ -18,9 +18,10 @@ class BudibaseEmitter extends EventEmitter {
|
|||
appId: string,
|
||||
row: Row,
|
||||
table?: Table,
|
||||
oldRow?: Row
|
||||
oldRow?: Row,
|
||||
user?: User
|
||||
) {
|
||||
rowEmission({ emitter: this, eventName, appId, row, table, oldRow })
|
||||
rowEmission({ emitter: this, eventName, appId, row, table, oldRow, user })
|
||||
}
|
||||
|
||||
emitTable(eventName: string, appId: string, table?: Table) {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Table, Row } from "@budibase/types"
|
||||
import { Table, Row, User } from "@budibase/types"
|
||||
import BudibaseEmitter from "./BudibaseEmitter"
|
||||
|
||||
type BBEventOpts = {
|
||||
|
@ -9,6 +9,7 @@ type BBEventOpts = {
|
|||
row?: Row
|
||||
oldRow?: Row
|
||||
metadata?: any
|
||||
user?: User
|
||||
}
|
||||
|
||||
interface BBEventTable extends Table {
|
||||
|
@ -24,6 +25,7 @@ type BBEvent = {
|
|||
id?: string
|
||||
revision?: string
|
||||
metadata?: any
|
||||
user?: User
|
||||
}
|
||||
|
||||
export function rowEmission({
|
||||
|
@ -34,12 +36,14 @@ export function rowEmission({
|
|||
table,
|
||||
metadata,
|
||||
oldRow,
|
||||
user,
|
||||
}: BBEventOpts) {
|
||||
let event: BBEvent = {
|
||||
row,
|
||||
oldRow,
|
||||
appId,
|
||||
tableId: row?.tableId,
|
||||
user,
|
||||
}
|
||||
if (table) {
|
||||
event.table = table
|
||||
|
|
|
@ -4,6 +4,7 @@ import {
|
|||
AutomationTriggerStepId,
|
||||
SEPARATOR,
|
||||
TableRowActions,
|
||||
User,
|
||||
VirtualDocumentType,
|
||||
} from "@budibase/types"
|
||||
import { generateRowActionsID } from "../../db/utils"
|
||||
|
@ -236,7 +237,12 @@ export async function remove(tableId: string, rowActionId: string) {
|
|||
})
|
||||
}
|
||||
|
||||
export async function run(tableId: any, rowActionId: any, rowId: string) {
|
||||
export async function run(
|
||||
tableId: any,
|
||||
rowActionId: any,
|
||||
rowId: string,
|
||||
user: User
|
||||
) {
|
||||
const table = await sdk.tables.getTable(tableId)
|
||||
if (!table) {
|
||||
throw new HTTPError("Table not found", 404)
|
||||
|
@ -258,6 +264,7 @@ export async function run(tableId: any, rowActionId: any, rowId: string) {
|
|||
row,
|
||||
table,
|
||||
},
|
||||
user,
|
||||
appId: context.getAppId(),
|
||||
},
|
||||
{ getResponses: true }
|
||||
|
|
|
@ -26,6 +26,7 @@ import {
|
|||
BranchStep,
|
||||
LoopStep,
|
||||
SearchFilters,
|
||||
User,
|
||||
} from "@budibase/types"
|
||||
import { AutomationContext, TriggerOutput } from "../definitions/automations"
|
||||
import { WorkerCallback } from "./definitions"
|
||||
|
@ -75,6 +76,7 @@ class Orchestrator {
|
|||
private loopStepOutputs: LoopStep[]
|
||||
private stopped: boolean
|
||||
private executionOutput: Omit<AutomationContext, "stepsByName" | "stepsById">
|
||||
private currentUser: User | undefined
|
||||
|
||||
constructor(job: AutomationJob) {
|
||||
let automation = job.data.automation
|
||||
|
@ -106,6 +108,7 @@ class Orchestrator {
|
|||
this.updateExecutionOutput(triggerId, triggerStepId, null, triggerOutput)
|
||||
this.loopStepOutputs = []
|
||||
this.stopped = false
|
||||
this.currentUser = triggerOutput.user
|
||||
}
|
||||
|
||||
cleanupTriggerOutputs(stepId: string, triggerOutput: TriggerOutput) {
|
||||
|
@ -258,6 +261,7 @@ class Orchestrator {
|
|||
automationId: this.automation._id,
|
||||
})
|
||||
this.context.env = await sdkUtils.getEnvironmentVariables()
|
||||
this.context.user = this.currentUser
|
||||
|
||||
let metadata
|
||||
|
||||
|
@ -572,7 +576,6 @@ class Orchestrator {
|
|||
originalStepInput,
|
||||
this.processContext(this.context)
|
||||
)
|
||||
|
||||
inputs = automationUtils.cleanInputValues(inputs, step.schema.inputs)
|
||||
|
||||
const outputs = await stepFn({
|
||||
|
|
|
@ -261,6 +261,7 @@ export type UpdatedRowEventEmitter = {
|
|||
oldRow: Row
|
||||
table: Table
|
||||
appId: string
|
||||
user: User
|
||||
}
|
||||
|
||||
export enum LoopStepType {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Automation, AutomationMetadata, Row } from "../../documents"
|
||||
import { Automation, AutomationMetadata, Row, User } from "../../documents"
|
||||
import { Job } from "bull"
|
||||
|
||||
export interface AutomationDataEvent {
|
||||
|
@ -8,6 +8,7 @@ export interface AutomationDataEvent {
|
|||
timeout?: number
|
||||
row?: Row
|
||||
oldRow?: Row
|
||||
user?: User
|
||||
}
|
||||
|
||||
export interface AutomationData {
|
||||
|
|
Loading…
Reference in New Issue