Merge branch 'feature/security-update' of github.com:Budibase/budibase into feature/self-hosting
This commit is contained in:
commit
f9d2e4e4e1
|
@ -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()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -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
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
},
|
},
|
||||||
|
|
|
@ -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>
|
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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} />
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue