mirror of
https://github.com/verdaccio/verdaccio.git
synced 2024-12-30 22:34:10 -05:00
refactor: pass options instead request object (#2605)
This commit is contained in:
parent
1322ffc2c4
commit
16458f801e
11 changed files with 163 additions and 40 deletions
|
@ -40,7 +40,7 @@ export default function (route: Router, auth: IAuth, storage: Storage, config: C
|
|||
route.get(
|
||||
'/:package/:version?',
|
||||
can('access'),
|
||||
function (req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer): void {
|
||||
function (req: $RequestExtend, _res: $ResponseExtend, next: $NextFunctionVer): void {
|
||||
debug('init package by version');
|
||||
const name = req.params.package;
|
||||
const getPackageMetaCallback = function (err, metadata: Package): void {
|
||||
|
@ -49,7 +49,11 @@ export default function (route: Router, auth: IAuth, storage: Storage, config: C
|
|||
return next(err);
|
||||
}
|
||||
debug('convert dist remote to local with prefix %o', config?.url_prefix);
|
||||
metadata = convertDistRemoteToLocalTarballUrls(metadata, req, config?.url_prefix);
|
||||
metadata = convertDistRemoteToLocalTarballUrls(
|
||||
metadata,
|
||||
{ protocol: req.protocol, headers: req.headers as any, host: req.host },
|
||||
config?.url_prefix
|
||||
);
|
||||
|
||||
let queryVersion = req.params.version;
|
||||
debug('query by param version: %o', queryVersion);
|
||||
|
|
|
@ -41,7 +41,6 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@verdaccio/types": "workspace:11.0.0-6-next.9",
|
||||
"express": "4.17.1",
|
||||
"node-mocks-http": "1.10.1"
|
||||
},
|
||||
"scripts": {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { Package } from '@verdaccio/types';
|
||||
import { Request } from 'express';
|
||||
import { RequestOptions } from '@verdaccio/url';
|
||||
import _ from 'lodash';
|
||||
|
||||
import { getLocalRegistryTarballUri } from './getLocalRegistryTarballUri';
|
||||
|
@ -13,7 +13,7 @@ import { getLocalRegistryTarballUri } from './getLocalRegistryTarballUri';
|
|||
*/
|
||||
export function convertDistRemoteToLocalTarballUrls(
|
||||
pkg: Package,
|
||||
req: Request,
|
||||
request: RequestOptions,
|
||||
urlPrefix: string | void
|
||||
): Package {
|
||||
for (const ver in pkg.versions) {
|
||||
|
@ -21,7 +21,12 @@ export function convertDistRemoteToLocalTarballUrls(
|
|||
const distName = pkg.versions[ver].dist;
|
||||
|
||||
if (_.isNull(distName) === false && _.isNull(distName.tarball) === false) {
|
||||
distName.tarball = getLocalRegistryTarballUri(distName.tarball, pkg.name, req, urlPrefix);
|
||||
distName.tarball = getLocalRegistryTarballUri(
|
||||
distName.tarball,
|
||||
pkg.name,
|
||||
request,
|
||||
urlPrefix
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
import URL from 'url';
|
||||
import { Request } from 'express';
|
||||
import { RequestOptions } from '@verdaccio/url';
|
||||
import buildDebug from 'debug';
|
||||
|
||||
import { getPublicUrl } from '@verdaccio/url';
|
||||
|
||||
const debug = buildDebug('verdaccio:core:url');
|
||||
|
||||
function extractTarballFromUrl(url: string): string {
|
||||
export function extractTarballFromUrl(url: string): string {
|
||||
// @ts-ignore
|
||||
return URL.parse(url).pathname.replace(/^.*\//, '');
|
||||
}
|
||||
|
@ -18,10 +18,10 @@ function extractTarballFromUrl(url: string): string {
|
|||
export function getLocalRegistryTarballUri(
|
||||
uri: string,
|
||||
pkgName: string,
|
||||
req: Request,
|
||||
requestOptions: RequestOptions,
|
||||
urlPrefix: string | void
|
||||
): string {
|
||||
const currentHost = req.headers.host;
|
||||
const currentHost = requestOptions?.headers?.host;
|
||||
|
||||
if (!currentHost) {
|
||||
return uri;
|
||||
|
@ -29,7 +29,7 @@ export function getLocalRegistryTarballUri(
|
|||
const tarballName = extractTarballFromUrl(uri);
|
||||
debug('tarball name %o', tarballName);
|
||||
// header only set with proxy that setup with HTTPS
|
||||
const domainRegistry = getPublicUrl(urlPrefix || '', req);
|
||||
const domainRegistry = getPublicUrl(urlPrefix || '', requestOptions);
|
||||
|
||||
return `${domainRegistry}${pkgName}/-/${tarballName}`;
|
||||
}
|
||||
|
|
|
@ -30,7 +30,11 @@ describe('convertDistRemoteToLocalTarballUrls', () => {
|
|||
},
|
||||
url: '/',
|
||||
});
|
||||
const convertDist = convertDistRemoteToLocalTarballUrls(cloneMetadata(), req);
|
||||
const convertDist = convertDistRemoteToLocalTarballUrls(cloneMetadata(), {
|
||||
host: req.hostname,
|
||||
headers: req.headers as any,
|
||||
protocol: req.protocol,
|
||||
});
|
||||
expect(convertDist.versions['1.0.0'].dist.tarball).toEqual(buildURI(fakeHost, '1.0.0'));
|
||||
expect(convertDist.versions['1.0.1'].dist.tarball).toEqual(buildURI(fakeHost, '1.0.1'));
|
||||
});
|
||||
|
@ -43,7 +47,11 @@ describe('convertDistRemoteToLocalTarballUrls', () => {
|
|||
},
|
||||
url: '/',
|
||||
});
|
||||
const convertDist = convertDistRemoteToLocalTarballUrls(cloneMetadata(), req);
|
||||
const convertDist = convertDistRemoteToLocalTarballUrls(cloneMetadata(), {
|
||||
host: req.hostname,
|
||||
headers: req.headers as any,
|
||||
protocol: req.protocol,
|
||||
});
|
||||
expect(convertDist.versions['1.0.0'].dist.tarball).toEqual(
|
||||
convertDist.versions['1.0.0'].dist.tarball
|
||||
);
|
||||
|
@ -57,7 +65,11 @@ describe('convertDistRemoteToLocalTarballUrls', () => {
|
|||
},
|
||||
url: '/',
|
||||
});
|
||||
const convertDist = convertDistRemoteToLocalTarballUrls(cloneMetadata(), req);
|
||||
const convertDist = convertDistRemoteToLocalTarballUrls(cloneMetadata(), {
|
||||
host: req.hostname,
|
||||
headers: req.headers as any,
|
||||
protocol: req.protocol,
|
||||
});
|
||||
expect(convertDist.versions['1.0.0'].dist.tarball).toEqual(
|
||||
convertDist.versions['1.0.0'].dist.tarball
|
||||
);
|
||||
|
|
|
@ -12,6 +12,9 @@
|
|||
},
|
||||
{
|
||||
"path": "../url"
|
||||
},
|
||||
{
|
||||
"path": "../core"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -88,18 +88,26 @@ export function validateURL(publicUrl: string | void) {
|
|||
}
|
||||
}
|
||||
|
||||
export function getPublicUrl(url_prefix: string = '', req): string {
|
||||
export type RequestOptions = {
|
||||
host: string;
|
||||
protocol: string;
|
||||
headers: { [key: string]: string };
|
||||
};
|
||||
|
||||
export function getPublicUrl(url_prefix: string = '', requestOptions: RequestOptions): string {
|
||||
if (validateURL(process.env.VERDACCIO_PUBLIC_URL as string)) {
|
||||
const envURL = new URL(wrapPrefix(url_prefix), process.env.VERDACCIO_PUBLIC_URL as string).href;
|
||||
debug('public url by env %o', envURL);
|
||||
return envURL;
|
||||
} else if (req.get('host')) {
|
||||
const host = req.get('host');
|
||||
} else if (requestOptions.headers['host']) {
|
||||
const host = requestOptions.headers['host'];
|
||||
if (!isHost(host)) {
|
||||
throw new Error('invalid host');
|
||||
}
|
||||
const protoHeader = process.env.VERDACCIO_FORWARDED_PROTO ?? HEADERS.FORWARDED_PROTO;
|
||||
const protocol = getWebProtocol(req.get(protoHeader), req.protocol);
|
||||
const protoHeader =
|
||||
process.env.VERDACCIO_FORWARDED_PROTO?.toLocaleLowerCase() ??
|
||||
HEADERS.FORWARDED_PROTO.toLowerCase();
|
||||
const protocol = getWebProtocol(requestOptions.headers[protoHeader], requestOptions.protocol);
|
||||
const combinedUrl = combineBaseUrl(protocol, host, url_prefix);
|
||||
debug('public url by request %o', combinedUrl);
|
||||
return combinedUrl;
|
||||
|
|
|
@ -11,7 +11,13 @@ describe('host', () => {
|
|||
method: 'GET',
|
||||
url: '/',
|
||||
});
|
||||
expect(getPublicUrl(undefined, req)).toEqual('/');
|
||||
expect(
|
||||
getPublicUrl(undefined, {
|
||||
host: req.hostname,
|
||||
headers: req.headers as any,
|
||||
protocol: req.protocol,
|
||||
})
|
||||
).toEqual('/');
|
||||
});
|
||||
|
||||
test('get a valid host', () => {
|
||||
|
@ -22,7 +28,13 @@ describe('host', () => {
|
|||
},
|
||||
url: '/',
|
||||
});
|
||||
expect(getPublicUrl(undefined, req)).toEqual('http://some.com/');
|
||||
expect(
|
||||
getPublicUrl(undefined, {
|
||||
host: req.hostname,
|
||||
headers: req.headers as any,
|
||||
protocol: req.protocol,
|
||||
})
|
||||
).toEqual('http://some.com/');
|
||||
});
|
||||
|
||||
test('check a valid host header injection', () => {
|
||||
|
@ -31,11 +43,15 @@ describe('host', () => {
|
|||
headers: {
|
||||
host: `some.com"><svg onload="alert(1)">`,
|
||||
},
|
||||
hostname: `some.com"><svg onload="alert(1)">`,
|
||||
url: '/',
|
||||
});
|
||||
expect(function () {
|
||||
// @ts-expect-error
|
||||
getPublicUrl({}, req);
|
||||
getPublicUrl('', {
|
||||
host: req.hostname,
|
||||
headers: req.headers as any,
|
||||
protocol: req.protocol,
|
||||
});
|
||||
}).toThrow('invalid host');
|
||||
});
|
||||
|
||||
|
@ -48,7 +64,13 @@ describe('host', () => {
|
|||
url: '/',
|
||||
});
|
||||
|
||||
expect(getPublicUrl('/prefix/', req)).toEqual('http://some.com/prefix/');
|
||||
expect(
|
||||
getPublicUrl('/prefix/', {
|
||||
host: req.hostname,
|
||||
headers: req.headers as any,
|
||||
protocol: req.protocol,
|
||||
})
|
||||
).toEqual('http://some.com/prefix/');
|
||||
});
|
||||
|
||||
test('get a valid host with prefix no trailing', () => {
|
||||
|
@ -60,7 +82,13 @@ describe('host', () => {
|
|||
url: '/',
|
||||
});
|
||||
|
||||
expect(getPublicUrl('/prefix-no-trailing', req)).toEqual('http://some.com/prefix-no-trailing/');
|
||||
expect(
|
||||
getPublicUrl('/prefix-no-trailing', {
|
||||
host: req.hostname,
|
||||
headers: req.headers as any,
|
||||
protocol: req.protocol,
|
||||
})
|
||||
).toEqual('http://some.com/prefix-no-trailing/');
|
||||
});
|
||||
|
||||
test('get a valid host with null prefix', () => {
|
||||
|
@ -72,7 +100,13 @@ describe('host', () => {
|
|||
url: '/',
|
||||
});
|
||||
|
||||
expect(getPublicUrl(null, req)).toEqual('http://some.com/');
|
||||
expect(
|
||||
getPublicUrl(null, {
|
||||
host: req.hostname,
|
||||
headers: req.headers as any,
|
||||
protocol: req.protocol,
|
||||
})
|
||||
).toEqual('http://some.com/');
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -87,7 +121,13 @@ describe('X-Forwarded-Proto', () => {
|
|||
url: '/',
|
||||
});
|
||||
|
||||
expect(getPublicUrl(undefined, req)).toEqual('https://some.com/');
|
||||
expect(
|
||||
getPublicUrl(undefined, {
|
||||
host: req.hostname,
|
||||
headers: req.headers as any,
|
||||
protocol: req.protocol,
|
||||
})
|
||||
).toEqual('https://some.com/');
|
||||
});
|
||||
|
||||
test('with a invalid X-Forwarded-Proto https', () => {
|
||||
|
@ -100,7 +140,13 @@ describe('X-Forwarded-Proto', () => {
|
|||
url: '/',
|
||||
});
|
||||
|
||||
expect(getPublicUrl(undefined, req)).toEqual('http://some.com/');
|
||||
expect(
|
||||
getPublicUrl(undefined, {
|
||||
host: req.hostname,
|
||||
headers: req.headers as any,
|
||||
protocol: req.protocol,
|
||||
})
|
||||
).toEqual('http://some.com/');
|
||||
});
|
||||
|
||||
test('with a HAProxy X-Forwarded-Proto https', () => {
|
||||
|
@ -113,7 +159,13 @@ describe('X-Forwarded-Proto', () => {
|
|||
url: '/',
|
||||
});
|
||||
|
||||
expect(getPublicUrl(undefined, req)).toEqual('https://some.com/');
|
||||
expect(
|
||||
getPublicUrl(undefined, {
|
||||
host: req.hostname,
|
||||
headers: req.headers as any,
|
||||
protocol: req.protocol,
|
||||
})
|
||||
).toEqual('https://some.com/');
|
||||
});
|
||||
|
||||
test('with a HAProxy X-Forwarded-Proto different protocol', () => {
|
||||
|
@ -126,7 +178,13 @@ describe('X-Forwarded-Proto', () => {
|
|||
url: '/',
|
||||
});
|
||||
|
||||
expect(getPublicUrl(undefined, req)).toEqual('http://some.com/');
|
||||
expect(
|
||||
getPublicUrl(undefined, {
|
||||
host: req.hostname,
|
||||
headers: req.headers as any,
|
||||
protocol: req.protocol,
|
||||
})
|
||||
).toEqual('http://some.com/');
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -142,7 +200,13 @@ describe('env variable', () => {
|
|||
url: '/',
|
||||
});
|
||||
|
||||
expect(getPublicUrl(undefined, req)).toEqual('https://env.domain.com/');
|
||||
expect(
|
||||
getPublicUrl(undefined, {
|
||||
host: req.hostname,
|
||||
headers: req.headers as any,
|
||||
protocol: req.protocol,
|
||||
})
|
||||
).toEqual('https://env.domain.com/');
|
||||
delete process.env.VERDACCIO_PUBLIC_URL;
|
||||
});
|
||||
|
||||
|
@ -157,7 +221,13 @@ describe('env variable', () => {
|
|||
url: '/',
|
||||
});
|
||||
|
||||
expect(getPublicUrl(undefined, req)).toEqual('https://env.domain.com/urlPrefix/');
|
||||
expect(
|
||||
getPublicUrl(undefined, {
|
||||
host: req.hostname,
|
||||
headers: req.headers as any,
|
||||
protocol: req.protocol,
|
||||
})
|
||||
).toEqual('https://env.domain.com/urlPrefix/');
|
||||
delete process.env.VERDACCIO_PUBLIC_URL;
|
||||
});
|
||||
|
||||
|
@ -172,7 +242,13 @@ describe('env variable', () => {
|
|||
url: '/',
|
||||
});
|
||||
|
||||
expect(getPublicUrl(undefined, req)).toEqual('https://env.domain.com/');
|
||||
expect(
|
||||
getPublicUrl(undefined, {
|
||||
host: req.hostname,
|
||||
headers: req.headers as any,
|
||||
protocol: req.protocol,
|
||||
})
|
||||
).toEqual('https://env.domain.com/');
|
||||
delete process.env.VERDACCIO_PUBLIC_URL;
|
||||
});
|
||||
|
||||
|
@ -187,7 +263,13 @@ describe('env variable', () => {
|
|||
url: '/',
|
||||
});
|
||||
|
||||
expect(getPublicUrl(undefined, req)).toEqual('http://some.com/');
|
||||
expect(
|
||||
getPublicUrl(undefined, {
|
||||
host: req.hostname,
|
||||
headers: req.headers as any,
|
||||
protocol: req.protocol,
|
||||
})
|
||||
).toEqual('http://some.com/');
|
||||
delete process.env.VERDACCIO_PUBLIC_URL;
|
||||
});
|
||||
|
||||
|
@ -202,7 +284,13 @@ describe('env variable', () => {
|
|||
url: '/',
|
||||
});
|
||||
|
||||
expect(getPublicUrl(undefined, req)).toEqual('http://some.com/');
|
||||
expect(
|
||||
getPublicUrl(undefined, {
|
||||
host: req.hostname,
|
||||
headers: req.headers as any,
|
||||
protocol: req.protocol,
|
||||
})
|
||||
).toEqual('http://some.com/');
|
||||
delete process.env.VERDACCIO_PUBLIC_URL;
|
||||
});
|
||||
|
||||
|
@ -217,7 +305,13 @@ describe('env variable', () => {
|
|||
url: '/',
|
||||
});
|
||||
|
||||
expect(getPublicUrl(undefined, req)).toEqual('http://some/');
|
||||
expect(
|
||||
getPublicUrl(undefined, {
|
||||
host: req.hostname,
|
||||
headers: req.headers as any,
|
||||
protocol: req.protocol,
|
||||
})
|
||||
).toEqual('http://some/');
|
||||
delete process.env.VERDACCIO_PUBLIC_URL;
|
||||
});
|
||||
});
|
||||
|
|
|
@ -80,7 +80,7 @@ function addPackageWebApi(route: Router, storage: Storage, auth: IAuth, config:
|
|||
pkgCopy.dist.tarball = getLocalRegistryTarballUri(
|
||||
pkgCopy.dist.tarball,
|
||||
pkg.name,
|
||||
req,
|
||||
{ protocol: req.protocol, headers: req.headers as any, host: req.hostname },
|
||||
config?.url_prefix
|
||||
);
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@ function addSidebarWebApi(route: Router, config: Config, storage: Storage, auth:
|
|||
let sideBarInfo = _.clone(info);
|
||||
sideBarInfo.versions = convertDistRemoteToLocalTarballUrls(
|
||||
info,
|
||||
req,
|
||||
{ protocol: req.protocol, headers: req.headers as any, host: req.hostname },
|
||||
config.url_prefix
|
||||
).versions;
|
||||
if (typeof v === 'string' && isVersionValid(info, v)) {
|
||||
|
|
|
@ -398,7 +398,6 @@ importers:
|
|||
'@verdaccio/types': workspace:11.0.0-6-next.9
|
||||
'@verdaccio/url': workspace:11.0.0-6-next.7
|
||||
'@verdaccio/utils': workspace:6.0.0-6-next.8
|
||||
express: 4.17.1
|
||||
lodash: 4.17.21
|
||||
node-mocks-http: 1.10.1
|
||||
dependencies:
|
||||
|
@ -408,7 +407,6 @@ importers:
|
|||
lodash: 4.17.21
|
||||
devDependencies:
|
||||
'@verdaccio/types': link:../types
|
||||
express: 4.17.1
|
||||
node-mocks-http: 1.10.1
|
||||
|
||||
packages/core/types:
|
||||
|
|
Loading…
Reference in a new issue