diff --git a/lerna.json b/lerna.json
index ed1c098f67..139293980b 100644
--- a/lerna.json
+++ b/lerna.json
@@ -1,5 +1,5 @@
{
- "version": "0.9.144-alpha.0",
+ "version": "0.9.146-alpha.3",
"npmClient": "yarn",
"packages": [
"packages/*"
diff --git a/packages/auth/deprovision.js b/packages/auth/deprovision.js
new file mode 100644
index 0000000000..b4b8dc6110
--- /dev/null
+++ b/packages/auth/deprovision.js
@@ -0,0 +1 @@
+module.exports = require("./src/tenancy/deprovision")
diff --git a/packages/auth/package.json b/packages/auth/package.json
index 067a5e66f6..ef73577635 100644
--- a/packages/auth/package.json
+++ b/packages/auth/package.json
@@ -1,6 +1,6 @@
{
"name": "@budibase/auth",
- "version": "0.9.144-alpha.0",
+ "version": "0.9.146-alpha.3",
"description": "Authentication middlewares for budibase builder and apps",
"main": "src/index.js",
"author": "Budibase",
diff --git a/packages/auth/src/tenancy/deprovision.js b/packages/auth/src/tenancy/deprovision.js
new file mode 100644
index 0000000000..b8e5bc82cf
--- /dev/null
+++ b/packages/auth/src/tenancy/deprovision.js
@@ -0,0 +1,81 @@
+const { getGlobalUserParams, getAllApps } = require("../db/utils")
+const { getDB, getCouch } = require("../db")
+const { getGlobalDB } = require("./tenancy")
+const { StaticDatabases } = require("../db/constants")
+
+const TENANT_DOC = StaticDatabases.PLATFORM_INFO.docs.tenants
+const PLATFORM_INFO_DB = StaticDatabases.PLATFORM_INFO.name
+
+const removeTenantFromInfoDB = async tenantId => {
+ try {
+ const infoDb = getDB(PLATFORM_INFO_DB)
+ let tenants = await infoDb.get(TENANT_DOC)
+ tenants.tenantIds = tenants.tenantIds.filter(id => id !== tenantId)
+
+ await infoDb.put(tenants)
+ } catch (err) {
+ console.error(`Error removing tenant ${tenantId} from info db`, err)
+ throw err
+ }
+}
+
+const removeUsersFromInfoDB = async tenantId => {
+ try {
+ const globalDb = getGlobalDB(tenantId)
+ const infoDb = getDB(PLATFORM_INFO_DB)
+ const allUsers = await globalDb.allDocs(
+ getGlobalUserParams(null, {
+ include_docs: true,
+ })
+ )
+ const allEmails = allUsers.rows.map(row => row.doc.email)
+ // get the id docs
+ let keys = allUsers.rows.map(row => row.id)
+ // and the email docs
+ keys = keys.concat(allEmails)
+ // retrieve the docs and delete them
+ const userDocs = await infoDb.allDocs({
+ keys,
+ include_docs: true,
+ })
+ const toDelete = userDocs.rows.map(row => {
+ return {
+ ...row.doc,
+ _deleted: true,
+ }
+ })
+ await infoDb.bulkDocs(toDelete)
+ } catch (err) {
+ console.error(`Error removing tenant ${tenantId} users from info db`, err)
+ throw err
+ }
+}
+
+const removeGlobalDB = async tenantId => {
+ try {
+ const globalDb = getGlobalDB(tenantId)
+ await globalDb.destroy()
+ } catch (err) {
+ console.error(`Error removing tenant ${tenantId} users from info db`, err)
+ throw err
+ }
+}
+
+const removeTenantApps = async tenantId => {
+ try {
+ const apps = await getAllApps(getCouch(), { all: true })
+ const destroyPromises = apps.map(app => getDB(app.appId).destroy())
+ await Promise.allSettled(destroyPromises)
+ } catch (err) {
+ console.error(`Error removing tenant ${tenantId} apps`, err)
+ throw err
+ }
+}
+
+// can't live in tenancy package due to circular dependency on db/utils
+exports.deleteTenant = async tenantId => {
+ await removeTenantFromInfoDB(tenantId)
+ await removeUsersFromInfoDB(tenantId)
+ await removeGlobalDB(tenantId)
+ await removeTenantApps(tenantId)
+}
diff --git a/packages/auth/src/utils.js b/packages/auth/src/utils.js
index f03ae300f7..93b483c6be 100644
--- a/packages/auth/src/utils.js
+++ b/packages/auth/src/utils.js
@@ -67,24 +67,22 @@ exports.getCookie = (ctx, name) => {
* @param {string|object} value The value of cookie which will be set.
*/
exports.setCookie = (ctx, value, name = "builder") => {
- if (!value) {
- ctx.cookies.set(name)
- } else {
+ if (value) {
value = jwt.sign(value, options.secretOrKey)
-
- const config = {
- maxAge: Number.MAX_SAFE_INTEGER,
- path: "/",
- httpOnly: false,
- overwrite: true,
- }
-
- if (environment.COOKIE_DOMAIN) {
- config.domain = environment.COOKIE_DOMAIN
- }
-
- ctx.cookies.set(name, value, config)
}
+
+ const config = {
+ maxAge: Number.MAX_SAFE_INTEGER,
+ path: "/",
+ httpOnly: false,
+ overwrite: true,
+ }
+
+ if (environment.COOKIE_DOMAIN) {
+ config.domain = environment.COOKIE_DOMAIN
+ }
+
+ ctx.cookies.set(name, value, config)
}
/**
diff --git a/packages/bbui/package.json b/packages/bbui/package.json
index 9d6488ccf7..a9302d7356 100644
--- a/packages/bbui/package.json
+++ b/packages/bbui/package.json
@@ -1,7 +1,7 @@
{
"name": "@budibase/bbui",
"description": "A UI solution used in the different Budibase projects.",
- "version": "0.9.144-alpha.0",
+ "version": "0.9.146-alpha.3",
"license": "AGPL-3.0",
"svelte": "src/index.js",
"module": "dist/bbui.es.js",
diff --git a/packages/bbui/src/Modal/ModalContent.svelte b/packages/bbui/src/Modal/ModalContent.svelte
index 678a813a61..09cc4f6c52 100644
--- a/packages/bbui/src/Modal/ModalContent.svelte
+++ b/packages/bbui/src/Modal/ModalContent.svelte
@@ -14,6 +14,7 @@
export let showConfirmButton = true
export let showCloseIcon = true
export let onConfirm = undefined
+ export let onCancel = undefined
export let disabled = false
export let showDivider = true
@@ -28,6 +29,14 @@
}
loading = false
}
+
+ async function close() {
+ loading = true
+ if (!onCancel || (await onCancel()) !== false) {
+ cancel()
+ }
+ loading = false
+ }
{#if showCancelButton}
-
+
{/if}
{#if showConfirmButton}
+
+
diff --git a/packages/builder/src/components/backend/DataTable/Table.svelte b/packages/builder/src/components/backend/DataTable/Table.svelte
index fcb17a774d..78c3cc37f8 100644
--- a/packages/builder/src/components/backend/DataTable/Table.svelte
+++ b/packages/builder/src/components/backend/DataTable/Table.svelte
@@ -1,8 +1,7 @@
-
-
- {#if title}
-
{title}
- {/if}
- {#if loading}
-
-
-
- {/if}
+
+
+
+ {#if title}
+
{title}
+ {/if}
+ {#if loading}
+
+
+
+ {/if}
+
+
+
+ {#if !isUsersTable && selectedRows.length > 0}
+
+ {/if}
+
-
-
- {#if !isUsersTable && selectedRows.length > 0}
-
- {/if}
-
-
-{#key tableId}
-
editColumn(e.detail)}
- on:editrow={e => editRow(e.detail)}
- on:clickrelationship={e => selectRelationship(e.detail)}
- />
-{/key}
+ {#key tableId}
+
+
editColumn(e.detail)}
+ on:editrow={e => editRow(e.detail)}
+ on:clickrelationship={e => selectRelationship(e.detail)}
+ on:sort
+ />
+
+ {/key}
+
-
+
-
+
diff --git a/packages/builder/src/components/backend/DataTable/buttons/FilterButton.svelte b/packages/builder/src/components/backend/DataTable/buttons/ViewFilterButton.svelte
similarity index 100%
rename from packages/builder/src/components/backend/DataTable/buttons/FilterButton.svelte
rename to packages/builder/src/components/backend/DataTable/buttons/ViewFilterButton.svelte
diff --git a/packages/builder/src/components/backend/DataTable/modals/CreateEditColumn.svelte b/packages/builder/src/components/backend/DataTable/modals/CreateEditColumn.svelte
index 1a7d75f28a..011c9bee43 100644
--- a/packages/builder/src/components/backend/DataTable/modals/CreateEditColumn.svelte
+++ b/packages/builder/src/components/backend/DataTable/modals/CreateEditColumn.svelte
@@ -10,6 +10,7 @@
ModalContent,
Context,
} from "@budibase/bbui"
+ import { createEventDispatcher } from "svelte"
import { cloneDeep } from "lodash/fp"
import { tables } from "stores/backend"
import { TableNames, UNEDITABLE_USER_FIELDS } from "constants"
@@ -30,8 +31,9 @@
const AUTO_TYPE = "auto"
const FORMULA_TYPE = FIELDS.FORMULA.type
const LINK_TYPE = FIELDS.LINK.type
- let fieldDefinitions = cloneDeep(FIELDS)
+ const dispatch = createEventDispatcher()
const { hide } = getContext(Context.Modal)
+ let fieldDefinitions = cloneDeep(FIELDS)
export let field = {
type: "string",
@@ -81,12 +83,13 @@
if (field.type === AUTO_TYPE) {
field = buildAutoColumn($tables.draft.name, field.name, field.subtype)
}
- tables.saveField({
+ await tables.saveField({
originalName,
field,
primaryDisplay,
indexes,
})
+ dispatch("updatecolumns")
}
function deleteColumn() {
@@ -99,6 +102,7 @@
hide()
deletion = false
}
+ dispatch("updatecolumns")
}
function handleTypeChange(event) {
diff --git a/packages/builder/src/components/backend/DataTable/modals/CreateEditRow.svelte b/packages/builder/src/components/backend/DataTable/modals/CreateEditRow.svelte
index ce52287c99..a60d9ecf31 100644
--- a/packages/builder/src/components/backend/DataTable/modals/CreateEditRow.svelte
+++ b/packages/builder/src/components/backend/DataTable/modals/CreateEditRow.svelte
@@ -1,4 +1,5 @@
diff --git a/packages/builder/src/components/backend/DataTable/modals/CreateEditUser.svelte b/packages/builder/src/components/backend/DataTable/modals/CreateEditUser.svelte
index 32f369ce3d..f1de23fb97 100644
--- a/packages/builder/src/components/backend/DataTable/modals/CreateEditUser.svelte
+++ b/packages/builder/src/components/backend/DataTable/modals/CreateEditUser.svelte
@@ -1,4 +1,5 @@
diff --git a/packages/builder/src/components/backend/DatasourceNavigator/DatasourceNavigator.svelte b/packages/builder/src/components/backend/DatasourceNavigator/DatasourceNavigator.svelte
index 6ba8e4042f..3c6fa83c01 100644
--- a/packages/builder/src/components/backend/DatasourceNavigator/DatasourceNavigator.svelte
+++ b/packages/builder/src/components/backend/DatasourceNavigator/DatasourceNavigator.svelte
@@ -1,9 +1,9 @@
diff --git a/packages/builder/src/components/backend/DatasourceNavigator/TableIntegrationMenu/IntegrationConfigForm.svelte b/packages/builder/src/components/backend/DatasourceNavigator/TableIntegrationMenu/IntegrationConfigForm.svelte
index 4541052acf..f67a46d9a1 100644
--- a/packages/builder/src/components/backend/DatasourceNavigator/TableIntegrationMenu/IntegrationConfigForm.svelte
+++ b/packages/builder/src/components/backend/DatasourceNavigator/TableIntegrationMenu/IntegrationConfigForm.svelte
@@ -1,20 +1,28 @@