commit
5342fd1a9d
|
@ -44,14 +44,14 @@
|
||||||
let config = {}
|
let config = {}
|
||||||
let updated = false
|
let updated = false
|
||||||
|
|
||||||
$: onConfigUpdate(config, mounted)
|
$: onConfigUpdate(config)
|
||||||
$: init = Object.keys(config).length > 0
|
$: initialised = Object.keys(config).length > 0
|
||||||
|
|
||||||
$: isCloud = $admin.cloud
|
$: isCloud = $admin.cloud
|
||||||
$: brandingEnabled = $licensing.brandingEnabled
|
$: brandingEnabled = $licensing.brandingEnabled
|
||||||
|
|
||||||
const onConfigUpdate = () => {
|
const onConfigUpdate = () => {
|
||||||
if (!mounted || updated || !init) {
|
if (!mounted || updated || !initialised) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
updated = true
|
updated = true
|
||||||
|
@ -122,34 +122,27 @@
|
||||||
return response
|
return response
|
||||||
}
|
}
|
||||||
|
|
||||||
async function saveConfig() {
|
async function saveFiles() {
|
||||||
saving = true
|
|
||||||
|
|
||||||
if (logoFile) {
|
if (logoFile) {
|
||||||
const logoResp = await uploadLogo(logoFile)
|
const logoResp = await uploadLogo(logoFile)
|
||||||
if (logoResp.url) {
|
if (logoResp.url) {
|
||||||
config = {
|
|
||||||
...config,
|
|
||||||
logoUrl: logoResp.url,
|
|
||||||
}
|
|
||||||
logoFile = null
|
logoFile = null
|
||||||
logoPreview = null
|
logoPreview = null
|
||||||
}
|
}
|
||||||
|
config.logoUrl = undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
if (faviconFile) {
|
if (faviconFile) {
|
||||||
const faviconResp = await uploadFavicon(faviconFile)
|
const faviconResp = await uploadFavicon(faviconFile)
|
||||||
if (faviconResp.url) {
|
if (faviconResp.url) {
|
||||||
config = {
|
|
||||||
...config,
|
|
||||||
faviconUrl: faviconResp.url,
|
|
||||||
}
|
|
||||||
faviconFile = null
|
faviconFile = null
|
||||||
faviconPreview = null
|
faviconPreview = null
|
||||||
}
|
}
|
||||||
|
config.faviconUrl = undefined
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Trim
|
function trimFields() {
|
||||||
const userStrings = [
|
const userStrings = [
|
||||||
"metaTitle",
|
"metaTitle",
|
||||||
"platformTitle",
|
"platformTitle",
|
||||||
|
@ -168,11 +161,18 @@
|
||||||
...config,
|
...config,
|
||||||
...trimmed,
|
...trimmed,
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function saveConfig() {
|
||||||
|
saving = true
|
||||||
|
|
||||||
|
await saveFiles()
|
||||||
|
trimFields()
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Update settings
|
// Update settings
|
||||||
await organisation.save(config)
|
await organisation.save(config)
|
||||||
await organisation.init()
|
await init()
|
||||||
notifications.success("Branding settings updated")
|
notifications.success("Branding settings updated")
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error("Branding updated failed", e)
|
console.error("Branding updated failed", e)
|
||||||
|
@ -182,9 +182,10 @@
|
||||||
saving = false
|
saving = false
|
||||||
}
|
}
|
||||||
|
|
||||||
onMount(async () => {
|
async function init() {
|
||||||
|
if (!$organisation.loaded) {
|
||||||
await organisation.init()
|
await organisation.init()
|
||||||
|
}
|
||||||
config = {
|
config = {
|
||||||
faviconUrl: $organisation.faviconUrl,
|
faviconUrl: $organisation.faviconUrl,
|
||||||
logoUrl: $organisation.logoUrl,
|
logoUrl: $organisation.logoUrl,
|
||||||
|
@ -197,6 +198,10 @@
|
||||||
metaImageUrl: $organisation.metaImageUrl,
|
metaImageUrl: $organisation.metaImageUrl,
|
||||||
metaTitle: $organisation.metaTitle,
|
metaTitle: $organisation.metaTitle,
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onMount(async () => {
|
||||||
|
await init()
|
||||||
mounted = true
|
mounted = true
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
@ -262,6 +267,7 @@
|
||||||
faviconFile = e.detail
|
faviconFile = e.detail
|
||||||
faviconPreview = null
|
faviconPreview = null
|
||||||
} else {
|
} else {
|
||||||
|
faviconFile = null
|
||||||
clone.faviconUrl = ""
|
clone.faviconUrl = ""
|
||||||
}
|
}
|
||||||
config = clone
|
config = clone
|
||||||
|
@ -408,7 +414,11 @@
|
||||||
Upgrade
|
Upgrade
|
||||||
</Button>
|
</Button>
|
||||||
{/if}
|
{/if}
|
||||||
<Button on:click={saveConfig} cta disabled={saving || !updated || !init}>
|
<Button
|
||||||
|
on:click={saveConfig}
|
||||||
|
cta
|
||||||
|
disabled={saving || !updated || !$organisation.loaded}
|
||||||
|
>
|
||||||
Save
|
Save
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -23,6 +23,7 @@ const DEFAULT_CONFIG = {
|
||||||
oidcCallbackUrl: "",
|
oidcCallbackUrl: "",
|
||||||
googleCallbackUrl: "",
|
googleCallbackUrl: "",
|
||||||
isSSOEnforced: false,
|
isSSOEnforced: false,
|
||||||
|
loaded: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createOrganisationStore() {
|
export function createOrganisationStore() {
|
||||||
|
@ -32,7 +33,7 @@ export function createOrganisationStore() {
|
||||||
async function init() {
|
async function init() {
|
||||||
const tenantId = get(auth).tenantId
|
const tenantId = get(auth).tenantId
|
||||||
const settingsConfigDoc = await API.getTenantConfig(tenantId)
|
const settingsConfigDoc = await API.getTenantConfig(tenantId)
|
||||||
set({ ...DEFAULT_CONFIG, ...settingsConfigDoc.config })
|
set({ ...DEFAULT_CONFIG, ...settingsConfigDoc.config, loaded: true })
|
||||||
}
|
}
|
||||||
|
|
||||||
async function save(config) {
|
async function save(config) {
|
||||||
|
@ -43,6 +44,10 @@ export function createOrganisationStore() {
|
||||||
delete storeConfig.googleDatasourceConfigured
|
delete storeConfig.googleDatasourceConfigured
|
||||||
delete storeConfig.oidcCallbackUrl
|
delete storeConfig.oidcCallbackUrl
|
||||||
delete storeConfig.googleCallbackUrl
|
delete storeConfig.googleCallbackUrl
|
||||||
|
|
||||||
|
// delete internal store field
|
||||||
|
delete storeConfig.loaded
|
||||||
|
|
||||||
await API.saveConfig({
|
await API.saveConfig({
|
||||||
type: "settings",
|
type: "settings",
|
||||||
config: { ...storeConfig, ...config },
|
config: { ...storeConfig, ...config },
|
||||||
|
|
|
@ -23,6 +23,7 @@ import {
|
||||||
isSettingsConfig,
|
isSettingsConfig,
|
||||||
isSMTPConfig,
|
isSMTPConfig,
|
||||||
OIDCConfigs,
|
OIDCConfigs,
|
||||||
|
SettingsBrandingConfig,
|
||||||
SettingsInnerConfig,
|
SettingsInnerConfig,
|
||||||
SSOConfig,
|
SSOConfig,
|
||||||
SSOConfigType,
|
SSOConfigType,
|
||||||
|
@ -142,13 +143,29 @@ async function hasActivatedConfig(ssoConfigs?: SSOConfigs) {
|
||||||
return !!Object.values(ssoConfigs).find(c => c?.activated)
|
return !!Object.values(ssoConfigs).find(c => c?.activated)
|
||||||
}
|
}
|
||||||
|
|
||||||
async function verifySettingsConfig(config: SettingsInnerConfig) {
|
async function verifySettingsConfig(
|
||||||
|
config: SettingsInnerConfig & SettingsBrandingConfig,
|
||||||
|
existingConfig?: SettingsInnerConfig & SettingsBrandingConfig
|
||||||
|
) {
|
||||||
if (config.isSSOEnforced) {
|
if (config.isSSOEnforced) {
|
||||||
const valid = await hasActivatedConfig()
|
const valid = await hasActivatedConfig()
|
||||||
if (!valid) {
|
if (!valid) {
|
||||||
throw new Error("Cannot enforce SSO without an activated configuration")
|
throw new Error("Cannot enforce SSO without an activated configuration")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// always preserve file attributes
|
||||||
|
// these should be set via upload instead
|
||||||
|
// only allow for deletion by checking empty string to bypass this behaviour
|
||||||
|
|
||||||
|
if (existingConfig && config.logoUrl !== "") {
|
||||||
|
config.logoUrl = existingConfig.logoUrl
|
||||||
|
config.logoUrlEtag = existingConfig.logoUrlEtag
|
||||||
|
}
|
||||||
|
if (existingConfig && config.faviconUrl !== "") {
|
||||||
|
config.faviconUrl = existingConfig.faviconUrl
|
||||||
|
config.faviconUrlEtag = existingConfig.faviconUrlEtag
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function verifySSOConfig(type: SSOConfigType, config: SSOConfig) {
|
async function verifySSOConfig(type: SSOConfigType, config: SSOConfig) {
|
||||||
|
@ -198,7 +215,7 @@ export async function save(ctx: UserCtx<Config>) {
|
||||||
await email.verifyConfig(config)
|
await email.verifyConfig(config)
|
||||||
break
|
break
|
||||||
case ConfigType.SETTINGS:
|
case ConfigType.SETTINGS:
|
||||||
await verifySettingsConfig(config)
|
await verifySettingsConfig(config, existingConfig?.config)
|
||||||
break
|
break
|
||||||
case ConfigType.GOOGLE:
|
case ConfigType.GOOGLE:
|
||||||
await verifyGoogleConfig(config)
|
await verifyGoogleConfig(config)
|
||||||
|
@ -320,14 +337,15 @@ export async function publicSettings(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (branding.faviconUrl && branding.faviconUrl !== "") {
|
// enrich the favicon url - empty url means deleted
|
||||||
// @ts-ignore
|
const faviconUrl =
|
||||||
config.faviconUrl = objectStore.getGlobalFileUrl(
|
branding.faviconUrl && branding.faviconUrl !== ""
|
||||||
|
? objectStore.getGlobalFileUrl(
|
||||||
"settings",
|
"settings",
|
||||||
"faviconUrl",
|
"faviconUrl",
|
||||||
branding.faviconUrl
|
branding.faviconUrlEtag
|
||||||
)
|
)
|
||||||
}
|
: undefined
|
||||||
|
|
||||||
// google
|
// google
|
||||||
const googleConfig = await configs.getGoogleConfig()
|
const googleConfig = await configs.getGoogleConfig()
|
||||||
|
@ -352,6 +370,7 @@ export async function publicSettings(
|
||||||
config: {
|
config: {
|
||||||
...config,
|
...config,
|
||||||
...branding,
|
...branding,
|
||||||
|
...{ faviconUrl },
|
||||||
google,
|
google,
|
||||||
googleDatasourceConfigured,
|
googleDatasourceConfigured,
|
||||||
oidc,
|
oidc,
|
||||||
|
|
Loading…
Reference in New Issue