verdaccio
Version:
A lightweight private npm proxy registry
104 lines (102 loc) • 14 kB
JavaScript
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.allow_action = allow_action;
exports.defaultSecurity = void 0;
exports.getDefaultPlugins = getDefaultPlugins;
exports.getSecurity = getSecurity;
exports.handleSpecialUnpublish = handleSpecialUnpublish;
exports.validatePassword = validatePassword;
var _debug = _interopRequireDefault(require("debug"));
var _lodash = _interopRequireDefault(require("lodash"));
var _constants = require("./constants");
var _logger = require("./logger");
var _utils = require("./utils");
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
const debug = (0, _debug.default)('verdaccio');
function validatePassword(password,
// pragma: allowlist secret
minLength = _constants.DEFAULT_MIN_LIMIT_PASSWORD) {
return typeof password === 'string' && password.length >= minLength;
}
function allow_action(action) {
return function (user, pkg, callback) {
debug('[auth/allow_action]: user: %o', user === null || user === void 0 ? void 0 : user.name);
const {
name,
groups
} = user;
const groupAccess = pkg[action];
const hasPermission = groupAccess.some(group => name === group || groups.includes(group));
debug('[auth/allow_action]: hasPermission? %o} for user: %o', hasPermission, user === null || user === void 0 ? void 0 : user.name);
if (hasPermission) {
_logger.logger.info({
user: user.name
}, `auth/allow_action: access granted to: @{user}`);
return callback(null, true);
}
if (name) {
callback(_utils.ErrorCode.getForbidden(`user ${name} is not allowed to ${action} package ${pkg.name}`));
} else {
callback(_utils.ErrorCode.getUnauthorized(`authorization required to ${action} package ${pkg.name}`));
}
};
}
/**
*
*/
function handleSpecialUnpublish() {
return function (user, pkg, callback) {
const action = 'unpublish';
// verify whether the unpublish prop has been defined
const isUnpublishMissing = _lodash.default.isNil(pkg[action]);
const hasGroups = isUnpublishMissing ? false : pkg[action].length > 0;
debug('fallback unpublish for @{name} has groups: %o for %o', hasGroups, user === null || user === void 0 ? void 0 : user.name);
if (isUnpublishMissing || hasGroups === false) {
return callback(null, undefined);
}
debug('allow_action for %o for %o has groups: %o for %o', action, user === null || user === void 0 ? void 0 : user.name, hasGroups, user);
return allow_action(action)(user, pkg, callback);
};
}
function getDefaultPlugins(logger) {
return {
authenticate(_user, _password, cb) {
// pragma: allowlist secret
cb(_utils.ErrorCode.getForbidden(_constants.API_ERROR.BAD_USERNAME_PASSWORD));
},
add_user(_user, _password, cb) {
// pragma: allowlist secret
return cb(_utils.ErrorCode.getConflict(_constants.API_ERROR.BAD_USERNAME_PASSWORD));
},
// FIXME: allow_action and allow_publish should be in the @verdaccio/types
// @ts-ignore
allow_access: allow_action('access', logger),
// @ts-ignore
allow_publish: allow_action('publish', logger),
allow_unpublish: handleSpecialUnpublish()
};
}
const defaultWebTokenOptions = {
sign: {
// The expiration token for the website is 1 hour
expiresIn: _constants.TIME_EXPIRATION_1H
},
verify: {}
};
const defaultApiTokenConf = {
legacy: true,
migrateToSecureLegacySignature: false
};
const defaultSecurity = exports.defaultSecurity = {
web: defaultWebTokenOptions,
api: defaultApiTokenConf
};
function getSecurity(config) {
if (_lodash.default.isNil(config.security) === false) {
return _lodash.default.merge(defaultSecurity, config.security);
}
return defaultSecurity;
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfZGVidWciLCJfaW50ZXJvcFJlcXVpcmVEZWZhdWx0IiwicmVxdWlyZSIsIl9sb2Rhc2giLCJfY29uc3RhbnRzIiwiX2xvZ2dlciIsIl91dGlscyIsImUiLCJfX2VzTW9kdWxlIiwiZGVmYXVsdCIsImRlYnVnIiwiYnVpbGREZWJ1ZyIsInZhbGlkYXRlUGFzc3dvcmQiLCJwYXNzd29yZCIsIm1pbkxlbmd0aCIsIkRFRkFVTFRfTUlOX0xJTUlUX1BBU1NXT1JEIiwibGVuZ3RoIiwiYWxsb3dfYWN0aW9uIiwiYWN0aW9uIiwidXNlciIsInBrZyIsImNhbGxiYWNrIiwibmFtZSIsImdyb3VwcyIsImdyb3VwQWNjZXNzIiwiaGFzUGVybWlzc2lvbiIsInNvbWUiLCJncm91cCIsImluY2x1ZGVzIiwibG9nZ2VyIiwiaW5mbyIsIkVycm9yQ29kZSIsImdldEZvcmJpZGRlbiIsImdldFVuYXV0aG9yaXplZCIsImhhbmRsZVNwZWNpYWxVbnB1Ymxpc2giLCJpc1VucHVibGlzaE1pc3NpbmciLCJfIiwiaXNOaWwiLCJoYXNHcm91cHMiLCJ1bmRlZmluZWQiLCJnZXREZWZhdWx0UGx1Z2lucyIsImF1dGhlbnRpY2F0ZSIsIl91c2VyIiwiX3Bhc3N3b3JkIiwiY2IiLCJBUElfRVJST1IiLCJCQURfVVNFUk5BTUVfUEFTU1dPUkQiLCJhZGRfdXNlciIsImdldENvbmZsaWN0IiwiYWxsb3dfYWNjZXNzIiwiYWxsb3dfcHVibGlzaCIsImFsbG93X3VucHVibGlzaCIsImRlZmF1bHRXZWJUb2tlbk9wdGlvbnMiLCJzaWduIiwiZXhwaXJlc0luIiwiVElNRV9FWFBJUkFUSU9OXzFIIiwidmVyaWZ5IiwiZGVmYXVsdEFwaVRva2VuQ29uZiIsImxlZ2FjeSIsIm1pZ3JhdGVUb1NlY3VyZUxlZ2FjeVNpZ25hdHVyZSIsImRlZmF1bHRTZWN1cml0eSIsImV4cG9ydHMiLCJ3ZWIiLCJhcGkiLCJnZXRTZWN1cml0eSIsImNvbmZpZyIsInNlY3VyaXR5IiwibWVyZ2UiXSwic291cmNlcyI6WyIuLi8uLi9zcmMvbGliL2F1dGgtdXRpbHMudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGJ1aWxkRGVidWcgZnJvbSAnZGVidWcnO1xuaW1wb3J0IF8gZnJvbSAnbG9kYXNoJztcblxuaW1wb3J0IHsgcGx1Z2luVXRpbHMgfSBmcm9tICdAdmVyZGFjY2lvL2NvcmUnO1xuaW1wb3J0IHtcbiAgQVBJVG9rZW5PcHRpb25zLFxuICBDYWxsYmFjayxcbiAgQ29uZmlnLFxuICBKV1RPcHRpb25zLFxuICBQYWNrYWdlLFxuICBSZW1vdGVVc2VyLFxuICBTZWN1cml0eSxcbn0gZnJvbSAnQHZlcmRhY2Npby90eXBlcyc7XG5cbmltcG9ydCB7IEFQSV9FUlJPUiwgREVGQVVMVF9NSU5fTElNSVRfUEFTU1dPUkQsIFRJTUVfRVhQSVJBVElPTl8xSCB9IGZyb20gJy4vY29uc3RhbnRzJztcbmltcG9ydCB7IGxvZ2dlciB9IGZyb20gJy4vbG9nZ2VyJztcbmltcG9ydCB7IEVycm9yQ29kZSB9IGZyb20gJy4vdXRpbHMnO1xuXG5jb25zdCBkZWJ1ZyA9IGJ1aWxkRGVidWcoJ3ZlcmRhY2NpbycpO1xuXG5leHBvcnQgZnVuY3Rpb24gdmFsaWRhdGVQYXNzd29yZChcbiAgcGFzc3dvcmQ6IHN0cmluZywgLy8gcHJhZ21hOiBhbGxvd2xpc3Qgc2VjcmV0XG4gIG1pbkxlbmd0aDogbnVtYmVyID0gREVGQVVMVF9NSU5fTElNSVRfUEFTU1dPUkRcbik6IGJvb2xlYW4ge1xuICByZXR1cm4gdHlwZW9mIHBhc3N3b3JkID09PSAnc3RyaW5nJyAmJiBwYXNzd29yZC5sZW5ndGggPj0gbWluTGVuZ3RoO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gYWxsb3dfYWN0aW9uKGFjdGlvbjogc3RyaW5nKTogRnVuY3Rpb24ge1xuICByZXR1cm4gZnVuY3Rpb24gKHVzZXI6IFJlbW90ZVVzZXIsIHBrZzogUGFja2FnZSwgY2FsbGJhY2s6IENhbGxiYWNrKTogdm9pZCB7XG4gICAgZGVidWcoJ1thdXRoL2FsbG93X2FjdGlvbl06IHVzZXI6ICVvJywgdXNlcj8ubmFtZSk7XG4gICAgY29uc3QgeyBuYW1lLCBncm91cHMgfSA9IHVzZXI7XG4gICAgY29uc3QgZ3JvdXBBY2Nlc3MgPSBwa2dbYWN0aW9uXTtcbiAgICBjb25zdCBoYXNQZXJtaXNzaW9uID0gZ3JvdXBBY2Nlc3Muc29tZSgoZ3JvdXApID0+IG5hbWUgPT09IGdyb3VwIHx8IGdyb3Vwcy5pbmNsdWRlcyhncm91cCkpO1xuICAgIGRlYnVnKCdbYXV0aC9hbGxvd19hY3Rpb25dOiBoYXNQZXJtaXNzaW9uPyAlb30gZm9yIHVzZXI6ICVvJywgaGFzUGVybWlzc2lvbiwgdXNlcj8ubmFtZSk7XG5cbiAgICBpZiAoaGFzUGVybWlzc2lvbikge1xuICAgICAgbG9nZ2VyLmluZm8oeyB1c2VyOiB1c2VyLm5hbWUgfSwgYGF1dGgvYWxsb3dfYWN0aW9uOiBhY2Nlc3MgZ3JhbnRlZCB0bzogQHt1c2VyfWApO1xuICAgICAgcmV0dXJuIGNhbGxiYWNrKG51bGwsIHRydWUpO1xuICAgIH1cblxuICAgIGlmIChuYW1lKSB7XG4gICAgICBjYWxsYmFjayhcbiAgICAgICAgRXJyb3JDb2RlLmdldEZvcmJpZGRlbihgdXNlciAke25hbWV9IGlzIG5vdCBhbGxvd2VkIHRvICR7YWN0aW9ufSBwYWNrYWdlICR7cGtnLm5hbWV9YClcbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNhbGxiYWNrKFxuICAgICAgICBFcnJvckNvZGUuZ2V0VW5hdXRob3JpemVkKGBhdXRob3JpemF0aW9uIHJlcXVpcmVkIHRvICR7YWN0aW9ufSBwYWNrYWdlICR7cGtnLm5hbWV9YClcbiAgICAgICk7XG4gICAgfVxuICB9O1xufVxuXG4vKipcbiAqXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBoYW5kbGVTcGVjaWFsVW5wdWJsaXNoKCk6IGFueSB7XG4gIHJldHVybiBmdW5jdGlvbiAodXNlcjogUmVtb3RlVXNlciwgcGtnOiBQYWNrYWdlLCBjYWxsYmFjazogQ2FsbGJhY2spOiB2b2lkIHtcbiAgICBjb25zdCBhY3Rpb24gPSAndW5wdWJsaXNoJztcbiAgICAvLyB2ZXJpZnkgd2hldGhlciB0aGUgdW5wdWJsaXNoIHByb3AgaGFzIGJlZW4gZGVmaW5lZFxuICAgIGNvbnN0IGlzVW5wdWJsaXNoTWlzc2luZzogYm9vbGVhbiA9IF8uaXNOaWwocGtnW2FjdGlvbl0pO1xuICAgIGNvbnN0IGhhc0dyb3VwczogYm9vbGVhbiA9IGlzVW5wdWJsaXNoTWlzc2luZyA/IGZhbHNlIDogcGtnW2FjdGlvbl0ubGVuZ3RoID4gMDtcbiAgICBkZWJ1ZygnZmFsbGJhY2sgdW5wdWJsaXNoIGZvciBAe25hbWV9IGhhcyBncm91cHM6ICVvIGZvciAlbycsIGhhc0dyb3VwcywgdXNlcj8ubmFtZSk7XG4gICAgaWYgKGlzVW5wdWJsaXNoTWlzc2luZyB8fCBoYXNHcm91cHMgPT09IGZhbHNlKSB7XG4gICAgICByZXR1cm4gY2FsbGJhY2sobnVsbCwgdW5kZWZpbmVkKTtcbiAgICB9XG4gICAgZGVidWcoJ2FsbG93X2FjdGlvbiBmb3IgJW8gZm9yICVvIGhhcyBncm91cHM6ICVvIGZvciAlbycsIGFjdGlvbiwgdXNlcj8ubmFtZSwgaGFzR3JvdXBzLCB1c2VyKTtcbiAgICByZXR1cm4gYWxsb3dfYWN0aW9uKGFjdGlvbikodXNlciwgcGtnLCBjYWxsYmFjayk7XG4gIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXREZWZhdWx0UGx1Z2lucyhsb2dnZXI6IGFueSk6IHBsdWdpblV0aWxzLkF1dGg8Q29uZmlnPiB7XG4gIHJldHVybiB7XG4gICAgYXV0aGVudGljYXRlKF91c2VyOiBzdHJpbmcsIF9wYXNzd29yZDogc3RyaW5nLCBjYjogQ2FsbGJhY2spOiB2b2lkIHtcbiAgICAgIC8vIHByYWdtYTogYWxsb3dsaXN0IHNlY3JldFxuICAgICAgY2IoRXJyb3JDb2RlLmdldEZvcmJpZGRlbihBUElfRVJST1IuQkFEX1VTRVJOQU1FX1BBU1NXT1JEKSk7XG4gICAgfSxcblxuICAgIGFkZF91c2VyKF91c2VyOiBzdHJpbmcsIF9wYXNzd29yZDogc3RyaW5nLCBjYjogQ2FsbGJhY2spOiB2b2lkIHtcbiAgICAgIC8vIHByYWdtYTogYWxsb3dsaXN0IHNlY3JldFxuICAgICAgcmV0dXJuIGNiKEVycm9yQ29kZS5nZXRDb25mbGljdChBUElfRVJST1IuQkFEX1VTRVJOQU1FX1BBU1NXT1JEKSk7XG4gICAgfSxcblxuICAgIC8vIEZJWE1FOiBhbGxvd19hY3Rpb24gYW5kIGFsbG93X3B1Ymxpc2ggc2hvdWxkIGJlIGluIHRoZSBAdmVyZGFjY2lvL3R5cGVzXG4gICAgLy8gQHRzLWlnbm9yZVxuICAgIGFsbG93X2FjY2VzczogYWxsb3dfYWN0aW9uKCdhY2Nlc3MnLCBsb2dnZXIpLFxuICAgIC8vIEB0cy1pZ25vcmVcbiAgICBhbGxvd19wdWJsaXNoOiBhbGxvd19hY3Rpb24oJ3B1Ymxpc2gnLCBsb2dnZXIpLFxuICAgIGFsbG93X3VucHVibGlzaDogaGFuZGxlU3BlY2lhbFVucHVibGlzaCgpLFxuICB9O1xufVxuXG5jb25zdCBkZWZhdWx0V2ViVG9rZW5PcHRpb25zOiBKV1RPcHRpb25zID0ge1xuICBzaWduOiB7XG4gICAgLy8gVGhlIGV4cGlyYXRpb24gdG9rZW4gZm9yIHRoZSB3ZWJzaXRlIGlzIDEgaG91clxuICAgIGV4cGlyZXNJbjogVElNRV9FWFBJUkFUSU9OXzFILFxuICB9LFxuICB2ZXJpZnk6IHt9LFxufTtcblxuY29uc3QgZGVmYXVsdEFwaVRva2VuQ29uZjogQVBJVG9rZW5PcHRpb25zID0ge1xuICBsZWdhY3k6IHRydWUsXG4gIG1pZ3JhdGVUb1NlY3VyZUxlZ2FjeVNpZ25hdHVyZTogZmFsc2UsXG59O1xuXG5leHBvcnQgY29uc3QgZGVmYXVsdFNlY3VyaXR5OiBTZWN1cml0eSA9IHtcbiAgd2ViOiBkZWZhdWx0V2ViVG9rZW5PcHRpb25zLFxuICBhcGk6IGRlZmF1bHRBcGlUb2tlbkNvbmYsXG59O1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0U2VjdXJpdHkoY29uZmlnOiBDb25maWcpOiBTZWN1cml0eSB7XG4gIGlmIChfLmlzTmlsKGNvbmZpZy5zZWN1cml0eSkgPT09IGZhbHNlKSB7XG4gICAgcmV0dXJuIF8ubWVyZ2UoZGVmYXVsdFNlY3VyaXR5LCBjb25maWcuc2VjdXJpdHkpO1xuICB9XG5cbiAgcmV0dXJuIGRlZmF1bHRTZWN1cml0eTtcbn1cbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7QUFBQSxJQUFBQSxNQUFBLEdBQUFDLHNCQUFBLENBQUFDLE9BQUE7QUFDQSxJQUFBQyxPQUFBLEdBQUFGLHNCQUFBLENBQUFDLE9BQUE7QUFhQSxJQUFBRSxVQUFBLEdBQUFGLE9BQUE7QUFDQSxJQUFBRyxPQUFBLEdBQUFILE9BQUE7QUFDQSxJQUFBSSxNQUFBLEdBQUFKLE9BQUE7QUFBb0MsU0FBQUQsdUJBQUFNLENBQUEsV0FBQUEsQ0FBQSxJQUFBQSxDQUFBLENBQUFDLFVBQUEsR0FBQUQsQ0FBQSxLQUFBRSxPQUFBLEVBQUFGLENBQUE7QUFFcEMsTUFBTUcsS0FBSyxHQUFHLElBQUFDLGNBQVUsRUFBQyxXQUFXLENBQUM7QUFFOUIsU0FBU0MsZ0JBQWdCQSxDQUM5QkMsUUFBZ0I7QUFBRTtBQUNsQkMsU0FBaUIsR0FBR0MscUNBQTBCLEVBQ3JDO0VBQ1QsT0FBTyxPQUFPRixRQUFRLEtBQUssUUFBUSxJQUFJQSxRQUFRLENBQUNHLE1BQU0sSUFBSUYsU0FBUztBQUNyRTtBQUVPLFNBQVNHLFlBQVlBLENBQUNDLE1BQWMsRUFBWTtFQUNyRCxPQUFPLFVBQVVDLElBQWdCLEVBQUVDLEdBQVksRUFBRUMsUUFBa0IsRUFBUTtJQUN6RVgsS0FBSyxDQUFDLCtCQUErQixFQUFFUyxJQUFJLGFBQUpBLElBQUksdUJBQUpBLElBQUksQ0FBRUcsSUFBSSxDQUFDO0lBQ2xELE1BQU07TUFBRUEsSUFBSTtNQUFFQztJQUFPLENBQUMsR0FBR0osSUFBSTtJQUM3QixNQUFNSyxXQUFXLEdBQUdKLEdBQUcsQ0FBQ0YsTUFBTSxDQUFDO0lBQy9CLE1BQU1PLGFBQWEsR0FBR0QsV0FBVyxDQUFDRSxJQUFJLENBQUVDLEtBQUssSUFBS0ws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
;