cnpm / cnpmjs.org

@@ -0,0 +1,28 @@
Loading
1 +
'use strict';
2 +
3 +
const BlockPackageVersion = require('../models').BlockPackageVersion;
4 +
5 +
exports.blockPackageVersion = function* (name, version, reason) {
6 +
  const row = yield BlockPackageVersion.findOne({ where: { name, version } });
7 +
  if (row) {
8 +
    row.reason = reason;
9 +
    yield row.save();
10 +
  } else {
11 +
    yield BlockPackageVersion.create({ name, version, reason });
12 +
  }
13 +
};
14 +
15 +
exports.findBlockPackageVersions = function* (name) {
16 +
  if (!BlockPackageVersion) {
17 +
    return null;
18 +
  }
19 +
  const rows = yield BlockPackageVersion.findAll({ where: { name } });
20 +
  if (rows.length === 0) {
21 +
    return null;
22 +
  }
23 +
  const blocks = {};
24 +
  for (const row of rows) {
25 +
    blocks[row.version] = row;
26 +
  }
27 +
  return blocks;
28 +
};

@@ -1,19 +1,5 @@
Loading
1 -
/**!
2 -
 * cnpmjs.org - models/download_total.js
3 -
 *
4 -
 * Copyright(c) fengmk2 and other contributors.
5 -
 * MIT Licensed
6 -
 *
7 -
 * Authors:
8 -
 *   fengmk2 <fengmk2@gmail.com> (http://fengmk2.github.com)
9 -
 */
10 -
11 1
'use strict';
12 2
13 -
/**
14 -
 * Module dependencies.
15 -
 */
16 -
17 3
// CREATE TABLE IF NOT EXISTS `downloads` (
18 4
//  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'primary key',
19 5
//  `gmt_create` datetime NOT NULL COMMENT 'create time',

@@ -3,6 +3,7 @@
Loading
3 3
var debug = require('debug')('cnpmjs.org:controllers:registry:package:list');
4 4
var utility = require('utility');
5 5
var packageService = require('../../../services/package');
6 +
var blocklistService = require('../../../services/blocklist');
6 7
var common = require('../../../lib/common');
7 8
var SyncModuleWorker = require('../../sync_module_worker');
8 9
var config = require('../../../config');
@@ -15,6 +16,13 @@
Loading
15 16
  return 'W/"' + utility.md5(JSON.stringify(objs)) + '"';
16 17
}
17 18
19 +
function filterBlockVerions(rows, blocks) {
20 +
  if (!blocks) {
21 +
    return rows;
22 +
  }
23 +
  return rows.filter(row => !blocks[row.version]);
24 +
}
25 +
18 26
/**
19 27
 * list all version of a module
20 28
 * GET /:name
@@ -63,9 +71,22 @@
Loading
63 71
  var rs = yield [
64 72
    packageService.getModuleLastModified(name),
65 73
    packageService.listModuleTags(name),
74 +
    blocklistService.findBlockPackageVersions(name),
66 75
  ];
67 76
  var modifiedTime = rs[0];
68 77
  var tags = rs[1];
78 +
  var blocks = rs[2];
79 +
80 +
  if (blocks && blocks['*']) {
81 +
    this.status = 451;
82 +
    const error = `[block] package was blocked, reason: ${blocks['*'].reason}`;
83 +
    this.jsonp = {
84 +
      name,
85 +
      error,
86 +
      reason: error,
87 +
    };
88 +
    return;
89 +
  }
69 90
70 91
  debug('show %s, last modified: %s, tags: %j', name, modifiedTime, tags);
71 92
  if (modifiedTime) {
@@ -89,11 +110,13 @@
Loading
89 110
90 111
  if (needAbbreviatedMeta) {
91 112
    var rows = yield packageService.listModuleAbbreviatedsByName(name);
113 +
    rows = filterBlockVerions(rows, blocks);
92 114
    if (rows.length > 0) {
93 115
      yield handleAbbreviatedMetaRequest(this, name, modifiedTime, tags, rows, cacheKey);
94 116
      return;
95 117
    }
96 118
    var fullRows = yield packageService.listModulesByName(name);
119 +
    fullRows = filterBlockVerions(fullRows, blocks);
97 120
    if (fullRows.length > 0) {
98 121
      // no abbreviated meta rows, use the full meta convert to abbreviated meta
99 122
      yield handleAbbreviatedMetaRequestWithFullMeta(this, name, modifiedTime, tags, fullRows);
@@ -106,7 +129,7 @@
Loading
106 129
    packageService.listStarUserNames(name),
107 130
    packageService.listMaintainers(name),
108 131
  ];
109 -
  var rows = r[0];
132 +
  var rows = filterBlockVerions(r[0], blocks);
110 133
  var starUsers = r[1];
111 134
  var maintainers = r[2];
112 135

@@ -10,6 +10,7 @@
Loading
10 10
11 11
var _ModuleAbbreviated = config.enableAbbreviatedMetadata ? load('module_abbreviated') : null;
12 12
var _PackageReadme = config.enableAbbreviatedMetadata ? load('package_readme') : null;
13 +
var _BlockPackageVersion = config.enableBlockPackageVersion ? load('block_package_version') : null;
13 14
14 15
module.exports = {
15 16
  sequelize: sequelize,
@@ -60,4 +61,14 @@
Loading
60 61
    }
61 62
    return _PackageReadme;
62 63
  },
64 +
65 +
  get BlockPackageVersion() {
66 +
    if (!config.enableBlockPackageVersion) {
67 +
      return null;
68 +
    }
69 +
    if (!_BlockPackageVersion) {
70 +
      _BlockPackageVersion = load('block_package_version');
71 +
    }
72 +
    return _BlockPackageVersion;
73 +
  }
63 74
};

@@ -1,19 +1,5 @@
Loading
1 -
/**!
2 -
 * cnpmjs.org - models/total.js
3 -
 *
4 -
 * Copyright(c) fengmk2 and other contributors.
5 -
 * MIT Licensed
6 -
 *
7 -
 * Authors:
8 -
 *   fengmk2 <fengmk2@gmail.com> (http://fengmk2.github.com)
9 -
 */
10 -
11 1
'use strict';
12 2
13 -
/**
14 -
 * Module dependencies.
15 -
 */
16 -
17 3
// CREATE TABLE IF NOT EXISTS `total` (
18 4
//  `name` varchar(214) NOT NULL COMMENT 'total name',
19 5
//  `gmt_modified` datetime NOT NULL COMMENT 'modified time',

@@ -287,6 +287,9 @@
Loading
287 287
  // if enable this option, must create module_abbreviated and package_readme table in database
288 288
  enableAbbreviatedMetadata: false,
289 289
290 +
  // enable package or package version block list, must create package_version_blocklist table in database
291 +
  enableBlockPackageVersion: false,
292 +
290 293
  // global hook function: function* (envelope) {}
291 294
  // envelope format please see https://github.com/npm/registry/blob/master/docs/hooks/hooks-payload.md#payload
292 295
  globalHook: null,
@@ -334,6 +337,8 @@
Loading
334 337
      yield next;
335 338
    };
336 339
  });
340 +
341 +
  config.enableBlockPackageVersion = true;
337 342
}
338 343
339 344
if (process.env.NODE_ENV !== 'test') {

@@ -0,0 +1,29 @@
Loading
1 +
'use strict';
2 +
3 +
module.exports = function (sequelize, DataTypes) {
4 +
  return sequelize.define('BlockPackageVersion', {
5 +
    name: {
6 +
      type: DataTypes.STRING(214),
7 +
      allowNull: false,
8 +
      comment: 'package name'
9 +
    },
10 +
    version: {
11 +
      type: DataTypes.STRING(30),
12 +
      allowNull: false,
13 +
      comment: 'package version'
14 +
    },
15 +
    reason: {
16 +
      type: DataTypes.LONGTEXT,
17 +
      comment: 'block reason',
18 +
    },
19 +
  }, {
20 +
    tableName: 'package_version_blocklist',
21 +
    comment: 'package version block list',
22 +
    indexes: [
23 +
      {
24 +
        unique: true,
25 +
        fields: ['name', 'version'],
26 +
      },
27 +
    ],
28 +
  });
29 +
};

@@ -12,6 +12,7 @@
Loading
12 12
var setDownloadURL = require('../../../lib/common').setDownloadURL;
13 13
var renderMarkdown = require('../../../common/markdown').render;
14 14
var packageService = require('../../../services/package');
15 +
var blocklistService = require('../../../services/blocklist');
15 16
var downloadTotalService = require('../../../services/download_total');
16 17
17 18
module.exports = function* show(next) {
@@ -71,6 +72,16 @@
Loading
71 72
    return yield next;
72 73
  }
73 74
75 +
  var blocks = yield blocklistService.findBlockPackageVersions(name);
76 +
  if (blocks) {
77 +
    var block = blocks['*'] || blocks[pkg.version];
78 +
    if (block) {
79 +
      this.status = 451;
80 +
      this.body = `[block] package@${pkg.version} was blocked, reason: ${block.reason}`;
81 +
      return;
82 +
    }
83 +
  }
84 +
74 85
  var r = yield [
75 86
    utils.getDownloadTotal(name),
76 87
    packageService.listDependents(name),
Files Coverage
common 67.39%
controllers 86.10%
middleware 94.34%
models 89.96%
routes 100.00%
servers 90.91%
services 90.92%
sync 89.61%
config/index.js 76.00%
lib/common.js 88.73%
Project Totals (99 files) 87.69%
Sunburst
The inner-most circle is the entire project, moving away from the center are folders then, finally, a single file. The size and color of each slice is representing the number of statements and the coverage, respectively.
Icicle
The top section represents the entire project. Proceeding with folders and finally individual files. The size and color of each slice is representing the number of statements and the coverage, respectively.
Grid
Each block represents a single file in the project. The size and color of each block is represented by the number of statements and the coverage, respectively.
Loading