-
-
-
-
- "{testimonial.text}"
-
-
-
{testimonial.name}
-
{testimonial.role}
-
-
-
+
+ {#if enabled}
+
+
+
+
+ "{testimonial.text}"
+
+
+
{testimonial.name}
+
{testimonial.role}
+
+
+
+ {/if}
diff --git a/packages/server/src/api/controllers/static/index.ts b/packages/server/src/api/controllers/static/index.ts
index c58e1a374d..a12e1b5713 100644
--- a/packages/server/src/api/controllers/static/index.ts
+++ b/packages/server/src/api/controllers/static/index.ts
@@ -105,14 +105,16 @@ export const serveApp = async function (ctx: any) {
if (!env.isJest()) {
const App = require("./templates/BudibaseApp.svelte").default
const plugins = objectStore.enrichPluginURLs(appInfo.usedPlugins)
+ console.log(appInfo)
const { head, html, css } = App.render({
metaImage:
"https://res.cloudinary.com/daog6scxm/image/upload/v1666109324/meta-images/budibase-meta-image_uukc1m.png",
- title: appInfo.name,
+ title: appInfo.name, //Replace Title here?
production: env.isProd(),
appId,
clientLibPath: objectStore.clientLibraryUrl(appId!, appInfo.version),
usedPlugins: plugins,
+ favicon: objectStore.getGlobalFileUrl("settings", "faviconUrl"),
})
const appHbs = loadHandlebarsFile(`${__dirname}/templates/app.hbs`)
diff --git a/packages/server/src/api/controllers/static/templates/BudibaseApp.svelte b/packages/server/src/api/controllers/static/templates/BudibaseApp.svelte
index 27dad289b4..be06c4f46e 100644
--- a/packages/server/src/api/controllers/static/templates/BudibaseApp.svelte
+++ b/packages/server/src/api/controllers/static/templates/BudibaseApp.svelte
@@ -22,7 +22,6 @@
-
{title}
diff --git a/packages/types/src/documents/global/config.ts b/packages/types/src/documents/global/config.ts
index 6e86ed2674..1146c5910e 100644
--- a/packages/types/src/documents/global/config.ts
+++ b/packages/types/src/documents/global/config.ts
@@ -27,6 +27,20 @@ export interface SettingsInnerConfig {
company?: string
logoUrl?: string // Populated on read
logoUrlEtag?: string
+
+ faviconUrl?: string
+ faviconUrlEtag?: string
+
+ emailBrandingEnabled?: boolean
+
+ // Self host only
+ appFooterEnabled?: boolean
+ testimonialsEnabled?: boolean
+ licenceAgreementEnabled?: boolean
+ platformTitle?: string
+ loginHeading?: string
+ loginButton?: string
+
uniqueTenantId?: string
analyticsEnabled?: boolean
isSSOEnforced?: boolean
diff --git a/packages/worker/src/api/controllers/global/configs.ts b/packages/worker/src/api/controllers/global/configs.ts
index 02459855c2..eced642155 100644
--- a/packages/worker/src/api/controllers/global/configs.ts
+++ b/packages/worker/src/api/controllers/global/configs.ts
@@ -285,6 +285,14 @@ export async function publicSettings(
)
}
+ if (config.faviconUrl && config.faviconUrl !== "") {
+ config.faviconUrl = objectStore.getGlobalFileUrl(
+ "settings",
+ "faviconUrl",
+ config.faviconUrl
+ )
+ }
+
// google
const googleConfig = await configs.getGoogleConfig()
const preActivated = googleConfig?.activated == null
diff --git a/packages/worker/src/constants/templates/core.hbs b/packages/worker/src/constants/templates/core.hbs
new file mode 100644
index 0000000000..3511aaa460
--- /dev/null
+++ b/packages/worker/src/constants/templates/core.hbs
@@ -0,0 +1,31 @@
+{{#if enableEmailBranding}}
+
+
+
+
+
+
+
+ Budibase
+ |
+
+
+
+ |
+
+{{/if}}
\ No newline at end of file
diff --git a/packages/worker/src/constants/templates/index.ts b/packages/worker/src/constants/templates/index.ts
index b0b6029c36..8c3899b1df 100644
--- a/packages/worker/src/constants/templates/index.ts
+++ b/packages/worker/src/constants/templates/index.ts
@@ -21,6 +21,8 @@ export const EmailTemplates = {
join(__dirname, "welcome.hbs")
),
[EmailTemplatePurpose.CUSTOM]: readStaticFile(join(__dirname, "custom.hbs")),
+ //Core wrapper
+ ["branding"]: readStaticFile(join(__dirname, "core.hbs")),
}
export function addBaseTemplates(templates: Template[], type?: string) {
diff --git a/packages/worker/src/utilities/email.ts b/packages/worker/src/utilities/email.ts
index 4fd8a82161..870dcc33fd 100644
--- a/packages/worker/src/utilities/email.ts
+++ b/packages/worker/src/utilities/email.ts
@@ -1,6 +1,6 @@
import env from "../environment"
import { EmailTemplatePurpose, TemplateType } from "../constants"
-import { getTemplateByPurpose } from "../constants/templates"
+import { getTemplateByPurpose, EmailTemplates } from "../constants/templates"
import { getSettingsTemplateContext } from "./templates"
import { processString } from "@budibase/string-templates"
import { getResetPasswordCode, getInviteCode } from "./redis"
@@ -108,30 +108,53 @@ async function buildEmail(
let [base, body] = await Promise.all([
getTemplateByPurpose(TYPE, EmailTemplatePurpose.BASE),
getTemplateByPurpose(TYPE, purpose),
+ //getTemplateByPurpose(TYPE, "branding"), //should generalise to 'branding'
])
- if (!base || !body) {
+
+ let branding = EmailTemplates["branding"]
+
+ if (!base || !body || !branding) {
throw "Unable to build email, missing base components"
}
base = base.contents
body = body.contents
+
+ //branding = branding.contents
+
let name = user ? user.name : undefined
if (user && !name && user.firstName) {
name = user.lastName ? `${user.firstName} ${user.lastName}` : user.firstName
}
context = {
- ...context,
+ ...context, //enableEmailBranding
contents,
email,
name,
user: user || {},
}
- body = await processString(body, context)
- // this should now be the complete email HTML
+ const core = branding + body
+
+ body = await processString(core, context)
+
+ // Conditional elements
+ // branding = await processString(branding, {
+ // ...context,
+ // body,
+ // })
+
+ // this should now be the core email HTML
return processString(base, {
...context,
- body,
+ body, //: branding, // pass as body as usual
})
+
+ // body = await processString(body, context)
+ // // this should now be the coree email HTML
+ // return processString(base, {
+ // ...context,
+ // body,
+ // })
}
/**
diff --git a/packages/worker/src/utilities/templates.ts b/packages/worker/src/utilities/templates.ts
index 1597325c7c..f801bdbb03 100644
--- a/packages/worker/src/utilities/templates.ts
+++ b/packages/worker/src/utilities/templates.ts
@@ -25,6 +25,11 @@ export async function getSettingsTemplateContext(
[InternalTemplateBinding.CURRENT_DATE]: new Date().toISOString(),
[InternalTemplateBinding.CURRENT_YEAR]: new Date().getFullYear(),
}
+
+ // Need to be careful with the binding as it shouldn't be surfacable
+ // Also default to false if not explicit
+ context["enableEmailBranding"] = settings.emailBrandingEnabled
+
// attach purpose specific context
switch (purpose) {
case EmailTemplatePurpose.PASSWORD_RECOVERY: