Merge branch 'feature/security-update' of github.com:Budibase/budibase into feature/self-hosting

This commit is contained in:
mike12345567 2020-12-08 16:12:29 +00:00
commit f9d2e4e4e1
10 changed files with 104 additions and 17 deletions

View File

@ -120,17 +120,17 @@ Cypress.Commands.add("createUser", (email, password, role) => {
cy.get(".modal").within(() => { cy.get(".modal").within(() => {
cy.get("input") cy.get("input")
.first() .first()
.type(password) .type(email)
cy.get("input") cy.get("input")
.eq(1) .eq(1)
.type(email) .type(password)
cy.get("select") cy.get("select")
.first() .first()
.select(role) .select(role)
// Save // Save
cy.get(".buttons") cy.get(".buttons")
.contains("Create Row") .contains("Create User")
.click() .click()
}) })
}) })

View File

@ -70,7 +70,7 @@ export const allScreens = derived(store, $store => {
export const mainLayout = derived(store, $store => { export const mainLayout = derived(store, $store => {
return $store.layouts?.find( return $store.layouts?.find(
layout => layout.props?._id === LAYOUT_NAMES.MASTER.PRIVATE layout => layout._id === LAYOUT_NAMES.MASTER.PRIVATE
) )
}) })

View File

@ -75,18 +75,29 @@
] ]
} }
const canEditColumn = key => {
if (!allowEditing) {
return false
}
return !(isUsersTable && ["email", "roleId"].indexOf(key) !== -1)
}
Object.entries(schema || {}).forEach(([key, value]) => { Object.entries(schema || {}).forEach(([key, value]) => {
result.push({ result.push({
headerCheckboxSelection: false, headerCheckboxSelection: false,
headerComponent: TableHeader, headerComponent: TableHeader,
headerComponentParams: { headerComponentParams: {
field: schema[key], field: schema[key],
editable: allowEditing, editable: canEditColumn(key),
}, },
headerName: value.displayFieldName || key, headerName: value.displayFieldName || key,
field: key, field: key,
sortable: true, sortable: true,
cellRenderer: getRenderer(schema[key], true), cellRenderer: getRenderer({
schema: schema[key],
editable: true,
isUsersTable,
}),
cellRendererParams: { cellRendererParams: {
selectRelationship, selectRelationship,
}, },

View File

@ -0,0 +1,43 @@
<!-- Module scoped cache of saved role options -->
<script context="module">
import builderApi from "builderStore/api"
let cachedRoles
async function getRoles(force = false) {
if (cachedRoles && !force) {
return await cachedRoles
}
cachedRoles = new Promise(resolve => {
console.log("HIT API")
builderApi
.get("/api/roles")
.then(response => response.json())
.then(resolve)
})
return await cachedRoles
}
</script>
<script>
export let roleId
let roleName
$: getRole()
async function getRole() {
// Try to find a matching role
let roles = await getRoles()
let role = roles.find(role => role._id === roleId)
// If we didn't find a matching role, try updating the cached results
if (!role) {
let roles = await getRoles(true)
let role = roles.find(role => role._id === roleId)
}
role = roles.find(role => role._id === roleId)
roleName = role?.name ?? "Unknown role"
}
</script>
<div>{roleName}</div>

View File

@ -3,15 +3,23 @@ import EditRow from "../modals/EditRow.svelte"
import CreateEditUser from "../modals/CreateEditUser.svelte" import CreateEditUser from "../modals/CreateEditUser.svelte"
import DeleteRow from "../modals/DeleteRow.svelte" import DeleteRow from "../modals/DeleteRow.svelte"
import RelationshipDisplay from "./RelationshipCell.svelte" import RelationshipDisplay from "./RelationshipCell.svelte"
import RoleCell from "./RoleCell.svelte"
const renderers = { const renderers = {
attachment: attachmentRenderer, attachment: attachmentRenderer,
link: linkedRowRenderer, link: linkedRowRenderer,
} }
export function getRenderer(schema, editable) { export function getRenderer({ schema, editable, isUsersTable }) {
const rendererParams = {
options: schema.options,
constraints: schema.constraints,
editable,
}
if (renderers[schema.type]) { if (renderers[schema.type]) {
return renderers[schema.type](schema.options, schema.constraints, editable) return renderers[schema.type](rendererParams)
} else if (isUsersTable && schema.name === "roleId") {
return roleRenderer(rendererParams)
} else { } else {
return false return false
} }
@ -63,15 +71,14 @@ export function userRowRenderer(params) {
return container return container
} }
/* eslint-disable no-unused-vars */ function attachmentRenderer() {
function attachmentRenderer(options, constraints, editable) {
return params => { return params => {
const container = document.createElement("div") const container = document.createElement("div")
container.style.height = "100%" container.style.height = "100%"
container.style.display = "flex" container.style.display = "flex"
container.style.alignItems = "center" container.style.alignItems = "center"
const attachmentInstance = new AttachmentList({ new AttachmentList({
target: container, target: container,
props: { props: {
files: params.value || [], files: params.value || [],
@ -82,7 +89,6 @@ function attachmentRenderer(options, constraints, editable) {
} }
} }
/* eslint-disable no-unused-vars */
function linkedRowRenderer() { function linkedRowRenderer() {
return params => { return params => {
let container = document.createElement("div") let container = document.createElement("div")
@ -102,3 +108,21 @@ function linkedRowRenderer() {
return container return container
} }
} }
function roleRenderer() {
return params => {
let container = document.createElement("div")
container.style.display = "grid"
container.style.height = "100%"
container.style.alignItems = "center"
new RoleCell({
target: container,
props: {
roleId: params.value,
},
})
return container
}
}

View File

@ -2,7 +2,6 @@
import { goto } from "@sveltech/routify" import { goto } from "@sveltech/routify"
import { backendUiStore } from "builderStore" import { backendUiStore } from "builderStore"
import { TableNames } from "constants" import { TableNames } from "constants"
import ListItem from "./ListItem.svelte"
import CreateTableModal from "./modals/CreateTableModal.svelte" import CreateTableModal from "./modals/CreateTableModal.svelte"
import EditTablePopover from "./popovers/EditTablePopover.svelte" import EditTablePopover from "./popovers/EditTablePopover.svelte"
import EditViewPopover from "./popovers/EditViewPopover.svelte" import EditViewPopover from "./popovers/EditViewPopover.svelte"
@ -47,7 +46,9 @@
text={table.name} text={table.name}
selected={selectedView === `all_${table._id}`} selected={selectedView === `all_${table._id}`}
on:click={() => selectTable(table)}> on:click={() => selectTable(table)}>
<EditTablePopover {table} /> {#if table._id !== TableNames.USERS}
<EditTablePopover {table} />
{/if}
</NavItem> </NavItem>
{#each Object.keys(table.views || {}) as viewName} {#each Object.keys(table.views || {}) as viewName}
<NavItem <NavItem

View File

@ -71,7 +71,7 @@
on:drop={dragDropStore.actions.drop} on:drop={dragDropStore.actions.drop}
text={isScreenslot(component._component) ? 'Screenslot' : component._instanceName} text={isScreenslot(component._component) ? 'Screenslot' : component._instanceName}
withArrow withArrow
indentLevel={level + 3} indentLevel={level + 1}
selected={$store.selectedComponentId === component._id}> selected={$store.selectedComponentId === component._id}>
<ComponentDropdownMenu {component} /> <ComponentDropdownMenu {component} />
</NavItem> </NavItem>

View File

@ -50,6 +50,7 @@
</NavItem> </NavItem>
{#if selectedScreen?._id === screenId} {#if selectedScreen?._id === screenId}
<ComponentTree <ComponentTree
level={1}
components={selectedScreen.props._children} components={selectedScreen.props._children}
currentComponent={$selectedComponent} currentComponent={$selectedComponent}
{dragDropStore} /> {dragDropStore} />

View File

@ -1,11 +1,12 @@
<script> <script>
import { goto } from "@sveltech/routify"
import { store } from "builderStore" import { store } from "builderStore"
import PathTree from "./PathTree.svelte" import PathTree from "./PathTree.svelte"
$: paths = Object.keys($store.routes || {}).sort()
</script> </script>
<div class="root"> <div class="root">
{#each Object.keys($store.routes || {}) as path} {#each paths as path}
<PathTree {path} route={$store.routes[path]} /> <PathTree {path} route={$store.routes[path]} />
{/each} {/each}
</div> </div>

View File

@ -21,6 +21,12 @@ const createRouteStore = () => {
}) })
}) })
}) })
// Sort route by paths so that the router matches correctly
routes.sort((a, b) => {
return a.path > b.path ? -1 : 1
})
store.update(state => { store.update(state => {
state.routes = routes state.routes = routes
return state return state