Skip to content

Commit

Permalink
fix: force detect unpkg-white-list
Browse files Browse the repository at this point in the history
  • Loading branch information
fengmk2 committed May 30, 2024
1 parent c8f5ee8 commit ddce7f0
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 2 deletions.
11 changes: 9 additions & 2 deletions app/core/service/PackageVersionFileService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import { PackageManagerService } from './PackageManagerService';
import { CacheAdapter } from '../../common/adapter/CacheAdapter';

const unpkgWhiteListUrl = 'https://github.com/cnpm/unpkg-white-list';
const CHECK_TIMEOUT = process.env.NODE_ENV === 'test' ? 1 : 60000;

@SingletonProto({
accessLevel: AccessLevel.PUBLIC,
Expand All @@ -46,6 +47,7 @@ export class PackageVersionFileService extends AbstractService {
@Inject()
private readonly cacheAdapter: CacheAdapter;

#unpkgWhiteListCheckTime: number = 0;
#unpkgWhiteListCurrentVersion: string = '';
#unpkgWhiteListAllowPackages: Record<string, {
version: string;
Expand Down Expand Up @@ -81,6 +83,11 @@ export class PackageVersionFileService extends AbstractService {

async #updateUnpkgWhiteList() {
if (!this.config.cnpmcore.enableSyncUnpkgFilesWhiteList) return;
if (Date.now() - this.#unpkgWhiteListCheckTime <= CHECK_TIMEOUT) {
// check update every 60s
return;
}
this.#unpkgWhiteListCheckTime = Date.now();
const whiteListScope = '';
const whiteListPackageName = 'unpkg-white-list';
const whiteListPackageVersion = await this.packageVersionRepository.findVersionByTag(
Expand All @@ -103,7 +110,7 @@ export class PackageVersionFileService extends AbstractService {
);
}

async #checkPackageVersionInUnpkgWhiteList(pkgScope: string, pkgName: string, pkgVersion: string) {
async checkPackageVersionInUnpkgWhiteList(pkgScope: string, pkgName: string, pkgVersion: string) {
if (!this.config.cnpmcore.enableSyncUnpkgFilesWhiteList) return;
await this.#updateUnpkgWhiteList();

Expand Down Expand Up @@ -180,7 +187,7 @@ export class PackageVersionFileService extends AbstractService {
if (!pkg) return files;

// check unpkg white list
await this.#checkPackageVersionInUnpkgWhiteList(pkg.scope, pkg.name, pkgVersion.version);
await this.checkPackageVersionInUnpkgWhiteList(pkg.scope, pkg.name, pkgVersion.version);

const dirname = `unpkg_${pkg.fullname.replace('/', '_')}@${pkgVersion.version}_${randomUUID()}`;
const tmpdir = await createTempDir(this.config.dataDir, dirname);
Expand Down
1 change: 1 addition & 0 deletions app/port/controller/PackageVersionFileController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ export class PackageVersionFileController extends AbstractController {
return files;
}

await this.packageVersionFileService.checkPackageVersionInUnpkgWhiteList(scope, name, packageVersion.version);
const file = await this.packageVersionFileService.showPackageVersionFile(packageVersion, path);
const hasMeta = typeof meta === 'string';

Expand Down
78 changes: 78 additions & 0 deletions test/port/controller/PackageVersionFileController/raw.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,84 @@ describe('test/port/controller/PackageVersionFileController/raw.test.ts', () =>
assert.equal(res.headers.vary, 'Origin, Accept, Accept-Encoding');
});

it('should block raw file when package not in white list', async () => {
mock(app.config.cnpmcore, 'allowPublishNonScopePackage', true);
let pkg = await TestUtil.getFullPackage({
name: 'foo',
version: '1.0.0',
versionObject: {
description: 'work with utf8mb4 💩, 𝌆 utf8_unicode_ci, foo𝌆bar 🍻',
},
});
await app.httpRequest()
.put(`/${pkg.name}`)
.set('authorization', publisher.authorization)
.set('user-agent', publisher.ua)
.send(pkg)
.expect(201);
let res = await app.httpRequest()
.get('/foo/1.0.0/files/package.json')
.expect(200)
.expect('content-type', 'application/json; charset=utf-8');
// console.log(res.body);
assert.equal(res.headers['cache-control'], 'public, max-age=31536000');
assert.equal(res.headers.vary, 'Origin, Accept, Accept-Encoding');
assert.deepEqual(res.body, {
name: 'mk2testmodule',
version: '0.0.1',
description: '',
main: 'index.js',
scripts: { test: 'echo "Error: no test specified" && exit 1' },
author: '',
license: 'ISC',
});

mock(app.config.cnpmcore, 'enableSyncUnpkgFilesWhiteList', true);
// should block
res = await app.httpRequest()
.get('/foo/1.0.0/files/package.json')
.expect(403)
.expect('content-type', 'application/json; charset=utf-8');
assert.equal(res.body.error,
'[FORBIDDEN] "foo" is not allow to unpkg files, see https://github.com/cnpm/unpkg-white-list');

// add white list
pkg = await TestUtil.getFullPackage({
name: 'unpkg-white-list',
version: '2.0.1111',
versionObject: {
description: 'work with utf8mb4 💩, 𝌆 utf8_unicode_ci, foo𝌆bar 🍻',
allowPackages: {
foo: {
version: '*',
},
},
},
});
await app.httpRequest()
.put(`/${pkg.name}`)
.set('authorization', publisher.authorization)
.set('user-agent', publisher.ua)
.send(pkg)
.expect(201);
res = await app.httpRequest()
.get('/foo/1.0.0/files/package.json')
// .expect(200)
.expect('content-type', 'application/json; charset=utf-8');
console.log(res.body);
// assert.equal(res.headers['cache-control'], 'public, max-age=31536000');
// assert.equal(res.headers.vary, 'Origin, Accept, Accept-Encoding');
assert.deepEqual(res.body, {
name: 'mk2testmodule',
version: '0.0.1',
description: '',
main: 'index.js',
scripts: { test: 'echo "Error: no test specified" && exit 1' },
author: '',
license: 'ISC',
});
});

it('should show one package version file meta', async () => {
mock(app.config.cnpmcore, 'allowPublishNonScopePackage', true);
const pkg = await TestUtil.getFullPackage({
Expand Down

0 comments on commit ddce7f0

Please sign in to comment.