From a0f69251c83938a39cced15a7d273e2744cae0b2 Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Wed, 29 Sep 2021 16:55:59 +0100 Subject: [PATCH] Adding the ability to run the monorepo in cloud mode without the connected account portal (login, org setting and admin creation are all available again) as well as re-working how the redirects work to massively reduce the chance of cycles which I was experiencing constantly. --- packages/auth/src/cache/user.js | 2 +- packages/auth/src/environment.js | 1 + .../builder/src/pages/builder/_layout.svelte | 41 +++++++++++-------- .../src/pages/builder/admin/index.svelte | 3 +- .../src/pages/builder/auth/_layout.svelte | 1 + .../builder/src/pages/builder/auth/org.svelte | 3 +- .../builder/src/pages/builder/index.svelte | 6 +-- .../pages/builder/portal/apps/index.svelte | 5 ++- packages/builder/src/stores/portal/admin.js | 4 ++ packages/server/scripts/dev/manage.js | 1 + packages/server/src/environment.js | 1 + packages/worker/scripts/dev/manage.js | 1 + .../src/api/controllers/global/users.js | 15 ++++++- .../src/api/controllers/system/environment.js | 1 + packages/worker/src/environment.js | 1 + 15 files changed, 59 insertions(+), 27 deletions(-) diff --git a/packages/auth/src/cache/user.js b/packages/auth/src/cache/user.js index 51bed0210e..60a2d341a8 100644 --- a/packages/auth/src/cache/user.js +++ b/packages/auth/src/cache/user.js @@ -12,7 +12,7 @@ const populateFromDB = async (userId, tenantId) => { const user = await getGlobalDB(tenantId).get(userId) user.budibaseAccess = true - if (!env.SELF_HOSTED) { + if (!env.SELF_HOSTED && !env.DISABLE_ACCOUNT_PORTAL) { const account = await accounts.getAccount(user.email) if (account) { user.account = account diff --git a/packages/auth/src/environment.js b/packages/auth/src/environment.js index da24afc8a0..7f822090d7 100644 --- a/packages/auth/src/environment.js +++ b/packages/auth/src/environment.js @@ -21,6 +21,7 @@ module.exports = { INTERNAL_API_KEY: process.env.INTERNAL_API_KEY, MULTI_TENANCY: process.env.MULTI_TENANCY, ACCOUNT_PORTAL_URL: process.env.ACCOUNT_PORTAL_URL, + DISABLE_ACCOUNT_PORTAL: process.env.DISABLE_ACCOUNT_PORTAL, SELF_HOSTED: !!parseInt(process.env.SELF_HOSTED), COOKIE_DOMAIN: process.env.COOKIE_DOMAIN, isTest, diff --git a/packages/builder/src/pages/builder/_layout.svelte b/packages/builder/src/pages/builder/_layout.svelte index 4b296854b6..975f92ec10 100644 --- a/packages/builder/src/pages/builder/_layout.svelte +++ b/packages/builder/src/pages/builder/_layout.svelte @@ -4,11 +4,13 @@ import { onMount } from "svelte" let loaded = false + // don't react to these + let cloud = $admin.cloud + let shouldRedirect = !cloud || $admin.disableAccountPortal $: multiTenancyEnabled = $admin.multiTenancy $: hasAdminUser = $admin?.checklist?.adminUser?.checked $: tenantSet = $auth.tenantSet - $: cloud = $admin.cloud onMount(async () => { await auth.checkAuth() @@ -18,30 +20,35 @@ $: { // We should never see the org or admin user creation screens in the cloud - if (!cloud) { - const apiReady = $admin.loaded && $auth.loaded - // if tenant is not set go to it - if (loaded && apiReady && multiTenancyEnabled && !tenantSet) { - $redirect("./auth/org") - } - // Force creation of an admin user if one doesn't exist - else if (loaded && apiReady && !hasAdminUser) { - $redirect("./admin") - } - } - } - // Redirect to log in at any time if the user isn't authenticated - $: { + const apiReady = $admin.loaded && $auth.loaded + // if tenant is not set go to it if ( + loaded && + shouldRedirect && + apiReady && + multiTenancyEnabled && + !tenantSet + ) { + $redirect("./auth/org") + } + // Force creation of an admin user if one doesn't exist + else if (loaded && shouldRedirect && apiReady && !hasAdminUser) { + $redirect("./admin") + } + // Redirect to log in at any time if the user isn't authenticated + else if ( loaded && (hasAdminUser || cloud) && !$auth.user && !$isActive("./auth") && - !$isActive("./invite") + !$isActive("./invite") && + !$isActive("./admin") ) { const returnUrl = encodeURIComponent(window.location.pathname) $redirect("./auth?", { returnUrl }) - } else if ($auth?.user?.forceResetPassword) { + } + // check if password reset required for user + else if ($auth.user?.forceResetPassword) { $redirect("./auth/reset") } } diff --git a/packages/builder/src/pages/builder/admin/index.svelte b/packages/builder/src/pages/builder/admin/index.svelte index f0517674de..f3a8d62d30 100644 --- a/packages/builder/src/pages/builder/admin/index.svelte +++ b/packages/builder/src/pages/builder/admin/index.svelte @@ -22,6 +22,7 @@ $: tenantId = $auth.tenantId $: multiTenancyEnabled = $admin.multiTenancy + $: cloud = $admin.cloud async function save() { try { @@ -72,7 +73,7 @@ > Change organisation - {:else} + {:else if !cloud} { diff --git a/packages/builder/src/pages/builder/auth/_layout.svelte b/packages/builder/src/pages/builder/auth/_layout.svelte index 7e8c41d2c5..f05030cc48 100644 --- a/packages/builder/src/pages/builder/auth/_layout.svelte +++ b/packages/builder/src/pages/builder/auth/_layout.svelte @@ -15,6 +15,7 @@ if ( !$auth.user && $admin.cloud && + !$admin.disableAccountPortal && $admin.accountPortalUrl && !$admin?.checklist?.sso?.checked ) { diff --git a/packages/builder/src/pages/builder/auth/org.svelte b/packages/builder/src/pages/builder/auth/org.svelte index fea8831935..1e6b58dbe2 100644 --- a/packages/builder/src/pages/builder/auth/org.svelte +++ b/packages/builder/src/pages/builder/auth/org.svelte @@ -9,6 +9,7 @@ let tenantId = get(auth).tenantSet ? get(auth).tenantId : "" $: multiTenancyEnabled = $admin.multiTenancy $: cloud = $admin.cloud + $: disableAccountPortal = $admin.disableAccountPortal async function setOrg() { if (tenantId == null || tenantId === "") { @@ -26,7 +27,7 @@ onMount(async () => { await auth.checkQueryString() - if (!multiTenancyEnabled || cloud) { + if (!multiTenancyEnabled || (cloud && !disableAccountPortal)) { $goto("../") } else { admin.unload() diff --git a/packages/builder/src/pages/builder/index.svelte b/packages/builder/src/pages/builder/index.svelte index fba581a046..fcaa7fc55b 100644 --- a/packages/builder/src/pages/builder/index.svelte +++ b/packages/builder/src/pages/builder/index.svelte @@ -5,11 +5,9 @@ auth.checkQueryString() $: { - if (!$auth.user) { - $redirect(`./auth`) - } else if ($auth.user.builder?.global) { + if ($auth.user?.builder?.global) { $redirect(`./portal`) - } else { + } else if ($auth.user) { $redirect(`./apps`) } } diff --git a/packages/builder/src/pages/builder/portal/apps/index.svelte b/packages/builder/src/pages/builder/portal/apps/index.svelte index 096c4ed5b5..995337da0a 100644 --- a/packages/builder/src/pages/builder/portal/apps/index.svelte +++ b/packages/builder/src/pages/builder/portal/apps/index.svelte @@ -35,6 +35,7 @@ let unpublishModal let creatingApp = false let loaded = false + let cloud = $admin.cloud $: enrichedApps = enrichApps($apps, $auth.user, sortBy) @@ -199,7 +200,9 @@
Apps - + {#if cloud} + + {/if} diff --git a/packages/builder/src/stores/portal/admin.js b/packages/builder/src/stores/portal/admin.js index 44ff63a082..ebe8294060 100644 --- a/packages/builder/src/stores/portal/admin.js +++ b/packages/builder/src/stores/portal/admin.js @@ -7,6 +7,7 @@ export function createAdminStore() { loaded: false, multiTenancy: false, cloud: false, + disableAccountPortal: false, accountPortalUrl: "", onboardingProgress: 0, checklist: { @@ -47,12 +48,14 @@ export function createAdminStore() { async function getEnvironment() { let multiTenancyEnabled = false let cloud = false + let disableAccountPortal = false let accountPortalUrl = "" try { const response = await api.get(`/api/system/environment`) const json = await response.json() multiTenancyEnabled = json.multiTenancy cloud = json.cloud + disableAccountPortal = json.disableAccountPortal accountPortalUrl = json.accountPortalUrl } catch (err) { // just let it stay disabled @@ -60,6 +63,7 @@ export function createAdminStore() { admin.update(store => { store.multiTenancy = multiTenancyEnabled store.cloud = cloud + store.disableAccountPortal = disableAccountPortal store.accountPortalUrl = accountPortalUrl return store }) diff --git a/packages/server/scripts/dev/manage.js b/packages/server/scripts/dev/manage.js index e0801bc9df..bd91056f84 100644 --- a/packages/server/scripts/dev/manage.js +++ b/packages/server/scripts/dev/manage.js @@ -48,6 +48,7 @@ async function init() { COUCH_DB_PASSWORD: "budibase", COUCH_DB_USER: "budibase", SELF_HOSTED: 1, + DISABLE_ACCOUNT_PORTAL: "", MULTI_TENANCY: "", } let envFile = "" diff --git a/packages/server/src/environment.js b/packages/server/src/environment.js index 89e015b6f5..688e74a679 100644 --- a/packages/server/src/environment.js +++ b/packages/server/src/environment.js @@ -40,6 +40,7 @@ module.exports = { NODE_ENV: process.env.NODE_ENV, JEST_WORKER_ID: process.env.JEST_WORKER_ID, BUDIBASE_ENVIRONMENT: process.env.BUDIBASE_ENVIRONMENT, + DISABLE_ACCOUNT_PORTAL: process.env.DISABLE_ACCOUNT_PORTAL, // minor SALT_ROUNDS: process.env.SALT_ROUNDS, LOGGER: process.env.LOGGER, diff --git a/packages/worker/scripts/dev/manage.js b/packages/worker/scripts/dev/manage.js index 3df0beb23c..4eb29847bb 100644 --- a/packages/worker/scripts/dev/manage.js +++ b/packages/worker/scripts/dev/manage.js @@ -21,6 +21,7 @@ async function init() { COUCH_DB_PASSWORD: "budibase", // empty string is false MULTI_TENANCY: "", + DISABLE_ACCOUNT_PORTAL: "", ACCOUNT_PORTAL_URL: "http://localhost:10001", } let envFile = "" diff --git a/packages/worker/src/api/controllers/global/users.js b/packages/worker/src/api/controllers/global/users.js index 7753370f09..65591e3231 100644 --- a/packages/worker/src/api/controllers/global/users.js +++ b/packages/worker/src/api/controllers/global/users.js @@ -65,7 +65,7 @@ async function saveUser( } // check root account users in account portal - if (!env.SELF_HOSTED) { + if (!env.SELF_HOSTED && !env.DISABLE_ACCOUNT_PORTAL) { const account = await accounts.getAccount(email) if (account) { throw "Email address already in use." @@ -132,7 +132,7 @@ exports.save = async ctx => { } const parseBooleanParam = param => { - if (param && param == "false") { + if (param && param === "false") { return false } else { return true @@ -160,6 +160,17 @@ exports.adminUser = async ctx => { // write usage quotas for cloud if (!env.SELF_HOSTED) { + // could be a scenario where it exists, make sure its clean + try { + const usageQuota = await db.get( + StaticDatabases.PLATFORM_INFO.docs.usageQuota + ) + if (usageQuota) { + await db.remove(usageQuota._id, usageQuota._rev) + } + } catch (err) { + // don't worry about errors + } await db.post(generateNewUsageQuotaDoc()) } diff --git a/packages/worker/src/api/controllers/system/environment.js b/packages/worker/src/api/controllers/system/environment.js index 664e950797..a4022561d4 100644 --- a/packages/worker/src/api/controllers/system/environment.js +++ b/packages/worker/src/api/controllers/system/environment.js @@ -5,5 +5,6 @@ exports.fetch = async ctx => { multiTenancy: !!env.MULTI_TENANCY, cloud: !env.SELF_HOSTED, accountPortalUrl: env.ACCOUNT_PORTAL_URL, + disableAccountPortal: env.DISABLE_ACCOUNT_PORTAL, } } diff --git a/packages/worker/src/environment.js b/packages/worker/src/environment.js index 28ab4e2e69..63115ea836 100644 --- a/packages/worker/src/environment.js +++ b/packages/worker/src/environment.js @@ -32,6 +32,7 @@ module.exports = { REDIS_PASSWORD: process.env.REDIS_PASSWORD, INTERNAL_API_KEY: process.env.INTERNAL_API_KEY, MULTI_TENANCY: process.env.MULTI_TENANCY, + DISABLE_ACCOUNT_PORTAL: process.env.DISABLE_ACCOUNT_PORTAL, ACCOUNT_PORTAL_URL: process.env.ACCOUNT_PORTAL_URL, SMTP_FALLBACK_ENABLED: process.env.SMTP_FALLBACK_ENABLED, SMTP_USER: process.env.SMTP_USER,