Fixes for google sso, cloud email url and cloud logo updates
This commit is contained in:
parent
1f7207be7b
commit
6af8ab2dc0
|
@ -1,6 +1,6 @@
|
||||||
const { newid } = require("../hashing")
|
const { newid } = require("../hashing")
|
||||||
const Replication = require("./Replication")
|
const Replication = require("./Replication")
|
||||||
const { DEFAULT_TENANT_ID } = require("../constants")
|
const { DEFAULT_TENANT_ID, Configs } = require("../constants")
|
||||||
const env = require("../environment")
|
const env = require("../environment")
|
||||||
const { StaticDatabases, SEPARATOR, DocumentTypes } = require("./constants")
|
const { StaticDatabases, SEPARATOR, DocumentTypes } = require("./constants")
|
||||||
const { getTenantId, getTenantIDFromAppID } = require("../tenancy")
|
const { getTenantId, getTenantIDFromAppID } = require("../tenancy")
|
||||||
|
@ -322,13 +322,50 @@ const getScopedFullConfig = async function (db, { type, user, workspace }) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find the config with the most granular scope based on context
|
// Find the config with the most granular scope based on context
|
||||||
const scopedConfig = response.rows.sort(
|
let scopedConfig = response.rows.sort(
|
||||||
(a, b) => determineScore(a) - determineScore(b)
|
(a, b) => determineScore(a) - determineScore(b)
|
||||||
)[0]
|
)[0]
|
||||||
|
|
||||||
|
// custom logic for settings doc
|
||||||
|
// always provide the platform URL
|
||||||
|
if (type === Configs.SETTINGS) {
|
||||||
|
if (scopedConfig && scopedConfig.doc) {
|
||||||
|
scopedConfig.doc.config.platformUrl = await getPlatformUrl(
|
||||||
|
scopedConfig.doc.config
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
scopedConfig = {
|
||||||
|
doc: {
|
||||||
|
config: {
|
||||||
|
platformUrl: await getPlatformUrl(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return scopedConfig && scopedConfig.doc
|
return scopedConfig && scopedConfig.doc
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const getPlatformUrl = async settings => {
|
||||||
|
let platformUrl = env.PLATFORM_URL
|
||||||
|
|
||||||
|
if (!env.SELF_HOSTED && env.MULTI_TENANCY) {
|
||||||
|
// cloud and multi tenant - add the tenant to the default platform url
|
||||||
|
const tenantId = getTenantId()
|
||||||
|
if (!platformUrl.includes("localhost:")) {
|
||||||
|
platformUrl = platformUrl.replace("://", `://${tenantId}.`)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// self hosted - check for platform url override
|
||||||
|
if (settings && settings.platformUrl) {
|
||||||
|
platformUrl = settings.platformUrl
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return platformUrl ? platformUrl : "http://localhost:10000"
|
||||||
|
}
|
||||||
|
|
||||||
async function getScopedConfig(db, params) {
|
async function getScopedConfig(db, params) {
|
||||||
const configDoc = await getScopedFullConfig(db, params)
|
const configDoc = await getScopedFullConfig(db, params)
|
||||||
return configDoc && configDoc.config ? configDoc.config : configDoc
|
return configDoc && configDoc.config ? configDoc.config : configDoc
|
||||||
|
|
|
@ -25,6 +25,7 @@ module.exports = {
|
||||||
DISABLE_ACCOUNT_PORTAL: process.env.DISABLE_ACCOUNT_PORTAL,
|
DISABLE_ACCOUNT_PORTAL: process.env.DISABLE_ACCOUNT_PORTAL,
|
||||||
SELF_HOSTED: !!parseInt(process.env.SELF_HOSTED),
|
SELF_HOSTED: !!parseInt(process.env.SELF_HOSTED),
|
||||||
COOKIE_DOMAIN: process.env.COOKIE_DOMAIN,
|
COOKIE_DOMAIN: process.env.COOKIE_DOMAIN,
|
||||||
|
PLATFORM_URL: process.env.PLATFORM_URL,
|
||||||
isTest,
|
isTest,
|
||||||
_set(key, value) {
|
_set(key, value) {
|
||||||
process.env[key] = value
|
process.env[key] = value
|
||||||
|
|
|
@ -6,6 +6,7 @@ exports.ObjectStoreBuckets = {
|
||||||
APPS: "prod-budi-app-assets",
|
APPS: "prod-budi-app-assets",
|
||||||
TEMPLATES: "templates",
|
TEMPLATES: "templates",
|
||||||
GLOBAL: "global",
|
GLOBAL: "global",
|
||||||
|
GLOBAL_CLOUD: "prod-budi-tenant-uploads",
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.budibaseTempDir = function () {
|
exports.budibaseTempDir = function () {
|
||||||
|
|
|
@ -1,16 +1,67 @@
|
||||||
<script>
|
<script>
|
||||||
import "@spectrum-css/fieldlabel/dist/index-vars.css"
|
import "@spectrum-css/fieldlabel/dist/index-vars.css"
|
||||||
|
import Tooltip from "../Tooltip/Tooltip.svelte"
|
||||||
|
import Icon from "../Icon/Icon.svelte"
|
||||||
|
|
||||||
export let size = "M"
|
export let size = "M"
|
||||||
|
export let tooltip = ""
|
||||||
|
export let showTooltip = false
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<label for="" class={`spectrum-FieldLabel spectrum-FieldLabel--size${size}`}>
|
{#if tooltip}
|
||||||
<slot />
|
<div class="container">
|
||||||
</label>
|
<label
|
||||||
|
for=""
|
||||||
|
class={`spectrum-FieldLabel spectrum-FieldLabel--size${size}`}
|
||||||
|
>
|
||||||
|
<slot />
|
||||||
|
</label>
|
||||||
|
<div class="icon-container">
|
||||||
|
<div
|
||||||
|
class="icon"
|
||||||
|
on:mouseover={() => (showTooltip = true)}
|
||||||
|
on:mouseleave={() => (showTooltip = false)}
|
||||||
|
>
|
||||||
|
<Icon name="InfoOutline" size="S" disabled={true} />
|
||||||
|
</div>
|
||||||
|
{#if showTooltip}
|
||||||
|
<div class="tooltip">
|
||||||
|
<Tooltip textWrapping={true} direction={"bottom"} text={tooltip} />
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{:else}
|
||||||
|
<label for="" class={`spectrum-FieldLabel spectrum-FieldLabel--size${size}`}>
|
||||||
|
<slot />
|
||||||
|
</label>
|
||||||
|
{/if}
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
label {
|
label {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
.container {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
.icon-container {
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
margin-top: 1px;
|
||||||
|
margin-left: 5px;
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
.tooltip {
|
||||||
|
position: absolute;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
top: 15px;
|
||||||
|
z-index: 1;
|
||||||
|
width: 160px;
|
||||||
|
}
|
||||||
|
.icon {
|
||||||
|
transform: scale(0.75);
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -3,12 +3,22 @@
|
||||||
|
|
||||||
export let direction = "top"
|
export let direction = "top"
|
||||||
export let text = ""
|
export let text = ""
|
||||||
|
export let textWrapping = false
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<span class="u-tooltip-showOnHover tooltip">
|
<!-- Showing / Hiding a text wrapped tooltip should be handled outside the component -->
|
||||||
<slot />
|
{#if textWrapping}
|
||||||
<div class={`spectrum-Tooltip spectrum-Tooltip--${direction}`}>
|
<span class="spectrum-Tooltip spectrum-Tooltip--{direction} is-open">
|
||||||
<span class="spectrum-Tooltip-label">{text}</span>
|
<span class="spectrum-Tooltip-label">{text}</span>
|
||||||
<span class="spectrum-Tooltip-tip" />
|
<span class="spectrum-Tooltip-tip" />
|
||||||
</div>
|
</span>
|
||||||
</span>
|
{:else}
|
||||||
|
<!-- The default show on hover tooltip does not support text wrapping -->
|
||||||
|
<span class="u-tooltip-showOnHover tooltip">
|
||||||
|
<slot />
|
||||||
|
<div class={`spectrum-Tooltip spectrum-Tooltip--${direction}`}>
|
||||||
|
<span class="spectrum-Tooltip-label">{text}</span>
|
||||||
|
<span class="spectrum-Tooltip-tip" />
|
||||||
|
</div>
|
||||||
|
</span>
|
||||||
|
{/if}
|
||||||
|
|
|
@ -21,26 +21,25 @@
|
||||||
} from "@budibase/bbui"
|
} from "@budibase/bbui"
|
||||||
import { onMount } from "svelte"
|
import { onMount } from "svelte"
|
||||||
import api from "builderStore/api"
|
import api from "builderStore/api"
|
||||||
import { organisation, auth, admin } from "stores/portal"
|
import { organisation, admin } from "stores/portal"
|
||||||
import { uuid } from "builderStore/uuid"
|
import { uuid } from "builderStore/uuid"
|
||||||
import analytics, { Events } from "analytics"
|
import analytics, { Events } from "analytics"
|
||||||
|
|
||||||
$: tenantId = $auth.tenantId
|
|
||||||
$: multiTenancyEnabled = $admin.multiTenancy
|
|
||||||
|
|
||||||
const ConfigTypes = {
|
const ConfigTypes = {
|
||||||
Google: "google",
|
Google: "google",
|
||||||
OIDC: "oidc",
|
OIDC: "oidc",
|
||||||
}
|
}
|
||||||
|
|
||||||
function callbackUrl(tenantId, end) {
|
// Some older google configs contain a manually specified value - retain the functionality to edit the field
|
||||||
let url = `/api/global/auth`
|
// When there is no value or we are in the cloud - prohibit editing the field, must use platform url to change
|
||||||
if (multiTenancyEnabled && tenantId) {
|
$: googleCallbackUrl = undefined
|
||||||
url += `/${tenantId}`
|
$: googleCallbackReadonly = $admin.cloud || !googleCallbackUrl
|
||||||
}
|
|
||||||
url += end
|
// Indicate to user that callback is based on platform url
|
||||||
return url
|
// If there is an existing value, indicate that it may be removed to return to default behaviour
|
||||||
}
|
$: googleCallbackTooltip = googleCallbackReadonly
|
||||||
|
? "Vist the organisation page to update the platform URL"
|
||||||
|
: "Leave blank to use the default callback URL"
|
||||||
|
|
||||||
$: GoogleConfigFields = {
|
$: GoogleConfigFields = {
|
||||||
Google: [
|
Google: [
|
||||||
|
@ -49,8 +48,9 @@
|
||||||
{
|
{
|
||||||
name: "callbackURL",
|
name: "callbackURL",
|
||||||
label: "Callback URL",
|
label: "Callback URL",
|
||||||
readonly: true,
|
readonly: googleCallbackReadonly,
|
||||||
placeholder: callbackUrl(tenantId, "/google/callback"),
|
tooltip: googleCallbackTooltip,
|
||||||
|
placeholder: $organisation.googleCallbackUrl,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
@ -62,9 +62,10 @@
|
||||||
{ name: "clientSecret", label: "Client Secret" },
|
{ name: "clientSecret", label: "Client Secret" },
|
||||||
{
|
{
|
||||||
name: "callbackURL",
|
name: "callbackURL",
|
||||||
label: "Callback URL",
|
|
||||||
readonly: true,
|
readonly: true,
|
||||||
placeholder: callbackUrl(tenantId, "/oidc/callback"),
|
tooltip: "Vist the organisation page to update the platform URL",
|
||||||
|
label: "Callback URL",
|
||||||
|
placeholder: $organisation.oidcCallbackUrl,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
@ -241,6 +242,8 @@
|
||||||
providers.google = googleDoc
|
providers.google = googleDoc
|
||||||
}
|
}
|
||||||
|
|
||||||
|
googleCallbackUrl = providers?.google?.config?.callbackURL
|
||||||
|
|
||||||
//Get the list of user uploaded logos and push it to the dropdown options.
|
//Get the list of user uploaded logos and push it to the dropdown options.
|
||||||
//This needs to be done before the config call so they're available when the dropdown renders
|
//This needs to be done before the config call so they're available when the dropdown renders
|
||||||
const res = await api.get(`/api/global/configs/logos_oidc`)
|
const res = await api.get(`/api/global/configs/logos_oidc`)
|
||||||
|
@ -308,7 +311,7 @@
|
||||||
<Layout gap="XS" noPadding>
|
<Layout gap="XS" noPadding>
|
||||||
{#each GoogleConfigFields.Google as field}
|
{#each GoogleConfigFields.Google as field}
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<Label size="L">{field.label}</Label>
|
<Label size="L" tooltip={field.tooltip}>{field.label}</Label>
|
||||||
<Input
|
<Input
|
||||||
bind:value={providers.google.config[field.name]}
|
bind:value={providers.google.config[field.name]}
|
||||||
readonly={field.readonly}
|
readonly={field.readonly}
|
||||||
|
@ -346,7 +349,7 @@
|
||||||
<Layout gap="XS" noPadding>
|
<Layout gap="XS" noPadding>
|
||||||
{#each OIDCConfigFields.Oidc as field}
|
{#each OIDCConfigFields.Oidc as field}
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<Label size="L">{field.label}</Label>
|
<Label size="L" tooltip={field.tooltip}>{field.label}</Label>
|
||||||
<Input
|
<Input
|
||||||
bind:value={providers.oidc.config.configs[0][field.name]}
|
bind:value={providers.oidc.config.configs[0][field.name]}
|
||||||
readonly={field.readonly}
|
readonly={field.readonly}
|
||||||
|
|
|
@ -116,7 +116,11 @@
|
||||||
</Layout>
|
</Layout>
|
||||||
<div class="fields">
|
<div class="fields">
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<Label size="L">Platform URL</Label>
|
<Label
|
||||||
|
size="L"
|
||||||
|
tooltip={"Update the Platform URL to match your Budibase web URL. This keeps email templates and authentication configs up to date."}
|
||||||
|
>Platform URL</Label
|
||||||
|
>
|
||||||
<Input thin bind:value={$values.platformUrl} />
|
<Input thin bind:value={$values.platformUrl} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -135,6 +139,7 @@
|
||||||
.field {
|
.field {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 100px 1fr;
|
grid-template-columns: 100px 1fr;
|
||||||
|
grid-gap: var(--spacing-l);
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
.file {
|
.file {
|
||||||
|
|
|
@ -3,12 +3,14 @@ import api from "builderStore/api"
|
||||||
import { auth } from "stores/portal"
|
import { auth } from "stores/portal"
|
||||||
|
|
||||||
const DEFAULT_CONFIG = {
|
const DEFAULT_CONFIG = {
|
||||||
platformUrl: "http://localhost:10000",
|
platformUrl: "",
|
||||||
logoUrl: undefined,
|
logoUrl: undefined,
|
||||||
docsUrl: undefined,
|
docsUrl: undefined,
|
||||||
company: "Budibase",
|
company: "Budibase",
|
||||||
oidc: undefined,
|
oidc: undefined,
|
||||||
google: undefined,
|
google: undefined,
|
||||||
|
oidcCallbackUrl: "",
|
||||||
|
googleCallbackUrl: "",
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createOrganisationStore() {
|
export function createOrganisationStore() {
|
||||||
|
@ -28,6 +30,13 @@ export function createOrganisationStore() {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function save(config) {
|
async function save(config) {
|
||||||
|
// delete non-persisted fields
|
||||||
|
const storeConfig = get(store)
|
||||||
|
delete storeConfig.oidc
|
||||||
|
delete storeConfig.google
|
||||||
|
delete storeConfig.oidcCallbackUrl
|
||||||
|
delete storeConfig.googleCallbackUrl
|
||||||
|
|
||||||
const res = await api.post("/api/global/configs", {
|
const res = await api.post("/api/global/configs", {
|
||||||
type: "settings",
|
type: "settings",
|
||||||
config: { ...get(store), ...config },
|
config: { ...get(store), ...config },
|
||||||
|
|
|
@ -130,7 +130,7 @@ module PostgresModule {
|
||||||
public tables: Record<string, Table> = {}
|
public tables: Record<string, Table> = {}
|
||||||
public schemaErrors: Record<string, string> = {}
|
public schemaErrors: Record<string, string> = {}
|
||||||
|
|
||||||
COLUMNS_SQL!: string
|
COLUMNS_SQL!: string
|
||||||
|
|
||||||
PRIMARY_KEYS_SQL = `
|
PRIMARY_KEYS_SQL = `
|
||||||
select tc.table_schema, tc.table_name, kc.column_name as primary_key
|
select tc.table_schema, tc.table_name, kc.column_name as primary_key
|
||||||
|
@ -165,11 +165,11 @@ module PostgresModule {
|
||||||
|
|
||||||
setSchema() {
|
setSchema() {
|
||||||
if (!this.config.schema) {
|
if (!this.config.schema) {
|
||||||
this.config.schema = 'public'
|
this.config.schema = "public"
|
||||||
}
|
}
|
||||||
this.client.on('connect', (client: any) => {
|
this.client.on("connect", (client: any) => {
|
||||||
client.query(`SET search_path TO ${this.config.schema}`);
|
client.query(`SET search_path TO ${this.config.schema}`)
|
||||||
});
|
})
|
||||||
this.COLUMNS_SQL = `select * from information_schema.columns where table_schema = '${this.config.schema}'`
|
this.COLUMNS_SQL = `select * from information_schema.columns where table_schema = '${this.config.schema}'`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
const authPkg = require("@budibase/auth")
|
const authPkg = require("@budibase/auth")
|
||||||
|
const { getScopedConfig } = require("@budibase/auth/db")
|
||||||
const { google } = require("@budibase/auth/src/middleware")
|
const { google } = require("@budibase/auth/src/middleware")
|
||||||
const { oidc } = require("@budibase/auth/src/middleware")
|
const { oidc } = require("@budibase/auth/src/middleware")
|
||||||
const { Configs, EmailTemplatePurpose } = require("../../../constants")
|
const { Configs, EmailTemplatePurpose } = require("../../../constants")
|
||||||
|
@ -21,17 +22,32 @@ const {
|
||||||
} = require("@budibase/auth/tenancy")
|
} = require("@budibase/auth/tenancy")
|
||||||
const env = require("../../../environment")
|
const env = require("../../../environment")
|
||||||
|
|
||||||
function googleCallbackUrl(config) {
|
const ssoCallbackUrl = async (config, type) => {
|
||||||
// incase there is a callback URL from before
|
// incase there is a callback URL from before
|
||||||
if (config && config.callbackURL) {
|
if (config && config.callbackURL) {
|
||||||
return config.callbackURL
|
return config.callbackURL
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const db = getGlobalDB()
|
||||||
|
const publicConfig = await getScopedConfig(db, {
|
||||||
|
type: Configs.SETTINGS,
|
||||||
|
})
|
||||||
|
|
||||||
let callbackUrl = `/api/global/auth`
|
let callbackUrl = `/api/global/auth`
|
||||||
if (isMultiTenant()) {
|
if (isMultiTenant()) {
|
||||||
callbackUrl += `/${getTenantId()}`
|
callbackUrl += `/${getTenantId()}`
|
||||||
}
|
}
|
||||||
callbackUrl += `/google/callback`
|
callbackUrl += `/${type}/callback`
|
||||||
return callbackUrl
|
|
||||||
|
return `${publicConfig.platformUrl}${callbackUrl}`
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.googleCallbackUrl = async config => {
|
||||||
|
return ssoCallbackUrl(config, "google")
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.oidcCallbackUrl = async config => {
|
||||||
|
return ssoCallbackUrl(config, "oidc")
|
||||||
}
|
}
|
||||||
|
|
||||||
async function authInternal(ctx, user, err = null, info = null) {
|
async function authInternal(ctx, user, err = null, info = null) {
|
||||||
|
@ -152,7 +168,7 @@ exports.googlePreAuth = async (ctx, next) => {
|
||||||
type: Configs.GOOGLE,
|
type: Configs.GOOGLE,
|
||||||
workspace: ctx.query.workspace,
|
workspace: ctx.query.workspace,
|
||||||
})
|
})
|
||||||
let callbackUrl = googleCallbackUrl(config)
|
let callbackUrl = await exports.googleCallbackUrl(config)
|
||||||
const strategy = await google.strategyFactory(config, callbackUrl)
|
const strategy = await google.strategyFactory(config, callbackUrl)
|
||||||
|
|
||||||
return passport.authenticate(strategy, {
|
return passport.authenticate(strategy, {
|
||||||
|
@ -167,7 +183,7 @@ exports.googleAuth = async (ctx, next) => {
|
||||||
type: Configs.GOOGLE,
|
type: Configs.GOOGLE,
|
||||||
workspace: ctx.query.workspace,
|
workspace: ctx.query.workspace,
|
||||||
})
|
})
|
||||||
const callbackUrl = googleCallbackUrl(config)
|
const callbackUrl = await exports.googleCallbackUrl(config)
|
||||||
const strategy = await google.strategyFactory(config, callbackUrl)
|
const strategy = await google.strategyFactory(config, callbackUrl)
|
||||||
|
|
||||||
return passport.authenticate(
|
return passport.authenticate(
|
||||||
|
@ -189,13 +205,7 @@ async function oidcStrategyFactory(ctx, configId) {
|
||||||
})
|
})
|
||||||
|
|
||||||
const chosenConfig = config.configs.filter(c => c.uuid === configId)[0]
|
const chosenConfig = config.configs.filter(c => c.uuid === configId)[0]
|
||||||
|
let callbackUrl = await exports.oidcCallbackUrl(chosenConfig)
|
||||||
const protocol = env.NODE_ENV === "production" ? "https" : "http"
|
|
||||||
let callbackUrl = `${protocol}://${ctx.host}/api/global/auth`
|
|
||||||
if (isMultiTenant()) {
|
|
||||||
callbackUrl += `/${getTenantId()}`
|
|
||||||
}
|
|
||||||
callbackUrl += `/oidc/callback`
|
|
||||||
|
|
||||||
return oidc.strategyFactory(chosenConfig, callbackUrl)
|
return oidc.strategyFactory(chosenConfig, callbackUrl)
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,8 +9,11 @@ const { Configs } = require("../../../constants")
|
||||||
const email = require("../../../utilities/email")
|
const email = require("../../../utilities/email")
|
||||||
const { upload, ObjectStoreBuckets } = require("@budibase/auth").objectStore
|
const { upload, ObjectStoreBuckets } = require("@budibase/auth").objectStore
|
||||||
const CouchDB = require("../../../db")
|
const CouchDB = require("../../../db")
|
||||||
const { getGlobalDB } = require("@budibase/auth/tenancy")
|
const { getGlobalDB, getTenantId } = require("@budibase/auth/tenancy")
|
||||||
const env = require("../../../environment")
|
const env = require("../../../environment")
|
||||||
|
const { googleCallbackUrl, oidcCallbackUrl } = require("./auth")
|
||||||
|
|
||||||
|
const BB_TENANT_CDN = "https://tenants.cdn.budi.live"
|
||||||
|
|
||||||
exports.save = async function (ctx) {
|
exports.save = async function (ctx) {
|
||||||
const db = getGlobalDB()
|
const db = getGlobalDB()
|
||||||
|
@ -155,6 +158,10 @@ exports.publicSettings = async function (ctx) {
|
||||||
config.config.google = false
|
config.config.google = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// callback urls
|
||||||
|
config.config.oidcCallbackUrl = await oidcCallbackUrl()
|
||||||
|
config.config.googleCallbackUrl = await googleCallbackUrl()
|
||||||
|
|
||||||
// oidc button flag
|
// oidc button flag
|
||||||
if (oidcConfig && oidcConfig.config) {
|
if (oidcConfig && oidcConfig.config) {
|
||||||
config.config.oidc = oidcConfig.config.configs[0].activated
|
config.config.oidc = oidcConfig.config.configs[0].activated
|
||||||
|
@ -182,7 +189,13 @@ exports.upload = async function (ctx) {
|
||||||
bucket = ObjectStoreBuckets.GLOBAL_CLOUD
|
bucket = ObjectStoreBuckets.GLOBAL_CLOUD
|
||||||
}
|
}
|
||||||
|
|
||||||
const key = `${type}/${name}`
|
let key
|
||||||
|
if (env.MULTI_TENANCY) {
|
||||||
|
key = `${getTenantId()}/${type}/${name}`
|
||||||
|
} else {
|
||||||
|
key = `${type}/${name}`
|
||||||
|
}
|
||||||
|
|
||||||
await upload({
|
await upload({
|
||||||
bucket,
|
bucket,
|
||||||
filename: key,
|
filename: key,
|
||||||
|
@ -200,7 +213,13 @@ exports.upload = async function (ctx) {
|
||||||
config: {},
|
config: {},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const url = `/${bucket}/${key}`
|
let url
|
||||||
|
if (env.SELF_HOSTED) {
|
||||||
|
url = `/${bucket}/${key}`
|
||||||
|
} else {
|
||||||
|
url = `${BB_TENANT_CDN}/${key}`
|
||||||
|
}
|
||||||
|
|
||||||
cfgStructure.config[`${name}`] = url
|
cfgStructure.config[`${name}`] = url
|
||||||
// write back to db with url updated
|
// write back to db with url updated
|
||||||
await db.put(cfgStructure)
|
await db.put(cfgStructure)
|
||||||
|
|
|
@ -76,7 +76,7 @@ describe("/api/global/auth", () => {
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
expect(strategyFactory).toBeCalledWith(
|
expect(strategyFactory).toBeCalledWith(
|
||||||
chosenConfig,
|
chosenConfig,
|
||||||
`http://127.0.0.1:4003/api/global/auth/${TENANT_ID}/oidc/callback` // calculated url
|
`http://localhost:10000/api/global/auth/${TENANT_ID}/oidc/callback`
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,6 @@ const {
|
||||||
EmailTemplatePurpose,
|
EmailTemplatePurpose,
|
||||||
} = require("../constants")
|
} = require("../constants")
|
||||||
const { checkSlashesInUrl } = require("./index")
|
const { checkSlashesInUrl } = require("./index")
|
||||||
const env = require("../environment")
|
|
||||||
const { getGlobalDB, addTenantToUrl } = require("@budibase/auth/tenancy")
|
const { getGlobalDB, addTenantToUrl } = require("@budibase/auth/tenancy")
|
||||||
const BASE_COMPANY = "Budibase"
|
const BASE_COMPANY = "Budibase"
|
||||||
|
|
||||||
|
@ -14,9 +13,6 @@ exports.getSettingsTemplateContext = async (purpose, code = null) => {
|
||||||
const db = getGlobalDB()
|
const db = getGlobalDB()
|
||||||
// TODO: use more granular settings in the future if required
|
// TODO: use more granular settings in the future if required
|
||||||
let settings = (await getScopedConfig(db, { type: Configs.SETTINGS })) || {}
|
let settings = (await getScopedConfig(db, { type: Configs.SETTINGS })) || {}
|
||||||
if (!settings || !settings.platformUrl) {
|
|
||||||
settings.platformUrl = env.PLATFORM_URL
|
|
||||||
}
|
|
||||||
const URL = settings.platformUrl
|
const URL = settings.platformUrl
|
||||||
const context = {
|
const context = {
|
||||||
[InternalTemplateBindings.LOGO_URL]:
|
[InternalTemplateBindings.LOGO_URL]:
|
||||||
|
|
Loading…
Reference in New Issue