mirror of
https://github.com/verdaccio/verdaccio.git
synced 2024-11-08 23:25:51 +01:00
fix: missing logo on header (#3636)
This commit is contained in:
parent
3dc0fd41f4
commit
4fc21146ab
8
.changeset/old-apples-fail.md
Normal file
8
.changeset/old-apples-fail.md
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
---
|
||||||
|
'@verdaccio/types': patch
|
||||||
|
'@verdaccio/middleware': patch
|
||||||
|
'@verdaccio/ui-theme': patch
|
||||||
|
'@verdaccio/web': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
fix: missing logo on header
|
@ -128,7 +128,6 @@ export type TemplateUIOptions = {
|
|||||||
base: string;
|
base: string;
|
||||||
primaryColor: string;
|
primaryColor: string;
|
||||||
version?: string;
|
version?: string;
|
||||||
logoURI?: string;
|
|
||||||
flags: FlagsConfig;
|
flags: FlagsConfig;
|
||||||
} & CommonWebConf;
|
} & CommonWebConf;
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ import { HTTP_STATUS } from '@verdaccio/core';
|
|||||||
import { isURLhasValidProtocol } from '@verdaccio/url';
|
import { isURLhasValidProtocol } from '@verdaccio/url';
|
||||||
|
|
||||||
import { setSecurityWebHeaders } from './security';
|
import { setSecurityWebHeaders } from './security';
|
||||||
import renderHTML, { isHTTPProtocol } from './utils/renderHTML';
|
import renderHTML from './utils/renderHTML';
|
||||||
|
|
||||||
const debug = buildDebug('verdaccio:web:render');
|
const debug = buildDebug('verdaccio:web:render');
|
||||||
|
|
||||||
@ -31,23 +31,10 @@ export function renderWebMiddleware(config, tokenMiddleware, pluginOptions) {
|
|||||||
if (typeof tokenMiddleware === 'function') {
|
if (typeof tokenMiddleware === 'function') {
|
||||||
router.use(tokenMiddleware);
|
router.use(tokenMiddleware);
|
||||||
}
|
}
|
||||||
|
|
||||||
router.use(setSecurityWebHeaders);
|
router.use(setSecurityWebHeaders);
|
||||||
|
|
||||||
// Logo
|
// any match within the static is routed to the file system
|
||||||
let logoURI = config?.web?.logo ?? '';
|
|
||||||
if (logoURI && !isURLhasValidProtocol(logoURI)) {
|
|
||||||
// URI related to a local file
|
|
||||||
|
|
||||||
// Note: `path.join` will break on Windows, because it transforms `/` to `\`
|
|
||||||
// Use POSIX version `path.posix.join` instead.
|
|
||||||
logoURI = path.posix.join('/-/static/', path.basename(logoURI));
|
|
||||||
router.get(logoURI, function (req, res, next) {
|
|
||||||
res.sendFile(path.resolve(config.web.logo), sendFileCallback(next));
|
|
||||||
debug('render static');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Static
|
|
||||||
router.get('/-/static/*', function (req, res, next) {
|
router.get('/-/static/*', function (req, res, next) {
|
||||||
const filename = req.params[0];
|
const filename = req.params[0];
|
||||||
const file = `${staticPath}/${filename}`;
|
const file = `${staticPath}/${filename}`;
|
||||||
@ -55,13 +42,13 @@ export function renderWebMiddleware(config, tokenMiddleware, pluginOptions) {
|
|||||||
res.sendFile(file, sendFileCallback(next));
|
res.sendFile(file, sendFileCallback(next));
|
||||||
});
|
});
|
||||||
|
|
||||||
// logo
|
// check the origin of the logo
|
||||||
if (config?.web?.logo && !isHTTPProtocol(config?.web?.logo)) {
|
if (config?.web?.logo && !isURLhasValidProtocol(config?.web?.logo)) {
|
||||||
// URI related to a local file
|
// URI related to a local file
|
||||||
const absoluteLocalFile = path.posix.resolve(config.web.logo);
|
const absoluteLocalFile = path.posix.resolve(config.web.logo);
|
||||||
debug('serve local logo %s', absoluteLocalFile);
|
debug('serve local logo %s', absoluteLocalFile);
|
||||||
try {
|
try {
|
||||||
// TODO: remove existsSync by async alternative
|
// TODO: replace existsSync by async alternative
|
||||||
if (
|
if (
|
||||||
fs.existsSync(absoluteLocalFile) &&
|
fs.existsSync(absoluteLocalFile) &&
|
||||||
typeof fs.accessSync(absoluteLocalFile, fs.constants.R_OK) === 'undefined'
|
typeof fs.accessSync(absoluteLocalFile, fs.constants.R_OK) === 'undefined'
|
||||||
|
@ -6,6 +6,7 @@ import { URL } from 'url';
|
|||||||
import { WEB_TITLE } from '@verdaccio/config';
|
import { WEB_TITLE } from '@verdaccio/config';
|
||||||
import { HEADERS } from '@verdaccio/core';
|
import { HEADERS } from '@verdaccio/core';
|
||||||
import { TemplateUIOptions } from '@verdaccio/types';
|
import { TemplateUIOptions } from '@verdaccio/types';
|
||||||
|
import { isURLhasValidProtocol } from '@verdaccio/url';
|
||||||
import { getPublicUrl } from '@verdaccio/url';
|
import { getPublicUrl } from '@verdaccio/url';
|
||||||
|
|
||||||
import renderTemplate from './template';
|
import renderTemplate from './template';
|
||||||
@ -21,20 +22,12 @@ const defaultManifestFiles = {
|
|||||||
ico: 'favicon.ico',
|
ico: 'favicon.ico',
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if URI is starting with "http://", "https://" or "//"
|
|
||||||
* @param {string} uri
|
|
||||||
*/
|
|
||||||
export function isHTTPProtocol(uri: string): boolean {
|
|
||||||
return /^(https?:)?\/\//.test(uri);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function resolveLogo(config, req) {
|
export function resolveLogo(config, req) {
|
||||||
const isLocalFile = config?.web?.logo && !isHTTPProtocol(config?.web?.logo);
|
const isLocalFile = config?.web?.logo && !isURLhasValidProtocol(config?.web?.logo);
|
||||||
|
|
||||||
if (isLocalFile) {
|
if (isLocalFile) {
|
||||||
return `${getPublicUrl(config?.url_prefix, req)}-/static/${path.basename(config?.web?.logo)}`;
|
return `${getPublicUrl(config?.url_prefix, req)}-/static/${path.basename(config?.web?.logo)}`;
|
||||||
} else if (isHTTPProtocol(config?.web?.logo)) {
|
} else if (isURLhasValidProtocol(config?.web?.logo)) {
|
||||||
return config?.web?.logo;
|
return config?.web?.logo;
|
||||||
} else {
|
} else {
|
||||||
return '';
|
return '';
|
||||||
@ -53,7 +46,7 @@ export default function renderHTML(config, manifest, manifestFiles, req, res) {
|
|||||||
const title = config?.web?.title ?? WEB_TITLE;
|
const title = config?.web?.title ?? WEB_TITLE;
|
||||||
const login = hasLogin(config);
|
const login = hasLogin(config);
|
||||||
const scope = config?.web?.scope ?? '';
|
const scope = config?.web?.scope ?? '';
|
||||||
const logoURI = resolveLogo(config, req);
|
const logo = resolveLogo(config, req);
|
||||||
const pkgManagers = config?.web?.pkgManagers ?? ['yarn', 'pnpm', 'npm'];
|
const pkgManagers = config?.web?.pkgManagers ?? ['yarn', 'pnpm', 'npm'];
|
||||||
const version = config?.web?.version;
|
const version = config?.web?.version;
|
||||||
const flags = {
|
const flags = {
|
||||||
@ -94,7 +87,7 @@ export default function renderHTML(config, manifest, manifestFiles, req, res) {
|
|||||||
base,
|
base,
|
||||||
primaryColor,
|
primaryColor,
|
||||||
version,
|
version,
|
||||||
logoURI,
|
logo,
|
||||||
flags,
|
flags,
|
||||||
login,
|
login,
|
||||||
pkgManagers,
|
pkgManagers,
|
||||||
|
BIN
packages/middleware/test/config/dark-logo.png
Normal file
BIN
packages/middleware/test/config/dark-logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.6 KiB |
24
packages/middleware/test/config/file-logo.yaml
Normal file
24
packages/middleware/test/config/file-logo.yaml
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
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: './test/config/dark-logo.png'
|
||||||
|
html_cache: false
|
||||||
|
|
||||||
|
url_prefix: /prefix
|
||||||
|
|
||||||
|
log: { type: stdout, format: pretty, level: trace }
|
||||||
|
|
||||||
|
flags:
|
||||||
|
changePassword: true
|
@ -8,6 +8,7 @@ auth:
|
|||||||
web:
|
web:
|
||||||
title: verdaccio
|
title: verdaccio
|
||||||
login: false
|
login: false
|
||||||
|
html_cache: false
|
||||||
|
|
||||||
publish:
|
publish:
|
||||||
allow_offline: false
|
allow_offline: false
|
||||||
|
24
packages/middleware/test/config/no-logo.yaml
Normal file
24
packages/middleware/test/config/no-logo.yaml
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
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:
|
||||||
|
html_cache: false
|
||||||
|
|
||||||
|
url_prefix: /prefix
|
||||||
|
|
||||||
|
log: { type: stdout, format: pretty, level: trace }
|
||||||
|
|
||||||
|
flags:
|
||||||
|
changePassword: true
|
@ -13,7 +13,8 @@ web:
|
|||||||
showDownloadTarball: true
|
showDownloadTarball: true
|
||||||
showRaw: true
|
showRaw: true
|
||||||
primary_color: '#ffffff'
|
primary_color: '#ffffff'
|
||||||
logoURI: 'http://logo.org/logo.png'
|
logo: 'http://logo.org/logo.png'
|
||||||
|
html_cache: false
|
||||||
|
|
||||||
url_prefix: /prefix
|
url_prefix: /prefix
|
||||||
|
|
||||||
|
24
packages/middleware/test/config/wrong-logo.yaml
Normal file
24
packages/middleware/test/config/wrong-logo.yaml
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
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: './does_not_exist/config/dark-logo.png'
|
||||||
|
html_cache: false
|
||||||
|
|
||||||
|
url_prefix: /prefix
|
||||||
|
|
||||||
|
log: { type: stdout, format: pretty, level: trace }
|
||||||
|
|
||||||
|
flags:
|
||||||
|
changePassword: true
|
@ -37,6 +37,10 @@ describe('test web server', () => {
|
|||||||
return new JSDOM(response.text, { runScripts: 'dangerously' });
|
return new JSDOM(response.text, { runScripts: 'dangerously' });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const loadLogo = async (config = 'default-test.yaml', url) => {
|
||||||
|
return supertest(initializeServer(config)).get(url).expect(HTTP_STATUS.OK);
|
||||||
|
};
|
||||||
|
|
||||||
test('should match render set ui properties', async () => {
|
test('should match render set ui properties', async () => {
|
||||||
const {
|
const {
|
||||||
window: { __VERDACCIO_BASENAME_UI_OPTIONS },
|
window: { __VERDACCIO_BASENAME_UI_OPTIONS },
|
||||||
@ -56,7 +60,7 @@ describe('test web server', () => {
|
|||||||
// FIXME: mock these values, avoid random
|
// FIXME: mock these values, avoid random
|
||||||
// base: 'http://127.0.0.1:60864/prefix/',
|
// base: 'http://127.0.0.1:60864/prefix/',
|
||||||
// version: '6.0.0-6-next.28',
|
// version: '6.0.0-6-next.28',
|
||||||
logoURI: '',
|
logo: 'http://logo.org/logo.png',
|
||||||
flags: { changePassword: true },
|
flags: { changePassword: true },
|
||||||
login: true,
|
login: true,
|
||||||
pkgManagers: ['pnpm', 'yarn'],
|
pkgManagers: ['pnpm', 'yarn'],
|
||||||
@ -67,6 +71,28 @@ describe('test web server', () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('should render logo as file', async () => {
|
||||||
|
const {
|
||||||
|
window: { __VERDACCIO_BASENAME_UI_OPTIONS },
|
||||||
|
} = await render('file-logo.yaml');
|
||||||
|
expect(__VERDACCIO_BASENAME_UI_OPTIONS.logo).toMatch('/prefix/-/static/dark-logo.png');
|
||||||
|
return loadLogo('file-logo.yaml', '/-/static/dark-logo.png');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should not render logo as absolute file is wrong', async () => {
|
||||||
|
const {
|
||||||
|
window: { __VERDACCIO_BASENAME_UI_OPTIONS },
|
||||||
|
} = await render('wrong-logo.yaml');
|
||||||
|
expect(__VERDACCIO_BASENAME_UI_OPTIONS.logo).toEqual('');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should render not render a logo', async () => {
|
||||||
|
const {
|
||||||
|
window: { __VERDACCIO_BASENAME_UI_OPTIONS },
|
||||||
|
} = await render('no-logo.yaml');
|
||||||
|
expect(__VERDACCIO_BASENAME_UI_OPTIONS.logo).toEqual('');
|
||||||
|
});
|
||||||
|
|
||||||
test.todo('should default title');
|
test.todo('should default title');
|
||||||
test.todo('should need html cache');
|
test.todo('should need html cache');
|
||||||
});
|
});
|
||||||
|
@ -109,9 +109,10 @@
|
|||||||
"test": "cross-env TZ=UTC jest --config ./jest/jest.config.js",
|
"test": "cross-env TZ=UTC jest --config ./jest/jest.config.js",
|
||||||
"test:update-snapshot": "yarn run test -- -u",
|
"test:update-snapshot": "yarn run test -- -u",
|
||||||
"lint": "pnpm lint:js && pnpm lint:css",
|
"lint": "pnpm lint:js && pnpm lint:css",
|
||||||
|
"clean": "rimraf ./static",
|
||||||
"lint:css": "yarn stylelint \"src/**/styles.ts\"",
|
"lint:css": "yarn stylelint \"src/**/styles.ts\"",
|
||||||
"verdaccio:server": "node tools/verdaccio.js",
|
"verdaccio:server": "node tools/verdaccio.js",
|
||||||
"build": "webpack --config tools/webpack.prod.config.babel.js",
|
"build": "pnpm clean && webpack --config tools/webpack.prod.config.babel.js",
|
||||||
"build:stats": "webpack --config tools/webpack.prod.config.babel.js --json > stats.json",
|
"build:stats": "webpack --config tools/webpack.prod.config.babel.js --json > stats.json",
|
||||||
"build:size": "webpack --config tools/webpack.prod.config.babel.js --json | webpack-bundle-size-analyzer"
|
"build:size": "webpack --config tools/webpack.prod.config.babel.js --json | webpack-bundle-size-analyzer"
|
||||||
},
|
},
|
||||||
|
BIN
packages/ui-components/public/dark-logo.png
Normal file
BIN
packages/ui-components/public/dark-logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.6 KiB |
@ -20,7 +20,7 @@ web:
|
|||||||
showDownloadTarball: true
|
showDownloadTarball: true
|
||||||
showRaw: true
|
showRaw: true
|
||||||
primary_color: '#ffffff'
|
primary_color: '#ffffff'
|
||||||
logoURI: 'http://logo.org/logo.png'
|
logo: 'http://logo.org/logo.png'
|
||||||
flags:
|
flags:
|
||||||
- something: false
|
- something: false
|
||||||
|
|
||||||
|
8
pnpm-lock.yaml
generated
8
pnpm-lock.yaml
generated
@ -10248,7 +10248,7 @@ packages:
|
|||||||
/axios/0.21.3_debug@4.3.4:
|
/axios/0.21.3_debug@4.3.4:
|
||||||
resolution: {integrity: sha512-JtoZ3Ndke/+Iwt5n+BgSli/3idTvpt5OjKyoCmz4LX5+lPiY5l7C1colYezhlxThjNa/NhngCUWZSZFypIFuaA==}
|
resolution: {integrity: sha512-JtoZ3Ndke/+Iwt5n+BgSli/3idTvpt5OjKyoCmz4LX5+lPiY5l7C1colYezhlxThjNa/NhngCUWZSZFypIFuaA==}
|
||||||
dependencies:
|
dependencies:
|
||||||
follow-redirects: 1.14.9_debug@4.3.4
|
follow-redirects: 1.14.9_debug@4.3.3
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- debug
|
- debug
|
||||||
dev: false
|
dev: false
|
||||||
@ -10256,7 +10256,7 @@ packages:
|
|||||||
/axios/0.25.0_debug@4.3.4:
|
/axios/0.25.0_debug@4.3.4:
|
||||||
resolution: {integrity: sha512-cD8FOb0tRH3uuEe6+evtAbgJtfxr7ly3fQjYcMcuPlgkwVS9xboaVIpcDV+cYQe+yGykgwZCs1pzjntcGa6l5g==}
|
resolution: {integrity: sha512-cD8FOb0tRH3uuEe6+evtAbgJtfxr7ly3fQjYcMcuPlgkwVS9xboaVIpcDV+cYQe+yGykgwZCs1pzjntcGa6l5g==}
|
||||||
dependencies:
|
dependencies:
|
||||||
follow-redirects: 1.14.9_debug@4.3.4
|
follow-redirects: 1.14.9_debug@4.3.3
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- debug
|
- debug
|
||||||
|
|
||||||
@ -25406,7 +25406,7 @@ packages:
|
|||||||
resolution: {integrity: sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==}
|
resolution: {integrity: sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==}
|
||||||
|
|
||||||
/truncate-utf8-bytes/1.0.2:
|
/truncate-utf8-bytes/1.0.2:
|
||||||
resolution: {integrity: sha1-QFkjkJWS1W94pYGENLC3hInKXys=}
|
resolution: {integrity: sha512-95Pu1QXQvruGEhv62XCMO3Mm90GscOCClvrIUwCM0PYOXK3kaF3l3sIHxx71ThJfcbM2O5Au6SO3AWCSEfW4mQ==}
|
||||||
dependencies:
|
dependencies:
|
||||||
utf8-byte-length: 1.0.4
|
utf8-byte-length: 1.0.4
|
||||||
dev: false
|
dev: false
|
||||||
@ -26157,7 +26157,7 @@ packages:
|
|||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/utf8-byte-length/1.0.4:
|
/utf8-byte-length/1.0.4:
|
||||||
resolution: {integrity: sha1-9F8VDExm7uloGGUFq5P8u4rWv2E=}
|
resolution: {integrity: sha512-4+wkEYLBbWxqTahEsWrhxepcoVOJ+1z5PGIjPZxRkytcdSUaNjIjBM7Xn8E+pdSuV7SzvWovBFA54FO0JSoqhA==}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/util-deprecate/1.0.2:
|
/util-deprecate/1.0.2:
|
||||||
|
Loading…
Reference in New Issue
Block a user