diff --git a/.changeset/cuddly-camels-relax.md b/.changeset/cuddly-camels-relax.md new file mode 100644 index 000000000..4e0b7a3ad --- /dev/null +++ b/.changeset/cuddly-camels-relax.md @@ -0,0 +1,5 @@ +--- +'@verdaccio/middleware': patch +--- + +fix(middleware): custom favicon diff --git a/packages/middleware/src/middlewares/web/render-web.ts b/packages/middleware/src/middlewares/web/render-web.ts index 3064a42d3..a52c0588e 100644 --- a/packages/middleware/src/middlewares/web/render-web.ts +++ b/packages/middleware/src/middlewares/web/render-web.ts @@ -37,7 +37,15 @@ export function renderWebMiddleware(config, tokenMiddleware, pluginOptions) { // any match within the static is routed to the file system router.get('/-/static/*', function (req, res, next) { const filename = req.params[0]; - const file = `${staticPath}/${filename}`; + let file = `${staticPath}/${filename}`; + if (filename === 'favicon.ico' && config?.web?.favicon) { + file = config?.web?.favicon; + if (isURLhasValidProtocol(file)) { + debug('redirect to favicon %s', file); + req.url = file; + return next(); + } + } debug('render static file %o', file); res.sendFile(file, sendFileCallback(next)); }); diff --git a/packages/middleware/src/middlewares/web/utils/renderHTML.ts b/packages/middleware/src/middlewares/web/utils/renderHTML.ts index 65f1f1077..3d8976285 100644 --- a/packages/middleware/src/middlewares/web/utils/renderHTML.ts +++ b/packages/middleware/src/middlewares/web/utils/renderHTML.ts @@ -65,6 +65,7 @@ export default function renderHTML( const title = config?.web?.title ?? WEB_TITLE; const login = hasLogin(config); const scope = config?.web?.scope ?? ''; + const favicon = resolveLogo(config?.web?.favicon, config?.url_prefix, requestOptions); const logo = resolveLogo(config?.web?.logo, config?.url_prefix, requestOptions); const logoDark = resolveLogo(config?.web?.logoDark, config?.url_prefix, requestOptions); const pkgManagers = config?.web?.pkgManagers ?? ['yarn', 'pnpm', 'npm']; @@ -114,6 +115,7 @@ export default function renderHTML( version, logo, logoDark, + favicon, flags, login, pkgManagers, diff --git a/packages/middleware/test/config/favicon.ico b/packages/middleware/test/config/favicon.ico new file mode 100644 index 000000000..1a4beb4b6 Binary files /dev/null and b/packages/middleware/test/config/favicon.ico differ diff --git a/packages/middleware/test/config/file-logo.yaml b/packages/middleware/test/config/file-logo.yaml index 468ad357a..50441befc 100644 --- a/packages/middleware/test/config/file-logo.yaml +++ b/packages/middleware/test/config/file-logo.yaml @@ -15,6 +15,7 @@ web: primary_color: '#ffffff' logo: './test/config/dark-logo.png' logoDark: './test/config/dark-logo.png' + favicon: './test/config/favicon.ico' html_cache: false url_prefix: /prefix diff --git a/packages/middleware/test/config/http-logo.yaml b/packages/middleware/test/config/http-logo.yaml new file mode 100644 index 000000000..6f59e43d7 --- /dev/null +++ b/packages/middleware/test/config/http-logo.yaml @@ -0,0 +1,26 @@ +web: + title: verdaccio web + login: true + scope: '@scope' + pkgManagers: + - pnpm + - yarn + showInfo: true + showSettings: true + showSearch: true + showFooter: true + showThemeSwitch: true + showDownloadTarball: true + showRaw: true + primary_color: '#ffffff' + logo: https://raw.githubusercontent.com/verdaccio/verdaccio/master/assets/svg/logo-small.svg + logoDark: https://raw.githubusercontent.com/verdaccio/verdaccio/master/assets/svg/logo-blackwhite.svg + favicon: https://raw.githubusercontent.com/verdaccio/verdaccio/master/website/static/img/favicon/favicon.ico + html_cache: false + +url_prefix: /prefix + +log: { type: stdout, format: pretty, level: trace } + +flags: + changePassword: true diff --git a/packages/middleware/test/config/no-logo.yaml b/packages/middleware/test/config/no-logo.yaml index 794b8a441..0a7c19308 100644 --- a/packages/middleware/test/config/no-logo.yaml +++ b/packages/middleware/test/config/no-logo.yaml @@ -14,6 +14,7 @@ web: showRaw: true primary_color: '#ffffff' logo: + favicon: html_cache: false url_prefix: /prefix diff --git a/packages/middleware/test/render.spec.ts b/packages/middleware/test/render.spec.ts index 810f3adb8..96916abcd 100644 --- a/packages/middleware/test/render.spec.ts +++ b/packages/middleware/test/render.spec.ts @@ -86,6 +86,21 @@ describe('test web server', () => { expect(__VERDACCIO_BASENAME_UI_OPTIONS.logoDark).toMatch('/prefix/-/static/dark-logo.png'); }); + test('should render favicon as file', async () => { + const { + window: { __VERDACCIO_BASENAME_UI_OPTIONS }, + } = await render('file-logo.yaml'); + expect(__VERDACCIO_BASENAME_UI_OPTIONS.favicon).toMatch('/prefix/-/static/favicon.ico'); + }); + + test('should render logo and favicon as URL', async () => { + const { + window: { __VERDACCIO_BASENAME_UI_OPTIONS }, + } = await render('http-logo.yaml'); + expect(__VERDACCIO_BASENAME_UI_OPTIONS.logo).toMatch(/https:.*logo-small.svg/i); + expect(__VERDACCIO_BASENAME_UI_OPTIONS.favicon).toMatch(/https:.*favicon.ico/i); + }); + test('should not render logo as absolute file is wrong', async () => { const { window: { __VERDACCIO_BASENAME_UI_OPTIONS }, @@ -98,6 +113,7 @@ describe('test web server', () => { window: { __VERDACCIO_BASENAME_UI_OPTIONS }, } = await render('no-logo.yaml'); expect(__VERDACCIO_BASENAME_UI_OPTIONS.logo).toEqual(''); + expect(__VERDACCIO_BASENAME_UI_OPTIONS.favicon).toEqual(''); }); test.todo('should default title');