diff --git a/x-pack/platform/plugins/shared/screenshotting/server/browsers/chromium/templates/index.test.ts b/x-pack/platform/plugins/shared/screenshotting/server/browsers/chromium/templates/index.test.ts new file mode 100644 index 0000000000000..90fdf4576c59e --- /dev/null +++ b/x-pack/platform/plugins/shared/screenshotting/server/browsers/chromium/templates/index.test.ts @@ -0,0 +1,124 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { getHeaderTemplate, getFooterTemplate, getDefaultFooterLogo } from '.'; + +let defaultFooterLogo: string; + +describe('templates/index', () => { + beforeAll(async () => { + defaultFooterLogo = (await getDefaultFooterLogo()).trim(); + }); + + describe('getHeaderTemplate()', () => { + it('works with a plain logo', async () => { + const title = 'plain'; + const result = await getHeaderTemplate({ title }); + expect(result).toBe(getHeader(title)); + }); + it('works with an html title', async () => { + const title = 'html'; + const result = await getHeaderTemplate({ title }); + expect(result).toBe(getHeader('<b>html</b>')); + }); + }); + + describe('getFooterTemplate()', () => { + it('works with no logo', async () => { + const result = await getFooterTemplate({}); + expect(result).toBe(getFooter()); + }); + it('works with a plain logo', async () => { + const logo = 'http://example.com/favico.ico'; + const result = await getFooterTemplate({ logo }); + expect(result).toBe(getFooter(logo)); + }); + it('works with an html logo', async () => { + const logo = '"/>${title} +`.trimStart(); +} + +function getFooter(logo?: string): string { + const hasLogo = !!logo; + + if (!hasLogo) { + logo = defFooterLogo(); + } + return ` + +
+ + +${getPoweredBy(hasLogo)}
+  of  +
+
+`.trimStart(); +} + +function getPoweredBy(hasLogo: boolean): string { + if (!hasLogo) return ''; + return `
Powered by Elastic
\n`; +} + +function defFooterLogo(): string { + return defaultFooterLogo!; +} diff --git a/x-pack/platform/plugins/shared/screenshotting/server/browsers/chromium/templates/index.ts b/x-pack/platform/plugins/shared/screenshotting/server/browsers/chromium/templates/index.ts index 7034dac76cfca..179e21ce94265 100644 --- a/x-pack/platform/plugins/shared/screenshotting/server/browsers/chromium/templates/index.ts +++ b/x-pack/platform/plugins/shared/screenshotting/server/browsers/chromium/templates/index.ts @@ -8,12 +8,27 @@ import { i18n } from '@kbn/i18n'; import fs from 'fs/promises'; import path from 'path'; -import Handlebars from 'handlebars'; +import Handlebars, { TemplateDelegate } from '@kbn/handlebars'; import { assetPath } from '../../../constants'; -async function compileTemplate(pathToTemplate: string): Promise> { +// see: https://handlebarsjs.com/guide/builtin-helpers.html +const HBCompileOptions = { + knownHelpersOnly: true, + knownHelpers: { + helperMissing: false, + blockHelperMissing: false, + each: false, + if: true, + unless: false, + with: false, + log: false, + lookup: false, + }, +}; + +async function compileTemplate(pathToTemplate: string): Promise> { const contentsBuffer = await fs.readFile(pathToTemplate); - return Handlebars.compile(contentsBuffer.toString()); + return Handlebars.compileAST(contentsBuffer.toString(), HBCompileOptions); } interface HeaderTemplateInput { @@ -30,7 +45,7 @@ export async function getHeaderTemplate({ title }: GetHeaderArgs): Promise { +export async function getDefaultFooterLogo(): Promise { const logoBuffer = await fs.readFile(path.resolve(assetPath, 'img', 'logo-grey.png')); return `data:image/png;base64,${logoBuffer.toString('base64')}`; } diff --git a/x-pack/platform/plugins/shared/screenshotting/tsconfig.json b/x-pack/platform/plugins/shared/screenshotting/tsconfig.json index 200c6d9c2592e..67363ecf6ffde 100644 --- a/x-pack/platform/plugins/shared/screenshotting/tsconfig.json +++ b/x-pack/platform/plugins/shared/screenshotting/tsconfig.json @@ -26,6 +26,7 @@ "@kbn/core-plugins-server", "@kbn/task-manager-plugin", "@kbn/screenshotting-server", + "@kbn/handlebars", ], "exclude": [ "target/**/*",