Merge pull request #692 from Budibase/external-webhooks

support for external webhooks
This commit is contained in:
Martin McKeaveney 2020-10-12 13:53:55 +01:00 committed by GitHub
commit 95cd3f84fc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 53 additions and 11 deletions

View File

@ -1,6 +1,7 @@
<script>
import { Input } from "@budibase/bbui"
import { Input, Label } from "@budibase/bbui"
import api from "builderStore/api"
import { backendUiStore } from "builderStore"
import analytics from "analytics"
let keys = { budibase: "" }
@ -38,6 +39,10 @@
edit
value={keys.budibase}
label="Budibase API Key" />
<div>
<Label extraSmall grey>Instance ID (Webhooks)</Label>
<span>{$backendUiStore.selectedDatabase._id}</span>
</div>
</div>
<style>
@ -45,4 +50,9 @@
display: grid;
grid-gap: var(--spacing-xl);
}
span {
font-size: var(--font-size-xs);
font-weight: 500;
}
</style>

View File

@ -136,7 +136,7 @@ exports.performLocalFileProcessing = async function(ctx) {
}
exports.serveApp = async function(ctx) {
const mainOrAuth = ctx.isAuthenticated ? "main" : "unauthenticated"
const mainOrAuth = ctx.auth.authenticated ? "main" : "unauthenticated"
// default to homedir
const appPath = resolve(
@ -154,7 +154,7 @@ exports.serveApp = async function(ctx) {
// only set the appId cookie for /appId .. we COULD check for valid appIds
// but would like to avoid that DB hit
const looksLikeAppId = /^(app_)?[0-9a-f]{32}$/.test(appId)
if (looksLikeAppId && !ctx.isAuthenticated) {
if (looksLikeAppId && !ctx.auth.authenticated) {
const anonUser = {
userId: "ANON",
accessLevelId: ANON_LEVEL_ID,
@ -200,7 +200,7 @@ exports.serveAttachment = async function(ctx) {
exports.serveAppAsset = async function(ctx) {
// default to homedir
const mainOrAuth = ctx.isAuthenticated ? "main" : "unauthenticated"
const mainOrAuth = ctx.auth.authenticated ? "main" : "unauthenticated"
const appPath = resolve(
budibaseAppsDir(),

View File

@ -24,6 +24,7 @@ app.use(
)
app.context.eventEmitter = eventEmitter
app.context.auth = {}
// api routes
app.use(api.routes())

View File

@ -20,8 +20,10 @@ module.exports = async (ctx, next) => {
if (builderToken) {
try {
const jwtPayload = jwt.verify(builderToken, ctx.config.jwtSecret)
ctx.apiKey = jwtPayload.apiKey
ctx.isAuthenticated = jwtPayload.accessLevelId === BUILDER_LEVEL_ID
ctx.auth = {
apiKey: jwtPayload.apiKey,
authenticated: jwtPayload.accessLevelId === BUILDER_LEVEL_ID,
}
ctx.user = {
...jwtPayload,
accessLevel: await getAccessLevel(
@ -38,14 +40,13 @@ module.exports = async (ctx, next) => {
}
if (!appToken) {
ctx.isAuthenticated = false
ctx.auth.authenticated = false
await next()
return
}
try {
const jwtPayload = jwt.verify(appToken, ctx.config.jwtSecret)
ctx.apiKey = jwtPayload.apiKey
ctx.user = {
...jwtPayload,
accessLevel: await getAccessLevel(
@ -53,7 +54,10 @@ module.exports = async (ctx, next) => {
jwtPayload.accessLevelId
),
}
ctx.isAuthenticated = ctx.user.accessLevelId !== ANON_LEVEL_ID
ctx.auth = {
authenticated: ctx.user.accessLevelId !== ANON_LEVEL_ID,
apiKey: jwtPayload.apiKey,
}
} catch (err) {
ctx.throw(err.status || STATUS_CODES.FORBIDDEN, err.text)
}

View File

@ -5,9 +5,36 @@ const {
BUILDER_LEVEL_ID,
BUILDER,
} = require("../utilities/accessLevels")
const environment = require("../environment")
const { apiKeyTable } = require("../db/dynamoClient")
module.exports = (permName, getItemId) => async (ctx, next) => {
if (!ctx.isAuthenticated) {
if (
environment.CLOUD &&
ctx.headers["x-api-key"] &&
ctx.headers["x-instanceid"]
) {
// api key header passed by external webhook
const apiKeyInfo = await apiKeyTable.get({
primary: ctx.headers["x-api-key"],
})
if (apiKeyInfo) {
ctx.auth = {
authenticated: true,
external: true,
apiKey: ctx.headers["x-api-key"],
}
ctx.user = {
instanceId: ctx.headers["x-instanceid"],
}
return next()
}
ctx.throw(403, "API key invalid")
}
if (!ctx.auth.authenticated) {
ctx.throw(403, "Session not authenticated")
}

View File

@ -55,7 +55,7 @@ module.exports = async (ctx, next) => {
return next()
}
try {
await usageQuota.update(ctx.apiKey, property, usage)
await usageQuota.update(ctx.auth.apiKey, property, usage)
return next()
} catch (err) {
ctx.throw(403, err)