@verdaccio/auth 6.0.0-6-next.12 → 6.0.0-6-next.13
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 +23 -0
- package/build/auth.js +9 -9
- package/build/auth.js.map +1 -1
- package/build/utils.d.ts +1 -1
- package/build/utils.js +9 -9
- package/build/utils.js.map +1 -1
- package/package.json +10 -10
- package/src/auth.ts +7 -9
- package/src/utils.ts +12 -11
- package/test/auth-utils.spec.ts +9 -5
- package/test/auth.spec.ts +2 -2
- package/tsconfig.json +0 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,28 @@
|
|
|
1
1
|
# @verdaccio/auth
|
|
2
2
|
|
|
3
|
+
## 6.0.0-6-next.13
|
|
4
|
+
|
|
5
|
+
### Major Changes
|
|
6
|
+
|
|
7
|
+
- 794af76c: Remove Node 12 support
|
|
8
|
+
|
|
9
|
+
- We need move to the new `undici` and does not support Node.js 12
|
|
10
|
+
|
|
11
|
+
### Minor Changes
|
|
12
|
+
|
|
13
|
+
- 154b2ecd: refactor: remove @verdaccio/commons-api in favor @verdaccio/core and remove duplications
|
|
14
|
+
|
|
15
|
+
### Patch Changes
|
|
16
|
+
|
|
17
|
+
- Updated dependencies [794af76c]
|
|
18
|
+
- Updated dependencies [154b2ecd]
|
|
19
|
+
- @verdaccio/config@6.0.0-6-next.9
|
|
20
|
+
- @verdaccio/core@6.0.0-6-next.2
|
|
21
|
+
- verdaccio-htpasswd@11.0.0-6-next.9
|
|
22
|
+
- @verdaccio/loaders@6.0.0-6-next.6
|
|
23
|
+
- @verdaccio/logger@6.0.0-6-next.6
|
|
24
|
+
- @verdaccio/utils@6.0.0-6-next.7
|
|
25
|
+
|
|
3
26
|
## 6.0.0-6-next.12
|
|
4
27
|
|
|
5
28
|
### Patch Changes
|
package/build/auth.js
CHANGED
|
@@ -9,7 +9,7 @@ var _lodash = _interopRequireDefault(require("lodash"));
|
|
|
9
9
|
|
|
10
10
|
var _debug = _interopRequireDefault(require("debug"));
|
|
11
11
|
|
|
12
|
-
var
|
|
12
|
+
var _core = require("@verdaccio/core");
|
|
13
13
|
|
|
14
14
|
var _loaders = require("@verdaccio/loaders");
|
|
15
15
|
|
|
@@ -106,7 +106,7 @@ class Auth {
|
|
|
106
106
|
const validPlugins = _lodash.default.filter(this.plugins, plugin => (0, _utils.isFunction)(plugin.changePassword));
|
|
107
107
|
|
|
108
108
|
if (_lodash.default.isEmpty(validPlugins)) {
|
|
109
|
-
return cb(
|
|
109
|
+
return cb(_core.errorUtils.getInternalError(_core.SUPPORT_ERRORS.PLUGIN_MISSING_INTERFACE));
|
|
110
110
|
}
|
|
111
111
|
|
|
112
112
|
for (const plugin of validPlugins) {
|
|
@@ -165,7 +165,7 @@ class Auth {
|
|
|
165
165
|
const isGroupValid = _lodash.default.isArray(groups);
|
|
166
166
|
|
|
167
167
|
if (!isGroupValid) {
|
|
168
|
-
throw new TypeError(
|
|
168
|
+
throw new TypeError(_core.API_ERROR.BAD_FORMAT_USER_GROUP);
|
|
169
169
|
}
|
|
170
170
|
|
|
171
171
|
debug('authentication for user %o was successfully. Groups: %o', username, groups);
|
|
@@ -380,7 +380,7 @@ class Auth {
|
|
|
380
380
|
|
|
381
381
|
if (!(0, _utils2.isAuthHeaderValid)(authorization)) {
|
|
382
382
|
debug('api middleware authentication heather is invalid');
|
|
383
|
-
return next(
|
|
383
|
+
return next(_core.errorUtils.getBadRequest(_core.API_ERROR.BAD_AUTH_HEADER));
|
|
384
384
|
}
|
|
385
385
|
|
|
386
386
|
const {
|
|
@@ -407,7 +407,7 @@ class Auth {
|
|
|
407
407
|
token
|
|
408
408
|
} = (0, _utils2.parseAuthTokenHeader)(authorization);
|
|
409
409
|
|
|
410
|
-
if (scheme.toUpperCase() ===
|
|
410
|
+
if (scheme.toUpperCase() === _core.TOKEN_BASIC.toUpperCase()) {
|
|
411
411
|
debug('handle basic token'); // this should happen when client tries to login with an existing user
|
|
412
412
|
|
|
413
413
|
const credentials = (0, _utils2.convertPayloadToBase64)(token).toString();
|
|
@@ -439,7 +439,7 @@ class Auth {
|
|
|
439
439
|
} else {
|
|
440
440
|
// with JWT throw 401
|
|
441
441
|
debug('jwt invalid token');
|
|
442
|
-
next(
|
|
442
|
+
next(_core.errorUtils.getForbidden(_core.API_ERROR.BAD_USERNAME_PASSWORD));
|
|
443
443
|
}
|
|
444
444
|
}
|
|
445
445
|
}
|
|
@@ -471,7 +471,7 @@ class Auth {
|
|
|
471
471
|
} else {
|
|
472
472
|
// we force npm client to ask again with basic authentication
|
|
473
473
|
debug('legacy invalid header');
|
|
474
|
-
return next(
|
|
474
|
+
return next(_core.errorUtils.getBadRequest(_core.API_ERROR.BAD_AUTH_HEADER));
|
|
475
475
|
}
|
|
476
476
|
}
|
|
477
477
|
|
|
@@ -511,10 +511,10 @@ class Auth {
|
|
|
511
511
|
}
|
|
512
512
|
|
|
513
513
|
if (!(0, _utils2.isAuthHeaderValid)(authorization)) {
|
|
514
|
-
return next(
|
|
514
|
+
return next(_core.errorUtils.getBadRequest(_core.API_ERROR.BAD_AUTH_HEADER));
|
|
515
515
|
}
|
|
516
516
|
|
|
517
|
-
const token = (authorization || '').replace(`${
|
|
517
|
+
const token = (authorization || '').replace(`${_core.TOKEN_BEARER} `, '');
|
|
518
518
|
|
|
519
519
|
if (!token) {
|
|
520
520
|
return next();
|
package/build/auth.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/auth.ts"],"names":["LoggerApi","require","debug","Auth","constructor","config","logger","child","sub","secret","plugins","_","isNil","auth","_loadPlugin","loadDefaultPlugin","_applyDefaultPlugins","plugingConf","file","pluginOptions","authPlugin","HTPasswd","error","plugin","authenticate","allow_access","allow_publish","push","changePassword","username","password","newPassword","cb","validPlugins","filter","isEmpty","SUPPORT_ERRORS","PLUGIN_MISSING_INTERFACE","err","profile","slice","next","shift","groups","message","length","isString","TypeError","isGroupValid","isArray","API_ERROR","BAD_FORMAT_USER_GROUP","add_user","user","self","method","warn","ok","packageName","packageVersion","callback","pkgAllowAcces","name","version","pkg","Object","assign","packages","allow_unpublish","arguments","isError","apiJWTmiddleware","helpers","createAnonymousRemoteUser","createRemoteUser","req","res","_next","pause","resume","remote_user","_isRemoteUserValid","authorization","headers","BAD_AUTH_HEADER","security","_handleAESMiddleware","_handleJWTAPIMiddleware","scheme","token","toUpperCase","TOKEN_BASIC","credentials","toString","BAD_USERNAME_PASSWORD","isUndefined","webUIJWTmiddleware","status","statusCode","send","replace","TOKEN_BEARER","jwtEncrypt","signOptions","real_groups","realGroupsValidated","groupedGroups","concat","payload","aesEncrypt","value"],"mappings":"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","sourcesContent":["import _ from 'lodash';\nimport { NextFunction, Request, Response } from 'express';\nimport buildDebug from 'debug';\n\nimport {\n API_ERROR,\n SUPPORT_ERRORS,\n TOKEN_BASIC,\n TOKEN_BEARER,\n VerdaccioError,\n getBadRequest,\n getInternalError,\n getForbidden,\n} from '@verdaccio/commons-api';\nimport { loadPlugin } from '@verdaccio/loaders';\nimport { HTPasswd, HTPasswdConfig } from 'verdaccio-htpasswd';\n\nimport {\n Config,\n Logger,\n Callback,\n IPluginAuth,\n RemoteUser,\n JWTSignOptions,\n Security,\n AuthPluginPackage,\n AllowAccess,\n PackageAccess,\n PluginOptions,\n} from '@verdaccio/types';\n\nimport { getMatchedPackagesSpec, isNil, isFunction } from '@verdaccio/utils';\nimport { createAnonymousRemoteUser, createRemoteUser } from '@verdaccio/config';\n\nimport {\n getMiddlewareCredentials,\n getDefaultPlugins,\n verifyJWTPayload,\n parseAuthTokenHeader,\n isAuthHeaderValid,\n isAESLegacy,\n convertPayloadToBase64,\n} from './utils';\n\nimport { signPayload } from './jwt-token';\nimport { aesEncrypt } from './legacy-token';\nimport { parseBasicPayload } from './token';\n\n/* eslint-disable @typescript-eslint/no-var-requires */\nconst LoggerApi = require('@verdaccio/logger');\n\nconst debug = buildDebug('verdaccio:auth');\n\nexport interface IBasicAuth<T> {\n config: T & Config;\n authenticate(user: string, password: string, cb: Callback): void;\n changePassword(user: string, password: string, newPassword: string, cb: Callback): void;\n allow_access(pkg: AuthPluginPackage, user: RemoteUser, callback: Callback): void;\n add_user(user: string, password: string, cb: Callback): any;\n}\n\nexport interface TokenEncryption {\n jwtEncrypt(user: RemoteUser, signOptions: JWTSignOptions): Promise<string>;\n aesEncrypt(buf: string): string | void;\n}\n\nexport interface AESPayload {\n user: string;\n password: string;\n}\n\nexport type $RequestExtend = Request & { remote_user?: any; log: Logger };\nexport type $ResponseExtend = Response & { cookies?: any };\nexport type $NextFunctionVer = NextFunction & any;\n\nexport interface IAuthMiddleware {\n apiJWTmiddleware(): $NextFunctionVer;\n webUIJWTmiddleware(): $NextFunctionVer;\n}\n\nexport interface IAuth extends IBasicAuth<Config>, IAuthMiddleware, TokenEncryption {\n config: Config;\n logger: Logger;\n secret: string;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n plugins: any[];\n allow_unpublish(pkg: AuthPluginPackage, user: RemoteUser, callback: Callback): void;\n}\n\nclass Auth implements IAuth {\n public config: Config;\n public logger: Logger;\n public secret: string;\n public plugins: IPluginAuth<Config>[];\n\n public constructor(config: Config) {\n this.config = config;\n this.logger = LoggerApi.logger.child({ sub: 'auth' });\n this.secret = config.secret;\n\n this.plugins =\n _.isNil(config?.auth) === false ? this._loadPlugin(config) : this.loadDefaultPlugin(config);\n this._applyDefaultPlugins();\n }\n\n private loadDefaultPlugin(config: Config) {\n const plugingConf: HTPasswdConfig = { ...config, file: './htpasswd' };\n const pluginOptions: PluginOptions<{}> = {\n config,\n logger: this.logger,\n };\n let authPlugin;\n try {\n authPlugin = new HTPasswd(plugingConf, pluginOptions);\n } catch (error: any) {\n debug('error on loading auth htpasswd plugin stack: %o', error);\n return [];\n }\n\n return [authPlugin];\n }\n\n private _loadPlugin(config: Config): IPluginAuth<Config>[] {\n const pluginOptions = {\n config,\n logger: this.logger,\n };\n\n return loadPlugin<IPluginAuth<Config>>(\n config,\n config.auth,\n pluginOptions,\n (plugin: IPluginAuth<Config>): boolean => {\n const { authenticate, allow_access, allow_publish } = plugin;\n\n // @ts-ignore\n return authenticate || allow_access || allow_publish;\n }\n );\n }\n\n private _applyDefaultPlugins(): void {\n // TODO: rename to applyFallbackPluginMethods\n this.plugins.push(getDefaultPlugins(this.logger));\n }\n\n public changePassword(\n username: string,\n password: string,\n newPassword: string,\n cb: Callback\n ): void {\n const validPlugins = _.filter(this.plugins, (plugin) => isFunction(plugin.changePassword));\n\n if (_.isEmpty(validPlugins)) {\n return cb(getInternalError(SUPPORT_ERRORS.PLUGIN_MISSING_INTERFACE));\n }\n\n for (const plugin of validPlugins) {\n if (isNil(plugin) || isFunction(plugin.changePassword) === false) {\n debug('auth plugin does not implement changePassword, trying next one');\n continue;\n } else {\n debug('updating password for %o', username);\n plugin.changePassword!(username, password, newPassword, (err, profile): void => {\n if (err) {\n this.logger.error(\n { username, err },\n `An error has been produced\n updating the password for @{username}. Error: @{err.message}`\n );\n return cb(err);\n }\n\n debug('updated password for %o was successful', username);\n return cb(null, profile);\n });\n }\n }\n }\n\n public authenticate(username: string, password: string, cb: Callback): void {\n const plugins = this.plugins.slice(0);\n (function next(): void {\n const plugin = plugins.shift() as IPluginAuth<Config>;\n\n if (isFunction(plugin.authenticate) === false) {\n return next();\n }\n\n debug('authenticating %o', username);\n plugin.authenticate(username, password, function (err, groups): void {\n if (err) {\n debug('authenticating for user %o failed. Error: %o', username, err?.message);\n return cb(err);\n }\n\n // Expect: SKIP if groups is falsey and not an array\n // with at least one item (truthy length)\n // Expect: CONTINUE otherwise (will error if groups is not\n // an array, but this is current behavior)\n // Caveat: STRING (if valid) will pass successfully\n // bug give unexpected results\n // Info: Cannot use `== false to check falsey values`\n if (!!groups && groups.length !== 0) {\n // TODO: create a better understanding of expectations\n if (_.isString(groups)) {\n throw new TypeError('plugin group error: invalid type for function');\n }\n const isGroupValid: boolean = _.isArray(groups);\n if (!isGroupValid) {\n throw new TypeError(API_ERROR.BAD_FORMAT_USER_GROUP);\n }\n\n debug('authentication for user %o was successfully. Groups: %o', username, groups);\n return cb(err, createRemoteUser(username, groups));\n }\n next();\n });\n })();\n }\n\n public add_user(user: string, password: string, cb: Callback): void {\n const self = this;\n const plugins = this.plugins.slice(0);\n debug('add user %o', user);\n\n (function next(): void {\n const plugin = plugins.shift() as IPluginAuth<Config>;\n let method = 'adduser';\n if (isFunction(plugin[method]) === false) {\n method = 'add_user';\n self.logger.warn(\n 'the plugin method add_user in the auth plugin is deprecated and will' +\n ' be removed in next major release, notify to the plugin author'\n );\n }\n\n if (isFunction(plugin[method]) === false) {\n next();\n } else {\n // p.add_user() execution\n plugin[method](user, password, function (err, ok): void {\n if (err) {\n debug('the user %o could not being added. Error: %o', user, err?.message);\n return cb(err);\n }\n if (ok) {\n debug('the user %o has been added', user);\n return self.authenticate(user, password, cb);\n }\n next();\n });\n }\n })();\n }\n\n /**\n * Allow user to access a package.\n */\n public allow_access(\n { packageName, packageVersion }: AuthPluginPackage,\n user: RemoteUser,\n callback: Callback\n ): void {\n const plugins = this.plugins.slice(0);\n const pkgAllowAcces: AllowAccess = { name: packageName, version: packageVersion };\n const pkg = Object.assign(\n {},\n pkgAllowAcces,\n getMatchedPackagesSpec(packageName, this.config.packages)\n ) as AllowAccess & PackageAccess;\n debug('allow access for %o', packageName);\n\n (function next(): void {\n const plugin: IPluginAuth<Config> = plugins.shift() as IPluginAuth<Config>;\n\n if (_.isNil(plugin) || isFunction(plugin.allow_access) === false) {\n return next();\n }\n\n plugin.allow_access!(user, pkg, function (err, ok: boolean): void {\n if (err) {\n debug('forbidden access for %o. Error: %o', packageName, err?.message);\n return callback(err);\n }\n\n if (ok) {\n debug('allowed access for %o', packageName);\n return callback(null, ok);\n }\n\n next(); // cb(null, false) causes next plugin to roll\n });\n })();\n }\n\n public allow_unpublish(\n { packageName, packageVersion }: AuthPluginPackage,\n user: RemoteUser,\n callback: Callback\n ): void {\n const pkg = Object.assign(\n { name: packageName, version: packageVersion },\n getMatchedPackagesSpec(packageName, this.config.packages)\n );\n debug('allow unpublish for %o', packageName);\n\n for (const plugin of this.plugins) {\n if (_.isNil(plugin) || isFunction(plugin.allow_unpublish) === false) {\n debug('allow unpublish for %o plugin does not implement allow_unpublish', packageName);\n continue;\n } else {\n // @ts-ignore\n plugin.allow_unpublish!(user, pkg, (err, ok: boolean): void => {\n if (err) {\n debug(\n 'forbidden publish for %o, it will fallback on unpublish permissions',\n packageName\n );\n return callback(err);\n }\n\n if (_.isNil(ok) === true) {\n debug('bypass unpublish for %o, publish will handle the access', packageName);\n // @ts-ignore\n // eslint-disable-next-line\n return this.allow_publish(...arguments);\n }\n\n if (ok) {\n debug('allowed unpublish for %o', packageName);\n return callback(null, ok);\n }\n });\n }\n }\n }\n\n /**\n * Allow user to publish a package.\n */\n public allow_publish(\n { packageName, packageVersion }: AuthPluginPackage,\n user: RemoteUser,\n callback: Callback\n ): void {\n const plugins = this.plugins.slice(0);\n const pkg = Object.assign(\n { name: packageName, version: packageVersion },\n getMatchedPackagesSpec(packageName, this.config.packages)\n );\n debug('allow publish for %o init | plugins: %o', packageName, plugins.length);\n\n (function next(): void {\n const plugin = plugins.shift();\n\n if (isFunction(plugin?.allow_publish) === false) {\n debug('allow publish for %o plugin does not implement allow_publish', packageName);\n return next();\n }\n\n // @ts-ignore\n plugin.allow_publish(\n user,\n // @ts-ignore\n pkg,\n // @ts-ignore\n (err: VerdaccioError, ok: boolean): void => {\n if (_.isNil(err) === false && _.isError(err)) {\n debug('forbidden publish for %o', packageName);\n return callback(err);\n }\n\n if (ok) {\n debug('allowed publish for %o', packageName);\n return callback(null, ok);\n }\n\n debug('allow publish skip validation for %o', packageName);\n next(); // cb(null, false) causes next plugin to roll\n }\n );\n })();\n }\n\n public apiJWTmiddleware(): Function {\n debug('jwt middleware');\n const plugins = this.plugins.slice(0);\n const helpers = { createAnonymousRemoteUser, createRemoteUser };\n for (const plugin of plugins) {\n if (plugin.apiJWTmiddleware) {\n return plugin.apiJWTmiddleware(helpers);\n }\n }\n\n return (req: $RequestExtend, res: $ResponseExtend, _next: NextFunction): void => {\n req.pause();\n\n const next = function (err: VerdaccioError | void): void {\n req.resume();\n // uncomment this to reject users with bad auth headers\n // return _next.apply(null, arguments)\n // swallow error, user remains unauthorized\n // set remoteUserError to indicate that user was attempting authentication\n if (err) {\n req.remote_user.error = err.message;\n }\n return _next();\n };\n\n if (this._isRemoteUserValid(req.remote_user)) {\n debug('jwt has a valid authentication header');\n return next();\n }\n\n // in case auth header does not exist we return anonymous function\n req.remote_user = createAnonymousRemoteUser();\n\n const { authorization } = req.headers;\n if (_.isNil(authorization)) {\n debug('jwt, authentication header is missing');\n return next();\n }\n\n if (!isAuthHeaderValid(authorization)) {\n debug('api middleware authentication heather is invalid');\n return next(getBadRequest(API_ERROR.BAD_AUTH_HEADER));\n }\n const { secret, security } = this.config;\n\n if (isAESLegacy(security)) {\n debug('api middleware using legacy auth token');\n this._handleAESMiddleware(req, security, secret, authorization, next);\n } else {\n debug('api middleware using JWT auth token');\n this._handleJWTAPIMiddleware(req, security, secret, authorization, next);\n }\n };\n }\n\n private _handleJWTAPIMiddleware(\n req: $RequestExtend,\n security: Security,\n secret: string,\n authorization: string,\n next: Function\n ): void {\n debug('handle JWT api middleware');\n const { scheme, token } = parseAuthTokenHeader(authorization);\n if (scheme.toUpperCase() === TOKEN_BASIC.toUpperCase()) {\n debug('handle basic token');\n // this should happen when client tries to login with an existing user\n const credentials = convertPayloadToBase64(token).toString();\n const { user, password } = parseBasicPayload(credentials) as AESPayload;\n debug('authenticating %o', user);\n this.authenticate(user, password, (err, user): void => {\n if (!err) {\n debug('generating a remote user');\n req.remote_user = user;\n next();\n } else {\n debug('generating anonymous user');\n req.remote_user = createAnonymousRemoteUser();\n next(err);\n }\n });\n } else {\n debug('handle jwt token');\n const credentials: any = getMiddlewareCredentials(security, secret, authorization);\n if (credentials) {\n // if the signature is valid we rely on it\n req.remote_user = credentials;\n debug('generating a remote user');\n next();\n } else {\n // with JWT throw 401\n debug('jwt invalid token');\n next(getForbidden(API_ERROR.BAD_USERNAME_PASSWORD));\n }\n }\n }\n\n private _handleAESMiddleware(\n req: $RequestExtend,\n security: Security,\n secret: string,\n authorization: string,\n next: Function\n ): void {\n debug('handle legacy api middleware');\n debug('api middleware secret %o', secret);\n debug('api middleware authorization %o', authorization);\n const credentials: any = getMiddlewareCredentials(security, secret, authorization);\n debug('api middleware credentials %o', credentials);\n if (credentials) {\n const { user, password } = credentials;\n debug('authenticating %o', user);\n this.authenticate(user, password, (err, user): void => {\n if (!err) {\n req.remote_user = user;\n debug('generating a remote user');\n next();\n } else {\n req.remote_user = createAnonymousRemoteUser();\n debug('generating anonymous user');\n next(err);\n }\n });\n } else {\n // we force npm client to ask again with basic authentication\n debug('legacy invalid header');\n return next(getBadRequest(API_ERROR.BAD_AUTH_HEADER));\n }\n }\n\n private _isRemoteUserValid(remote_user: RemoteUser): boolean {\n return _.isUndefined(remote_user) === false && _.isUndefined(remote_user.name) === false;\n }\n\n /**\n * JWT middleware for WebUI\n */\n public webUIJWTmiddleware(): Function {\n return (req: $RequestExtend, res: $ResponseExtend, _next: NextFunction): void => {\n if (this._isRemoteUserValid(req.remote_user)) {\n return _next();\n }\n\n req.pause();\n const next = (err: VerdaccioError | void): void => {\n req.resume();\n if (err) {\n // req.remote_user.error = err.message;\n res.status(err.statusCode).send(err.message);\n }\n\n return _next();\n };\n\n const { authorization } = req.headers;\n if (_.isNil(authorization)) {\n return next();\n }\n\n if (!isAuthHeaderValid(authorization)) {\n return next(getBadRequest(API_ERROR.BAD_AUTH_HEADER));\n }\n\n const token = (authorization || '').replace(`${TOKEN_BEARER} `, '');\n if (!token) {\n return next();\n }\n\n let credentials;\n try {\n credentials = verifyJWTPayload(token, this.config.secret);\n } catch (err: any) {\n // FIXME: intended behaviour, do we want it?\n }\n\n if (this._isRemoteUserValid(credentials)) {\n const { name, groups } = credentials;\n // $FlowFixMe\n req.remote_user = createRemoteUser(name, groups);\n } else {\n req.remote_user = createAnonymousRemoteUser();\n }\n\n next();\n };\n }\n\n public async jwtEncrypt(user: RemoteUser, signOptions: JWTSignOptions): Promise<string> {\n const { real_groups, name, groups } = user;\n debug('jwt encrypt %o', name);\n const realGroupsValidated = _.isNil(real_groups) ? [] : real_groups;\n const groupedGroups = _.isNil(groups) ? real_groups : groups.concat(realGroupsValidated);\n const payload: RemoteUser = {\n real_groups: realGroupsValidated,\n name,\n groups: groupedGroups,\n };\n\n const token: string = await signPayload(payload, this.secret, signOptions);\n\n return token;\n }\n\n /**\n * Encrypt a string.\n */\n public aesEncrypt(value: string): string | void {\n return aesEncrypt(value, this.secret);\n }\n}\n\nexport { Auth };\n"],"file":"auth.js"}
|
|
1
|
+
{"version":3,"sources":["../src/auth.ts"],"names":["LoggerApi","require","debug","Auth","constructor","config","logger","child","sub","secret","plugins","_","isNil","auth","_loadPlugin","loadDefaultPlugin","_applyDefaultPlugins","plugingConf","file","pluginOptions","authPlugin","HTPasswd","error","plugin","authenticate","allow_access","allow_publish","push","changePassword","username","password","newPassword","cb","validPlugins","filter","isEmpty","errorUtils","getInternalError","SUPPORT_ERRORS","PLUGIN_MISSING_INTERFACE","err","profile","slice","next","shift","groups","message","length","isString","TypeError","isGroupValid","isArray","API_ERROR","BAD_FORMAT_USER_GROUP","add_user","user","self","method","warn","ok","packageName","packageVersion","callback","pkgAllowAcces","name","version","pkg","Object","assign","packages","allow_unpublish","arguments","isError","apiJWTmiddleware","helpers","createAnonymousRemoteUser","createRemoteUser","req","res","_next","pause","resume","remote_user","_isRemoteUserValid","authorization","headers","getBadRequest","BAD_AUTH_HEADER","security","_handleAESMiddleware","_handleJWTAPIMiddleware","scheme","token","toUpperCase","TOKEN_BASIC","credentials","toString","getForbidden","BAD_USERNAME_PASSWORD","isUndefined","webUIJWTmiddleware","status","statusCode","send","replace","TOKEN_BEARER","jwtEncrypt","signOptions","real_groups","realGroupsValidated","groupedGroups","concat","payload","aesEncrypt","value"],"mappings":"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","sourcesContent":["import _ from 'lodash';\nimport { NextFunction, Request, Response } from 'express';\nimport buildDebug from 'debug';\n\nimport {\n API_ERROR,\n SUPPORT_ERRORS,\n TOKEN_BASIC,\n TOKEN_BEARER,\n VerdaccioError,\n errorUtils,\n} from '@verdaccio/core';\nimport { loadPlugin } from '@verdaccio/loaders';\nimport { HTPasswd, HTPasswdConfig } from 'verdaccio-htpasswd';\n\nimport {\n Config,\n Logger,\n Callback,\n IPluginAuth,\n RemoteUser,\n JWTSignOptions,\n Security,\n AuthPluginPackage,\n AllowAccess,\n PackageAccess,\n PluginOptions,\n} from '@verdaccio/types';\n\nimport { getMatchedPackagesSpec, isNil, isFunction } from '@verdaccio/utils';\nimport { createAnonymousRemoteUser, createRemoteUser } from '@verdaccio/config';\n\nimport {\n getMiddlewareCredentials,\n getDefaultPlugins,\n verifyJWTPayload,\n parseAuthTokenHeader,\n isAuthHeaderValid,\n isAESLegacy,\n convertPayloadToBase64,\n} from './utils';\n\nimport { signPayload } from './jwt-token';\nimport { aesEncrypt } from './legacy-token';\nimport { parseBasicPayload } from './token';\n\n/* eslint-disable @typescript-eslint/no-var-requires */\nconst LoggerApi = require('@verdaccio/logger');\n\nconst debug = buildDebug('verdaccio:auth');\n\nexport interface IBasicAuth<T> {\n config: T & Config;\n authenticate(user: string, password: string, cb: Callback): void;\n changePassword(user: string, password: string, newPassword: string, cb: Callback): void;\n allow_access(pkg: AuthPluginPackage, user: RemoteUser, callback: Callback): void;\n add_user(user: string, password: string, cb: Callback): any;\n}\n\nexport interface TokenEncryption {\n jwtEncrypt(user: RemoteUser, signOptions: JWTSignOptions): Promise<string>;\n aesEncrypt(buf: string): string | void;\n}\n\nexport interface AESPayload {\n user: string;\n password: string;\n}\n\nexport type $RequestExtend = Request & { remote_user?: any; log: Logger };\nexport type $ResponseExtend = Response & { cookies?: any };\nexport type $NextFunctionVer = NextFunction & any;\n\nexport interface IAuthMiddleware {\n apiJWTmiddleware(): $NextFunctionVer;\n webUIJWTmiddleware(): $NextFunctionVer;\n}\n\nexport interface IAuth extends IBasicAuth<Config>, IAuthMiddleware, TokenEncryption {\n config: Config;\n logger: Logger;\n secret: string;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n plugins: any[];\n allow_unpublish(pkg: AuthPluginPackage, user: RemoteUser, callback: Callback): void;\n}\n\nclass Auth implements IAuth {\n public config: Config;\n public logger: Logger;\n public secret: string;\n public plugins: IPluginAuth<Config>[];\n\n public constructor(config: Config) {\n this.config = config;\n this.logger = LoggerApi.logger.child({ sub: 'auth' });\n this.secret = config.secret;\n\n this.plugins =\n _.isNil(config?.auth) === false ? this._loadPlugin(config) : this.loadDefaultPlugin(config);\n this._applyDefaultPlugins();\n }\n\n private loadDefaultPlugin(config: Config) {\n const plugingConf: HTPasswdConfig = { ...config, file: './htpasswd' };\n const pluginOptions: PluginOptions<{}> = {\n config,\n logger: this.logger,\n };\n let authPlugin;\n try {\n authPlugin = new HTPasswd(plugingConf, pluginOptions);\n } catch (error: any) {\n debug('error on loading auth htpasswd plugin stack: %o', error);\n return [];\n }\n\n return [authPlugin];\n }\n\n private _loadPlugin(config: Config): IPluginAuth<Config>[] {\n const pluginOptions = {\n config,\n logger: this.logger,\n };\n\n return loadPlugin<IPluginAuth<Config>>(\n config,\n config.auth,\n pluginOptions,\n (plugin: IPluginAuth<Config>): boolean => {\n const { authenticate, allow_access, allow_publish } = plugin;\n\n // @ts-ignore\n return authenticate || allow_access || allow_publish;\n }\n );\n }\n\n private _applyDefaultPlugins(): void {\n // TODO: rename to applyFallbackPluginMethods\n this.plugins.push(getDefaultPlugins(this.logger));\n }\n\n public changePassword(\n username: string,\n password: string,\n newPassword: string,\n cb: Callback\n ): void {\n const validPlugins = _.filter(this.plugins, (plugin) => isFunction(plugin.changePassword));\n\n if (_.isEmpty(validPlugins)) {\n return cb(errorUtils.getInternalError(SUPPORT_ERRORS.PLUGIN_MISSING_INTERFACE));\n }\n\n for (const plugin of validPlugins) {\n if (isNil(plugin) || isFunction(plugin.changePassword) === false) {\n debug('auth plugin does not implement changePassword, trying next one');\n continue;\n } else {\n debug('updating password for %o', username);\n plugin.changePassword!(username, password, newPassword, (err, profile): void => {\n if (err) {\n this.logger.error(\n { username, err },\n `An error has been produced\n updating the password for @{username}. Error: @{err.message}`\n );\n return cb(err);\n }\n\n debug('updated password for %o was successful', username);\n return cb(null, profile);\n });\n }\n }\n }\n\n public authenticate(username: string, password: string, cb: Callback): void {\n const plugins = this.plugins.slice(0);\n (function next(): void {\n const plugin = plugins.shift() as IPluginAuth<Config>;\n\n if (isFunction(plugin.authenticate) === false) {\n return next();\n }\n\n debug('authenticating %o', username);\n plugin.authenticate(username, password, function (err, groups): void {\n if (err) {\n debug('authenticating for user %o failed. Error: %o', username, err?.message);\n return cb(err);\n }\n\n // Expect: SKIP if groups is falsey and not an array\n // with at least one item (truthy length)\n // Expect: CONTINUE otherwise (will error if groups is not\n // an array, but this is current behavior)\n // Caveat: STRING (if valid) will pass successfully\n // bug give unexpected results\n // Info: Cannot use `== false to check falsey values`\n if (!!groups && groups.length !== 0) {\n // TODO: create a better understanding of expectations\n if (_.isString(groups)) {\n throw new TypeError('plugin group error: invalid type for function');\n }\n const isGroupValid: boolean = _.isArray(groups);\n if (!isGroupValid) {\n throw new TypeError(API_ERROR.BAD_FORMAT_USER_GROUP);\n }\n\n debug('authentication for user %o was successfully. Groups: %o', username, groups);\n return cb(err, createRemoteUser(username, groups));\n }\n next();\n });\n })();\n }\n\n public add_user(user: string, password: string, cb: Callback): void {\n const self = this;\n const plugins = this.plugins.slice(0);\n debug('add user %o', user);\n\n (function next(): void {\n const plugin = plugins.shift() as IPluginAuth<Config>;\n let method = 'adduser';\n if (isFunction(plugin[method]) === false) {\n method = 'add_user';\n self.logger.warn(\n 'the plugin method add_user in the auth plugin is deprecated and will' +\n ' be removed in next major release, notify to the plugin author'\n );\n }\n\n if (isFunction(plugin[method]) === false) {\n next();\n } else {\n // p.add_user() execution\n plugin[method](user, password, function (err, ok): void {\n if (err) {\n debug('the user %o could not being added. Error: %o', user, err?.message);\n return cb(err);\n }\n if (ok) {\n debug('the user %o has been added', user);\n return self.authenticate(user, password, cb);\n }\n next();\n });\n }\n })();\n }\n\n /**\n * Allow user to access a package.\n */\n public allow_access(\n { packageName, packageVersion }: AuthPluginPackage,\n user: RemoteUser,\n callback: Callback\n ): void {\n const plugins = this.plugins.slice(0);\n const pkgAllowAcces: AllowAccess = { name: packageName, version: packageVersion };\n const pkg = Object.assign(\n {},\n pkgAllowAcces,\n getMatchedPackagesSpec(packageName, this.config.packages)\n ) as AllowAccess & PackageAccess;\n debug('allow access for %o', packageName);\n\n (function next(): void {\n const plugin: IPluginAuth<Config> = plugins.shift() as IPluginAuth<Config>;\n\n if (_.isNil(plugin) || isFunction(plugin.allow_access) === false) {\n return next();\n }\n\n plugin.allow_access!(user, pkg, function (err, ok: boolean): void {\n if (err) {\n debug('forbidden access for %o. Error: %o', packageName, err?.message);\n return callback(err);\n }\n\n if (ok) {\n debug('allowed access for %o', packageName);\n return callback(null, ok);\n }\n\n next(); // cb(null, false) causes next plugin to roll\n });\n })();\n }\n\n public allow_unpublish(\n { packageName, packageVersion }: AuthPluginPackage,\n user: RemoteUser,\n callback: Callback\n ): void {\n const pkg = Object.assign(\n { name: packageName, version: packageVersion },\n getMatchedPackagesSpec(packageName, this.config.packages)\n );\n debug('allow unpublish for %o', packageName);\n\n for (const plugin of this.plugins) {\n if (_.isNil(plugin) || isFunction(plugin.allow_unpublish) === false) {\n debug('allow unpublish for %o plugin does not implement allow_unpublish', packageName);\n continue;\n } else {\n // @ts-ignore\n plugin.allow_unpublish!(user, pkg, (err, ok: boolean): void => {\n if (err) {\n debug(\n 'forbidden publish for %o, it will fallback on unpublish permissions',\n packageName\n );\n return callback(err);\n }\n\n if (_.isNil(ok) === true) {\n debug('bypass unpublish for %o, publish will handle the access', packageName);\n // @ts-ignore\n // eslint-disable-next-line\n return this.allow_publish(...arguments);\n }\n\n if (ok) {\n debug('allowed unpublish for %o', packageName);\n return callback(null, ok);\n }\n });\n }\n }\n }\n\n /**\n * Allow user to publish a package.\n */\n public allow_publish(\n { packageName, packageVersion }: AuthPluginPackage,\n user: RemoteUser,\n callback: Callback\n ): void {\n const plugins = this.plugins.slice(0);\n const pkg = Object.assign(\n { name: packageName, version: packageVersion },\n getMatchedPackagesSpec(packageName, this.config.packages)\n );\n debug('allow publish for %o init | plugins: %o', packageName, plugins.length);\n\n (function next(): void {\n const plugin = plugins.shift();\n\n if (isFunction(plugin?.allow_publish) === false) {\n debug('allow publish for %o plugin does not implement allow_publish', packageName);\n return next();\n }\n\n // @ts-ignore\n plugin.allow_publish(\n user,\n // @ts-ignore\n pkg,\n // @ts-ignore\n (err: VerdaccioError, ok: boolean): void => {\n if (_.isNil(err) === false && _.isError(err)) {\n debug('forbidden publish for %o', packageName);\n return callback(err);\n }\n\n if (ok) {\n debug('allowed publish for %o', packageName);\n return callback(null, ok);\n }\n\n debug('allow publish skip validation for %o', packageName);\n next(); // cb(null, false) causes next plugin to roll\n }\n );\n })();\n }\n\n public apiJWTmiddleware(): Function {\n debug('jwt middleware');\n const plugins = this.plugins.slice(0);\n const helpers = { createAnonymousRemoteUser, createRemoteUser };\n for (const plugin of plugins) {\n if (plugin.apiJWTmiddleware) {\n return plugin.apiJWTmiddleware(helpers);\n }\n }\n\n return (req: $RequestExtend, res: $ResponseExtend, _next: NextFunction): void => {\n req.pause();\n\n const next = function (err: VerdaccioError | void): void {\n req.resume();\n // uncomment this to reject users with bad auth headers\n // return _next.apply(null, arguments)\n // swallow error, user remains unauthorized\n // set remoteUserError to indicate that user was attempting authentication\n if (err) {\n req.remote_user.error = err.message;\n }\n return _next();\n };\n\n if (this._isRemoteUserValid(req.remote_user)) {\n debug('jwt has a valid authentication header');\n return next();\n }\n\n // in case auth header does not exist we return anonymous function\n req.remote_user = createAnonymousRemoteUser();\n\n const { authorization } = req.headers;\n if (_.isNil(authorization)) {\n debug('jwt, authentication header is missing');\n return next();\n }\n\n if (!isAuthHeaderValid(authorization)) {\n debug('api middleware authentication heather is invalid');\n return next(errorUtils.getBadRequest(API_ERROR.BAD_AUTH_HEADER));\n }\n const { secret, security } = this.config;\n\n if (isAESLegacy(security)) {\n debug('api middleware using legacy auth token');\n this._handleAESMiddleware(req, security, secret, authorization, next);\n } else {\n debug('api middleware using JWT auth token');\n this._handleJWTAPIMiddleware(req, security, secret, authorization, next);\n }\n };\n }\n\n private _handleJWTAPIMiddleware(\n req: $RequestExtend,\n security: Security,\n secret: string,\n authorization: string,\n next: Function\n ): void {\n debug('handle JWT api middleware');\n const { scheme, token } = parseAuthTokenHeader(authorization);\n if (scheme.toUpperCase() === TOKEN_BASIC.toUpperCase()) {\n debug('handle basic token');\n // this should happen when client tries to login with an existing user\n const credentials = convertPayloadToBase64(token).toString();\n const { user, password } = parseBasicPayload(credentials) as AESPayload;\n debug('authenticating %o', user);\n this.authenticate(user, password, (err, user): void => {\n if (!err) {\n debug('generating a remote user');\n req.remote_user = user;\n next();\n } else {\n debug('generating anonymous user');\n req.remote_user = createAnonymousRemoteUser();\n next(err);\n }\n });\n } else {\n debug('handle jwt token');\n const credentials: any = getMiddlewareCredentials(security, secret, authorization);\n if (credentials) {\n // if the signature is valid we rely on it\n req.remote_user = credentials;\n debug('generating a remote user');\n next();\n } else {\n // with JWT throw 401\n debug('jwt invalid token');\n next(errorUtils.getForbidden(API_ERROR.BAD_USERNAME_PASSWORD));\n }\n }\n }\n\n private _handleAESMiddleware(\n req: $RequestExtend,\n security: Security,\n secret: string,\n authorization: string,\n next: Function\n ): void {\n debug('handle legacy api middleware');\n debug('api middleware secret %o', secret);\n debug('api middleware authorization %o', authorization);\n const credentials: any = getMiddlewareCredentials(security, secret, authorization);\n debug('api middleware credentials %o', credentials);\n if (credentials) {\n const { user, password } = credentials;\n debug('authenticating %o', user);\n this.authenticate(user, password, (err, user): void => {\n if (!err) {\n req.remote_user = user;\n debug('generating a remote user');\n next();\n } else {\n req.remote_user = createAnonymousRemoteUser();\n debug('generating anonymous user');\n next(err);\n }\n });\n } else {\n // we force npm client to ask again with basic authentication\n debug('legacy invalid header');\n return next(errorUtils.getBadRequest(API_ERROR.BAD_AUTH_HEADER));\n }\n }\n\n private _isRemoteUserValid(remote_user: RemoteUser): boolean {\n return _.isUndefined(remote_user) === false && _.isUndefined(remote_user.name) === false;\n }\n\n /**\n * JWT middleware for WebUI\n */\n public webUIJWTmiddleware(): Function {\n return (req: $RequestExtend, res: $ResponseExtend, _next: NextFunction): void => {\n if (this._isRemoteUserValid(req.remote_user)) {\n return _next();\n }\n\n req.pause();\n const next = (err: VerdaccioError | void): void => {\n req.resume();\n if (err) {\n // req.remote_user.error = err.message;\n res.status(err.statusCode).send(err.message);\n }\n\n return _next();\n };\n\n const { authorization } = req.headers;\n if (_.isNil(authorization)) {\n return next();\n }\n\n if (!isAuthHeaderValid(authorization)) {\n return next(errorUtils.getBadRequest(API_ERROR.BAD_AUTH_HEADER));\n }\n\n const token = (authorization || '').replace(`${TOKEN_BEARER} `, '');\n if (!token) {\n return next();\n }\n\n let credentials;\n try {\n credentials = verifyJWTPayload(token, this.config.secret);\n } catch (err: any) {\n // FIXME: intended behaviour, do we want it?\n }\n\n if (this._isRemoteUserValid(credentials)) {\n const { name, groups } = credentials;\n // $FlowFixMe\n req.remote_user = createRemoteUser(name, groups);\n } else {\n req.remote_user = createAnonymousRemoteUser();\n }\n\n next();\n };\n }\n\n public async jwtEncrypt(user: RemoteUser, signOptions: JWTSignOptions): Promise<string> {\n const { real_groups, name, groups } = user;\n debug('jwt encrypt %o', name);\n const realGroupsValidated = _.isNil(real_groups) ? [] : real_groups;\n const groupedGroups = _.isNil(groups) ? real_groups : groups.concat(realGroupsValidated);\n const payload: RemoteUser = {\n real_groups: realGroupsValidated,\n name,\n groups: groupedGroups,\n };\n\n const token: string = await signPayload(payload, this.secret, signOptions);\n\n return token;\n }\n\n /**\n * Encrypt a string.\n */\n public aesEncrypt(value: string): string | void {\n return aesEncrypt(value, this.secret);\n }\n}\n\nexport { Auth };\n"],"file":"auth.js"}
|
package/build/utils.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
import { Config, IPluginAuth, RemoteUser, Security, AuthPackageAllow } from '@verdaccio/types';
|
|
3
|
-
import { VerdaccioError } from '@verdaccio/
|
|
3
|
+
import { VerdaccioError } from '@verdaccio/core';
|
|
4
4
|
import { TokenEncryption, AESPayload } from './auth';
|
|
5
5
|
export declare type BasicPayload = AESPayload | void;
|
|
6
6
|
export declare type AuthMiddlewarePayload = RemoteUser | BasicPayload;
|
package/build/utils.js
CHANGED
|
@@ -21,7 +21,7 @@ var _lodash = _interopRequireDefault(require("lodash"));
|
|
|
21
21
|
|
|
22
22
|
var _debug = _interopRequireDefault(require("debug"));
|
|
23
23
|
|
|
24
|
-
var
|
|
24
|
+
var _core = require("@verdaccio/core");
|
|
25
25
|
|
|
26
26
|
var _config = require("@verdaccio/config");
|
|
27
27
|
|
|
@@ -56,11 +56,11 @@ function parseAESCredentials(authorizationHeader, secret) {
|
|
|
56
56
|
} = parseAuthTokenHeader(authorizationHeader); // basic is deprecated and should not be enforced
|
|
57
57
|
// basic is currently being used for functional test
|
|
58
58
|
|
|
59
|
-
if (scheme.toUpperCase() ===
|
|
59
|
+
if (scheme.toUpperCase() === _core.TOKEN_BASIC.toUpperCase()) {
|
|
60
60
|
debug('legacy header basic');
|
|
61
61
|
const credentials = convertPayloadToBase64(token).toString();
|
|
62
62
|
return credentials;
|
|
63
|
-
} else if (scheme.toUpperCase() ===
|
|
63
|
+
} else if (scheme.toUpperCase() === _core.TOKEN_BEARER.toUpperCase()) {
|
|
64
64
|
debug('legacy header bearer');
|
|
65
65
|
const credentials = (0, _legacyToken.aesDecrypt)(token, secret);
|
|
66
66
|
return credentials;
|
|
@@ -95,7 +95,7 @@ function getMiddlewareCredentials(security, secretKey, authorizationHeader) {
|
|
|
95
95
|
} = parseAuthTokenHeader(authorizationHeader);
|
|
96
96
|
debug('is jwt');
|
|
97
97
|
|
|
98
|
-
if (_lodash.default.isString(token) && scheme.toUpperCase() ===
|
|
98
|
+
if (_lodash.default.isString(token) && scheme.toUpperCase() === _core.TOKEN_BEARER.toUpperCase()) {
|
|
99
99
|
return verifyJWTPayload(token, secretKey);
|
|
100
100
|
}
|
|
101
101
|
}
|
|
@@ -151,7 +151,7 @@ function verifyJWTPayload(token, secret) {
|
|
|
151
151
|
return (0, _config.createAnonymousRemoteUser)();
|
|
152
152
|
}
|
|
153
153
|
|
|
154
|
-
throw
|
|
154
|
+
throw _core.errorUtils.getCode(_core.HTTP_STATUS.UNAUTHORIZED, error.message);
|
|
155
155
|
}
|
|
156
156
|
}
|
|
157
157
|
|
|
@@ -162,11 +162,11 @@ function isAuthHeaderValid(authorization) {
|
|
|
162
162
|
function getDefaultPlugins(logger) {
|
|
163
163
|
return {
|
|
164
164
|
authenticate(user, password, cb) {
|
|
165
|
-
cb(
|
|
165
|
+
cb(_core.errorUtils.getForbidden(_core.API_ERROR.BAD_USERNAME_PASSWORD));
|
|
166
166
|
},
|
|
167
167
|
|
|
168
168
|
adduser(user, password, cb) {
|
|
169
|
-
return cb(
|
|
169
|
+
return cb(_core.errorUtils.getConflict(_core.API_ERROR.BAD_USERNAME_PASSWORD));
|
|
170
170
|
},
|
|
171
171
|
|
|
172
172
|
// FIXME: allow_action and allow_publish should be in the @verdaccio/types
|
|
@@ -204,9 +204,9 @@ function allow_action(action, logger) {
|
|
|
204
204
|
}
|
|
205
205
|
|
|
206
206
|
if (name) {
|
|
207
|
-
callback(
|
|
207
|
+
callback(_core.errorUtils.getForbidden(`user ${name} is not allowed to ${action} package ${pkg.name}`));
|
|
208
208
|
} else {
|
|
209
|
-
callback(
|
|
209
|
+
callback(_core.errorUtils.getUnauthorized(`authorization required to ${action} package ${pkg.name}`));
|
|
210
210
|
}
|
|
211
211
|
};
|
|
212
212
|
}
|
package/build/utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils.ts"],"names":["debug","parseAuthTokenHeader","authorizationHeader","parts","split","scheme","token","parseAESCredentials","secret","toUpperCase","TOKEN_BASIC","credentials","convertPayloadToBase64","toString","TOKEN_BEARER","getMiddlewareCredentials","security","secretKey","isAESLegacy","parsedCredentials","_","isString","verifyJWTPayload","legacy","jwt","api","isNil","getApiToken","auth","config","remoteUser","aesPassword","Promise","resolve","aesEncrypt","buildUser","name","sign","jwtEncrypt","expireReasons","payload","error","includes","HTTP_STATUS","UNAUTHORIZED","message","isAuthHeaderValid","authorization","length","getDefaultPlugins","logger","authenticate","user","password","cb","API_ERROR","BAD_USERNAME_PASSWORD","adduser","allow_access","allow_action","allow_publish","allow_unpublish","handleSpecialUnpublish","action","allowActionCallback","pkg","callback","trace","remote","groups","groupAccess","hasPermission","some","group","pkgName","isUnpublishMissing","hasGroups","undefined","String","Buffer","from"],"mappings":"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","sourcesContent":["import _ from 'lodash';\nimport buildDebug from 'debug';\nimport {\n Callback,\n Config,\n IPluginAuth,\n RemoteUser,\n Security,\n AuthPackageAllow,\n} from '@verdaccio/types';\nimport {\n HTTP_STATUS,\n TOKEN_BASIC,\n TOKEN_BEARER,\n API_ERROR,\n getForbidden,\n getUnauthorized,\n getConflict,\n getCode,\n} from '@verdaccio/commons-api';\nimport { VerdaccioError } from '@verdaccio/commons-api';\n\nimport { createAnonymousRemoteUser } from '@verdaccio/config';\nimport { TokenEncryption, AESPayload } from './auth';\nimport { aesDecrypt } from './legacy-token';\nimport { verifyPayload } from './jwt-token';\nimport { parseBasicPayload } from './token';\n\nconst debug = buildDebug('verdaccio:auth:utils');\n\nexport type BasicPayload = AESPayload | void;\nexport type AuthMiddlewarePayload = RemoteUser | BasicPayload;\n\nexport interface AuthTokenHeader {\n scheme: string;\n token: string;\n}\nexport type AllowActionCallbackResponse = boolean | undefined;\nexport type AllowActionCallback = (\n error: VerdaccioError | null,\n allowed?: AllowActionCallbackResponse\n) => void;\n\nexport type AllowAction = (\n user: RemoteUser,\n pkg: AuthPackageAllow,\n callback: AllowActionCallback\n) => void;\n\n/**\n * Split authentication header eg: Bearer [secret_token]\n * @param authorizationHeader auth token\n */\nexport function parseAuthTokenHeader(authorizationHeader: string): AuthTokenHeader {\n const parts = authorizationHeader.split(' ');\n const [scheme, token] = parts;\n\n return { scheme, token };\n}\n\nexport function parseAESCredentials(authorizationHeader: string, secret: string) {\n debug('parseAESCredentials');\n const { scheme, token } = parseAuthTokenHeader(authorizationHeader);\n\n // basic is deprecated and should not be enforced\n // basic is currently being used for functional test\n if (scheme.toUpperCase() === TOKEN_BASIC.toUpperCase()) {\n debug('legacy header basic');\n const credentials = convertPayloadToBase64(token).toString();\n\n return credentials;\n } else if (scheme.toUpperCase() === TOKEN_BEARER.toUpperCase()) {\n debug('legacy header bearer');\n const credentials = aesDecrypt(token, secret);\n\n return credentials;\n }\n}\n\nexport function getMiddlewareCredentials(\n security: Security,\n secretKey: string,\n authorizationHeader: string\n): AuthMiddlewarePayload {\n debug('getMiddlewareCredentials');\n // comment out for debugging purposes\n if (isAESLegacy(security)) {\n debug('is legacy');\n const credentials = parseAESCredentials(authorizationHeader, secretKey);\n if (!credentials) {\n debug('parse legacy credentials failed');\n return;\n }\n\n const parsedCredentials = parseBasicPayload(credentials);\n if (!parsedCredentials) {\n debug('parse legacy basic payload credentials failed');\n return;\n }\n\n return parsedCredentials;\n }\n const { scheme, token } = parseAuthTokenHeader(authorizationHeader);\n\n debug('is jwt');\n if (_.isString(token) && scheme.toUpperCase() === TOKEN_BEARER.toUpperCase()) {\n return verifyJWTPayload(token, secretKey);\n }\n}\n\nexport function isAESLegacy(security: Security): boolean {\n const { legacy, jwt } = security.api;\n\n return _.isNil(legacy) === false && _.isNil(jwt) && legacy === true;\n}\n\nexport async function getApiToken(\n auth: TokenEncryption,\n config: Config,\n remoteUser: RemoteUser,\n aesPassword: string\n): Promise<string | void> {\n debug('get api token');\n const { security } = config;\n\n if (isAESLegacy(security)) {\n debug('security legacy enabled');\n // fallback all goes to AES encryption\n return await new Promise((resolve): void => {\n resolve(auth.aesEncrypt(buildUser(remoteUser.name as string, aesPassword)));\n });\n }\n const { jwt } = security.api;\n\n if (jwt?.sign) {\n return await auth.jwtEncrypt(remoteUser, jwt.sign);\n }\n return await new Promise((resolve): void => {\n resolve(auth.aesEncrypt(buildUser(remoteUser.name as string, aesPassword)));\n });\n}\n\nexport const expireReasons: string[] = ['JsonWebTokenError', 'TokenExpiredError'];\n\nexport function verifyJWTPayload(token: string, secret: string): RemoteUser {\n try {\n const payload: RemoteUser = verifyPayload(token, secret);\n\n return payload;\n } catch (error: any) {\n // #168 this check should be removed as soon AES encrypt is removed.\n if (expireReasons.includes(error.name)) {\n // it might be possible the jwt configuration is enabled and\n // old tokens fails still remains in usage, thus\n // we return an anonymous user to force log in.\n return createAnonymousRemoteUser();\n }\n throw getCode(HTTP_STATUS.UNAUTHORIZED, error.message);\n }\n}\n\nexport function isAuthHeaderValid(authorization: string): boolean {\n return authorization.split(' ').length === 2;\n}\n\nexport function getDefaultPlugins(logger: any): IPluginAuth<Config> {\n return {\n authenticate(user: string, password: string, cb: Callback): void {\n cb(getForbidden(API_ERROR.BAD_USERNAME_PASSWORD));\n },\n\n adduser(user: string, password: string, cb: Callback): void {\n return cb(getConflict(API_ERROR.BAD_USERNAME_PASSWORD));\n },\n\n // FIXME: allow_action and allow_publish should be in the @verdaccio/types\n // @ts-ignore\n allow_access: allow_action('access', logger),\n // @ts-ignore\n allow_publish: allow_action('publish', logger),\n allow_unpublish: handleSpecialUnpublish(logger),\n };\n}\n\nexport type ActionsAllowed = 'publish' | 'unpublish' | 'access';\n\nexport function allow_action(action: ActionsAllowed, logger): AllowAction {\n return function allowActionCallback(\n user: RemoteUser,\n pkg: AuthPackageAllow,\n callback: AllowActionCallback\n ): void {\n logger.trace({ remote: user.name }, `[auth/allow_action]: user: @{user.name}`);\n const { name, groups } = user;\n const groupAccess = pkg[action] as string[];\n const hasPermission = groupAccess.some((group) => name === group || groups.includes(group));\n logger.trace(\n { pkgName: pkg.name, hasPermission, remote: user.name, groupAccess },\n `[auth/allow_action]: hasPermission? @{hasPermission} for user: @{user}`\n );\n\n if (hasPermission) {\n logger.trace({ remote: user.name }, `auth/allow_action: access granted to: @{user}`);\n return callback(null, true);\n }\n\n if (name) {\n callback(getForbidden(`user ${name} is not allowed to ${action} package ${pkg.name}`));\n } else {\n callback(getUnauthorized(`authorization required to ${action} package ${pkg.name}`));\n }\n };\n}\n\n/**\n *\n */\nexport function handleSpecialUnpublish(logger): any {\n return function (user: RemoteUser, pkg: AuthPackageAllow, callback: AllowActionCallback): void {\n const action = 'unpublish';\n // verify whether the unpublish prop has been defined\n const isUnpublishMissing: boolean = _.isNil(pkg[action]);\n const hasGroups: boolean = isUnpublishMissing ? false : (pkg[action] as string[]).length > 0;\n logger.trace(\n { user: user.name, name: pkg.name, hasGroups },\n `fallback unpublish for @{name} has groups: @{hasGroups} for @{user}`\n );\n\n if (isUnpublishMissing || hasGroups === false) {\n return callback(null, undefined);\n }\n\n logger.trace(\n { user: user.name, name: pkg.name, action, hasGroups },\n `allow_action for @{action} for @{name} has groups: @{hasGroups} for @{user}`\n );\n return allow_action(action, logger)(user, pkg, callback);\n };\n}\n\nexport function buildUser(name: string, password: string): string {\n return String(`${name}:${password}`);\n}\n\nexport function convertPayloadToBase64(payload: string): Buffer {\n return Buffer.from(payload, 'base64');\n}\n"],"file":"utils.js"}
|
|
1
|
+
{"version":3,"sources":["../src/utils.ts"],"names":["debug","parseAuthTokenHeader","authorizationHeader","parts","split","scheme","token","parseAESCredentials","secret","toUpperCase","TOKEN_BASIC","credentials","convertPayloadToBase64","toString","TOKEN_BEARER","getMiddlewareCredentials","security","secretKey","isAESLegacy","parsedCredentials","_","isString","verifyJWTPayload","legacy","jwt","api","isNil","getApiToken","auth","config","remoteUser","aesPassword","Promise","resolve","aesEncrypt","buildUser","name","sign","jwtEncrypt","expireReasons","payload","error","includes","errorUtils","getCode","HTTP_STATUS","UNAUTHORIZED","message","isAuthHeaderValid","authorization","length","getDefaultPlugins","logger","authenticate","user","password","cb","getForbidden","API_ERROR","BAD_USERNAME_PASSWORD","adduser","getConflict","allow_access","allow_action","allow_publish","allow_unpublish","handleSpecialUnpublish","action","allowActionCallback","pkg","callback","trace","remote","groups","groupAccess","hasPermission","some","group","pkgName","getUnauthorized","isUnpublishMissing","hasGroups","undefined","String","Buffer","from"],"mappings":"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","sourcesContent":["import _ from 'lodash';\nimport buildDebug from 'debug';\nimport {\n Callback,\n Config,\n IPluginAuth,\n RemoteUser,\n Security,\n AuthPackageAllow,\n} from '@verdaccio/types';\nimport {\n HTTP_STATUS,\n TOKEN_BASIC,\n TOKEN_BEARER,\n API_ERROR,\n VerdaccioError,\n errorUtils,\n} from '@verdaccio/core';\n\nimport { createAnonymousRemoteUser } from '@verdaccio/config';\nimport { TokenEncryption, AESPayload } from './auth';\nimport { aesDecrypt } from './legacy-token';\nimport { verifyPayload } from './jwt-token';\nimport { parseBasicPayload } from './token';\n\nconst debug = buildDebug('verdaccio:auth:utils');\n\nexport type BasicPayload = AESPayload | void;\nexport type AuthMiddlewarePayload = RemoteUser | BasicPayload;\n\nexport interface AuthTokenHeader {\n scheme: string;\n token: string;\n}\nexport type AllowActionCallbackResponse = boolean | undefined;\nexport type AllowActionCallback = (\n error: VerdaccioError | null,\n allowed?: AllowActionCallbackResponse\n) => void;\n\nexport type AllowAction = (\n user: RemoteUser,\n pkg: AuthPackageAllow,\n callback: AllowActionCallback\n) => void;\n\n/**\n * Split authentication header eg: Bearer [secret_token]\n * @param authorizationHeader auth token\n */\nexport function parseAuthTokenHeader(authorizationHeader: string): AuthTokenHeader {\n const parts = authorizationHeader.split(' ');\n const [scheme, token] = parts;\n\n return { scheme, token };\n}\n\nexport function parseAESCredentials(authorizationHeader: string, secret: string) {\n debug('parseAESCredentials');\n const { scheme, token } = parseAuthTokenHeader(authorizationHeader);\n\n // basic is deprecated and should not be enforced\n // basic is currently being used for functional test\n if (scheme.toUpperCase() === TOKEN_BASIC.toUpperCase()) {\n debug('legacy header basic');\n const credentials = convertPayloadToBase64(token).toString();\n\n return credentials;\n } else if (scheme.toUpperCase() === TOKEN_BEARER.toUpperCase()) {\n debug('legacy header bearer');\n const credentials = aesDecrypt(token, secret);\n\n return credentials;\n }\n}\n\nexport function getMiddlewareCredentials(\n security: Security,\n secretKey: string,\n authorizationHeader: string\n): AuthMiddlewarePayload {\n debug('getMiddlewareCredentials');\n // comment out for debugging purposes\n if (isAESLegacy(security)) {\n debug('is legacy');\n const credentials = parseAESCredentials(authorizationHeader, secretKey);\n if (!credentials) {\n debug('parse legacy credentials failed');\n return;\n }\n\n const parsedCredentials = parseBasicPayload(credentials);\n if (!parsedCredentials) {\n debug('parse legacy basic payload credentials failed');\n return;\n }\n\n return parsedCredentials;\n }\n const { scheme, token } = parseAuthTokenHeader(authorizationHeader);\n\n debug('is jwt');\n if (_.isString(token) && scheme.toUpperCase() === TOKEN_BEARER.toUpperCase()) {\n return verifyJWTPayload(token, secretKey);\n }\n}\n\nexport function isAESLegacy(security: Security): boolean {\n const { legacy, jwt } = security.api;\n\n return _.isNil(legacy) === false && _.isNil(jwt) && legacy === true;\n}\n\nexport async function getApiToken(\n auth: TokenEncryption,\n config: Config,\n remoteUser: RemoteUser,\n aesPassword: string\n): Promise<string | void> {\n debug('get api token');\n const { security } = config;\n\n if (isAESLegacy(security)) {\n debug('security legacy enabled');\n // fallback all goes to AES encryption\n return await new Promise((resolve): void => {\n resolve(auth.aesEncrypt(buildUser(remoteUser.name as string, aesPassword)));\n });\n }\n const { jwt } = security.api;\n\n if (jwt?.sign) {\n return await auth.jwtEncrypt(remoteUser, jwt.sign);\n }\n return await new Promise((resolve): void => {\n resolve(auth.aesEncrypt(buildUser(remoteUser.name as string, aesPassword)));\n });\n}\n\nexport const expireReasons: string[] = ['JsonWebTokenError', 'TokenExpiredError'];\n\nexport function verifyJWTPayload(token: string, secret: string): RemoteUser {\n try {\n const payload: RemoteUser = verifyPayload(token, secret);\n\n return payload;\n } catch (error: any) {\n // #168 this check should be removed as soon AES encrypt is removed.\n if (expireReasons.includes(error.name)) {\n // it might be possible the jwt configuration is enabled and\n // old tokens fails still remains in usage, thus\n // we return an anonymous user to force log in.\n return createAnonymousRemoteUser();\n }\n throw errorUtils.getCode(HTTP_STATUS.UNAUTHORIZED, error.message);\n }\n}\n\nexport function isAuthHeaderValid(authorization: string): boolean {\n return authorization.split(' ').length === 2;\n}\n\nexport function getDefaultPlugins(logger: any): IPluginAuth<Config> {\n return {\n authenticate(user: string, password: string, cb: Callback): void {\n cb(errorUtils.getForbidden(API_ERROR.BAD_USERNAME_PASSWORD));\n },\n\n adduser(user: string, password: string, cb: Callback): void {\n return cb(errorUtils.getConflict(API_ERROR.BAD_USERNAME_PASSWORD));\n },\n\n // FIXME: allow_action and allow_publish should be in the @verdaccio/types\n // @ts-ignore\n allow_access: allow_action('access', logger),\n // @ts-ignore\n allow_publish: allow_action('publish', logger),\n allow_unpublish: handleSpecialUnpublish(logger),\n };\n}\n\nexport type ActionsAllowed = 'publish' | 'unpublish' | 'access';\n\nexport function allow_action(action: ActionsAllowed, logger): AllowAction {\n return function allowActionCallback(\n user: RemoteUser,\n pkg: AuthPackageAllow,\n callback: AllowActionCallback\n ): void {\n logger.trace({ remote: user.name }, `[auth/allow_action]: user: @{user.name}`);\n const { name, groups } = user;\n const groupAccess = pkg[action] as string[];\n const hasPermission = groupAccess.some((group) => name === group || groups.includes(group));\n logger.trace(\n { pkgName: pkg.name, hasPermission, remote: user.name, groupAccess },\n `[auth/allow_action]: hasPermission? @{hasPermission} for user: @{user}`\n );\n\n if (hasPermission) {\n logger.trace({ remote: user.name }, `auth/allow_action: access granted to: @{user}`);\n return callback(null, true);\n }\n\n if (name) {\n callback(\n errorUtils.getForbidden(`user ${name} is not allowed to ${action} package ${pkg.name}`)\n );\n } else {\n callback(\n errorUtils.getUnauthorized(`authorization required to ${action} package ${pkg.name}`)\n );\n }\n };\n}\n\n/**\n *\n */\nexport function handleSpecialUnpublish(logger): any {\n return function (user: RemoteUser, pkg: AuthPackageAllow, callback: AllowActionCallback): void {\n const action = 'unpublish';\n // verify whether the unpublish prop has been defined\n const isUnpublishMissing: boolean = _.isNil(pkg[action]);\n const hasGroups: boolean = isUnpublishMissing ? false : (pkg[action] as string[]).length > 0;\n logger.trace(\n { user: user.name, name: pkg.name, hasGroups },\n `fallback unpublish for @{name} has groups: @{hasGroups} for @{user}`\n );\n\n if (isUnpublishMissing || hasGroups === false) {\n return callback(null, undefined);\n }\n\n logger.trace(\n { user: user.name, name: pkg.name, action, hasGroups },\n `allow_action for @{action} for @{name} has groups: @{hasGroups} for @{user}`\n );\n return allow_action(action, logger)(user, pkg, callback);\n };\n}\n\nexport function buildUser(name: string, password: string): string {\n return String(`${name}:${password}`);\n}\n\nexport function convertPayloadToBase64(payload: string): Buffer {\n return Buffer.from(payload, 'base64');\n}\n"],"file":"utils.js"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@verdaccio/auth",
|
|
3
|
-
"version": "6.0.0-6-next.
|
|
3
|
+
"version": "6.0.0-6-next.13",
|
|
4
4
|
"description": "logger",
|
|
5
5
|
"main": "./build/index.js",
|
|
6
6
|
"types": "build/index.d.ts",
|
|
@@ -25,25 +25,25 @@
|
|
|
25
25
|
"verdaccio"
|
|
26
26
|
],
|
|
27
27
|
"engines": {
|
|
28
|
-
"node": ">=
|
|
28
|
+
"node": ">=14",
|
|
29
29
|
"npm": ">=6"
|
|
30
30
|
},
|
|
31
31
|
"license": "MIT",
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@verdaccio/
|
|
34
|
-
"@verdaccio/config": "6.0.0-6-next.
|
|
35
|
-
"@verdaccio/loaders": "6.0.0-6-next.
|
|
36
|
-
"@verdaccio/logger": "6.0.0-6-next.
|
|
37
|
-
"@verdaccio/utils": "6.0.0-6-next.
|
|
33
|
+
"@verdaccio/core": "6.0.0-6-next.2",
|
|
34
|
+
"@verdaccio/config": "6.0.0-6-next.9",
|
|
35
|
+
"@verdaccio/loaders": "6.0.0-6-next.6",
|
|
36
|
+
"@verdaccio/logger": "6.0.0-6-next.6",
|
|
37
|
+
"@verdaccio/utils": "6.0.0-6-next.7",
|
|
38
38
|
"debug": "4.3.2",
|
|
39
39
|
"express": "4.17.1",
|
|
40
40
|
"jsonwebtoken": "8.5.1",
|
|
41
41
|
"lodash": "4.17.21",
|
|
42
|
-
"verdaccio-htpasswd": "11.0.0-6-next.
|
|
42
|
+
"verdaccio-htpasswd": "11.0.0-6-next.9"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
|
-
"@verdaccio/mock": "6.0.0-6-next.
|
|
46
|
-
"@verdaccio/types": "11.0.0-6-next.
|
|
45
|
+
"@verdaccio/mock": "6.0.0-6-next.10",
|
|
46
|
+
"@verdaccio/types": "11.0.0-6-next.9"
|
|
47
47
|
},
|
|
48
48
|
"funding": {
|
|
49
49
|
"type": "opencollective",
|
package/src/auth.ts
CHANGED
|
@@ -8,10 +8,8 @@ import {
|
|
|
8
8
|
TOKEN_BASIC,
|
|
9
9
|
TOKEN_BEARER,
|
|
10
10
|
VerdaccioError,
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
getForbidden,
|
|
14
|
-
} from '@verdaccio/commons-api';
|
|
11
|
+
errorUtils,
|
|
12
|
+
} from '@verdaccio/core';
|
|
15
13
|
import { loadPlugin } from '@verdaccio/loaders';
|
|
16
14
|
import { HTPasswd, HTPasswdConfig } from 'verdaccio-htpasswd';
|
|
17
15
|
|
|
@@ -153,7 +151,7 @@ class Auth implements IAuth {
|
|
|
153
151
|
const validPlugins = _.filter(this.plugins, (plugin) => isFunction(plugin.changePassword));
|
|
154
152
|
|
|
155
153
|
if (_.isEmpty(validPlugins)) {
|
|
156
|
-
return cb(getInternalError(SUPPORT_ERRORS.PLUGIN_MISSING_INTERFACE));
|
|
154
|
+
return cb(errorUtils.getInternalError(SUPPORT_ERRORS.PLUGIN_MISSING_INTERFACE));
|
|
157
155
|
}
|
|
158
156
|
|
|
159
157
|
for (const plugin of validPlugins) {
|
|
@@ -425,7 +423,7 @@ class Auth implements IAuth {
|
|
|
425
423
|
|
|
426
424
|
if (!isAuthHeaderValid(authorization)) {
|
|
427
425
|
debug('api middleware authentication heather is invalid');
|
|
428
|
-
return next(getBadRequest(API_ERROR.BAD_AUTH_HEADER));
|
|
426
|
+
return next(errorUtils.getBadRequest(API_ERROR.BAD_AUTH_HEADER));
|
|
429
427
|
}
|
|
430
428
|
const { secret, security } = this.config;
|
|
431
429
|
|
|
@@ -476,7 +474,7 @@ class Auth implements IAuth {
|
|
|
476
474
|
} else {
|
|
477
475
|
// with JWT throw 401
|
|
478
476
|
debug('jwt invalid token');
|
|
479
|
-
next(getForbidden(API_ERROR.BAD_USERNAME_PASSWORD));
|
|
477
|
+
next(errorUtils.getForbidden(API_ERROR.BAD_USERNAME_PASSWORD));
|
|
480
478
|
}
|
|
481
479
|
}
|
|
482
480
|
}
|
|
@@ -510,7 +508,7 @@ class Auth implements IAuth {
|
|
|
510
508
|
} else {
|
|
511
509
|
// we force npm client to ask again with basic authentication
|
|
512
510
|
debug('legacy invalid header');
|
|
513
|
-
return next(getBadRequest(API_ERROR.BAD_AUTH_HEADER));
|
|
511
|
+
return next(errorUtils.getBadRequest(API_ERROR.BAD_AUTH_HEADER));
|
|
514
512
|
}
|
|
515
513
|
}
|
|
516
514
|
|
|
@@ -544,7 +542,7 @@ class Auth implements IAuth {
|
|
|
544
542
|
}
|
|
545
543
|
|
|
546
544
|
if (!isAuthHeaderValid(authorization)) {
|
|
547
|
-
return next(getBadRequest(API_ERROR.BAD_AUTH_HEADER));
|
|
545
|
+
return next(errorUtils.getBadRequest(API_ERROR.BAD_AUTH_HEADER));
|
|
548
546
|
}
|
|
549
547
|
|
|
550
548
|
const token = (authorization || '').replace(`${TOKEN_BEARER} `, '');
|
package/src/utils.ts
CHANGED
|
@@ -13,12 +13,9 @@ import {
|
|
|
13
13
|
TOKEN_BASIC,
|
|
14
14
|
TOKEN_BEARER,
|
|
15
15
|
API_ERROR,
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
getCode,
|
|
20
|
-
} from '@verdaccio/commons-api';
|
|
21
|
-
import { VerdaccioError } from '@verdaccio/commons-api';
|
|
16
|
+
VerdaccioError,
|
|
17
|
+
errorUtils,
|
|
18
|
+
} from '@verdaccio/core';
|
|
22
19
|
|
|
23
20
|
import { createAnonymousRemoteUser } from '@verdaccio/config';
|
|
24
21
|
import { TokenEncryption, AESPayload } from './auth';
|
|
@@ -155,7 +152,7 @@ export function verifyJWTPayload(token: string, secret: string): RemoteUser {
|
|
|
155
152
|
// we return an anonymous user to force log in.
|
|
156
153
|
return createAnonymousRemoteUser();
|
|
157
154
|
}
|
|
158
|
-
throw getCode(HTTP_STATUS.UNAUTHORIZED, error.message);
|
|
155
|
+
throw errorUtils.getCode(HTTP_STATUS.UNAUTHORIZED, error.message);
|
|
159
156
|
}
|
|
160
157
|
}
|
|
161
158
|
|
|
@@ -166,11 +163,11 @@ export function isAuthHeaderValid(authorization: string): boolean {
|
|
|
166
163
|
export function getDefaultPlugins(logger: any): IPluginAuth<Config> {
|
|
167
164
|
return {
|
|
168
165
|
authenticate(user: string, password: string, cb: Callback): void {
|
|
169
|
-
cb(getForbidden(API_ERROR.BAD_USERNAME_PASSWORD));
|
|
166
|
+
cb(errorUtils.getForbidden(API_ERROR.BAD_USERNAME_PASSWORD));
|
|
170
167
|
},
|
|
171
168
|
|
|
172
169
|
adduser(user: string, password: string, cb: Callback): void {
|
|
173
|
-
return cb(getConflict(API_ERROR.BAD_USERNAME_PASSWORD));
|
|
170
|
+
return cb(errorUtils.getConflict(API_ERROR.BAD_USERNAME_PASSWORD));
|
|
174
171
|
},
|
|
175
172
|
|
|
176
173
|
// FIXME: allow_action and allow_publish should be in the @verdaccio/types
|
|
@@ -205,9 +202,13 @@ export function allow_action(action: ActionsAllowed, logger): AllowAction {
|
|
|
205
202
|
}
|
|
206
203
|
|
|
207
204
|
if (name) {
|
|
208
|
-
callback(
|
|
205
|
+
callback(
|
|
206
|
+
errorUtils.getForbidden(`user ${name} is not allowed to ${action} package ${pkg.name}`)
|
|
207
|
+
);
|
|
209
208
|
} else {
|
|
210
|
-
callback(
|
|
209
|
+
callback(
|
|
210
|
+
errorUtils.getUnauthorized(`authorization required to ${action} package ${pkg.name}`)
|
|
211
|
+
);
|
|
211
212
|
}
|
|
212
213
|
};
|
|
213
214
|
}
|
package/test/auth-utils.spec.ts
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import path from 'path';
|
|
2
2
|
import _ from 'lodash';
|
|
3
3
|
|
|
4
|
-
import { CHARACTER_ENCODING, TOKEN_BEARER, API_ERROR } from '@verdaccio/commons-api';
|
|
5
|
-
|
|
6
4
|
import { configExample } from '@verdaccio/mock';
|
|
7
5
|
import {
|
|
8
6
|
Config as AppConfig,
|
|
@@ -20,7 +18,13 @@ import {
|
|
|
20
18
|
} from '@verdaccio/utils';
|
|
21
19
|
|
|
22
20
|
import { Config, Security, RemoteUser } from '@verdaccio/types';
|
|
23
|
-
import {
|
|
21
|
+
import {
|
|
22
|
+
VerdaccioError,
|
|
23
|
+
CHARACTER_ENCODING,
|
|
24
|
+
TOKEN_BEARER,
|
|
25
|
+
API_ERROR,
|
|
26
|
+
errorUtils,
|
|
27
|
+
} from '@verdaccio/core';
|
|
24
28
|
import { setup } from '@verdaccio/logger';
|
|
25
29
|
import {
|
|
26
30
|
IAuth,
|
|
@@ -110,7 +114,7 @@ describe('Auth utilities', () => {
|
|
|
110
114
|
test('authentication should fail by default (default)', () => {
|
|
111
115
|
const plugin = getDefaultPlugins({ trace: jest.fn() });
|
|
112
116
|
plugin.authenticate('foo', 'bar', (error: any) => {
|
|
113
|
-
expect(error).toEqual(getForbidden(API_ERROR.BAD_USERNAME_PASSWORD));
|
|
117
|
+
expect(error).toEqual(errorUtils.getForbidden(API_ERROR.BAD_USERNAME_PASSWORD));
|
|
114
118
|
});
|
|
115
119
|
});
|
|
116
120
|
|
|
@@ -118,7 +122,7 @@ describe('Auth utilities', () => {
|
|
|
118
122
|
const plugin = getDefaultPlugins({ trace: jest.fn() });
|
|
119
123
|
// @ts-ignore
|
|
120
124
|
plugin.adduser('foo', 'bar', (error: any) => {
|
|
121
|
-
expect(error).toEqual(getForbidden(API_ERROR.BAD_USERNAME_PASSWORD));
|
|
125
|
+
expect(error).toEqual(errorUtils.getForbidden(API_ERROR.BAD_USERNAME_PASSWORD));
|
|
122
126
|
});
|
|
123
127
|
});
|
|
124
128
|
});
|
package/test/auth.spec.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { ROLES, Config as AppConfig } from '@verdaccio/config';
|
|
|
3
3
|
import { setup } from '@verdaccio/logger';
|
|
4
4
|
import { IAuth } from '@verdaccio/auth';
|
|
5
5
|
import { Config } from '@verdaccio/types';
|
|
6
|
-
import {
|
|
6
|
+
import { errorUtils } from '@verdaccio/core';
|
|
7
7
|
|
|
8
8
|
import { Auth } from '../src';
|
|
9
9
|
|
|
@@ -57,7 +57,7 @@ describe('AuthTest', () => {
|
|
|
57
57
|
|
|
58
58
|
auth.authenticate('foo', 'bar', callback);
|
|
59
59
|
expect(callback).toHaveBeenCalledTimes(1);
|
|
60
|
-
expect(callback).toHaveBeenCalledWith(getInternalError());
|
|
60
|
+
expect(callback).toHaveBeenCalledWith(errorUtils.getInternalError());
|
|
61
61
|
});
|
|
62
62
|
});
|
|
63
63
|
|