@verdaccio/middleware 6.0.0-6-next.39 → 6.0.0-6-next.41
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +21 -0
- package/build/middlewares/web/render-web.js +6 -22
- package/build/middlewares/web/render-web.js.map +1 -1
- package/build/middlewares/web/utils/renderHTML.d.ts +0 -5
- package/build/middlewares/web/utils/renderHTML.js +4 -13
- package/build/middlewares/web/utils/renderHTML.js.map +1 -1
- package/package.json +7 -7
- package/src/middlewares/web/render-web.ts +6 -19
- package/src/middlewares/web/utils/renderHTML.ts +5 -12
- package/test/config/dark-logo.png +0 -0
- package/test/config/file-logo.yaml +24 -0
- package/test/config/login-disabled.yaml +1 -0
- package/test/config/no-logo.yaml +24 -0
- package/test/config/web.yaml +2 -1
- package/test/config/wrong-logo.yaml +24 -0
- package/test/render.spec.ts +27 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,26 @@
|
|
|
1
1
|
# @verdaccio/middleware
|
|
2
2
|
|
|
3
|
+
## 6.0.0-6-next.41
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 4fc21146: fix: missing logo on header
|
|
8
|
+
- Updated dependencies [378e907d]
|
|
9
|
+
- @verdaccio/core@6.0.0-6-next.62
|
|
10
|
+
- @verdaccio/url@11.0.0-6-next.28
|
|
11
|
+
- @verdaccio/config@6.0.0-6-next.62
|
|
12
|
+
- @verdaccio/utils@6.0.0-6-next.30
|
|
13
|
+
|
|
14
|
+
## 6.0.0-6-next.40
|
|
15
|
+
|
|
16
|
+
### Patch Changes
|
|
17
|
+
|
|
18
|
+
- Updated dependencies [d167f92e]
|
|
19
|
+
- @verdaccio/config@6.0.0-6-next.61
|
|
20
|
+
- @verdaccio/core@6.0.0-6-next.61
|
|
21
|
+
- @verdaccio/url@11.0.0-6-next.27
|
|
22
|
+
- @verdaccio/utils@6.0.0-6-next.29
|
|
23
|
+
|
|
3
24
|
## 6.0.0-6-next.39
|
|
4
25
|
|
|
5
26
|
### Minor Changes
|
|
@@ -11,9 +11,7 @@ var _path = _interopRequireDefault(require("path"));
|
|
|
11
11
|
var _core = require("@verdaccio/core");
|
|
12
12
|
var _url = require("@verdaccio/url");
|
|
13
13
|
var _security = require("./security");
|
|
14
|
-
var _renderHTML =
|
|
15
|
-
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
16
|
-
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
14
|
+
var _renderHTML = _interopRequireDefault(require("./utils/renderHTML"));
|
|
17
15
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
18
16
|
const debug = (0, _debug.default)('verdaccio:web:render');
|
|
19
17
|
const sendFileCallback = next => err => {
|
|
@@ -27,7 +25,7 @@ const sendFileCallback = next => err => {
|
|
|
27
25
|
}
|
|
28
26
|
};
|
|
29
27
|
function renderWebMiddleware(config, tokenMiddleware, pluginOptions) {
|
|
30
|
-
var _config$web
|
|
28
|
+
var _config$web, _config$web2;
|
|
31
29
|
const {
|
|
32
30
|
staticPath,
|
|
33
31
|
manifest,
|
|
@@ -42,21 +40,7 @@ function renderWebMiddleware(config, tokenMiddleware, pluginOptions) {
|
|
|
42
40
|
}
|
|
43
41
|
router.use(_security.setSecurityWebHeaders);
|
|
44
42
|
|
|
45
|
-
//
|
|
46
|
-
let logoURI = (_config$web$logo = config === null || config === void 0 ? void 0 : (_config$web = config.web) === null || _config$web === void 0 ? void 0 : _config$web.logo) !== null && _config$web$logo !== void 0 ? _config$web$logo : '';
|
|
47
|
-
if (logoURI && !(0, _url.isURLhasValidProtocol)(logoURI)) {
|
|
48
|
-
// URI related to a local file
|
|
49
|
-
|
|
50
|
-
// Note: `path.join` will break on Windows, because it transforms `/` to `\`
|
|
51
|
-
// Use POSIX version `path.posix.join` instead.
|
|
52
|
-
logoURI = _path.default.posix.join('/-/static/', _path.default.basename(logoURI));
|
|
53
|
-
router.get(logoURI, function (req, res, next) {
|
|
54
|
-
res.sendFile(_path.default.resolve(config.web.logo), sendFileCallback(next));
|
|
55
|
-
debug('render static');
|
|
56
|
-
});
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
// Static
|
|
43
|
+
// any match within the static is routed to the file system
|
|
60
44
|
router.get('/-/static/*', function (req, res, next) {
|
|
61
45
|
const filename = req.params[0];
|
|
62
46
|
const file = `${staticPath}/${filename}`;
|
|
@@ -64,13 +48,13 @@ function renderWebMiddleware(config, tokenMiddleware, pluginOptions) {
|
|
|
64
48
|
res.sendFile(file, sendFileCallback(next));
|
|
65
49
|
});
|
|
66
50
|
|
|
67
|
-
// logo
|
|
68
|
-
if (config !== null && config !== void 0 && (_config$
|
|
51
|
+
// check the origin of the logo
|
|
52
|
+
if (config !== null && config !== void 0 && (_config$web = config.web) !== null && _config$web !== void 0 && _config$web.logo && !(0, _url.isURLhasValidProtocol)(config === null || config === void 0 ? void 0 : (_config$web2 = config.web) === null || _config$web2 === void 0 ? void 0 : _config$web2.logo)) {
|
|
69
53
|
// URI related to a local file
|
|
70
54
|
const absoluteLocalFile = _path.default.posix.resolve(config.web.logo);
|
|
71
55
|
debug('serve local logo %s', absoluteLocalFile);
|
|
72
56
|
try {
|
|
73
|
-
// TODO:
|
|
57
|
+
// TODO: replace existsSync by async alternative
|
|
74
58
|
if (_fs.default.existsSync(absoluteLocalFile) && typeof _fs.default.accessSync(absoluteLocalFile, _fs.default.constants.R_OK) === 'undefined') {
|
|
75
59
|
// Note: `path.join` will break on Windows, because it transforms `/` to `\`
|
|
76
60
|
// Use POSIX version `path.posix.join` instead.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"render-web.js","names":["debug","buildDebug","sendFileCallback","next","err","status","HTTP_STATUS","NOT_FOUND","renderWebMiddleware","config","tokenMiddleware","pluginOptions","staticPath","manifest","manifestFiles","router","express","Router","use","setSecurityWebHeaders","
|
|
1
|
+
{"version":3,"file":"render-web.js","names":["debug","buildDebug","sendFileCallback","next","err","status","HTTP_STATUS","NOT_FOUND","renderWebMiddleware","config","tokenMiddleware","pluginOptions","staticPath","manifest","manifestFiles","router","express","Router","use","setSecurityWebHeaders","get","req","res","filename","params","file","sendFile","web","logo","isURLhasValidProtocol","absoluteLocalFile","path","posix","resolve","fs","existsSync","accessSync","constants","R_OK","join","basename","_req","undefined","renderHTML"],"sources":["../../../src/middlewares/web/render-web.ts"],"sourcesContent":["import buildDebug from 'debug';\nimport express from 'express';\nimport fs from 'fs';\nimport path from 'path';\n\nimport { HTTP_STATUS } from '@verdaccio/core';\nimport { isURLhasValidProtocol } from '@verdaccio/url';\n\nimport { setSecurityWebHeaders } from './security';\nimport renderHTML from './utils/renderHTML';\n\nconst debug = buildDebug('verdaccio:web:render');\n\nconst sendFileCallback = (next) => (err) => {\n if (!err) {\n return;\n }\n if (err.status === HTTP_STATUS.NOT_FOUND) {\n next();\n } else {\n next(err);\n }\n};\n\nexport function renderWebMiddleware(config, tokenMiddleware, pluginOptions) {\n const { staticPath, manifest, manifestFiles } = pluginOptions;\n debug('static path %o', staticPath);\n\n /* eslint new-cap:off */\n const router = express.Router();\n if (typeof tokenMiddleware === 'function') {\n router.use(tokenMiddleware);\n }\n\n router.use(setSecurityWebHeaders);\n\n // any match within the static is routed to the file system\n router.get('/-/static/*', function (req, res, next) {\n const filename = req.params[0];\n const file = `${staticPath}/${filename}`;\n debug('render static file %o', file);\n res.sendFile(file, sendFileCallback(next));\n });\n\n // check the origin of the logo\n if (config?.web?.logo && !isURLhasValidProtocol(config?.web?.logo)) {\n // URI related to a local file\n const absoluteLocalFile = path.posix.resolve(config.web.logo);\n debug('serve local logo %s', absoluteLocalFile);\n try {\n // TODO: replace existsSync by async alternative\n if (\n fs.existsSync(absoluteLocalFile) &&\n typeof fs.accessSync(absoluteLocalFile, fs.constants.R_OK) === 'undefined'\n ) {\n // Note: `path.join` will break on Windows, because it transforms `/` to `\\`\n // Use POSIX version `path.posix.join` instead.\n config.web.logo = path.posix.join('/-/static/', path.basename(config.web.logo));\n router.get(config.web.logo, function (_req, res, next) {\n // @ts-ignore\n debug('serve custom logo web:%s - local:%s', config.web.logo, absoluteLocalFile);\n res.sendFile(absoluteLocalFile, sendFileCallback(next));\n });\n debug('enabled custom logo %s', config.web.logo);\n } else {\n config.web.logo = undefined;\n debug(`web logo is wrong, path ${absoluteLocalFile} does not exist or is not readable`);\n }\n } catch {\n config.web.logo = undefined;\n debug(`web logo is wrong, path ${absoluteLocalFile} does not exist or is not readable`);\n }\n }\n\n router.get('/-/web/:section/*', function (req, res) {\n renderHTML(config, manifest, manifestFiles, req, res);\n debug('render html section');\n });\n\n router.get('/', function (req, res) {\n renderHTML(config, manifest, manifestFiles, req, res);\n debug('render root');\n });\n\n return router;\n}\n"],"mappings":"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"}
|
|
@@ -1,7 +1,2 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Check if URI is starting with "http://", "https://" or "//"
|
|
3
|
-
* @param {string} uri
|
|
4
|
-
*/
|
|
5
|
-
export declare function isHTTPProtocol(uri: string): boolean;
|
|
6
1
|
export declare function resolveLogo(config: any, req: any): any;
|
|
7
2
|
export default function renderHTML(config: any, manifest: any, manifestFiles: any, req: any, res: any): void;
|
|
@@ -4,7 +4,6 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = renderHTML;
|
|
7
|
-
exports.isHTTPProtocol = isHTTPProtocol;
|
|
8
7
|
exports.resolveLogo = resolveLogo;
|
|
9
8
|
var _debug = _interopRequireDefault(require("debug"));
|
|
10
9
|
var _lruCache = _interopRequireDefault(require("lru-cache"));
|
|
@@ -26,21 +25,13 @@ const defaultManifestFiles = {
|
|
|
26
25
|
js: ['runtime.js', 'vendors.js', 'main.js'],
|
|
27
26
|
ico: 'favicon.ico'
|
|
28
27
|
};
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Check if URI is starting with "http://", "https://" or "//"
|
|
32
|
-
* @param {string} uri
|
|
33
|
-
*/
|
|
34
|
-
function isHTTPProtocol(uri) {
|
|
35
|
-
return /^(https?:)?\/\//.test(uri);
|
|
36
|
-
}
|
|
37
28
|
function resolveLogo(config, req) {
|
|
38
29
|
var _config$web, _config$web2, _config$web4;
|
|
39
|
-
const isLocalFile = (config === null || config === void 0 ? void 0 : (_config$web = config.web) === null || _config$web === void 0 ? void 0 : _config$web.logo) && !
|
|
30
|
+
const isLocalFile = (config === null || config === void 0 ? void 0 : (_config$web = config.web) === null || _config$web === void 0 ? void 0 : _config$web.logo) && !(0, _url2.isURLhasValidProtocol)(config === null || config === void 0 ? void 0 : (_config$web2 = config.web) === null || _config$web2 === void 0 ? void 0 : _config$web2.logo);
|
|
40
31
|
if (isLocalFile) {
|
|
41
32
|
var _config$web3;
|
|
42
33
|
return `${(0, _url2.getPublicUrl)(config === null || config === void 0 ? void 0 : config.url_prefix, req)}-/static/${_path.default.basename(config === null || config === void 0 ? void 0 : (_config$web3 = config.web) === null || _config$web3 === void 0 ? void 0 : _config$web3.logo)}`;
|
|
43
|
-
} else if (
|
|
34
|
+
} else if ((0, _url2.isURLhasValidProtocol)(config === null || config === void 0 ? void 0 : (_config$web4 = config.web) === null || _config$web4 === void 0 ? void 0 : _config$web4.logo)) {
|
|
44
35
|
var _config$web5;
|
|
45
36
|
return config === null || config === void 0 ? void 0 : (_config$web5 = config.web) === null || _config$web5 === void 0 ? void 0 : _config$web5.logo;
|
|
46
37
|
} else {
|
|
@@ -60,7 +51,7 @@ function renderHTML(config, manifest, manifestFiles, req, res) {
|
|
|
60
51
|
const title = (_config$web$title = config === null || config === void 0 ? void 0 : (_config$web8 = config.web) === null || _config$web8 === void 0 ? void 0 : _config$web8.title) !== null && _config$web$title !== void 0 ? _config$web$title : _config.WEB_TITLE;
|
|
61
52
|
const login = (0, _webUtils.hasLogin)(config);
|
|
62
53
|
const scope = (_config$web$scope = config === null || config === void 0 ? void 0 : (_config$web9 = config.web) === null || _config$web9 === void 0 ? void 0 : _config$web9.scope) !== null && _config$web$scope !== void 0 ? _config$web$scope : '';
|
|
63
|
-
const
|
|
54
|
+
const logo = resolveLogo(config, req);
|
|
64
55
|
const pkgManagers = (_config$web$pkgManage = config === null || config === void 0 ? void 0 : (_config$web10 = config.web) === null || _config$web10 === void 0 ? void 0 : _config$web10.pkgManagers) !== null && _config$web$pkgManage !== void 0 ? _config$web$pkgManage : ['yarn', 'pnpm', 'npm'];
|
|
65
56
|
const version = config === null || config === void 0 ? void 0 : (_config$web11 = config.web) === null || _config$web11 === void 0 ? void 0 : _config$web11.version;
|
|
66
57
|
const flags = {
|
|
@@ -97,7 +88,7 @@ function renderHTML(config, manifest, manifestFiles, req, res) {
|
|
|
97
88
|
base,
|
|
98
89
|
primaryColor,
|
|
99
90
|
version,
|
|
100
|
-
|
|
91
|
+
logo,
|
|
101
92
|
flags,
|
|
102
93
|
login,
|
|
103
94
|
pkgManagers,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"renderHTML.js","names":["DEFAULT_LANGUAGE","cache","LRU","max","ttl","debug","buildDebug","defaultManifestFiles","js","ico","
|
|
1
|
+
{"version":3,"file":"renderHTML.js","names":["DEFAULT_LANGUAGE","cache","LRU","max","ttl","debug","buildDebug","defaultManifestFiles","js","ico","resolveLogo","config","req","isLocalFile","web","logo","isURLhasValidProtocol","getPublicUrl","url_prefix","path","basename","renderHTML","manifest","manifestFiles","res","base","URL","pathname","language","i18n","needHtmlCache","undefined","includes","html_cache","darkMode","title","WEB_TITLE","login","hasLogin","scope","pkgManagers","version","flags","experiments","primaryColor","validatePrimaryColor","primary_color","scriptsBodyAfter","metaScripts","scriptsbodyBefore","showInfo","showSettings","showThemeSwitch","showFooter","showSearch","showDownloadTarball","Object","assign","bodyBefore","options","webPage","get","renderTemplate","set","error","Error","stack","setHeader","HEADERS","TEXT_HTML","send"],"sources":["../../../../src/middlewares/web/utils/renderHTML.ts"],"sourcesContent":["import buildDebug from 'debug';\nimport LRU from 'lru-cache';\nimport path from 'path';\nimport { URL } from 'url';\n\nimport { WEB_TITLE } from '@verdaccio/config';\nimport { HEADERS } from '@verdaccio/core';\nimport { TemplateUIOptions } from '@verdaccio/types';\nimport { isURLhasValidProtocol } from '@verdaccio/url';\nimport { getPublicUrl } from '@verdaccio/url';\n\nimport renderTemplate from './template';\nimport { hasLogin, validatePrimaryColor } from './web-utils';\n\nconst DEFAULT_LANGUAGE = 'es-US';\nconst cache = new LRU({ max: 500, ttl: 1000 * 60 * 60 });\n\nconst debug = buildDebug('verdaccio:web:render');\n\nconst defaultManifestFiles = {\n js: ['runtime.js', 'vendors.js', 'main.js'],\n ico: 'favicon.ico',\n};\n\nexport function resolveLogo(config, req) {\n const isLocalFile = config?.web?.logo && !isURLhasValidProtocol(config?.web?.logo);\n\n if (isLocalFile) {\n return `${getPublicUrl(config?.url_prefix, req)}-/static/${path.basename(config?.web?.logo)}`;\n } else if (isURLhasValidProtocol(config?.web?.logo)) {\n return config?.web?.logo;\n } else {\n return '';\n }\n}\n\nexport default function renderHTML(config, manifest, manifestFiles, req, res) {\n const { url_prefix } = config;\n const base = getPublicUrl(config?.url_prefix, req);\n const basename = new URL(base).pathname;\n const language = config?.i18n?.web ?? DEFAULT_LANGUAGE;\n const needHtmlCache = [undefined, null].includes(config?.web?.html_cache)\n ? true\n : config.web.html_cache;\n const darkMode = config?.web?.darkMode ?? false;\n const title = config?.web?.title ?? WEB_TITLE;\n const login = hasLogin(config);\n const scope = config?.web?.scope ?? '';\n const logo = resolveLogo(config, req);\n const pkgManagers = config?.web?.pkgManagers ?? ['yarn', 'pnpm', 'npm'];\n const version = config?.web?.version;\n const flags = {\n ...config.flags,\n // legacy from 5.x\n ...config.experiments,\n };\n const primaryColor = validatePrimaryColor(config?.web?.primary_color) ?? '#4b5e40';\n const {\n scriptsBodyAfter,\n metaScripts,\n scriptsbodyBefore,\n showInfo,\n showSettings,\n showThemeSwitch,\n showFooter,\n showSearch,\n showDownloadTarball,\n } = Object.assign(\n {},\n {\n scriptsBodyAfter: [],\n bodyBefore: [],\n metaScripts: [],\n },\n config?.web\n );\n const options: TemplateUIOptions = {\n showInfo,\n showSettings,\n showThemeSwitch,\n showFooter,\n showSearch,\n showDownloadTarball,\n darkMode,\n url_prefix,\n basename,\n base,\n primaryColor,\n version,\n logo,\n flags,\n login,\n pkgManagers,\n title,\n scope,\n language,\n };\n\n let webPage;\n\n try {\n webPage = cache.get('template');\n if (!webPage) {\n webPage = renderTemplate(\n {\n manifest: manifestFiles ?? defaultManifestFiles,\n options,\n scriptsBodyAfter,\n metaScripts,\n scriptsbodyBefore,\n },\n manifest\n );\n if (needHtmlCache) {\n cache.set('template', webPage);\n debug('set template cache');\n }\n } else {\n debug('reuse template cache');\n }\n } catch (error: any) {\n throw new Error(`theme could not be load, stack ${error.stack}`);\n }\n res.setHeader('Content-Type', HEADERS.TEXT_HTML);\n res.send(webPage);\n debug('web rendered');\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@verdaccio/middleware",
|
|
3
|
-
"version": "6.0.0-6-next.
|
|
3
|
+
"version": "6.0.0-6-next.41",
|
|
4
4
|
"description": "express middleware utils",
|
|
5
5
|
"main": "./build/index.js",
|
|
6
6
|
"types": "build/index.d.ts",
|
|
@@ -29,12 +29,12 @@
|
|
|
29
29
|
"node": ">=12"
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@verdaccio/core": "6.0.0-6-next.
|
|
33
|
-
"@verdaccio/utils": "6.0.0-6-next.
|
|
34
|
-
"@verdaccio/config": "6.0.0-6-next.
|
|
35
|
-
"@verdaccio/url": "11.0.0-6-next.
|
|
32
|
+
"@verdaccio/core": "6.0.0-6-next.62",
|
|
33
|
+
"@verdaccio/utils": "6.0.0-6-next.30",
|
|
34
|
+
"@verdaccio/config": "6.0.0-6-next.62",
|
|
35
|
+
"@verdaccio/url": "11.0.0-6-next.28",
|
|
36
36
|
"debug": "4.3.4",
|
|
37
|
-
"lru-cache": "7.
|
|
37
|
+
"lru-cache": "7.16.1",
|
|
38
38
|
"express": "4.18.2",
|
|
39
39
|
"lodash": "4.17.21",
|
|
40
40
|
"mime": "2.6.0",
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"url": "https://opencollective.com/verdaccio"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
|
-
"@verdaccio/logger": "6.0.0-6-next.
|
|
48
|
+
"@verdaccio/logger": "6.0.0-6-next.30",
|
|
49
49
|
"body-parser": "1.20.1",
|
|
50
50
|
"supertest": "6.3.3"
|
|
51
51
|
},
|
|
@@ -7,7 +7,7 @@ import { HTTP_STATUS } from '@verdaccio/core';
|
|
|
7
7
|
import { isURLhasValidProtocol } from '@verdaccio/url';
|
|
8
8
|
|
|
9
9
|
import { setSecurityWebHeaders } from './security';
|
|
10
|
-
import renderHTML
|
|
10
|
+
import renderHTML from './utils/renderHTML';
|
|
11
11
|
|
|
12
12
|
const debug = buildDebug('verdaccio:web:render');
|
|
13
13
|
|
|
@@ -31,23 +31,10 @@ export function renderWebMiddleware(config, tokenMiddleware, pluginOptions) {
|
|
|
31
31
|
if (typeof tokenMiddleware === 'function') {
|
|
32
32
|
router.use(tokenMiddleware);
|
|
33
33
|
}
|
|
34
|
-
router.use(setSecurityWebHeaders);
|
|
35
|
-
|
|
36
|
-
// Logo
|
|
37
|
-
let logoURI = config?.web?.logo ?? '';
|
|
38
|
-
if (logoURI && !isURLhasValidProtocol(logoURI)) {
|
|
39
|
-
// URI related to a local file
|
|
40
34
|
|
|
41
|
-
|
|
42
|
-
// Use POSIX version `path.posix.join` instead.
|
|
43
|
-
logoURI = path.posix.join('/-/static/', path.basename(logoURI));
|
|
44
|
-
router.get(logoURI, function (req, res, next) {
|
|
45
|
-
res.sendFile(path.resolve(config.web.logo), sendFileCallback(next));
|
|
46
|
-
debug('render static');
|
|
47
|
-
});
|
|
48
|
-
}
|
|
35
|
+
router.use(setSecurityWebHeaders);
|
|
49
36
|
|
|
50
|
-
//
|
|
37
|
+
// any match within the static is routed to the file system
|
|
51
38
|
router.get('/-/static/*', function (req, res, next) {
|
|
52
39
|
const filename = req.params[0];
|
|
53
40
|
const file = `${staticPath}/${filename}`;
|
|
@@ -55,13 +42,13 @@ export function renderWebMiddleware(config, tokenMiddleware, pluginOptions) {
|
|
|
55
42
|
res.sendFile(file, sendFileCallback(next));
|
|
56
43
|
});
|
|
57
44
|
|
|
58
|
-
// logo
|
|
59
|
-
if (config?.web?.logo && !
|
|
45
|
+
// check the origin of the logo
|
|
46
|
+
if (config?.web?.logo && !isURLhasValidProtocol(config?.web?.logo)) {
|
|
60
47
|
// URI related to a local file
|
|
61
48
|
const absoluteLocalFile = path.posix.resolve(config.web.logo);
|
|
62
49
|
debug('serve local logo %s', absoluteLocalFile);
|
|
63
50
|
try {
|
|
64
|
-
// TODO:
|
|
51
|
+
// TODO: replace existsSync by async alternative
|
|
65
52
|
if (
|
|
66
53
|
fs.existsSync(absoluteLocalFile) &&
|
|
67
54
|
typeof fs.accessSync(absoluteLocalFile, fs.constants.R_OK) === 'undefined'
|
|
@@ -6,6 +6,7 @@ import { URL } from 'url';
|
|
|
6
6
|
import { WEB_TITLE } from '@verdaccio/config';
|
|
7
7
|
import { HEADERS } from '@verdaccio/core';
|
|
8
8
|
import { TemplateUIOptions } from '@verdaccio/types';
|
|
9
|
+
import { isURLhasValidProtocol } from '@verdaccio/url';
|
|
9
10
|
import { getPublicUrl } from '@verdaccio/url';
|
|
10
11
|
|
|
11
12
|
import renderTemplate from './template';
|
|
@@ -21,20 +22,12 @@ const defaultManifestFiles = {
|
|
|
21
22
|
ico: 'favicon.ico',
|
|
22
23
|
};
|
|
23
24
|
|
|
24
|
-
/**
|
|
25
|
-
* Check if URI is starting with "http://", "https://" or "//"
|
|
26
|
-
* @param {string} uri
|
|
27
|
-
*/
|
|
28
|
-
export function isHTTPProtocol(uri: string): boolean {
|
|
29
|
-
return /^(https?:)?\/\//.test(uri);
|
|
30
|
-
}
|
|
31
|
-
|
|
32
25
|
export function resolveLogo(config, req) {
|
|
33
|
-
const isLocalFile = config?.web?.logo && !
|
|
26
|
+
const isLocalFile = config?.web?.logo && !isURLhasValidProtocol(config?.web?.logo);
|
|
34
27
|
|
|
35
28
|
if (isLocalFile) {
|
|
36
29
|
return `${getPublicUrl(config?.url_prefix, req)}-/static/${path.basename(config?.web?.logo)}`;
|
|
37
|
-
} else if (
|
|
30
|
+
} else if (isURLhasValidProtocol(config?.web?.logo)) {
|
|
38
31
|
return config?.web?.logo;
|
|
39
32
|
} else {
|
|
40
33
|
return '';
|
|
@@ -53,7 +46,7 @@ export default function renderHTML(config, manifest, manifestFiles, req, res) {
|
|
|
53
46
|
const title = config?.web?.title ?? WEB_TITLE;
|
|
54
47
|
const login = hasLogin(config);
|
|
55
48
|
const scope = config?.web?.scope ?? '';
|
|
56
|
-
const
|
|
49
|
+
const logo = resolveLogo(config, req);
|
|
57
50
|
const pkgManagers = config?.web?.pkgManagers ?? ['yarn', 'pnpm', 'npm'];
|
|
58
51
|
const version = config?.web?.version;
|
|
59
52
|
const flags = {
|
|
@@ -94,7 +87,7 @@ export default function renderHTML(config, manifest, manifestFiles, req, res) {
|
|
|
94
87
|
base,
|
|
95
88
|
primaryColor,
|
|
96
89
|
version,
|
|
97
|
-
|
|
90
|
+
logo,
|
|
98
91
|
flags,
|
|
99
92
|
login,
|
|
100
93
|
pkgManagers,
|
|
Binary file
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
web:
|
|
2
|
+
title: verdaccio web
|
|
3
|
+
login: true
|
|
4
|
+
scope: '@scope'
|
|
5
|
+
pkgManagers:
|
|
6
|
+
- pnpm
|
|
7
|
+
- yarn
|
|
8
|
+
showInfo: true
|
|
9
|
+
showSettings: true
|
|
10
|
+
showSearch: true
|
|
11
|
+
showFooter: true
|
|
12
|
+
showThemeSwitch: true
|
|
13
|
+
showDownloadTarball: true
|
|
14
|
+
showRaw: true
|
|
15
|
+
primary_color: '#ffffff'
|
|
16
|
+
logo: './test/config/dark-logo.png'
|
|
17
|
+
html_cache: false
|
|
18
|
+
|
|
19
|
+
url_prefix: /prefix
|
|
20
|
+
|
|
21
|
+
log: { type: stdout, format: pretty, level: trace }
|
|
22
|
+
|
|
23
|
+
flags:
|
|
24
|
+
changePassword: true
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
web:
|
|
2
|
+
title: verdaccio web
|
|
3
|
+
login: true
|
|
4
|
+
scope: '@scope'
|
|
5
|
+
pkgManagers:
|
|
6
|
+
- pnpm
|
|
7
|
+
- yarn
|
|
8
|
+
showInfo: true
|
|
9
|
+
showSettings: true
|
|
10
|
+
showSearch: true
|
|
11
|
+
showFooter: true
|
|
12
|
+
showThemeSwitch: true
|
|
13
|
+
showDownloadTarball: true
|
|
14
|
+
showRaw: true
|
|
15
|
+
primary_color: '#ffffff'
|
|
16
|
+
logo:
|
|
17
|
+
html_cache: false
|
|
18
|
+
|
|
19
|
+
url_prefix: /prefix
|
|
20
|
+
|
|
21
|
+
log: { type: stdout, format: pretty, level: trace }
|
|
22
|
+
|
|
23
|
+
flags:
|
|
24
|
+
changePassword: true
|
package/test/config/web.yaml
CHANGED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
web:
|
|
2
|
+
title: verdaccio web
|
|
3
|
+
login: true
|
|
4
|
+
scope: '@scope'
|
|
5
|
+
pkgManagers:
|
|
6
|
+
- pnpm
|
|
7
|
+
- yarn
|
|
8
|
+
showInfo: true
|
|
9
|
+
showSettings: true
|
|
10
|
+
showSearch: true
|
|
11
|
+
showFooter: true
|
|
12
|
+
showThemeSwitch: true
|
|
13
|
+
showDownloadTarball: true
|
|
14
|
+
showRaw: true
|
|
15
|
+
primary_color: '#ffffff'
|
|
16
|
+
logo: './does_not_exist/config/dark-logo.png'
|
|
17
|
+
html_cache: false
|
|
18
|
+
|
|
19
|
+
url_prefix: /prefix
|
|
20
|
+
|
|
21
|
+
log: { type: stdout, format: pretty, level: trace }
|
|
22
|
+
|
|
23
|
+
flags:
|
|
24
|
+
changePassword: true
|
package/test/render.spec.ts
CHANGED
|
@@ -37,6 +37,10 @@ describe('test web server', () => {
|
|
|
37
37
|
return new JSDOM(response.text, { runScripts: 'dangerously' });
|
|
38
38
|
};
|
|
39
39
|
|
|
40
|
+
const loadLogo = async (config = 'default-test.yaml', url) => {
|
|
41
|
+
return supertest(initializeServer(config)).get(url).expect(HTTP_STATUS.OK);
|
|
42
|
+
};
|
|
43
|
+
|
|
40
44
|
test('should match render set ui properties', async () => {
|
|
41
45
|
const {
|
|
42
46
|
window: { __VERDACCIO_BASENAME_UI_OPTIONS },
|
|
@@ -56,7 +60,7 @@ describe('test web server', () => {
|
|
|
56
60
|
// FIXME: mock these values, avoid random
|
|
57
61
|
// base: 'http://127.0.0.1:60864/prefix/',
|
|
58
62
|
// version: '6.0.0-6-next.28',
|
|
59
|
-
|
|
63
|
+
logo: 'http://logo.org/logo.png',
|
|
60
64
|
flags: { changePassword: true },
|
|
61
65
|
login: true,
|
|
62
66
|
pkgManagers: ['pnpm', 'yarn'],
|
|
@@ -67,6 +71,28 @@ describe('test web server', () => {
|
|
|
67
71
|
);
|
|
68
72
|
});
|
|
69
73
|
|
|
74
|
+
test('should render logo as file', async () => {
|
|
75
|
+
const {
|
|
76
|
+
window: { __VERDACCIO_BASENAME_UI_OPTIONS },
|
|
77
|
+
} = await render('file-logo.yaml');
|
|
78
|
+
expect(__VERDACCIO_BASENAME_UI_OPTIONS.logo).toMatch('/prefix/-/static/dark-logo.png');
|
|
79
|
+
return loadLogo('file-logo.yaml', '/-/static/dark-logo.png');
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
test('should not render logo as absolute file is wrong', async () => {
|
|
83
|
+
const {
|
|
84
|
+
window: { __VERDACCIO_BASENAME_UI_OPTIONS },
|
|
85
|
+
} = await render('wrong-logo.yaml');
|
|
86
|
+
expect(__VERDACCIO_BASENAME_UI_OPTIONS.logo).toEqual('');
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
test('should render not render a logo', async () => {
|
|
90
|
+
const {
|
|
91
|
+
window: { __VERDACCIO_BASENAME_UI_OPTIONS },
|
|
92
|
+
} = await render('no-logo.yaml');
|
|
93
|
+
expect(__VERDACCIO_BASENAME_UI_OPTIONS.logo).toEqual('');
|
|
94
|
+
});
|
|
95
|
+
|
|
70
96
|
test.todo('should default title');
|
|
71
97
|
test.todo('should need html cache');
|
|
72
98
|
});
|