Merge branch 'master' of github.com:Budibase/budibase into feat/linked-records-data-source

This commit is contained in:
Andrew Kingston 2020-10-12 14:21:39 +01:00
commit dfd6a4d856
7 changed files with 60 additions and 19 deletions

View File

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

View File

@ -361,19 +361,18 @@ export const typography = [
label: "Font", label: "Font",
key: "font-family", key: "font-family",
control: OptionSelect, control: OptionSelect,
defaultValue: "initial", defaultValue: "Arial",
options: [ options: [
"initial",
"Arial", "Arial",
"Arial Black", "Arial Black",
"Cursive", "Cursive",
"Courier", "Courier",
"Comic Sans MS", "Comic Sans MS",
"Helvetica", "Helvetica",
"Helvetica Neue",
"Impact", "Impact",
"Inter", "Inter",
"Lucida Sans Unicode", "Lucida Sans Unicode",
"Open Sans",
"Roboto", "Roboto",
"Roboto Mono", "Roboto Mono",
"Times New Roman", "Times New Roman",
@ -467,9 +466,9 @@ export const background = [
label: "Gradient", label: "Gradient",
key: "background-image", key: "background-image",
control: OptionSelect, control: OptionSelect,
defaultValue: "None", defaultValue: "",
options: [ options: [
{ label: "None", value: "None" }, { label: "Select option", value: "" },
{ {
label: "Warm Flame", label: "Warm Flame",
value: "linear-gradient(45deg, #ff9a9e 0%, #fad0c4 99%, #fad0c4 100%);", value: "linear-gradient(45deg, #ff9a9e 0%, #fad0c4 99%, #fad0c4 100%);",
@ -518,9 +517,9 @@ export const background = [
}, },
{ {
label: "Image", label: "Image",
key: "background-image", key: "background",
control: Input, control: Input,
placeholder: "Src", placeholder: "url",
}, },
] ]
@ -665,7 +664,7 @@ export const transitions = [
control: OptionSelect, control: OptionSelect,
textAlign: "center", textAlign: "center",
placeholder: "sec", placeholder: "sec",
options: ["0.2ms", "0.4ms", "0.8ms", "1s", "2s", "4s"], options: ["0.4s", "0.6s", "0.8s", "1s", "2s", "4s"],
}, },
{ {
label: "Ease", label: "Ease",

View File

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

View File

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

View File

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

View File

@ -5,9 +5,36 @@ const {
BUILDER_LEVEL_ID, BUILDER_LEVEL_ID,
BUILDER, BUILDER,
} = require("../utilities/accessLevels") } = require("../utilities/accessLevels")
const environment = require("../environment")
const { apiKeyTable } = require("../db/dynamoClient")
module.exports = (permName, getItemId) => async (ctx, next) => { 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") ctx.throw(403, "Session not authenticated")
} }

View File

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