1
0
Fork 0
mirror of synced 2024-06-21 11:51:00 +12:00

Fixing an issue with webhooks, couldn't use them in development (like getting schema) and making sure trigger will always use production app #3143.

This commit is contained in:
mike12345567 2021-11-03 14:08:47 +00:00
parent 62613f6a74
commit 9ce1866fab
5 changed files with 47 additions and 25 deletions

View file

@ -3,6 +3,7 @@ const { generateWebhookID, getWebhookParams } = require("../../db/utils")
const toJsonSchema = require("to-json-schema")
const validate = require("jsonschema").validate
const triggers = require("../../automations/triggers")
const { getDeployedAppID } = require("@budibase/auth/db")
const AUTOMATION_DESCRIPTION = "Generated from Webhook Schema"
@ -76,24 +77,34 @@ exports.buildSchema = async ctx => {
}
exports.trigger = async ctx => {
const db = new CouchDB(ctx.params.instance)
const webhook = await db.get(ctx.params.id)
// validate against the schema
if (webhook.bodySchema) {
validate(ctx.request.body, webhook.bodySchema)
}
const target = await db.get(webhook.action.target)
if (webhook.action.type === exports.WebhookType.AUTOMATION) {
// trigger with both the pure request and then expand it
// incase the user has produced a schema to bind to
await triggers.externalTrigger(target, {
body: ctx.request.body,
...ctx.request.body,
appId: ctx.params.instance,
})
}
ctx.status = 200
ctx.body = {
message: "Webhook trigger fired successfully",
const prodAppId = getDeployedAppID(ctx.params.instance)
try {
const db = new CouchDB(prodAppId)
const webhook = await db.get(ctx.params.id)
// validate against the schema
if (webhook.bodySchema) {
validate(ctx.request.body, webhook.bodySchema)
}
const target = await db.get(webhook.action.target)
if (webhook.action.type === exports.WebhookType.AUTOMATION) {
// trigger with both the pure request and then expand it
// incase the user has produced a schema to bind to
await triggers.externalTrigger(target, {
body: ctx.request.body,
...ctx.request.body,
appId: prodAppId,
})
}
ctx.status = 200
ctx.body = {
message: "Webhook trigger fired successfully",
}
} catch (err) {
if (err.status === 404) {
ctx.status = 200
ctx.body = {
message: "Application not deployed yet.",
}
}
}
}

View file

@ -6,6 +6,7 @@ const { queue } = require("./bullboard")
const newid = require("../db/newid")
const { updateEntityMetadata } = require("../utilities")
const { MetadataTypes } = require("../constants")
const { getDeployedAppID } = require("@budibase/auth/db")
const WH_STEP_ID = definitions.WEBHOOK.stepId
const CRON_STEP_ID = definitions.CRON.stepId
@ -150,9 +151,13 @@ exports.checkForWebhooks = async ({ appId, oldAuto, newAuto }) => {
await webhooks.save(ctx)
const id = ctx.body.webhook._id
newTrigger.webhookId = id
// the app ID has to be development for this endpoint
// it can only be used when building the app
// but the trigger endpoint will always be used in production
const prodAppId = getDeployedAppID(appId)
newTrigger.inputs = {
schemaUrl: `api/webhooks/schema/${appId}/${id}`,
triggerUrl: `api/webhooks/trigger/${appId}/${id}`,
triggerUrl: `api/webhooks/trigger/${prodAppId}/${id}`,
}
}
return newAuto

View file

@ -5,20 +5,17 @@ const {
doesHaveBasePermission,
} = require("@budibase/auth/permissions")
const builderMiddleware = require("./builder")
const { isWebhookEndpoint } = require("./utils")
function hasResource(ctx) {
return ctx.resourceId != null
}
const WEBHOOK_ENDPOINTS = new RegExp(
["webhooks/trigger", "webhooks/schema"].join("|")
)
module.exports =
(permType, permLevel = null) =>
async (ctx, next) => {
// webhooks don't need authentication, each webhook unique
if (WEBHOOK_ENDPOINTS.test(ctx.request.url)) {
if (isWebhookEndpoint(ctx)) {
return next()
}

View file

@ -9,6 +9,7 @@ const { isUserInAppTenant } = require("@budibase/auth/tenancy")
const { getCachedSelf } = require("../utilities/global")
const CouchDB = require("../db")
const env = require("../environment")
const { isWebhookEndpoint } = require("./utils")
module.exports = async (ctx, next) => {
// try to get the appID from the request
@ -38,6 +39,7 @@ module.exports = async (ctx, next) => {
// deny access to application preview
if (
isDevAppID(requestAppId) &&
!isWebhookEndpoint(ctx) &&
(!ctx.user || !ctx.user.builder || !ctx.user.builder.global)
) {
clearCookie(ctx, Cookies.CurrentApp)

View file

@ -0,0 +1,7 @@
const WEBHOOK_ENDPOINTS = new RegExp(
["webhooks/trigger", "webhooks/schema"].join("|")
)
exports.isWebhookEndpoint = ctx => {
return WEBHOOK_ENDPOINTS.test(ctx.request.url)
}