@verdaccio/config 7.0.0-next.4 → 7.0.0-next.6
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 +27 -7
- package/LICENSE +1 -1
- package/build/config.d.ts +1 -0
- package/build/config.js +28 -13
- package/build/config.js.map +1 -1
- package/build/package-access.js +1 -1
- package/build/package-access.js.map +1 -1
- package/jest.config.js +1 -2
- package/package.json +4 -4
- package/src/config.ts +27 -14
- package/src/package-access.ts +1 -1
- package/test/agent.spec.ts +42 -0
- package/test/builder.spec.ts +6 -0
- package/test/config.spec.ts +29 -0
- package/test/package-access.spec.ts +27 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
# @verdaccio/config
|
|
2
2
|
|
|
3
|
+
## 7.0.0-next.6
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 4d96324: chore(config): increase test coverage
|
|
8
|
+
- @verdaccio/core@7.0.0-next.6
|
|
9
|
+
- @verdaccio/utils@7.0.0-next.6
|
|
10
|
+
|
|
11
|
+
## 7.0.0-next.5
|
|
12
|
+
|
|
13
|
+
### Minor Changes
|
|
14
|
+
|
|
15
|
+
- f047cc8: refactor: auth with legacy sign support
|
|
16
|
+
|
|
17
|
+
### Patch Changes
|
|
18
|
+
|
|
19
|
+
- Updated dependencies [f047cc8]
|
|
20
|
+
- @verdaccio/core@7.0.0-next.5
|
|
21
|
+
- @verdaccio/utils@7.0.0-next.5
|
|
22
|
+
|
|
3
23
|
## 7.0.0-next.4
|
|
4
24
|
|
|
5
25
|
### Patch Changes
|
|
@@ -225,12 +245,12 @@
|
|
|
225
245
|
- 8f43bf17d: feat: node api new structure based on promise
|
|
226
246
|
|
|
227
247
|
```js
|
|
228
|
-
import { runServer } from
|
|
248
|
+
import { runServer } from "@verdaccio/node-api";
|
|
229
249
|
// or
|
|
230
|
-
import { runServer } from
|
|
250
|
+
import { runServer } from "verdaccio";
|
|
231
251
|
|
|
232
252
|
const app = await runServer(); // default configuration
|
|
233
|
-
const app = await runServer(
|
|
253
|
+
const app = await runServer("./config/config.yaml");
|
|
234
254
|
const app = await runServer({ configuration });
|
|
235
255
|
app.listen(4000, (event) => {
|
|
236
256
|
// do something
|
|
@@ -1000,14 +1020,14 @@
|
|
|
1000
1020
|
- 5c5057fc: feat: node api new structure based on promise
|
|
1001
1021
|
|
|
1002
1022
|
```js
|
|
1003
|
-
import { runServer } from
|
|
1023
|
+
import { runServer } from "@verdaccio/node-api";
|
|
1004
1024
|
// or
|
|
1005
|
-
import { runServer } from
|
|
1025
|
+
import { runServer } from "verdaccio";
|
|
1006
1026
|
|
|
1007
1027
|
const app = await runServer(); // default configuration
|
|
1008
|
-
const app = await runServer(
|
|
1028
|
+
const app = await runServer("./config/config.yaml");
|
|
1009
1029
|
const app = await runServer({ configuration });
|
|
1010
|
-
app.listen(4000, event => {
|
|
1030
|
+
app.listen(4000, (event) => {
|
|
1011
1031
|
// do something
|
|
1012
1032
|
});
|
|
1013
1033
|
```
|
package/LICENSE
CHANGED
package/build/config.d.ts
CHANGED
package/build/config.js
CHANGED
|
@@ -39,7 +39,12 @@ class Config {
|
|
|
39
39
|
|
|
40
40
|
// @ts-ignore
|
|
41
41
|
|
|
42
|
-
constructor(config,
|
|
42
|
+
constructor(config,
|
|
43
|
+
// forceEnhancedLegacySignature is a property that
|
|
44
|
+
// allows switch a new legacy aes signature token signature
|
|
45
|
+
// for older versions do not want to have this new signature model
|
|
46
|
+
// this property must be false
|
|
47
|
+
configOptions = {
|
|
43
48
|
forceEnhancedLegacySignature: true
|
|
44
49
|
}) {
|
|
45
50
|
var _config$flags$searchR, _config$flags, _config$flags$changeP, _config$flags2;
|
|
@@ -107,6 +112,15 @@ class Config {
|
|
|
107
112
|
this.server_id = (0, _utils.generateRandomHexString)(6);
|
|
108
113
|
}
|
|
109
114
|
}
|
|
115
|
+
getEnhancedLegacySignature() {
|
|
116
|
+
if (typeof (this === null || this === void 0 ? void 0 : this.security.enhancedLegacySignature) !== 'undefined') {
|
|
117
|
+
if (this.security.enhancedLegacySignature === true) {
|
|
118
|
+
return true;
|
|
119
|
+
}
|
|
120
|
+
return false;
|
|
121
|
+
}
|
|
122
|
+
return this.configOptions.forceEnhancedLegacySignature;
|
|
123
|
+
}
|
|
110
124
|
getConfigPath() {
|
|
111
125
|
return this.configPath;
|
|
112
126
|
}
|
|
@@ -124,7 +138,7 @@ class Config {
|
|
|
124
138
|
* @secret external secret key
|
|
125
139
|
*/
|
|
126
140
|
checkSecretKey(secret) {
|
|
127
|
-
var _this$secret;
|
|
141
|
+
var _this$security, _this$secret;
|
|
128
142
|
debug('check secret key');
|
|
129
143
|
if (typeof secret === 'string' && _lodash.default.isEmpty(secret) === false) {
|
|
130
144
|
this.secret = secret;
|
|
@@ -133,20 +147,21 @@ class Config {
|
|
|
133
147
|
}
|
|
134
148
|
// generate a new a secret key
|
|
135
149
|
// FUTURE: this might be an external secret key, perhaps within config file?
|
|
136
|
-
debug('
|
|
137
|
-
|
|
138
|
-
|
|
150
|
+
debug('generating a new secret key');
|
|
151
|
+
if (this.getEnhancedLegacySignature()) {
|
|
152
|
+
debug('key generated with "enhanced" legacy signature user config');
|
|
139
153
|
this.secret = (0, _token.generateRandomSecretKey)();
|
|
140
154
|
} else {
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
155
|
+
debug('key generated with legacy signature user config');
|
|
156
|
+
this.secret = (0, _utils.generateRandomHexString)(32);
|
|
157
|
+
}
|
|
158
|
+
// set this to false allow use old token signature and is not recommended
|
|
159
|
+
// only use for migration reasons, major release will remove this property and
|
|
160
|
+
// set it by default
|
|
161
|
+
if (((_this$security = this.security) === null || _this$security === void 0 ? void 0 : _this$security.enhancedLegacySignature) === false) {
|
|
162
|
+
_core.warningUtils.emit(_warningUtils.Codes.VERWAR005);
|
|
148
163
|
}
|
|
149
|
-
debug('generated a new secret key %s', (_this$secret = this.secret) === null || _this$secret === void 0 ? void 0 : _this$secret.length);
|
|
164
|
+
debug('generated a new secret key length %s', (_this$secret = this.secret) === null || _this$secret === void 0 ? void 0 : _this$secret.length);
|
|
150
165
|
return this.secret;
|
|
151
166
|
}
|
|
152
167
|
}
|
package/build/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","names":["_assert","_interopRequireDefault","require","_debug","_lodash","_core","_warningUtils","_utils","_agent","_packageAccess","_security","_serverSettings","_token","_uplinks","obj","__esModule","default","strategicConfigProps","allowedEnvConfig","debug","buildDebug","WEB_TITLE","exports","defaultUserRateLimiting","windowMs","max","Config","constructor","config","configOptions","forceEnhancedLegacySignature","_config$flags$searchR","_config$flags","_config$flags$changeP","_config$flags2","self","storage","process","env","VERDACCIO_STORAGE_PATH","configPath","_config$config_path","config_path","self_path","Error","plugins","security","_","merge","defaultSecurity","serverSettings","flags","searchRemote","changePassword","user_agent","configProp","getUserAgent","userRateLimit","assert","isObject","APP_ERROR","CONFIG_NOT_VALID","forEach","x","uplinks","sanityCheckUplinksProps","uplinkSanityCheck","packages","normalisePackageAccess","envConf","toUpperCase","server_id","generateRandomHexString","getConfigPath","getMatchedPackagesSpec","pkgName","checkSecretKey","secret","_this$secret","isEmpty","generateRandomSecretKey","enhancedLegacySignature","warningUtils","emit","Codes","VERWAR005","length"],"sources":["../src/config.ts"],"sourcesContent":["import assert from 'assert';\nimport buildDebug from 'debug';\nimport _ from 'lodash';\n\nimport { APP_ERROR, warningUtils } from '@verdaccio/core';\nimport { Codes } from '@verdaccio/core/build/warning-utils';\nimport {\n Config as AppConfig,\n AuthConf,\n ConfigYaml,\n FlagsConfig,\n PackageAccess,\n PackageList,\n RateLimit,\n Security,\n ServerSettingsConf,\n} from '@verdaccio/types';\nimport { generateRandomHexString, getMatchedPackagesSpec, isObject } from '@verdaccio/utils';\n\nimport { getUserAgent } from './agent';\nimport { normalisePackageAccess } from './package-access';\nimport { defaultSecurity } from './security';\nimport serverSettings from './serverSettings';\nimport { generateRandomSecretKey } from './token';\nimport { sanityCheckUplinksProps, uplinkSanityCheck } from './uplinks';\n\nconst strategicConfigProps = ['uplinks', 'packages'];\nconst allowedEnvConfig = ['http_proxy', 'https_proxy', 'no_proxy'];\nconst debug = buildDebug('verdaccio:config');\n\nexport const WEB_TITLE = 'Verdaccio';\n\n// we limit max 1000 request per 15 minutes on user endpoints\nexport const defaultUserRateLimiting = {\n windowMs: 15 * 60 * 1000, // 15 minutes\n max: 1000,\n};\n\n/**\n * Coordinates the application configuration\n */\nclass Config implements AppConfig {\n public user_agent: string | undefined;\n public uplinks: any;\n public packages: PackageList;\n public users: any;\n public auth: AuthConf;\n public server_id: string;\n public configPath: string;\n /**\n * @deprecated use configPath or config.getConfigPath();\n */\n public self_path: string;\n public storage: string | void;\n\n public plugins: string | void | null;\n public security: Security;\n public serverSettings: ServerSettingsConf;\n // @ts-ignore\n public secret: string;\n public flags: FlagsConfig;\n public userRateLimit: RateLimit;\n private configOptions: { forceEnhancedLegacySignature: boolean };\n public constructor(\n config: ConfigYaml & { config_path: string },\n configOptions = { forceEnhancedLegacySignature: true }\n ) {\n const self = this;\n this.configOptions = configOptions;\n this.storage = process.env.VERDACCIO_STORAGE_PATH || config.storage;\n if (!config.configPath) {\n // backport self_path for previous to version 6\n // @ts-expect-error\n config.configPath = config.config_path ?? config.self_path;\n if (!config.configPath) {\n throw new Error('configPath property is required');\n }\n }\n this.configPath = config.configPath;\n this.self_path = this.configPath;\n debug('config path: %s', this.configPath);\n this.plugins = config.plugins;\n this.security = _.merge(defaultSecurity, config.security);\n this.serverSettings = serverSettings;\n this.flags = {\n searchRemote: config.flags?.searchRemote ?? true,\n changePassword: config.flags?.changePassword ?? false,\n };\n this.user_agent = config.user_agent;\n\n for (const configProp in config) {\n if (self[configProp] == null) {\n self[configProp] = config[configProp];\n }\n }\n\n if (typeof this.user_agent === 'undefined') {\n // by default user agent is hidden\n debug('set default user agent');\n this.user_agent = getUserAgent(false);\n }\n\n this.userRateLimit = { ...defaultUserRateLimiting, ...config?.userRateLimit };\n\n // some weird shell scripts are valid yaml files parsed as string\n assert(_.isObject(config), APP_ERROR.CONFIG_NOT_VALID);\n\n // sanity check for strategic config properties\n strategicConfigProps.forEach(function (x): void {\n if (self[x] == null) {\n self[x] = {};\n }\n\n assert(isObject(self[x]), `CONFIG: bad \"${x}\" value (object expected)`);\n });\n\n this.uplinks = sanityCheckUplinksProps(uplinkSanityCheck(this.uplinks));\n this.packages = normalisePackageAccess(self.packages);\n\n // loading these from ENV if aren't in config\n allowedEnvConfig.forEach((envConf): void => {\n if (!(envConf in self)) {\n self[envConf] = process.env[envConf] || process.env[envConf.toUpperCase()];\n }\n });\n\n // unique identifier of self server (or a cluster), used to avoid loops\n // @ts-ignore\n if (!this.server_id) {\n this.server_id = generateRandomHexString(6);\n }\n }\n\n public getConfigPath() {\n return this.configPath;\n }\n\n /**\n * Check for package spec\n */\n public getMatchedPackagesSpec(pkgName: string): PackageAccess | void {\n // TODO: remove this method and replace by library utils\n return getMatchedPackagesSpec(pkgName, this.packages);\n }\n\n /**\n * Store or create whether receive a secret key\n * @secret external secret key\n */\n public checkSecretKey(secret?: string): string {\n debug('check secret key');\n if (typeof secret === 'string' && _.isEmpty(secret) === false) {\n this.secret = secret;\n debug('reusing previous key');\n return secret;\n }\n // generate a new a secret key\n // FUTURE: this might be an external secret key, perhaps within config file?\n debug('generate a new key');\n //\n if (this.configOptions.forceEnhancedLegacySignature) {\n this.secret = generateRandomSecretKey();\n } else {\n this.secret =\n this.security.enhancedLegacySignature === true\n ? generateRandomSecretKey()\n : generateRandomHexString(32);\n // set this to false allow use old token signature and is not recommended\n // only use for migration reasons, major release will remove this property and\n // set it by default\n if (this.security.enhancedLegacySignature === false) {\n warningUtils.emit(Codes.VERWAR005);\n }\n }\n\n debug('generated a new secret key %s', this.secret?.length);\n return this.secret;\n }\n}\n\nexport { Config };\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"config.js","names":["_assert","_interopRequireDefault","require","_debug","_lodash","_core","_warningUtils","_utils","_agent","_packageAccess","_security","_serverSettings","_token","_uplinks","obj","__esModule","default","strategicConfigProps","allowedEnvConfig","debug","buildDebug","WEB_TITLE","exports","defaultUserRateLimiting","windowMs","max","Config","constructor","config","configOptions","forceEnhancedLegacySignature","_config$flags$searchR","_config$flags","_config$flags$changeP","_config$flags2","self","storage","process","env","VERDACCIO_STORAGE_PATH","configPath","_config$config_path","config_path","self_path","Error","plugins","security","_","merge","defaultSecurity","serverSettings","flags","searchRemote","changePassword","user_agent","configProp","getUserAgent","userRateLimit","assert","isObject","APP_ERROR","CONFIG_NOT_VALID","forEach","x","uplinks","sanityCheckUplinksProps","uplinkSanityCheck","packages","normalisePackageAccess","envConf","toUpperCase","server_id","generateRandomHexString","getEnhancedLegacySignature","enhancedLegacySignature","getConfigPath","getMatchedPackagesSpec","pkgName","checkSecretKey","secret","_this$security","_this$secret","isEmpty","generateRandomSecretKey","warningUtils","emit","Codes","VERWAR005","length"],"sources":["../src/config.ts"],"sourcesContent":["import assert from 'assert';\nimport buildDebug from 'debug';\nimport _ from 'lodash';\n\nimport { APP_ERROR, warningUtils } from '@verdaccio/core';\nimport { Codes } from '@verdaccio/core/build/warning-utils';\nimport {\n Config as AppConfig,\n AuthConf,\n ConfigYaml,\n FlagsConfig,\n PackageAccess,\n PackageList,\n RateLimit,\n Security,\n ServerSettingsConf,\n} from '@verdaccio/types';\nimport { generateRandomHexString, getMatchedPackagesSpec, isObject } from '@verdaccio/utils';\n\nimport { getUserAgent } from './agent';\nimport { normalisePackageAccess } from './package-access';\nimport { defaultSecurity } from './security';\nimport serverSettings from './serverSettings';\nimport { generateRandomSecretKey } from './token';\nimport { sanityCheckUplinksProps, uplinkSanityCheck } from './uplinks';\n\nconst strategicConfigProps = ['uplinks', 'packages'];\nconst allowedEnvConfig = ['http_proxy', 'https_proxy', 'no_proxy'];\nconst debug = buildDebug('verdaccio:config');\n\nexport const WEB_TITLE = 'Verdaccio';\n\n// we limit max 1000 request per 15 minutes on user endpoints\nexport const defaultUserRateLimiting = {\n windowMs: 15 * 60 * 1000, // 15 minutes\n max: 1000,\n};\n\n/**\n * Coordinates the application configuration\n */\nclass Config implements AppConfig {\n public user_agent: string | undefined;\n public uplinks: any;\n public packages: PackageList;\n public users: any;\n public auth: AuthConf;\n public server_id: string;\n public configPath: string;\n /**\n * @deprecated use configPath or config.getConfigPath();\n */\n public self_path: string;\n public storage: string | void;\n\n public plugins: string | void | null;\n public security: Security;\n public serverSettings: ServerSettingsConf;\n // @ts-ignore\n public secret: string;\n public flags: FlagsConfig;\n public userRateLimit: RateLimit;\n private configOptions: { forceEnhancedLegacySignature: boolean };\n public constructor(\n config: ConfigYaml & { config_path: string },\n // forceEnhancedLegacySignature is a property that\n // allows switch a new legacy aes signature token signature\n // for older versions do not want to have this new signature model\n // this property must be false\n configOptions = { forceEnhancedLegacySignature: true }\n ) {\n const self = this;\n this.configOptions = configOptions;\n this.storage = process.env.VERDACCIO_STORAGE_PATH || config.storage;\n if (!config.configPath) {\n // backport self_path for previous to version 6\n // @ts-expect-error\n config.configPath = config.config_path ?? config.self_path;\n if (!config.configPath) {\n throw new Error('configPath property is required');\n }\n }\n this.configPath = config.configPath;\n this.self_path = this.configPath;\n debug('config path: %s', this.configPath);\n this.plugins = config.plugins;\n this.security = _.merge(defaultSecurity, config.security);\n this.serverSettings = serverSettings;\n this.flags = {\n searchRemote: config.flags?.searchRemote ?? true,\n changePassword: config.flags?.changePassword ?? false,\n };\n this.user_agent = config.user_agent;\n\n for (const configProp in config) {\n if (self[configProp] == null) {\n self[configProp] = config[configProp];\n }\n }\n\n if (typeof this.user_agent === 'undefined') {\n // by default user agent is hidden\n debug('set default user agent');\n this.user_agent = getUserAgent(false);\n }\n\n this.userRateLimit = { ...defaultUserRateLimiting, ...config?.userRateLimit };\n\n // some weird shell scripts are valid yaml files parsed as string\n assert(_.isObject(config), APP_ERROR.CONFIG_NOT_VALID);\n\n // sanity check for strategic config properties\n strategicConfigProps.forEach(function (x): void {\n if (self[x] == null) {\n self[x] = {};\n }\n\n assert(isObject(self[x]), `CONFIG: bad \"${x}\" value (object expected)`);\n });\n\n this.uplinks = sanityCheckUplinksProps(uplinkSanityCheck(this.uplinks));\n this.packages = normalisePackageAccess(self.packages);\n\n // loading these from ENV if aren't in config\n allowedEnvConfig.forEach((envConf): void => {\n if (!(envConf in self)) {\n self[envConf] = process.env[envConf] || process.env[envConf.toUpperCase()];\n }\n });\n\n // unique identifier of self server (or a cluster), used to avoid loops\n // @ts-ignore\n if (!this.server_id) {\n this.server_id = generateRandomHexString(6);\n }\n }\n\n public getEnhancedLegacySignature() {\n if (typeof this?.security.enhancedLegacySignature !== 'undefined') {\n if (this.security.enhancedLegacySignature === true) {\n return true;\n }\n return false;\n }\n return this.configOptions.forceEnhancedLegacySignature;\n }\n\n public getConfigPath() {\n return this.configPath;\n }\n\n /**\n * Check for package spec\n */\n public getMatchedPackagesSpec(pkgName: string): PackageAccess | void {\n // TODO: remove this method and replace by library utils\n return getMatchedPackagesSpec(pkgName, this.packages);\n }\n\n /**\n * Store or create whether receive a secret key\n * @secret external secret key\n */\n public checkSecretKey(secret?: string): string {\n debug('check secret key');\n if (typeof secret === 'string' && _.isEmpty(secret) === false) {\n this.secret = secret;\n debug('reusing previous key');\n return secret;\n }\n // generate a new a secret key\n // FUTURE: this might be an external secret key, perhaps within config file?\n debug('generating a new secret key');\n\n if (this.getEnhancedLegacySignature()) {\n debug('key generated with \"enhanced\" legacy signature user config');\n this.secret = generateRandomSecretKey();\n } else {\n debug('key generated with legacy signature user config');\n this.secret = generateRandomHexString(32);\n }\n // set this to false allow use old token signature and is not recommended\n // only use for migration reasons, major release will remove this property and\n // set it by default\n if (this.security?.enhancedLegacySignature === false) {\n warningUtils.emit(Codes.VERWAR005);\n }\n\n debug('generated a new secret key length %s', this.secret?.length);\n return this.secret;\n }\n}\n\nexport { Config };\n"],"mappings":"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"}
|
package/build/package-access.js
CHANGED
|
@@ -28,7 +28,7 @@ const PACKAGE_ACCESS = exports.PACKAGE_ACCESS = {
|
|
|
28
28
|
};
|
|
29
29
|
function normalizeUserList(groupsList) {
|
|
30
30
|
const result = [];
|
|
31
|
-
if (_lodash.default.isNil(groupsList)) {
|
|
31
|
+
if (_lodash.default.isNil(groupsList) || _lodash.default.isEmpty(groupsList)) {
|
|
32
32
|
return result;
|
|
33
33
|
}
|
|
34
34
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"package-access.js","names":["_assert","_interopRequireDefault","require","_lodash","_core","obj","__esModule","default","ROLES","exports","$ALL","ALL","$AUTH","$ANONYMOUS","DEPRECATED_ALL","DEPRECATED_AUTH","DEPRECATED_ANONYMOUS","PACKAGE_ACCESS","SCOPE","normalizeUserList","groupsList","result","_","isNil","isString","groupsArray","split","push","Array","isArray","errorUtils","getInternalError","JSON","stringify","flatten","normalisePackageAccess","packages","normalizedPkgs","access","publish","unpublish","proxy","pkg","Object","prototype","hasOwnProperty","call","packageAccess","isInvalid","isObject","assert","isUndefined"],"sources":["../src/package-access.ts"],"sourcesContent":["import assert from 'assert';\nimport _ from 'lodash';\n\nimport { errorUtils } from '@verdaccio/core';\nimport { PackageAccess } from '@verdaccio/types';\n\nexport interface LegacyPackageList {\n [key: string]: PackageAccess;\n}\n\n// @deprecated use @verdaccio/core:authUtils\nexport const ROLES = {\n $ALL: '$all',\n ALL: 'all',\n $AUTH: '$authenticated',\n $ANONYMOUS: '$anonymous',\n DEPRECATED_ALL: '@all',\n DEPRECATED_AUTH: '@authenticated',\n DEPRECATED_ANONYMOUS: '@anonymous',\n};\n\n// @deprecated use @verdaccio/core:authUtils\nexport const PACKAGE_ACCESS = {\n SCOPE: '@*/*',\n ALL: '**',\n};\n\nexport function normalizeUserList(groupsList: any): any {\n const result: any[] = [];\n if (_.isNil(groupsList)) {\n return result;\n }\n\n // if it's a string, split it to array\n if (_.isString(groupsList)) {\n const groupsArray = groupsList.split(/\\s+/);\n\n result.push(groupsArray);\n } else if (Array.isArray(groupsList)) {\n result.push(groupsList);\n } else {\n throw errorUtils.getInternalError(\n 'CONFIG: bad package acl (array or string expected): ' + JSON.stringify(groupsList)\n );\n }\n\n return _.flatten(result);\n}\n\nexport function normalisePackageAccess(packages: LegacyPackageList): LegacyPackageList {\n const normalizedPkgs: LegacyPackageList = { ...packages };\n if (_.isNil(normalizedPkgs['**'])) {\n normalizedPkgs['**'] = {\n access: [],\n publish: [],\n unpublish: [],\n proxy: [],\n };\n }\n\n for (const pkg in packages) {\n if (Object.prototype.hasOwnProperty.call(packages, pkg)) {\n const packageAccess = packages[pkg];\n const isInvalid = _.isObject(packageAccess) && _.isArray(packageAccess) === false;\n assert(isInvalid, `CONFIG: bad \"'${pkg}'\" package description (object expected)`);\n\n normalizedPkgs[pkg].access = normalizeUserList(packageAccess.access);\n normalizedPkgs[pkg].publish = normalizeUserList(packageAccess.publish);\n normalizedPkgs[pkg].proxy = normalizeUserList(packageAccess.proxy);\n // if unpublish is not defined, we set to false to fallback in publish access\n normalizedPkgs[pkg].unpublish = _.isUndefined(packageAccess.unpublish)\n ? false\n : normalizeUserList(packageAccess.unpublish);\n }\n }\n\n return normalizedPkgs;\n}\n"],"mappings":";;;;;;;;AAAA,IAAAA,OAAA,GAAAC,sBAAA,CAAAC,OAAA;AACA,IAAAC,OAAA,GAAAF,sBAAA,CAAAC,OAAA;AAEA,IAAAE,KAAA,GAAAF,OAAA;AAA6C,SAAAD,uBAAAI,GAAA,WAAAA,GAAA,IAAAA,GAAA,CAAAC,UAAA,GAAAD,GAAA,KAAAE,OAAA,EAAAF,GAAA;AAO7C;AACO,MAAMG,KAAK,GAAAC,OAAA,CAAAD,KAAA,GAAG;EACnBE,IAAI,EAAE,MAAM;EACZC,GAAG,EAAE,KAAK;EACVC,KAAK,EAAE,gBAAgB;EACvBC,UAAU,EAAE,YAAY;EACxBC,cAAc,EAAE,MAAM;EACtBC,eAAe,EAAE,gBAAgB;EACjCC,oBAAoB,EAAE;AACxB,CAAC;;AAED;AACO,MAAMC,cAAc,GAAAR,OAAA,CAAAQ,cAAA,GAAG;EAC5BC,KAAK,EAAE,MAAM;EACbP,GAAG,EAAE;AACP,CAAC;AAEM,SAASQ,iBAAiBA,CAACC,UAAe,EAAO;EACtD,MAAMC,MAAa,GAAG,EAAE;EACxB,IAAIC,eAAC,CAACC,KAAK,CAACH,UAAU,CAAC,EAAE;
|
|
1
|
+
{"version":3,"file":"package-access.js","names":["_assert","_interopRequireDefault","require","_lodash","_core","obj","__esModule","default","ROLES","exports","$ALL","ALL","$AUTH","$ANONYMOUS","DEPRECATED_ALL","DEPRECATED_AUTH","DEPRECATED_ANONYMOUS","PACKAGE_ACCESS","SCOPE","normalizeUserList","groupsList","result","_","isNil","isEmpty","isString","groupsArray","split","push","Array","isArray","errorUtils","getInternalError","JSON","stringify","flatten","normalisePackageAccess","packages","normalizedPkgs","access","publish","unpublish","proxy","pkg","Object","prototype","hasOwnProperty","call","packageAccess","isInvalid","isObject","assert","isUndefined"],"sources":["../src/package-access.ts"],"sourcesContent":["import assert from 'assert';\nimport _ from 'lodash';\n\nimport { errorUtils } from '@verdaccio/core';\nimport { PackageAccess } from '@verdaccio/types';\n\nexport interface LegacyPackageList {\n [key: string]: PackageAccess;\n}\n\n// @deprecated use @verdaccio/core:authUtils\nexport const ROLES = {\n $ALL: '$all',\n ALL: 'all',\n $AUTH: '$authenticated',\n $ANONYMOUS: '$anonymous',\n DEPRECATED_ALL: '@all',\n DEPRECATED_AUTH: '@authenticated',\n DEPRECATED_ANONYMOUS: '@anonymous',\n};\n\n// @deprecated use @verdaccio/core:authUtils\nexport const PACKAGE_ACCESS = {\n SCOPE: '@*/*',\n ALL: '**',\n};\n\nexport function normalizeUserList(groupsList: any): any {\n const result: any[] = [];\n if (_.isNil(groupsList) || _.isEmpty(groupsList)) {\n return result;\n }\n\n // if it's a string, split it to array\n if (_.isString(groupsList)) {\n const groupsArray = groupsList.split(/\\s+/);\n\n result.push(groupsArray);\n } else if (Array.isArray(groupsList)) {\n result.push(groupsList);\n } else {\n throw errorUtils.getInternalError(\n 'CONFIG: bad package acl (array or string expected): ' + JSON.stringify(groupsList)\n );\n }\n\n return _.flatten(result);\n}\n\nexport function normalisePackageAccess(packages: LegacyPackageList): LegacyPackageList {\n const normalizedPkgs: LegacyPackageList = { ...packages };\n if (_.isNil(normalizedPkgs['**'])) {\n normalizedPkgs['**'] = {\n access: [],\n publish: [],\n unpublish: [],\n proxy: [],\n };\n }\n\n for (const pkg in packages) {\n if (Object.prototype.hasOwnProperty.call(packages, pkg)) {\n const packageAccess = packages[pkg];\n const isInvalid = _.isObject(packageAccess) && _.isArray(packageAccess) === false;\n assert(isInvalid, `CONFIG: bad \"'${pkg}'\" package description (object expected)`);\n\n normalizedPkgs[pkg].access = normalizeUserList(packageAccess.access);\n normalizedPkgs[pkg].publish = normalizeUserList(packageAccess.publish);\n normalizedPkgs[pkg].proxy = normalizeUserList(packageAccess.proxy);\n // if unpublish is not defined, we set to false to fallback in publish access\n normalizedPkgs[pkg].unpublish = _.isUndefined(packageAccess.unpublish)\n ? false\n : normalizeUserList(packageAccess.unpublish);\n }\n }\n\n return normalizedPkgs;\n}\n"],"mappings":"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"}
|
package/jest.config.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@verdaccio/config",
|
|
3
|
-
"version": "7.0.0-next.
|
|
3
|
+
"version": "7.0.0-next.6",
|
|
4
4
|
"description": "logger",
|
|
5
5
|
"main": "./build/index.js",
|
|
6
6
|
"types": "build/index.d.ts",
|
|
@@ -29,8 +29,8 @@
|
|
|
29
29
|
"node": ">=12"
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@verdaccio/core": "7.0.0-next.
|
|
33
|
-
"@verdaccio/utils": "7.0.0-next.
|
|
32
|
+
"@verdaccio/core": "7.0.0-next.6",
|
|
33
|
+
"@verdaccio/utils": "7.0.0-next.6",
|
|
34
34
|
"debug": "4.3.4",
|
|
35
35
|
"js-yaml": "4.1.0",
|
|
36
36
|
"lodash": "4.17.21",
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
41
41
|
"@types/minimatch": "5.1.2",
|
|
42
|
-
"@types/yup": "0.
|
|
42
|
+
"@types/yup": "0.32.0"
|
|
43
43
|
},
|
|
44
44
|
"funding": {
|
|
45
45
|
"type": "opencollective",
|
package/src/config.ts
CHANGED
|
@@ -63,6 +63,10 @@ class Config implements AppConfig {
|
|
|
63
63
|
private configOptions: { forceEnhancedLegacySignature: boolean };
|
|
64
64
|
public constructor(
|
|
65
65
|
config: ConfigYaml & { config_path: string },
|
|
66
|
+
// forceEnhancedLegacySignature is a property that
|
|
67
|
+
// allows switch a new legacy aes signature token signature
|
|
68
|
+
// for older versions do not want to have this new signature model
|
|
69
|
+
// this property must be false
|
|
66
70
|
configOptions = { forceEnhancedLegacySignature: true }
|
|
67
71
|
) {
|
|
68
72
|
const self = this;
|
|
@@ -131,6 +135,16 @@ class Config implements AppConfig {
|
|
|
131
135
|
}
|
|
132
136
|
}
|
|
133
137
|
|
|
138
|
+
public getEnhancedLegacySignature() {
|
|
139
|
+
if (typeof this?.security.enhancedLegacySignature !== 'undefined') {
|
|
140
|
+
if (this.security.enhancedLegacySignature === true) {
|
|
141
|
+
return true;
|
|
142
|
+
}
|
|
143
|
+
return false;
|
|
144
|
+
}
|
|
145
|
+
return this.configOptions.forceEnhancedLegacySignature;
|
|
146
|
+
}
|
|
147
|
+
|
|
134
148
|
public getConfigPath() {
|
|
135
149
|
return this.configPath;
|
|
136
150
|
}
|
|
@@ -156,24 +170,23 @@ class Config implements AppConfig {
|
|
|
156
170
|
}
|
|
157
171
|
// generate a new a secret key
|
|
158
172
|
// FUTURE: this might be an external secret key, perhaps within config file?
|
|
159
|
-
debug('
|
|
160
|
-
|
|
161
|
-
if (this.
|
|
173
|
+
debug('generating a new secret key');
|
|
174
|
+
|
|
175
|
+
if (this.getEnhancedLegacySignature()) {
|
|
176
|
+
debug('key generated with "enhanced" legacy signature user config');
|
|
162
177
|
this.secret = generateRandomSecretKey();
|
|
163
178
|
} else {
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
warningUtils.emit(Codes.VERWAR005);
|
|
173
|
-
}
|
|
179
|
+
debug('key generated with legacy signature user config');
|
|
180
|
+
this.secret = generateRandomHexString(32);
|
|
181
|
+
}
|
|
182
|
+
// set this to false allow use old token signature and is not recommended
|
|
183
|
+
// only use for migration reasons, major release will remove this property and
|
|
184
|
+
// set it by default
|
|
185
|
+
if (this.security?.enhancedLegacySignature === false) {
|
|
186
|
+
warningUtils.emit(Codes.VERWAR005);
|
|
174
187
|
}
|
|
175
188
|
|
|
176
|
-
debug('generated a new secret key %s', this.secret?.length);
|
|
189
|
+
debug('generated a new secret key length %s', this.secret?.length);
|
|
177
190
|
return this.secret;
|
|
178
191
|
}
|
|
179
192
|
}
|
package/src/package-access.ts
CHANGED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { getUserAgent } from '../src';
|
|
2
|
+
|
|
3
|
+
describe('getUserAgent', () => {
|
|
4
|
+
test('should return custom user agent when customUserAgent is true', () => {
|
|
5
|
+
const customUserAgent = true;
|
|
6
|
+
const version = '1.0.0';
|
|
7
|
+
const name = 'MyAgent';
|
|
8
|
+
|
|
9
|
+
const result = getUserAgent(customUserAgent, version, name);
|
|
10
|
+
|
|
11
|
+
expect(result).toBe('MyAgent/1.0.0');
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
test('should return custom user agent when customUserAgent is a non-empty string', () => {
|
|
15
|
+
const customUserAgent = 'CustomAgent/1.0.0';
|
|
16
|
+
const version = '1.0.0';
|
|
17
|
+
const name = 'MyAgent';
|
|
18
|
+
|
|
19
|
+
const result = getUserAgent(customUserAgent, version, name);
|
|
20
|
+
|
|
21
|
+
expect(result).toBe('CustomAgent/1.0.0');
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
test('should return "hidden" when customUserAgent is false', () => {
|
|
25
|
+
const customUserAgent = false;
|
|
26
|
+
const version = '1.0.0';
|
|
27
|
+
const name = 'MyAgent';
|
|
28
|
+
|
|
29
|
+
const result = getUserAgent(customUserAgent, version, name);
|
|
30
|
+
|
|
31
|
+
expect(result).toBe('hidden');
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
test('should return default user agent when customUserAgent is undefined', () => {
|
|
35
|
+
const version = '1.0.0';
|
|
36
|
+
const name = 'MyAgent';
|
|
37
|
+
|
|
38
|
+
const result = getUserAgent(undefined, version, name);
|
|
39
|
+
|
|
40
|
+
expect(result).toBe('MyAgent/1.0.0');
|
|
41
|
+
});
|
|
42
|
+
});
|
package/test/builder.spec.ts
CHANGED
|
@@ -13,6 +13,7 @@ describe('Config builder', () => {
|
|
|
13
13
|
proxy: 'some',
|
|
14
14
|
})
|
|
15
15
|
.addLogger({ level: 'info', type: 'stdout', format: 'json' })
|
|
16
|
+
.addAuth({ htpasswd: { file: '.htpasswd' } })
|
|
16
17
|
.addStorage('/tmp/verdaccio')
|
|
17
18
|
.addSecurity({ api: { legacy: true } });
|
|
18
19
|
expect(config.getConfig()).toEqual({
|
|
@@ -21,6 +22,11 @@ describe('Config builder', () => {
|
|
|
21
22
|
legacy: true,
|
|
22
23
|
},
|
|
23
24
|
},
|
|
25
|
+
auth: {
|
|
26
|
+
htpasswd: {
|
|
27
|
+
file: '.htpasswd',
|
|
28
|
+
},
|
|
29
|
+
},
|
|
24
30
|
storage: '/tmp/verdaccio',
|
|
25
31
|
packages: {
|
|
26
32
|
'upstream/*': {
|
package/test/config.spec.ts
CHANGED
|
@@ -106,6 +106,20 @@ describe('checkSecretKey', () => {
|
|
|
106
106
|
const config = new Config(parseConfigFile(resolveConf('default')));
|
|
107
107
|
expect(typeof config.checkSecretKey('') === 'string').toBeTruthy();
|
|
108
108
|
});
|
|
109
|
+
|
|
110
|
+
test('with enhanced legacy signature', () => {
|
|
111
|
+
const config = new Config(parseConfigFile(resolveConf('default')));
|
|
112
|
+
config.security.enhancedLegacySignature = true;
|
|
113
|
+
expect(typeof config.checkSecretKey() === 'string').toBeTruthy();
|
|
114
|
+
expect(config.secret.length).toBe(32);
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
test('without enhanced legacy signature', () => {
|
|
118
|
+
const config = new Config(parseConfigFile(resolveConf('default')));
|
|
119
|
+
config.security.enhancedLegacySignature = false;
|
|
120
|
+
expect(typeof config.checkSecretKey() === 'string').toBeTruthy();
|
|
121
|
+
expect(config.secret.length).toBe(64);
|
|
122
|
+
});
|
|
109
123
|
});
|
|
110
124
|
|
|
111
125
|
describe('getMatchedPackagesSpec', () => {
|
|
@@ -159,3 +173,18 @@ describe('VERDACCIO_STORAGE_PATH', () => {
|
|
|
159
173
|
delete process.env.VERDACCIO_STORAGE_PATH;
|
|
160
174
|
});
|
|
161
175
|
});
|
|
176
|
+
|
|
177
|
+
describe('configPath', () => {
|
|
178
|
+
test('should set configPath in config', () => {
|
|
179
|
+
const defaultConfig = parseConfigFile(resolveConf('default'));
|
|
180
|
+
const config = new Config(defaultConfig);
|
|
181
|
+
expect(config.getConfigPath()).toBe(path.join(__dirname, '../src/conf/default.yaml'));
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
test('should throw an error if configPath is not provided', () => {
|
|
185
|
+
const defaultConfig = parseConfigFile(resolveConf('default'));
|
|
186
|
+
defaultConfig.configPath = '';
|
|
187
|
+
defaultConfig.config_path = '';
|
|
188
|
+
expect(() => new Config(defaultConfig)).toThrow('configPath property is required');
|
|
189
|
+
});
|
|
190
|
+
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import _ from 'lodash';
|
|
2
2
|
|
|
3
3
|
import { parseConfigFile } from '../src';
|
|
4
|
-
import { PACKAGE_ACCESS, normalisePackageAccess } from '../src/package-access';
|
|
4
|
+
import { PACKAGE_ACCESS, normalisePackageAccess, normalizeUserList } from '../src/package-access';
|
|
5
5
|
import { parseConfigurationFile } from './utils';
|
|
6
6
|
|
|
7
7
|
describe('Package access utilities', () => {
|
|
@@ -123,4 +123,30 @@ describe('Package access utilities', () => {
|
|
|
123
123
|
expect(_.isArray(all.publish)).toBeTruthy();
|
|
124
124
|
});
|
|
125
125
|
});
|
|
126
|
+
describe('normaliseUserList', () => {
|
|
127
|
+
test('should normalize user list', () => {
|
|
128
|
+
const groupsList = 'admin superadmin';
|
|
129
|
+
const result = normalizeUserList(groupsList);
|
|
130
|
+
expect(result).toEqual(['admin', 'superadmin']);
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
test('should normalize empty user list', () => {
|
|
134
|
+
const groupsList = '';
|
|
135
|
+
const result = normalizeUserList(groupsList);
|
|
136
|
+
expect(result).toEqual([]);
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
test('should normalize user list array', () => {
|
|
140
|
+
const groupsList = ['admin', 'superadmin'];
|
|
141
|
+
const result = normalizeUserList(groupsList);
|
|
142
|
+
expect(result).toEqual(['admin', 'superadmin']);
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
test('should throw error for invalid user list', () => {
|
|
146
|
+
const groupsList = { group: 'admin' };
|
|
147
|
+
expect(() => {
|
|
148
|
+
normalizeUserList(groupsList);
|
|
149
|
+
}).toThrow('CONFIG: bad package acl (array or string expected): {"group":"admin"}');
|
|
150
|
+
});
|
|
151
|
+
});
|
|
126
152
|
});
|