1
0
Fork 0
mirror of synced 2024-09-30 09:07:25 +13:00
This commit is contained in:
Michael Drury 2021-06-21 22:42:57 +01:00
parent 9f520ae8f3
commit 82d17af808
15 changed files with 119 additions and 96 deletions

View file

@ -2,21 +2,23 @@ import { store } from "./index"
import { get as svelteGet } from "svelte/store" import { get as svelteGet } from "svelte/store"
import { removeCookie, Cookies } from "./cookies" import { removeCookie, Cookies } from "./cookies"
const apiCall = const apiCall = method => async (
method => url,
async (url, body, headers = { "Content-Type": "application/json" }) => { body,
headers["x-budibase-app-id"] = svelteGet(store).appId headers = { "Content-Type": "application/json" }
const json = headers["Content-Type"] === "application/json" ) => {
const resp = await fetch(url, { headers["x-budibase-app-id"] = svelteGet(store).appId
method: method, const json = headers["Content-Type"] === "application/json"
body: json ? JSON.stringify(body) : body, const resp = await fetch(url, {
headers, method: method,
}) body: json ? JSON.stringify(body) : body,
if (resp.status === 403) { headers,
removeCookie(Cookies.Auth) })
} if (resp.status === 403) {
return resp removeCookie(Cookies.Auth)
} }
return resp
}
export const post = apiCall("POST") export const post = apiCall("POST")
export const get = apiCall("GET") export const get = apiCall("GET")

View file

@ -100,10 +100,9 @@ const automationActions = store => ({
}, },
deleteAutomationBlock: block => { deleteAutomationBlock: block => {
store.update(state => { store.update(state => {
const idx = const idx = state.selectedAutomation.automation.definition.steps.findIndex(
state.selectedAutomation.automation.definition.steps.findIndex( x => x.id === block.id
x => x.id === block.id )
)
state.selectedAutomation.deleteBlock(block.id) state.selectedAutomation.deleteBlock(block.id)
// Select next closest step // Select next closest step

View file

@ -59,7 +59,9 @@
<section> <section>
<Heading size="XS">Columns</Heading> <Heading size="XS">Columns</Heading>
<ul> <ul>
{#each context.filter( context => context.readableBinding.match(searchRgx) ) as { readableBinding }} {#each context.filter(context =>
context.readableBinding.match(searchRgx)
) as { readableBinding }}
<li <li
on:click={() => { on:click={() => {
value = addToText(value, getCaretPosition(), readableBinding) value = addToText(value, getCaretPosition(), readableBinding)
@ -75,7 +77,9 @@
<section> <section>
<Heading size="XS">Components</Heading> <Heading size="XS">Components</Heading>
<ul> <ul>
{#each instance.filter( instance => instance.readableBinding.match(searchRgx) ) as { readableBinding }} {#each instance.filter(instance =>
instance.readableBinding.match(searchRgx)
) as { readableBinding }}
<li on:click={() => addToText(readableBinding)}> <li on:click={() => addToText(readableBinding)}>
{readableBinding} {readableBinding}
</li> </li>

View file

@ -49,7 +49,9 @@
<div class="section"> <div class="section">
{#each categories as [categoryName, bindings]} {#each categories as [categoryName, bindings]}
<Heading size="XS">{categoryName}</Heading> <Heading size="XS">{categoryName}</Heading>
{#each bindings.filter( binding => binding.label.match(searchRgx) ) as binding} {#each bindings.filter(binding =>
binding.label.match(searchRgx)
) as binding}
<div <div
class="binding" class="binding"
on:click={() => { on:click={() => {

View file

@ -103,9 +103,8 @@
} }
function fetchQueryDefinition(query) { function fetchQueryDefinition(query) {
const source = $datasources.list.find( const source = $datasources.list.find(ds => ds._id === query.datasourceId)
ds => ds._id === query.datasourceId .source
).source
return $integrations[source].query[query.queryVerb] return $integrations[source].query[query.queryVerb]
} }
</script> </script>

View file

@ -18,9 +18,8 @@
) )
function fetchQueryDefinition(query) { function fetchQueryDefinition(query) {
const source = $datasources.list.find( const source = $datasources.list.find(ds => ds._id === query.datasourceId)
ds => ds._id === query.datasourceId .source
).source
return $integrations[source].query[query.queryVerb] return $integrations[source].query[query.queryVerb]
} }
</script> </script>

View file

@ -9,7 +9,8 @@ export const SOME_QUERY = {
queryVerb: "read", queryVerb: "read",
schema: {}, schema: {},
name: "Speakers", name: "Speakers",
_id: "query_datasource_04b003a7b4a8428eadd3bb2f7eae0255_bcb8ffc6fcbc484e8d63121fc0bf986f", _id:
"query_datasource_04b003a7b4a8428eadd3bb2f7eae0255_bcb8ffc6fcbc484e8d63121fc0bf986f",
_rev: "2-941f8699eb0adf995f8bd59c99203b26", _rev: "2-941f8699eb0adf995f8bd59c99203b26",
readable: true, readable: true,
} }
@ -74,7 +75,8 @@ export const SAVE_QUERY_RESPONSE = {
}, },
}, },
name: "Speakers", name: "Speakers",
_id: "query_datasource_04b003a7b4a8428eadd3bb2f7eae0255_bcb8ffc6fcbc484e8d63121fc0bf986f", _id:
"query_datasource_04b003a7b4a8428eadd3bb2f7eae0255_bcb8ffc6fcbc484e8d63121fc0bf986f",
_rev: "3-5a64adef494b1e9c793dc91b51ce73c6", _rev: "3-5a64adef494b1e9c793dc91b51ce73c6",
readable: true, readable: true,
} }

View file

@ -40,10 +40,12 @@ router
) )
// DEPRECATED - this is an old API, but for backwards compat it needs to be // DEPRECATED - this is an old API, but for backwards compat it needs to be
// supported still // supported still
.post("/api/search/:tableId/rows", .post(
"/api/search/:tableId/rows",
paramResource("tableId"), paramResource("tableId"),
authorized(PermissionTypes.TABLE, PermissionLevels.READ), authorized(PermissionTypes.TABLE, PermissionLevels.READ),
rowController.search) rowController.search
)
.post( .post(
"/api/:tableId/rows", "/api/:tableId/rows",
paramResource("tableId"), paramResource("tableId"),

View file

@ -2,7 +2,8 @@ const { Client } = require("@elastic/elasticsearch")
const { QUERY_TYPES, FIELD_TYPES } = require("./Integration") const { QUERY_TYPES, FIELD_TYPES } = require("./Integration")
const SCHEMA = { const SCHEMA = {
docs: "https://www.elastic.co/guide/en/elasticsearch/client/javascript-api/current/index.html", docs:
"https://www.elastic.co/guide/en/elasticsearch/client/javascript-api/current/index.html",
description: description:
"Elasticsearch is a search engine based on the Lucene library. It provides a distributed, multitenant-capable full-text search engine with an HTTP web interface and schema-free JSON documents.", "Elasticsearch is a search engine based on the Lucene library. It provides a distributed, multitenant-capable full-text search engine with an HTTP web interface and schema-free JSON documents.",
friendlyName: "ElasticSearch", friendlyName: "ElasticSearch",

View file

@ -14,52 +14,50 @@ const WEBHOOK_ENDPOINTS = new RegExp(
["webhooks/trigger", "webhooks/schema"].join("|") ["webhooks/trigger", "webhooks/schema"].join("|")
) )
module.exports = module.exports = (permType, permLevel = null) => async (ctx, next) => {
(permType, permLevel = null) => // webhooks don't need authentication, each webhook unique
async (ctx, next) => { if (WEBHOOK_ENDPOINTS.test(ctx.request.url)) {
// webhooks don't need authentication, each webhook unique
if (WEBHOOK_ENDPOINTS.test(ctx.request.url)) {
return next()
}
if (!ctx.user) {
return ctx.throw(403, "No user info found")
}
// check general builder stuff, this middleware is a good way
// to find API endpoints which are builder focused
await builderMiddleware(ctx, permType)
const isAuthed = ctx.isAuthenticated
const { basePermissions, permissions } = await getUserPermissions(
ctx.appId,
ctx.roleId
)
// builders for now have permission to do anything
// TODO: in future should consider separating permissions with an require("@budibase/auth").isClient check
let isBuilder = ctx.user && ctx.user.builder && ctx.user.builder.global
const isBuilderApi = permType === PermissionTypes.BUILDER
if (isBuilder) {
return next()
} else if (isBuilderApi && !isBuilder) {
return ctx.throw(403, "Not Authorized")
}
if (
hasResource(ctx) &&
doesHaveResourcePermission(permissions, permLevel, ctx)
) {
return next()
}
if (!isAuthed) {
ctx.throw(403, "Session not authenticated")
}
if (!doesHaveBasePermission(permType, permLevel, basePermissions)) {
ctx.throw(403, "User does not have permission")
}
return next() return next()
} }
if (!ctx.user) {
return ctx.throw(403, "No user info found")
}
// check general builder stuff, this middleware is a good way
// to find API endpoints which are builder focused
await builderMiddleware(ctx, permType)
const isAuthed = ctx.isAuthenticated
const { basePermissions, permissions } = await getUserPermissions(
ctx.appId,
ctx.roleId
)
// builders for now have permission to do anything
// TODO: in future should consider separating permissions with an require("@budibase/auth").isClient check
let isBuilder = ctx.user && ctx.user.builder && ctx.user.builder.global
const isBuilderApi = permType === PermissionTypes.BUILDER
if (isBuilder) {
return next()
} else if (isBuilderApi && !isBuilder) {
return ctx.throw(403, "Not Authorized")
}
if (
hasResource(ctx) &&
doesHaveResourcePermission(permissions, permLevel, ctx)
) {
return next()
}
if (!isAuthed) {
ctx.throw(403, "Session not authenticated")
}
if (!doesHaveBasePermission(permType, permLevel, basePermissions)) {
ctx.throw(403, "User does not have permission")
}
return next()
}

View file

@ -1,5 +1,9 @@
const { getAppId, setCookie, getCookie, clearCookie } = const {
require("@budibase/auth").utils getAppId,
setCookie,
getCookie,
clearCookie,
} = require("@budibase/auth").utils
const { Cookies } = require("@budibase/auth").constants const { Cookies } = require("@budibase/auth").constants
const { getRole } = require("@budibase/auth/roles") const { getRole } = require("@budibase/auth/roles")
const { getGlobalSelf } = require("../utilities/workerRequests") const { getGlobalSelf } = require("../utilities/workerRequests")

View file

@ -90,17 +90,15 @@ const numericalConstraint = (constraint, error) => value => {
return null return null
} }
const inclusionConstraint = const inclusionConstraint = (options = []) => value => {
(options = []) => if (value == null || value === "") {
value => {
if (value == null || value === "") {
return null
}
if (!options.includes(value)) {
return "Invalid value"
}
return null return null
} }
if (!options.includes(value)) {
return "Invalid value"
}
return null
}
const dateConstraint = (dateString, isEarliest) => { const dateConstraint = (dateString, isEarliest) => {
const dateLimit = Date.parse(dateString) const dateLimit = Date.parse(dateString)

View file

@ -5,8 +5,15 @@ const authPkg = require("@budibase/auth")
const GLOBAL_DB = authPkg.StaticDatabases.GLOBAL.name const GLOBAL_DB = authPkg.StaticDatabases.GLOBAL.name
exports.sendEmail = async ctx => { exports.sendEmail = async ctx => {
const { groupId, email, userId, purpose, contents, from, subject } = const {
ctx.request.body groupId,
email,
userId,
purpose,
contents,
from,
subject,
} = ctx.request.body
let user let user
if (userId) { if (userId) {
const db = new CouchDB(GLOBAL_DB) const db = new CouchDB(GLOBAL_DB)

View file

@ -1,6 +1,9 @@
const CouchDB = require("../../../db") const CouchDB = require("../../../db")
const { getGroupParams, generateGroupID, StaticDatabases } = const {
require("@budibase/auth").db getGroupParams,
generateGroupID,
StaticDatabases,
} = require("@budibase/auth").db
const GLOBAL_DB = StaticDatabases.GLOBAL.name const GLOBAL_DB = StaticDatabases.GLOBAL.name

View file

@ -1,6 +1,9 @@
const CouchDB = require("../../../db") const CouchDB = require("../../../db")
const { generateGlobalUserID, getGlobalUserParams, StaticDatabases } = const {
require("@budibase/auth").db generateGlobalUserID,
getGlobalUserParams,
StaticDatabases,
} = require("@budibase/auth").db
const { hash, getGlobalUserByEmail } = require("@budibase/auth").utils const { hash, getGlobalUserByEmail } = require("@budibase/auth").utils
const { UserStatus, EmailTemplatePurpose } = require("../../../constants") const { UserStatus, EmailTemplatePurpose } = require("../../../constants")
const { checkInviteCode } = require("../../../utilities/redis") const { checkInviteCode } = require("../../../utilities/redis")