@verdaccio/auth 8.0.0-next-8.3 → 8.0.0-next-8.5

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 CHANGED
@@ -1,5 +1,37 @@
1
1
  # @verdaccio/auth
2
2
 
3
+ ## 8.0.0-next-8.5
4
+
5
+ ### Patch Changes
6
+
7
+ - 9041b0f: chore: add info to log when audit, htpasswd, theme are used
8
+ - eca6259: fix: E409 username is already registered (adduser)
9
+ - Updated dependencies [ba71932]
10
+ - Updated dependencies [64a7fc0]
11
+ - Updated dependencies [4adaa83]
12
+ - Updated dependencies [5cbee6f]
13
+ - Updated dependencies [a049bba]
14
+ - @verdaccio/loaders@8.0.0-next-8.4
15
+ - @verdaccio/config@8.0.0-next-8.5
16
+ - @verdaccio/core@8.0.0-next-8.5
17
+ - verdaccio-htpasswd@13.0.0-next-8.5
18
+ - @verdaccio/signature@8.0.0-next-8.1
19
+ - @verdaccio/utils@8.1.0-next-8.5
20
+
21
+ ## 8.0.0-next-8.4
22
+
23
+ ### Patch Changes
24
+
25
+ - e93d6a3: chore: auth package requires logger as parameter
26
+ - Updated dependencies [48aa89f]
27
+ - Updated dependencies [58e0d95]
28
+ - @verdaccio/core@8.0.0-next-8.4
29
+ - @verdaccio/config@8.0.0-next-8.4
30
+ - @verdaccio/loaders@8.0.0-next-8.3
31
+ - verdaccio-htpasswd@13.0.0-next-8.4
32
+ - @verdaccio/utils@8.1.0-next-8.4
33
+ - @verdaccio/signature@8.0.0-next-8.1
34
+
3
35
  ## 8.0.0-next-8.3
4
36
 
5
37
  ### Patch Changes
package/build/auth.d.ts CHANGED
@@ -1,11 +1,12 @@
1
1
  import { VerdaccioError, pluginUtils } from '@verdaccio/core';
2
- import { Callback, Config, JWTSignOptions, RemoteUser } from '@verdaccio/types';
2
+ import { Callback, Config, JWTSignOptions, Logger, RemoteUser } from '@verdaccio/types';
3
3
  import { $RequestExtend, $ResponseExtend, IAuthMiddleware, NextFunction, TokenEncryption } from './types';
4
4
  declare class Auth implements IAuthMiddleware, TokenEncryption, pluginUtils.IBasicAuth {
5
5
  config: Config;
6
6
  secret: string;
7
+ logger: Logger;
7
8
  plugins: pluginUtils.Auth<Config>[];
8
- constructor(config: Config);
9
+ constructor(config: Config, logger: Logger);
9
10
  init(): Promise<void>;
10
11
  private loadDefaultPlugin;
11
12
  private loadPlugin;
package/build/auth.js CHANGED
@@ -10,16 +10,16 @@ var _verdaccioHtpasswd = require("verdaccio-htpasswd");
10
10
  var _config = require("@verdaccio/config");
11
11
  var _core = require("@verdaccio/core");
12
12
  var _loaders = require("@verdaccio/loaders");
13
- var _logger = require("@verdaccio/logger");
14
13
  var _signature = require("@verdaccio/signature");
15
14
  var _utils = require("@verdaccio/utils");
16
15
  var _utils2 = require("./utils");
17
16
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
18
17
  const debug = (0, _debug.default)('verdaccio:auth');
19
18
  class Auth {
20
- constructor(config) {
19
+ constructor(config, logger) {
21
20
  this.config = config;
22
21
  this.secret = config.secret;
22
+ this.logger = logger;
23
23
  this.plugins = [];
24
24
  if (!this.secret) {
25
25
  throw new TypeError('secret it is required value on initialize the auth class');
@@ -38,16 +38,20 @@ class Auth {
38
38
  debug('load default auth plugin');
39
39
  const pluginOptions = {
40
40
  config: this.config,
41
- logger: _logger.logger
41
+ logger: this.logger
42
42
  };
43
43
  let authPlugin;
44
44
  try {
45
45
  authPlugin = new _verdaccioHtpasswd.HTPasswd({
46
46
  file: './htpasswd'
47
47
  }, pluginOptions);
48
+ this.logger.info({
49
+ name: 'verdaccio-htpasswd',
50
+ pluginCategory: _core.PLUGIN_CATEGORY.AUTHENTICATION
51
+ }, 'plugin @{name} successfully loaded (@{pluginCategory})');
48
52
  } catch (error) {
49
53
  debug('error on loading auth htpasswd plugin stack: %o', error);
50
- _logger.logger.info({}, 'no auth plugin has been found');
54
+ this.logger.info({}, 'no auth plugin has been found');
51
55
  return [];
52
56
  }
53
57
  return [authPlugin];
@@ -55,7 +59,7 @@ class Auth {
55
59
  async loadPlugin() {
56
60
  return (0, _loaders.asyncLoadPlugin)(this.config.auth, {
57
61
  config: this.config,
58
- logger: _logger.logger
62
+ logger: this.logger
59
63
  }, plugin => {
60
64
  const {
61
65
  authenticate,
@@ -67,7 +71,7 @@ class Auth {
67
71
  }
68
72
  _applyDefaultPlugins() {
69
73
  // TODO: rename to applyFallbackPluginMethods
70
- this.plugins.push((0, _utils2.getDefaultPlugins)(_logger.logger));
74
+ this.plugins.push((0, _utils2.getDefaultPlugins)(this.logger));
71
75
  }
72
76
  changePassword(username, password, newPassword, cb) {
73
77
  const validPlugins = _lodash.default.filter(this.plugins, plugin => (0, _utils.isFunction)(plugin.changePassword));
@@ -82,7 +86,7 @@ class Auth {
82
86
  debug('updating password for %o', username);
83
87
  plugin.changePassword(username, password, newPassword, (err, profile) => {
84
88
  if (err) {
85
- _logger.logger.error({
89
+ this.logger.error({
86
90
  username,
87
91
  err
88
92
  }, `An error has been produced
package/build/auth.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"auth.js","names":["_debug","_interopRequireDefault","require","_lodash","_verdaccioHtpasswd","_config","_core","_loaders","_logger","_signature","_utils","_utils2","e","__esModule","default","debug","buildDebug","Auth","constructor","config","secret","plugins","TypeError","init","loadPlugin","length","loadDefaultPlugin","_applyDefaultPlugins","pluginOptions","logger","authPlugin","HTPasswd","file","error","info","asyncLoadPlugin","auth","plugin","authenticate","allow_access","allow_publish","serverSettings","pluginPrefix","PLUGIN_CATEGORY","AUTHENTICATION","push","getDefaultPlugins","changePassword","username","password","newPassword","cb","validPlugins","_","filter","isFunction","isEmpty","errorUtils","getInternalError","SUPPORT_ERRORS","PLUGIN_MISSING_INTERFACE","isNil","err","profile","invalidateToken","token","console","log","Promise","resolve","slice","next","shift","groups","message","isString","isGroupValid","isArray","API_ERROR","BAD_FORMAT_USER_GROUP","createRemoteUser","add_user","user","self","method","adduser","warningUtils","emit","Codes","VERWAR006","ok","packageName","packageVersion","callback","pkgAllowAccess","name","version","pkg","Object","assign","getMatchedPackagesSpec","packages","allow_unpublish","isError","apiJWTmiddleware","helpers","createAnonymousRemoteUser","req","res","_next","pause","resume","remote_user","remoteUser","locals","authorization","headers","isAuthHeaderValid","getBadRequest","BAD_AUTH_HEADER","security","isAESLegacy","handleAESMiddleware","handleJWTAPIMiddleware","scheme","parseAuthTokenHeader","toUpperCase","TOKEN_BASIC","credentials","convertPayloadToBase64","toString","parseBasicPayload","getMiddlewareCredentials","getForbidden","BAD_USERNAME_PASSWORD","_isRemoteUserValid","isUndefined","webUIJWTmiddleware","status","statusCode","send","replace","TOKEN_BEARER","verifyJWTPayload","jwtEncrypt","signOptions","real_groups","realGroupsValidated","groupedGroups","Array","from","Set","concat","payload","signPayload","aesEncrypt","value","signatureUtils","TOKEN_VALID_LENGTH","aesEncryptDeprecated","Buffer","exports"],"sources":["../src/auth.ts"],"sourcesContent":["import buildDebug from 'debug';\nimport _ from 'lodash';\nimport { HTPasswd } from 'verdaccio-htpasswd';\n\nimport { createAnonymousRemoteUser, createRemoteUser } from '@verdaccio/config';\nimport {\n API_ERROR,\n PLUGIN_CATEGORY,\n SUPPORT_ERRORS,\n TOKEN_BASIC,\n TOKEN_BEARER,\n VerdaccioError,\n errorUtils,\n pluginUtils,\n warningUtils,\n} from '@verdaccio/core';\nimport { asyncLoadPlugin } from '@verdaccio/loaders';\nimport { logger } from '@verdaccio/logger';\nimport {\n aesEncrypt,\n aesEncryptDeprecated,\n parseBasicPayload,\n signPayload,\n utils as signatureUtils,\n} from '@verdaccio/signature';\nimport {\n AllowAccess,\n Callback,\n Config,\n JWTSignOptions,\n PackageAccess,\n RemoteUser,\n Security,\n} from '@verdaccio/types';\nimport { getMatchedPackagesSpec, isFunction, isNil } from '@verdaccio/utils';\n\nimport {\n $RequestExtend,\n $ResponseExtend,\n AESPayload,\n IAuthMiddleware,\n NextFunction,\n TokenEncryption,\n} from './types';\nimport {\n convertPayloadToBase64,\n getDefaultPlugins,\n getMiddlewareCredentials,\n isAESLegacy,\n isAuthHeaderValid,\n parseAuthTokenHeader,\n verifyJWTPayload,\n} from './utils';\n\nconst debug = buildDebug('verdaccio:auth');\n\nclass Auth implements IAuthMiddleware, TokenEncryption, pluginUtils.IBasicAuth {\n public config: Config;\n public secret: string;\n public plugins: pluginUtils.Auth<Config>[];\n\n public constructor(config: Config) {\n this.config = config;\n this.secret = config.secret;\n this.plugins = [];\n if (!this.secret) {\n throw new TypeError('secret it is required value on initialize the auth class');\n }\n }\n\n public async init() {\n let plugins = (await this.loadPlugin()) as pluginUtils.Auth<unknown>[];\n\n debug('auth plugins found %s', plugins.length);\n if (!plugins || plugins.length === 0) {\n plugins = this.loadDefaultPlugin();\n }\n this.plugins = plugins;\n\n this._applyDefaultPlugins();\n }\n\n private loadDefaultPlugin() {\n debug('load default auth plugin');\n const pluginOptions: pluginUtils.PluginOptions = {\n config: this.config,\n logger,\n };\n let authPlugin;\n try {\n authPlugin = new HTPasswd(\n { file: './htpasswd' },\n pluginOptions as any as pluginUtils.PluginOptions\n );\n } catch (error: any) {\n debug('error on loading auth htpasswd plugin stack: %o', error);\n logger.info({}, 'no auth plugin has been found');\n return [];\n }\n\n return [authPlugin];\n }\n\n private async loadPlugin() {\n return asyncLoadPlugin<pluginUtils.Auth<unknown>>(\n this.config.auth,\n {\n config: this.config,\n logger,\n },\n (plugin): boolean => {\n const { authenticate, allow_access, allow_publish } = plugin;\n\n return (\n typeof authenticate !== 'undefined' ||\n typeof allow_access !== 'undefined' ||\n typeof allow_publish !== 'undefined'\n );\n },\n this.config?.serverSettings?.pluginPrefix,\n PLUGIN_CATEGORY.AUTHENTICATION\n );\n }\n\n private _applyDefaultPlugins(): void {\n // TODO: rename to applyFallbackPluginMethods\n this.plugins.push(getDefaultPlugins(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 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 async invalidateToken(token: string) {\n // eslint-disable-next-line no-console\n console.log('invalidate token pending to implement', token);\n return Promise.resolve();\n }\n\n public authenticate(\n username: string,\n password: string,\n cb: (error: VerdaccioError | null, user?: RemoteUser) => void\n ): void {\n const plugins = this.plugins.slice(0);\n (function next(): void {\n const plugin = plugins.shift() as pluginUtils.Auth<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: VerdaccioError | null, 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(\n user: string,\n password: string,\n cb: (error: VerdaccioError | null, user?: RemoteUser) => void\n ): void {\n const self = this;\n const plugins = this.plugins.slice(0);\n debug('add user %o', user);\n\n (function next(): void {\n let method = 'adduser';\n const plugin = plugins.shift() as pluginUtils.Auth<Config>;\n // @ts-expect-error future major (7.x) should remove this section\n if (typeof plugin.adduser === 'undefined' && typeof plugin.add_user === 'function') {\n method = 'add_user';\n warningUtils.emit(warningUtils.Codes.VERWAR006);\n }\n // @ts-ignore\n if (typeof plugin[method] !== 'function') {\n next();\n } else {\n // TODO: replace by adduser whenever add_user deprecation method has been removed\n // @ts-ignore\n plugin[method](\n user,\n password,\n function (err: VerdaccioError | null, ok?: boolean | string): void {\n if (err) {\n debug('the user %o could not be 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 debug('user could not be added, skip to next auth plugin');\n next();\n }\n );\n }\n })();\n }\n\n /**\n * Allow user to access a package.\n */\n public allow_access(\n { packageName, packageVersion }: pluginUtils.AuthPluginPackage,\n user: RemoteUser,\n callback: pluginUtils.AccessCallback\n ): void {\n const plugins = this.plugins.slice(0);\n const pkgAllowAccess: AllowAccess = { name: packageName, version: packageVersion };\n const pkg = Object.assign(\n {},\n pkgAllowAccess,\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: pluginUtils.Auth<unknown> = plugins.shift() as pluginUtils.Auth<unknown>;\n\n if (_.isNil(plugin) || isFunction(plugin.allow_access) === false) {\n return next();\n }\n\n plugin.allow_access!(user, pkg, function (err: VerdaccioError | null, 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 }: pluginUtils.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 (typeof plugin?.allow_unpublish !== 'function') {\n debug('allow unpublish for %o plugin does not implement allow_unpublish', packageName);\n continue;\n } else {\n plugin.allow_unpublish(user, pkg, (err, ok): 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 return this.allow_publish({ packageName, packageVersion }, user, callback);\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 }: pluginUtils.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 (typeof plugin?.allow_publish !== 'function') {\n debug('allow publish for %o plugin does not implement allow_publish', packageName);\n return next();\n }\n\n plugin.allow_publish(user, pkg, (err: VerdaccioError | null, 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 public apiJWTmiddleware(): any {\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) => {\n req.pause();\n const next = function (err?: VerdaccioError): NextFunction {\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\n return _next() as unknown as NextFunction;\n };\n\n // FUTURE: disabled, not removed yet but seems unreacable code\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 const remoteUser = createAnonymousRemoteUser();\n req.remote_user = remoteUser;\n res.locals.remote_user = remoteUser;\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: any\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: VerdaccioError | null, 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 has a secret? %o', typeof secret === 'string');\n debug('api middleware authorization %o', typeof authorization === 'string');\n const credentials: any = getMiddlewareCredentials(security, secret, authorization);\n debug('api middleware credentials %o', credentials?.name);\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() {\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: RemoteUser | undefined;\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 as RemoteUser;\n req.remote_user = createRemoteUser(name as string, 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)\n ? real_groups\n : Array.from(new Set([...groups.concat(realGroupsValidated)]));\n const payload: RemoteUser = {\n real_groups: realGroupsValidated,\n name,\n groups: groupedGroups,\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 if (this.secret.length === signatureUtils.TOKEN_VALID_LENGTH) {\n debug('signing with enhanced aes legacy');\n const token = aesEncrypt(value, this.secret);\n return token;\n } else {\n debug('signing with enhanced aes deprecated legacy');\n // deprecated aes (legacy) signature, only must be used for legacy version\n const token = aesEncryptDeprecated(Buffer.from(value), this.secret).toString('base64');\n return token;\n }\n }\n}\n\nexport { Auth };\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"auth.js","names":["_debug","_interopRequireDefault","require","_lodash","_verdaccioHtpasswd","_config","_core","_loaders","_signature","_utils","_utils2","e","__esModule","default","debug","buildDebug","Auth","constructor","config","logger","secret","plugins","TypeError","init","loadPlugin","length","loadDefaultPlugin","_applyDefaultPlugins","pluginOptions","authPlugin","HTPasswd","file","info","name","pluginCategory","PLUGIN_CATEGORY","AUTHENTICATION","error","asyncLoadPlugin","auth","plugin","authenticate","allow_access","allow_publish","serverSettings","pluginPrefix","push","getDefaultPlugins","changePassword","username","password","newPassword","cb","validPlugins","_","filter","isFunction","isEmpty","errorUtils","getInternalError","SUPPORT_ERRORS","PLUGIN_MISSING_INTERFACE","isNil","err","profile","invalidateToken","token","console","log","Promise","resolve","slice","next","shift","groups","message","isString","isGroupValid","isArray","API_ERROR","BAD_FORMAT_USER_GROUP","createRemoteUser","add_user","user","self","method","adduser","warningUtils","emit","Codes","VERWAR006","ok","packageName","packageVersion","callback","pkgAllowAccess","version","pkg","Object","assign","getMatchedPackagesSpec","packages","allow_unpublish","isError","apiJWTmiddleware","helpers","createAnonymousRemoteUser","req","res","_next","pause","resume","remote_user","remoteUser","locals","authorization","headers","isAuthHeaderValid","getBadRequest","BAD_AUTH_HEADER","security","isAESLegacy","handleAESMiddleware","handleJWTAPIMiddleware","scheme","parseAuthTokenHeader","toUpperCase","TOKEN_BASIC","credentials","convertPayloadToBase64","toString","parseBasicPayload","getMiddlewareCredentials","getForbidden","BAD_USERNAME_PASSWORD","_isRemoteUserValid","isUndefined","webUIJWTmiddleware","status","statusCode","send","replace","TOKEN_BEARER","verifyJWTPayload","jwtEncrypt","signOptions","real_groups","realGroupsValidated","groupedGroups","Array","from","Set","concat","payload","signPayload","aesEncrypt","value","signatureUtils","TOKEN_VALID_LENGTH","aesEncryptDeprecated","Buffer","exports"],"sources":["../src/auth.ts"],"sourcesContent":["import buildDebug from 'debug';\nimport _ from 'lodash';\nimport { HTPasswd } from 'verdaccio-htpasswd';\n\nimport { createAnonymousRemoteUser, createRemoteUser } from '@verdaccio/config';\nimport {\n API_ERROR,\n PLUGIN_CATEGORY,\n SUPPORT_ERRORS,\n TOKEN_BASIC,\n TOKEN_BEARER,\n VerdaccioError,\n errorUtils,\n pluginUtils,\n warningUtils,\n} from '@verdaccio/core';\nimport { asyncLoadPlugin } from '@verdaccio/loaders';\nimport {\n aesEncrypt,\n aesEncryptDeprecated,\n parseBasicPayload,\n signPayload,\n utils as signatureUtils,\n} from '@verdaccio/signature';\nimport {\n AllowAccess,\n Callback,\n Config,\n JWTSignOptions,\n Logger,\n PackageAccess,\n RemoteUser,\n Security,\n} from '@verdaccio/types';\nimport { getMatchedPackagesSpec, isFunction, isNil } from '@verdaccio/utils';\n\nimport {\n $RequestExtend,\n $ResponseExtend,\n AESPayload,\n IAuthMiddleware,\n NextFunction,\n TokenEncryption,\n} from './types';\nimport {\n convertPayloadToBase64,\n getDefaultPlugins,\n getMiddlewareCredentials,\n isAESLegacy,\n isAuthHeaderValid,\n parseAuthTokenHeader,\n verifyJWTPayload,\n} from './utils';\n\nconst debug = buildDebug('verdaccio:auth');\n\nclass Auth implements IAuthMiddleware, TokenEncryption, pluginUtils.IBasicAuth {\n public config: Config;\n public secret: string;\n public logger: Logger;\n public plugins: pluginUtils.Auth<Config>[];\n\n public constructor(config: Config, logger: Logger) {\n this.config = config;\n this.secret = config.secret;\n this.logger = logger;\n this.plugins = [];\n if (!this.secret) {\n throw new TypeError('secret it is required value on initialize the auth class');\n }\n }\n\n public async init() {\n let plugins = (await this.loadPlugin()) as pluginUtils.Auth<unknown>[];\n\n debug('auth plugins found %s', plugins.length);\n if (!plugins || plugins.length === 0) {\n plugins = this.loadDefaultPlugin();\n }\n this.plugins = plugins;\n\n this._applyDefaultPlugins();\n }\n\n private loadDefaultPlugin() {\n debug('load default auth plugin');\n const pluginOptions: pluginUtils.PluginOptions = {\n config: this.config,\n logger: this.logger,\n };\n let authPlugin;\n try {\n authPlugin = new HTPasswd(\n { file: './htpasswd' },\n pluginOptions as any as pluginUtils.PluginOptions\n );\n this.logger.info(\n { name: 'verdaccio-htpasswd', pluginCategory: PLUGIN_CATEGORY.AUTHENTICATION },\n 'plugin @{name} successfully loaded (@{pluginCategory})'\n );\n } catch (error: any) {\n debug('error on loading auth htpasswd plugin stack: %o', error);\n this.logger.info({}, 'no auth plugin has been found');\n return [];\n }\n\n return [authPlugin];\n }\n\n private async loadPlugin() {\n return asyncLoadPlugin<pluginUtils.Auth<unknown>>(\n this.config.auth,\n {\n config: this.config,\n logger: this.logger,\n },\n (plugin): boolean => {\n const { authenticate, allow_access, allow_publish } = plugin;\n\n return (\n typeof authenticate !== 'undefined' ||\n typeof allow_access !== 'undefined' ||\n typeof allow_publish !== 'undefined'\n );\n },\n this.config?.serverSettings?.pluginPrefix,\n PLUGIN_CATEGORY.AUTHENTICATION\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 async invalidateToken(token: string) {\n // eslint-disable-next-line no-console\n console.log('invalidate token pending to implement', token);\n return Promise.resolve();\n }\n\n public authenticate(\n username: string,\n password: string,\n cb: (error: VerdaccioError | null, user?: RemoteUser) => void\n ): void {\n const plugins = this.plugins.slice(0);\n (function next(): void {\n const plugin = plugins.shift() as pluginUtils.Auth<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: VerdaccioError | null, 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(\n user: string,\n password: string,\n cb: (error: VerdaccioError | null, user?: RemoteUser) => void\n ): void {\n const self = this;\n const plugins = this.plugins.slice(0);\n debug('add user %o', user);\n\n (function next(): void {\n let method = 'adduser';\n const plugin = plugins.shift() as pluginUtils.Auth<Config>;\n // @ts-expect-error future major (7.x) should remove this section\n if (typeof plugin.adduser === 'undefined' && typeof plugin.add_user === 'function') {\n method = 'add_user';\n warningUtils.emit(warningUtils.Codes.VERWAR006);\n }\n // @ts-ignore\n if (typeof plugin[method] !== 'function') {\n next();\n } else {\n // TODO: replace by adduser whenever add_user deprecation method has been removed\n // @ts-ignore\n plugin[method](\n user,\n password,\n function (err: VerdaccioError | null, ok?: boolean | string): void {\n if (err) {\n debug('the user %o could not be 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 debug('user could not be added, skip to next auth plugin');\n next();\n }\n );\n }\n })();\n }\n\n /**\n * Allow user to access a package.\n */\n public allow_access(\n { packageName, packageVersion }: pluginUtils.AuthPluginPackage,\n user: RemoteUser,\n callback: pluginUtils.AccessCallback\n ): void {\n const plugins = this.plugins.slice(0);\n const pkgAllowAccess: AllowAccess = { name: packageName, version: packageVersion };\n const pkg = Object.assign(\n {},\n pkgAllowAccess,\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: pluginUtils.Auth<unknown> = plugins.shift() as pluginUtils.Auth<unknown>;\n\n if (_.isNil(plugin) || isFunction(plugin.allow_access) === false) {\n return next();\n }\n\n plugin.allow_access!(user, pkg, function (err: VerdaccioError | null, 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 }: pluginUtils.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 (typeof plugin?.allow_unpublish !== 'function') {\n debug('allow unpublish for %o plugin does not implement allow_unpublish', packageName);\n continue;\n } else {\n plugin.allow_unpublish(user, pkg, (err, ok): 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 return this.allow_publish({ packageName, packageVersion }, user, callback);\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 }: pluginUtils.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 (typeof plugin?.allow_publish !== 'function') {\n debug('allow publish for %o plugin does not implement allow_publish', packageName);\n return next();\n }\n\n plugin.allow_publish(user, pkg, (err: VerdaccioError | null, 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 public apiJWTmiddleware(): any {\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) => {\n req.pause();\n const next = function (err?: VerdaccioError): NextFunction {\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\n return _next() as unknown as NextFunction;\n };\n\n // FUTURE: disabled, not removed yet but seems unreacable code\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 const remoteUser = createAnonymousRemoteUser();\n req.remote_user = remoteUser;\n res.locals.remote_user = remoteUser;\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: any\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: VerdaccioError | null, 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 has a secret? %o', typeof secret === 'string');\n debug('api middleware authorization %o', typeof authorization === 'string');\n const credentials: any = getMiddlewareCredentials(security, secret, authorization);\n debug('api middleware credentials %o', credentials?.name);\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() {\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: RemoteUser | undefined;\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 as RemoteUser;\n req.remote_user = createRemoteUser(name as string, 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)\n ? real_groups\n : Array.from(new Set([...groups.concat(realGroupsValidated)]));\n const payload: RemoteUser = {\n real_groups: realGroupsValidated,\n name,\n groups: groupedGroups,\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 if (this.secret.length === signatureUtils.TOKEN_VALID_LENGTH) {\n debug('signing with enhanced aes legacy');\n const token = aesEncrypt(value, this.secret);\n return token;\n } else {\n debug('signing with enhanced aes deprecated legacy');\n // deprecated aes (legacy) signature, only must be used for legacy version\n const token = aesEncryptDeprecated(Buffer.from(value), this.secret).toString('base64');\n return token;\n }\n }\n}\n\nexport { Auth };\n"],"mappings":";;;;;;AAAA,IAAAA,MAAA,GAAAC,sBAAA,CAAAC,OAAA;AACA,IAAAC,OAAA,GAAAF,sBAAA,CAAAC,OAAA;AACA,IAAAE,kBAAA,GAAAF,OAAA;AAEA,IAAAG,OAAA,GAAAH,OAAA;AACA,IAAAI,KAAA,GAAAJ,OAAA;AAWA,IAAAK,QAAA,GAAAL,OAAA;AACA,IAAAM,UAAA,GAAAN,OAAA;AAiBA,IAAAO,MAAA,GAAAP,OAAA;AAUA,IAAAQ,OAAA,GAAAR,OAAA;AAQiB,SAAAD,uBAAAU,CAAA,WAAAA,CAAA,IAAAA,CAAA,CAAAC,UAAA,GAAAD,CAAA,KAAAE,OAAA,EAAAF,CAAA;AAEjB,MAAMG,KAAK,GAAG,IAAAC,cAAU,EAAC,gBAAgB,CAAC;AAE1C,MAAMC,IAAI,CAAqE;EAMtEC,WAAWA,CAACC,MAAc,EAAEC,MAAc,EAAE;IACjD,IAAI,CAACD,MAAM,GAAGA,MAAM;IACpB,IAAI,CAACE,MAAM,GAAGF,MAAM,CAACE,MAAM;IAC3B,IAAI,CAACD,MAAM,GAAGA,MAAM;IACpB,IAAI,CAACE,OAAO,GAAG,EAAE;IACjB,IAAI,CAAC,IAAI,CAACD,MAAM,EAAE;MAChB,MAAM,IAAIE,SAAS,CAAC,0DAA0D,CAAC;IACjF;EACF;EAEA,MAAaC,IAAIA,CAAA,EAAG;IAClB,IAAIF,OAAO,GAAI,MAAM,IAAI,CAACG,UAAU,CAAC,CAAiC;IAEtEV,KAAK,CAAC,uBAAuB,EAAEO,OAAO,CAACI,MAAM,CAAC;IAC9C,IAAI,CAACJ,OAAO,IAAIA,OAAO,CAACI,MAAM,KAAK,CAAC,EAAE;MACpCJ,OAAO,GAAG,IAAI,CAACK,iBAAiB,CAAC,CAAC;IACpC;IACA,IAAI,CAACL,OAAO,GAAGA,OAAO;IAEtB,IAAI,CAACM,oBAAoB,CAAC,CAAC;EAC7B;EAEQD,iBAAiBA,CAAA,EAAG;IAC1BZ,KAAK,CAAC,0BAA0B,CAAC;IACjC,MAAMc,aAAwC,GAAG;MAC/CV,MAAM,EAAE,IAAI,CAACA,MAAM;MACnBC,MAAM,EAAE,IAAI,CAACA;IACf,CAAC;IACD,IAAIU,UAAU;IACd,IAAI;MACFA,UAAU,GAAG,IAAIC,2BAAQ,CACvB;QAAEC,IAAI,EAAE;MAAa,CAAC,EACtBH,aACF,CAAC;MACD,IAAI,CAACT,MAAM,CAACa,IAAI,CACd;QAAEC,IAAI,EAAE,oBAAoB;QAAEC,cAAc,EAAEC,qBAAe,CAACC;MAAe,CAAC,EAC9E,wDACF,CAAC;IACH,CAAC,CAAC,OAAOC,KAAU,EAAE;MACnBvB,KAAK,CAAC,iDAAiD,EAAEuB,KAAK,CAAC;MAC/D,IAAI,CAAClB,MAAM,CAACa,IAAI,CAAC,CAAC,CAAC,EAAE,+BAA+B,CAAC;MACrD,OAAO,EAAE;IACX;IAEA,OAAO,CAACH,UAAU,CAAC;EACrB;EAEA,MAAcL,UAAUA,CAAA,EAAG;IACzB,OAAO,IAAAc,wBAAe,EACpB,IAAI,CAACpB,MAAM,CAACqB,IAAI,EAChB;MACErB,MAAM,EAAE,IAAI,CAACA,MAAM;MACnBC,MAAM,EAAE,IAAI,CAACA;IACf,CAAC,EACAqB,MAAM,IAAc;MACnB,MAAM;QAAEC,YAAY;QAAEC,YAAY;QAAEC;MAAc,CAAC,GAAGH,MAAM;MAE5D,OACE,OAAOC,YAAY,KAAK,WAAW,IACnC,OAAOC,YAAY,KAAK,WAAW,IACnC,OAAOC,aAAa,KAAK,WAAW;IAExC,CAAC,EACD,IAAI,CAACzB,MAAM,EAAE0B,cAAc,EAAEC,YAAY,EACzCV,qBAAe,CAACC,cAClB,CAAC;EACH;EAEQT,oBAAoBA,CAAA,EAAS;IACnC;IACA,IAAI,CAACN,OAAO,CAACyB,IAAI,CAAC,IAAAC,yBAAiB,EAAC,IAAI,CAAC5B,MAAM,CAAC,CAAC;EACnD;EAEO6B,cAAcA,CACnBC,QAAgB,EAChBC,QAAgB,EAChBC,WAAmB,EACnBC,EAAY,EACN;IACN,MAAMC,YAAY,GAAGC,eAAC,CAACC,MAAM,CAAC,IAAI,CAAClC,OAAO,EAAGmB,MAAM,IAAK,IAAAgB,iBAAU,EAAChB,MAAM,CAACQ,cAAc,CAAC,CAAC;IAE1F,IAAIM,eAAC,CAACG,OAAO,CAACJ,YAAY,CAAC,EAAE;MAC3B,OAAOD,EAAE,CAACM,gBAAU,CAACC,gBAAgB,CAACC,oBAAc,CAACC,wBAAwB,CAAC,CAAC;IACjF;IAEA,KAAK,MAAMrB,MAAM,IAAIa,YAAY,EAAE;MACjC,IAAI,IAAAS,YAAK,EAACtB,MAAM,CAAC,IAAI,IAAAgB,iBAAU,EAAChB,MAAM,CAACQ,cAAc,CAAC,KAAK,KAAK,EAAE;QAChElC,KAAK,CAAC,gEAAgE,CAAC;QACvE;MACF,CAAC,MAAM;QACLA,KAAK,CAAC,0BAA0B,EAAEmC,QAAQ,CAAC;QAC3CT,MAAM,CAACQ,cAAc,CAAEC,QAAQ,EAAEC,QAAQ,EAAEC,WAAW,EAAE,CAACY,GAAG,EAAEC,OAAO,KAAW;UAC9E,IAAID,GAAG,EAAE;YACP,IAAI,CAAC5C,MAAM,CAACkB,KAAK,CACf;cAAEY,QAAQ;cAAEc;YAAI,CAAC,EACjB;AACd,yEACY,CAAC;YACD,OAAOX,EAAE,CAACW,GAAG,CAAC;UAChB;UAEAjD,KAAK,CAAC,wCAAwC,EAAEmC,QAAQ,CAAC;UACzD,OAAOG,EAAE,CAAC,IAAI,EAAEY,OAAO,CAAC;QAC1B,CAAC,CAAC;MACJ;IACF;EACF;EAEA,MAAaC,eAAeA,CAACC,KAAa,EAAE;IAC1C;IACAC,OAAO,CAACC,GAAG,CAAC,uCAAuC,EAAEF,KAAK,CAAC;IAC3D,OAAOG,OAAO,CAACC,OAAO,CAAC,CAAC;EAC1B;EAEO7B,YAAYA,CACjBQ,QAAgB,EAChBC,QAAgB,EAChBE,EAA6D,EACvD;IACN,MAAM/B,OAAO,GAAG,IAAI,CAACA,OAAO,CAACkD,KAAK,CAAC,CAAC,CAAC;IACrC,CAAC,SAASC,IAAIA,CAAA,EAAS;MACrB,MAAMhC,MAAM,GAAGnB,OAAO,CAACoD,KAAK,CAAC,CAA6B;MAE1D,IAAI,IAAAjB,iBAAU,EAAChB,MAAM,CAACC,YAAY,CAAC,KAAK,KAAK,EAAE;QAC7C,OAAO+B,IAAI,CAAC,CAAC;MACf;MAEA1D,KAAK,CAAC,mBAAmB,EAAEmC,QAAQ,CAAC;MACpCT,MAAM,CAACC,YAAY,CAACQ,QAAQ,EAAEC,QAAQ,EAAE,UAAUa,GAA0B,EAAEW,MAAM,EAAQ;QAC1F,IAAIX,GAAG,EAAE;UACPjD,KAAK,CAAC,8CAA8C,EAAEmC,QAAQ,EAAEc,GAAG,EAAEY,OAAO,CAAC;UAC7E,OAAOvB,EAAE,CAACW,GAAG,CAAC;QAChB;;QAEA;QACA;QACA;QACA;QACA;QACA;QACA;QACA,IAAI,CAAC,CAACW,MAAM,IAAIA,MAAM,CAACjD,MAAM,KAAK,CAAC,EAAE;UACnC;UACA,IAAI6B,eAAC,CAACsB,QAAQ,CAACF,MAAM,CAAC,EAAE;YACtB,MAAM,IAAIpD,SAAS,CAAC,+CAA+C,CAAC;UACtE;UACA,MAAMuD,YAAqB,GAAGvB,eAAC,CAACwB,OAAO,CAACJ,MAAM,CAAC;UAC/C,IAAI,CAACG,YAAY,EAAE;YACjB,MAAM,IAAIvD,SAAS,CAACyD,eAAS,CAACC,qBAAqB,CAAC;UACtD;UAEAlE,KAAK,CAAC,yDAAyD,EAAEmC,QAAQ,EAAEyB,MAAM,CAAC;UAClF,OAAOtB,EAAE,CAACW,GAAG,EAAE,IAAAkB,wBAAgB,EAAChC,QAAQ,EAAEyB,MAAM,CAAC,CAAC;QACpD;QACAF,IAAI,CAAC,CAAC;MACR,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC;EACN;EAEOU,QAAQA,CACbC,IAAY,EACZjC,QAAgB,EAChBE,EAA6D,EACvD;IACN,MAAMgC,IAAI,GAAG,IAAI;IACjB,MAAM/D,OAAO,GAAG,IAAI,CAACA,OAAO,CAACkD,KAAK,CAAC,CAAC,CAAC;IACrCzD,KAAK,CAAC,aAAa,EAAEqE,IAAI,CAAC;IAE1B,CAAC,SAASX,IAAIA,CAAA,EAAS;MACrB,IAAIa,MAAM,GAAG,SAAS;MACtB,MAAM7C,MAAM,GAAGnB,OAAO,CAACoD,KAAK,CAAC,CAA6B;MAC1D;MACA,IAAI,OAAOjC,MAAM,CAAC8C,OAAO,KAAK,WAAW,IAAI,OAAO9C,MAAM,CAAC0C,QAAQ,KAAK,UAAU,EAAE;QAClFG,MAAM,GAAG,UAAU;QACnBE,kBAAY,CAACC,IAAI,CAACD,kBAAY,CAACE,KAAK,CAACC,SAAS,CAAC;MACjD;MACA;MACA,IAAI,OAAOlD,MAAM,CAAC6C,MAAM,CAAC,KAAK,UAAU,EAAE;QACxCb,IAAI,CAAC,CAAC;MACR,CAAC,MAAM;QACL;QACA;QACAhC,MAAM,CAAC6C,MAAM,CAAC,CACZF,IAAI,EACJjC,QAAQ,EACR,UAAUa,GAA0B,EAAE4B,EAAqB,EAAQ;UACjE,IAAI5B,GAAG,EAAE;YACPjD,KAAK,CAAC,2CAA2C,EAAEqE,IAAI,EAAEpB,GAAG,EAAEY,OAAO,CAAC;YACtE,OAAOvB,EAAE,CAACW,GAAG,CAAC;UAChB;UACA,IAAI4B,EAAE,EAAE;YACN7E,KAAK,CAAC,4BAA4B,EAAEqE,IAAI,CAAC;YACzC,OAAOC,IAAI,CAAC3C,YAAY,CAAC0C,IAAI,EAAEjC,QAAQ,EAAEE,EAAE,CAAC;UAC9C;UACAtC,KAAK,CAAC,mDAAmD,CAAC;UAC1D0D,IAAI,CAAC,CAAC;QACR,CACF,CAAC;MACH;IACF,CAAC,EAAE,CAAC;EACN;;EAEA;AACF;AACA;EACS9B,YAAYA,CACjB;IAAEkD,WAAW;IAAEC;EAA8C,CAAC,EAC9DV,IAAgB,EAChBW,QAAoC,EAC9B;IACN,MAAMzE,OAAO,GAAG,IAAI,CAACA,OAAO,CAACkD,KAAK,CAAC,CAAC,CAAC;IACrC,MAAMwB,cAA2B,GAAG;MAAE9D,IAAI,EAAE2D,WAAW;MAAEI,OAAO,EAAEH;IAAe,CAAC;IAClF,MAAMI,GAAG,GAAGC,MAAM,CAACC,MAAM,CACvB,CAAC,CAAC,EACFJ,cAAc,EACd,IAAAK,6BAAsB,EAACR,WAAW,EAAE,IAAI,CAAC1E,MAAM,CAACmF,QAAQ,CAC1D,CAAgC;IAChCvF,KAAK,CAAC,qBAAqB,EAAE8E,WAAW,CAAC;IAEzC,CAAC,SAASpB,IAAIA,CAAA,EAAS;MACrB,MAAMhC,MAAiC,GAAGnB,OAAO,CAACoD,KAAK,CAAC,CAA8B;MAEtF,IAAInB,eAAC,CAACQ,KAAK,CAACtB,MAAM,CAAC,IAAI,IAAAgB,iBAAU,EAAChB,MAAM,CAACE,YAAY,CAAC,KAAK,KAAK,EAAE;QAChE,OAAO8B,IAAI,CAAC,CAAC;MACf;MAEAhC,MAAM,CAACE,YAAY,CAAEyC,IAAI,EAAEc,GAAG,EAAE,UAAUlC,GAA0B,EAAE4B,EAAY,EAAQ;QACxF,IAAI5B,GAAG,EAAE;UACPjD,KAAK,CAAC,oCAAoC,EAAE8E,WAAW,EAAE7B,GAAG,EAAEY,OAAO,CAAC;UACtE,OAAOmB,QAAQ,CAAC/B,GAAG,CAAC;QACtB;QAEA,IAAI4B,EAAE,EAAE;UACN7E,KAAK,CAAC,uBAAuB,EAAE8E,WAAW,CAAC;UAC3C,OAAOE,QAAQ,CAAC,IAAI,EAAEH,EAAE,CAAC;QAC3B;QAEAnB,IAAI,CAAC,CAAC,CAAC,CAAC;MACV,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC;EACN;EAEO8B,eAAeA,CACpB;IAAEV,WAAW;IAAEC;EAA8C,CAAC,EAC9DV,IAAgB,EAChBW,QAAkB,EACZ;IACN,MAAMG,GAAG,GAAGC,MAAM,CAACC,MAAM,CACvB;MAAElE,IAAI,EAAE2D,WAAW;MAAEI,OAAO,EAAEH;IAAe,CAAC,EAC9C,IAAAO,6BAAsB,EAACR,WAAW,EAAE,IAAI,CAAC1E,MAAM,CAACmF,QAAQ,CAC1D,CAAC;IACDvF,KAAK,CAAC,wBAAwB,EAAE8E,WAAW,CAAC;IAE5C,KAAK,MAAMpD,MAAM,IAAI,IAAI,CAACnB,OAAO,EAAE;MACjC,IAAI,OAAOmB,MAAM,EAAE8D,eAAe,KAAK,UAAU,EAAE;QACjDxF,KAAK,CAAC,kEAAkE,EAAE8E,WAAW,CAAC;QACtF;MACF,CAAC,MAAM;QACLpD,MAAM,CAAC8D,eAAe,CAACnB,IAAI,EAAEc,GAAG,EAAE,CAAClC,GAAG,EAAE4B,EAAE,KAAW;UACnD,IAAI5B,GAAG,EAAE;YACPjD,KAAK,CACH,qEAAqE,EACrE8E,WACF,CAAC;YACD,OAAOE,QAAQ,CAAC/B,GAAG,CAAC;UACtB;UAEA,IAAIT,eAAC,CAACQ,KAAK,CAAC6B,EAAE,CAAC,KAAK,IAAI,EAAE;YACxB7E,KAAK,CAAC,yDAAyD,EAAE8E,WAAW,CAAC;YAC7E,OAAO,IAAI,CAACjD,aAAa,CAAC;cAAEiD,WAAW;cAAEC;YAAe,CAAC,EAAEV,IAAI,EAAEW,QAAQ,CAAC;UAC5E;UAEA,IAAIH,EAAE,EAAE;YACN7E,KAAK,CAAC,0BAA0B,EAAE8E,WAAW,CAAC;YAC9C,OAAOE,QAAQ,CAAC,IAAI,EAAEH,EAAE,CAAC;UAC3B;QACF,CAAC,CAAC;MACJ;IACF;EACF;;EAEA;AACF;AACA;EACShD,aAAaA,CAClB;IAAEiD,WAAW;IAAEC;EAA8C,CAAC,EAC9DV,IAAgB,EAChBW,QAAkB,EACZ;IACN,MAAMzE,OAAO,GAAG,IAAI,CAACA,OAAO,CAACkD,KAAK,CAAC,CAAC,CAAC;IACrC,MAAM0B,GAAG,GAAGC,MAAM,CAACC,MAAM,CACvB;MAAElE,IAAI,EAAE2D,WAAW;MAAEI,OAAO,EAAEH;IAAe,CAAC,EAC9C,IAAAO,6BAAsB,EAACR,WAAW,EAAE,IAAI,CAAC1E,MAAM,CAACmF,QAAQ,CAC1D,CAAC;IACDvF,KAAK,CAAC,yCAAyC,EAAE8E,WAAW,EAAEvE,OAAO,CAACI,MAAM,CAAC;IAE7E,CAAC,SAAS+C,IAAIA,CAAA,EAAS;MACrB,MAAMhC,MAAM,GAAGnB,OAAO,CAACoD,KAAK,CAAC,CAAC;MAE9B,IAAI,OAAOjC,MAAM,EAAEG,aAAa,KAAK,UAAU,EAAE;QAC/C7B,KAAK,CAAC,8DAA8D,EAAE8E,WAAW,CAAC;QAClF,OAAOpB,IAAI,CAAC,CAAC;MACf;MAEAhC,MAAM,CAACG,aAAa,CAACwC,IAAI,EAAEc,GAAG,EAAE,CAAClC,GAA0B,EAAE4B,EAAY,KAAW;QAClF,IAAIrC,eAAC,CAACQ,KAAK,CAACC,GAAG,CAAC,KAAK,KAAK,IAAIT,eAAC,CAACiD,OAAO,CAACxC,GAAG,CAAC,EAAE;UAC5CjD,KAAK,CAAC,0BAA0B,EAAE8E,WAAW,CAAC;UAC9C,OAAOE,QAAQ,CAAC/B,GAAG,CAAC;QACtB;QAEA,IAAI4B,EAAE,EAAE;UACN7E,KAAK,CAAC,wBAAwB,EAAE8E,WAAW,CAAC;UAC5C,OAAOE,QAAQ,CAAC,IAAI,EAAEH,EAAE,CAAC;QAC3B;QAEA7E,KAAK,CAAC,sCAAsC,EAAE8E,WAAW,CAAC;QAC1DpB,IAAI,CAAC,CAAC,CAAC,CAAC;MACV,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC;EACN;EAEOgC,gBAAgBA,CAAA,EAAQ;IAC7B1F,KAAK,CAAC,gBAAgB,CAAC;IACvB,MAAMO,OAAO,GAAG,IAAI,CAACA,OAAO,CAACkD,KAAK,CAAC,CAAC,CAAC;IACrC,MAAMkC,OAAO,GAAG;MAAEC,yBAAyB,EAAzBA,iCAAyB;MAAEzB,gBAAgB,EAAhBA;IAAiB,CAAC;IAC/D,KAAK,MAAMzC,MAAM,IAAInB,OAAO,EAAE;MAC5B,IAAImB,MAAM,CAACgE,gBAAgB,EAAE;QAC3B,OAAOhE,MAAM,CAACgE,gBAAgB,CAACC,OAAO,CAAC;MACzC;IACF;IAEA,OAAO,CAACE,GAAmB,EAAEC,GAAoB,EAAEC,KAAmB,KAAK;MACzEF,GAAG,CAACG,KAAK,CAAC,CAAC;MACX,MAAMtC,IAAI,GAAG,SAAAA,CAAUT,GAAoB,EAAgB;QACzD4C,GAAG,CAACI,MAAM,CAAC,CAAC;QACZ;QACA;QACA;QACA;QACA,IAAIhD,GAAG,EAAE;UACP4C,GAAG,CAACK,WAAW,CAAC3E,KAAK,GAAG0B,GAAG,CAACY,OAAO;QACrC;QAEA,OAAOkC,KAAK,CAAC,CAAC;MAChB,CAAC;;MAED;MACA;MACA;MACA;MACA;;MAEA;MACA,MAAMI,UAAU,GAAG,IAAAP,iCAAyB,EAAC,CAAC;MAC9CC,GAAG,CAACK,WAAW,GAAGC,UAAU;MAC5BL,GAAG,CAACM,MAAM,CAACF,WAAW,GAAGC,UAAU;MAEnC,MAAM;QAAEE;MAAc,CAAC,GAAGR,GAAG,CAACS,OAAO;MACrC,IAAI9D,eAAC,CAACQ,KAAK,CAACqD,aAAa,CAAC,EAAE;QAC1BrG,KAAK,CAAC,uCAAuC,CAAC;QAC9C,OAAO0D,IAAI,CAAC,CAAC;MACf;MAEA,IAAI,CAAC,IAAA6C,yBAAiB,EAACF,aAAa,CAAC,EAAE;QACrCrG,KAAK,CAAC,kDAAkD,CAAC;QACzD,OAAO0D,IAAI,CAACd,gBAAU,CAAC4D,aAAa,CAACvC,eAAS,CAACwC,eAAe,CAAC,CAAC;MAClE;MACA,MAAM;QAAEnG,MAAM;QAAEoG;MAAS,CAAC,GAAG,IAAI,CAACtG,MAAM;MAExC,IAAI,IAAAuG,mBAAW,EAACD,QAAQ,CAAC,EAAE;QACzB1G,KAAK,CAAC,wCAAwC,CAAC;QAC/C,IAAI,CAAC4G,mBAAmB,CAACf,GAAG,EAAEa,QAAQ,EAAEpG,MAAM,EAAE+F,aAAa,EAAE3C,IAAI,CAAC;MACtE,CAAC,MAAM;QACL1D,KAAK,CAAC,qCAAqC,CAAC;QAC5C,IAAI,CAAC6G,sBAAsB,CAAChB,GAAG,EAAEa,QAAQ,EAAEpG,MAAM,EAAE+F,aAAa,EAAE3C,IAAI,CAAC;MACzE;IACF,CAAC;EACH;EAEQmD,sBAAsBA,CAC5BhB,GAAmB,EACnBa,QAAkB,EAClBpG,MAAc,EACd+F,aAAqB,EACrB3C,IAAS,EACH;IACN1D,KAAK,CAAC,2BAA2B,CAAC;IAClC,MAAM;MAAE8G,MAAM;MAAE1D;IAAM,CAAC,GAAG,IAAA2D,4BAAoB,EAACV,aAAa,CAAC;IAC7D,IAAIS,MAAM,CAACE,WAAW,CAAC,CAAC,KAAKC,iBAAW,CAACD,WAAW,CAAC,CAAC,EAAE;MACtDhH,KAAK,CAAC,oBAAoB,CAAC;MAC3B;MACA,MAAMkH,WAAW,GAAG,IAAAC,8BAAsB,EAAC/D,KAAK,CAAC,CAACgE,QAAQ,CAAC,CAAC;MAC5D,MAAM;QAAE/C,IAAI;QAAEjC;MAAS,CAAC,GAAG,IAAAiF,4BAAiB,EAACH,WAAW,CAAe;MACvElH,KAAK,CAAC,mBAAmB,EAAEqE,IAAI,CAAC;MAChC,IAAI,CAAC1C,YAAY,CAAC0C,IAAI,EAAEjC,QAAQ,EAAE,CAACa,GAA0B,EAAEoB,IAAI,KAAW;QAC5E,IAAI,CAACpB,GAAG,EAAE;UACRjD,KAAK,CAAC,0BAA0B,CAAC;UACjC6F,GAAG,CAACK,WAAW,GAAG7B,IAAI;UACtBX,IAAI,CAAC,CAAC;QACR,CAAC,MAAM;UACL1D,KAAK,CAAC,2BAA2B,CAAC;UAClC6F,GAAG,CAACK,WAAW,GAAG,IAAAN,iCAAyB,EAAC,CAAC;UAC7ClC,IAAI,CAACT,GAAG,CAAC;QACX;MACF,CAAC,CAAC;IACJ,CAAC,MAAM;MACLjD,KAAK,CAAC,kBAAkB,CAAC;MACzB,MAAMkH,WAAgB,GAAG,IAAAI,gCAAwB,EAACZ,QAAQ,EAAEpG,MAAM,EAAE+F,aAAa,CAAC;MAClF,IAAIa,WAAW,EAAE;QACf;QACArB,GAAG,CAACK,WAAW,GAAGgB,WAAW;QAC7BlH,KAAK,CAAC,0BAA0B,CAAC;QACjC0D,IAAI,CAAC,CAAC;MACR,CAAC,MAAM;QACL;QACA1D,KAAK,CAAC,mBAAmB,CAAC;QAC1B0D,IAAI,CAACd,gBAAU,CAAC2E,YAAY,CAACtD,eAAS,CAACuD,qBAAqB,CAAC,CAAC;MAChE;IACF;EACF;EAEQZ,mBAAmBA,CACzBf,GAAmB,EACnBa,QAAkB,EAClBpG,MAAc,EACd+F,aAAqB,EACrB3C,IAAc,EACR;IACN1D,KAAK,CAAC,8BAA8B,CAAC;IACrCA,KAAK,CAAC,iCAAiC,EAAE,OAAOM,MAAM,KAAK,QAAQ,CAAC;IACpEN,KAAK,CAAC,iCAAiC,EAAE,OAAOqG,aAAa,KAAK,QAAQ,CAAC;IAC3E,MAAMa,WAAgB,GAAG,IAAAI,gCAAwB,EAACZ,QAAQ,EAAEpG,MAAM,EAAE+F,aAAa,CAAC;IAClFrG,KAAK,CAAC,+BAA+B,EAAEkH,WAAW,EAAE/F,IAAI,CAAC;IACzD,IAAI+F,WAAW,EAAE;MACf,MAAM;QAAE7C,IAAI;QAAEjC;MAAS,CAAC,GAAG8E,WAAW;MACtClH,KAAK,CAAC,mBAAmB,EAAEqE,IAAI,CAAC;MAChC,IAAI,CAAC1C,YAAY,CAAC0C,IAAI,EAAEjC,QAAQ,EAAE,CAACa,GAAG,EAAEoB,IAAI,KAAW;QACrD,IAAI,CAACpB,GAAG,EAAE;UACR4C,GAAG,CAACK,WAAW,GAAG7B,IAAI;UACtBrE,KAAK,CAAC,0BAA0B,CAAC;UACjC0D,IAAI,CAAC,CAAC;QACR,CAAC,MAAM;UACLmC,GAAG,CAACK,WAAW,GAAG,IAAAN,iCAAyB,EAAC,CAAC;UAC7C5F,KAAK,CAAC,2BAA2B,CAAC;UAClC0D,IAAI,CAACT,GAAG,CAAC;QACX;MACF,CAAC,CAAC;IACJ,CAAC,MAAM;MACL;MACAjD,KAAK,CAAC,uBAAuB,CAAC;MAC9B,OAAO0D,IAAI,CAACd,gBAAU,CAAC4D,aAAa,CAACvC,eAAS,CAACwC,eAAe,CAAC,CAAC;IAClE;EACF;EAEQgB,kBAAkBA,CAACvB,WAAwB,EAAW;IAC5D,OAAO1D,eAAC,CAACkF,WAAW,CAACxB,WAAW,CAAC,KAAK,KAAK,IAAI1D,eAAC,CAACkF,WAAW,CAACxB,WAAW,EAAE/E,IAAI,CAAC,KAAK,KAAK;EAC3F;;EAEA;AACF;AACA;EACSwG,kBAAkBA,CAAA,EAAG;IAC1B,OAAO,CAAC9B,GAAmB,EAAEC,GAAoB,EAAEC,KAAmB,KAAW;MAC/E,IAAI,IAAI,CAAC0B,kBAAkB,CAAC5B,GAAG,CAACK,WAAW,CAAC,EAAE;QAC5C,OAAOH,KAAK,CAAC,CAAC;MAChB;MAEAF,GAAG,CAACG,KAAK,CAAC,CAAC;MACX,MAAMtC,IAAI,GAAIT,GAA0B,IAAW;QACjD4C,GAAG,CAACI,MAAM,CAAC,CAAC;QACZ,IAAIhD,GAAG,EAAE;UACP4C,GAAG,CAACK,WAAW,CAAC3E,KAAK,GAAG0B,GAAG,CAACY,OAAO;UACnCiC,GAAG,CAAC8B,MAAM,CAAC3E,GAAG,CAAC4E,UAAU,CAAC,CAACC,IAAI,CAAC7E,GAAG,CAACY,OAAO,CAAC;QAC9C;QAEA,OAAOkC,KAAK,CAAC,CAAC;MAChB,CAAC;MAED,MAAM;QAAEM;MAAc,CAAC,GAAGR,GAAG,CAACS,OAAO;MACrC,IAAI9D,eAAC,CAACQ,KAAK,CAACqD,aAAa,CAAC,EAAE;QAC1B,OAAO3C,IAAI,CAAC,CAAC;MACf;MAEA,IAAI,CAAC,IAAA6C,yBAAiB,EAACF,aAAa,CAAC,EAAE;QACrC,OAAO3C,IAAI,CAACd,gBAAU,CAAC4D,aAAa,CAACvC,eAAS,CAACwC,eAAe,CAAC,CAAC;MAClE;MAEA,MAAMrD,KAAK,GAAG,CAACiD,aAAa,IAAI,EAAE,EAAE0B,OAAO,CAAC,GAAGC,kBAAY,GAAG,EAAE,EAAE,CAAC;MACnE,IAAI,CAAC5E,KAAK,EAAE;QACV,OAAOM,IAAI,CAAC,CAAC;MACf;MAEA,IAAIwD,WAAmC;MACvC,IAAI;QACFA,WAAW,GAAG,IAAAe,wBAAgB,EAAC7E,KAAK,EAAE,IAAI,CAAChD,MAAM,CAACE,MAAM,CAAC;MAC3D,CAAC,CAAC,OAAO2C,GAAQ,EAAE;QACjB;MAAA;MAGF,IAAI,IAAI,CAACwE,kBAAkB,CAACP,WAAW,CAAC,EAAE;QACxC,MAAM;UAAE/F,IAAI;UAAEyC;QAAO,CAAC,GAAGsD,WAAyB;QAClDrB,GAAG,CAACK,WAAW,GAAG,IAAA/B,wBAAgB,EAAChD,IAAI,EAAYyC,MAAM,CAAC;MAC5D,CAAC,MAAM;QACLiC,GAAG,CAACK,WAAW,GAAG,IAAAN,iCAAyB,EAAC,CAAC;MAC/C;MAEAlC,IAAI,CAAC,CAAC;IACR,CAAC;EACH;EAEA,MAAawE,UAAUA,CAAC7D,IAAgB,EAAE8D,WAA2B,EAAmB;IACtF,MAAM;MAAEC,WAAW;MAAEjH,IAAI;MAAEyC;IAAO,CAAC,GAAGS,IAAI;IAC1CrE,KAAK,CAAC,gBAAgB,EAAEmB,IAAI,CAAC;IAC7B,MAAMkH,mBAAmB,GAAG7F,eAAC,CAACQ,KAAK,CAACoF,WAAW,CAAC,GAAG,EAAE,GAAGA,WAAW;IACnE,MAAME,aAAa,GAAG9F,eAAC,CAACQ,KAAK,CAACY,MAAM,CAAC,GACjCwE,WAAW,GACXG,KAAK,CAACC,IAAI,CAAC,IAAIC,GAAG,CAAC,CAAC,GAAG7E,MAAM,CAAC8E,MAAM,CAACL,mBAAmB,CAAC,CAAC,CAAC,CAAC;IAChE,MAAMM,OAAmB,GAAG;MAC1BP,WAAW,EAAEC,mBAAmB;MAChClH,IAAI;MACJyC,MAAM,EAAE0E;IACV,CAAC;IACD,MAAMlF,KAAa,GAAG,MAAM,IAAAwF,sBAAW,EAACD,OAAO,EAAE,IAAI,CAACrI,MAAM,EAAE6H,WAAW,CAAC;IAE1E,OAAO/E,KAAK;EACd;;EAEA;AACF;AACA;EACSyF,UAAUA,CAACC,KAAa,EAAiB;IAC9C,IAAI,IAAI,CAACxI,MAAM,CAACK,MAAM,KAAKoI,gBAAc,CAACC,kBAAkB,EAAE;MAC5DhJ,KAAK,CAAC,kCAAkC,CAAC;MACzC,MAAMoD,KAAK,GAAG,IAAAyF,qBAAU,EAACC,KAAK,EAAE,IAAI,CAACxI,MAAM,CAAC;MAC5C,OAAO8C,KAAK;IACd,CAAC,MAAM;MACLpD,KAAK,CAAC,6CAA6C,CAAC;MACpD;MACA,MAAMoD,KAAK,GAAG,IAAA6F,+BAAoB,EAACC,MAAM,CAACV,IAAI,CAACM,KAAK,CAAC,EAAE,IAAI,CAACxI,MAAM,CAAC,CAAC8G,QAAQ,CAAC,QAAQ,CAAC;MACtF,OAAOhE,KAAK;IACd;EACF;AACF;AAAC+F,OAAA,CAAAjJ,IAAA,GAAAA,IAAA","ignoreList":[]}
package/build/utils.js CHANGED
@@ -151,7 +151,9 @@ function getDefaultPlugins(logger) {
151
151
  },
152
152
  adduser(_user, _password, cb) {
153
153
  debug('triggered default adduser method');
154
- return cb(_core.errorUtils.getConflict(_core.API_ERROR.BAD_USERNAME_PASSWORD));
154
+ // since adduser is not implemented but optional, continue without error
155
+ // this assumes that the user is added by an external system
156
+ cb(null, true);
155
157
  },
156
158
  // @ts-ignore
157
159
  allow_access: allow_action('access', logger),
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","names":["_debug","_interopRequireDefault","require","_lodash","_config","_core","_signature","e","__esModule","default","debug","buildDebug","parseAuthTokenHeader","authorizationHeader","parts","split","scheme","token","parseAESCredentials","secret","toUpperCase","TOKEN_BASIC","credentials","convertPayloadToBase64","toString","TOKEN_BEARER","length","isLegacyUnsecure","aesDecryptDeprecated","aesDecrypt","getMiddlewareCredentials","security","secretKey","isAESLegacy","parsedCredentials","parseBasicPayload","_","isString","verifyJWTPayload","legacy","jwt","api","isNil","getApiToken","auth","config","remoteUser","aesPassword","Promise","resolve","aesEncrypt","buildUser","name","sign","jwtEncrypt","expireReasons","exports","payload","verifyPayload","error","includes","createAnonymousRemoteUser","errorUtils","getCode","HTTP_STATUS","UNAUTHORIZED","message","isAuthHeaderValid","authorization","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","user","pkg","callback","trace","remote","groups","groupAccess","hasPermission","some","group","pkgName","getUnauthorized","isUnpublishMissing","hasGroups","undefined","password","String","Buffer","from"],"sources":["../src/utils.ts"],"sourcesContent":["import buildDebug from 'debug';\nimport _ from 'lodash';\n\nimport { createAnonymousRemoteUser } from '@verdaccio/config';\nimport {\n API_ERROR,\n HTTP_STATUS,\n TOKEN_BASIC,\n TOKEN_BEARER,\n errorUtils,\n pluginUtils,\n} from '@verdaccio/core';\nimport {\n aesDecrypt,\n aesDecryptDeprecated,\n parseBasicPayload,\n verifyPayload,\n} from '@verdaccio/signature';\nimport { AuthPackageAllow, Config, Logger, RemoteUser, Security } from '@verdaccio/types';\n\nimport {\n ActionsAllowed,\n AllowAction,\n AllowActionCallback,\n AuthMiddlewarePayload,\n AuthTokenHeader,\n TokenEncryption,\n} from './types';\n\nconst debug = buildDebug('verdaccio:auth:utils');\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 init');\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 debug('secret length %o', secret.length);\n const isLegacyUnsecure = secret.length > 32;\n debug('is legacy unsecure %o', isLegacyUnsecure);\n if (isLegacyUnsecure) {\n debug('legacy unsecure enabled');\n return aesDecryptDeprecated(convertPayloadToBase64(token), secret).toString('utf-8');\n } else {\n debug('legacy secure enabled');\n return aesDecrypt(token.toString(), secret);\n }\n }\n}\n\nexport function getMiddlewareCredentials(\n security: Security,\n secretKey: string,\n authorizationHeader: string\n): AuthMiddlewarePayload {\n debug('getMiddlewareCredentials init');\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\n/**\n * Return a default configuration for authentication if none is provided.\n * @param logger {Logger}\n * @returns object of default implementations.\n */\nexport function getDefaultPlugins(logger: Logger): pluginUtils.Auth<Config> {\n return {\n authenticate(_user: string, _password: string, cb: pluginUtils.AuthCallback): void {\n debug('triggered default authenticate method');\n cb(errorUtils.getForbidden(API_ERROR.BAD_USERNAME_PASSWORD));\n },\n\n adduser(_user: string, _password: string, cb: pluginUtils.AuthUserCallback): void {\n debug('triggered default adduser method');\n return cb(errorUtils.getConflict(API_ERROR.BAD_USERNAME_PASSWORD));\n },\n\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 function allow_action(action: ActionsAllowed, logger: 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: @{remote}`);\n const { name, groups } = user;\n debug('allow_action \"%s\": groups %s', action, groups);\n const groupAccess = pkg[action] as string[];\n debug('allow_action \"%s\": groupAccess %s', action, groupAccess);\n const hasPermission = groupAccess.some((group) => {\n return name === group || groups.includes(group);\n });\n debug('package \"%s\" has permission \"%s\"', name, hasPermission);\n logger.trace(\n { pkgName: pkg.name, hasPermission, remote: user.name, groupAccess },\n `[auth/allow_action]: hasPermission? @{hasPermission} for user: @{remote}, package: @{pkgName}`\n );\n\n if (hasPermission) {\n logger.trace({ remote: user.name }, `auth/allow_action: access granted to: @{remote}`);\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: 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 = !pkg[action];\n debug('is unpublish method missing ? %s', isUnpublishMissing);\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"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"utils.js","names":["_debug","_interopRequireDefault","require","_lodash","_config","_core","_signature","e","__esModule","default","debug","buildDebug","parseAuthTokenHeader","authorizationHeader","parts","split","scheme","token","parseAESCredentials","secret","toUpperCase","TOKEN_BASIC","credentials","convertPayloadToBase64","toString","TOKEN_BEARER","length","isLegacyUnsecure","aesDecryptDeprecated","aesDecrypt","getMiddlewareCredentials","security","secretKey","isAESLegacy","parsedCredentials","parseBasicPayload","_","isString","verifyJWTPayload","legacy","jwt","api","isNil","getApiToken","auth","config","remoteUser","aesPassword","Promise","resolve","aesEncrypt","buildUser","name","sign","jwtEncrypt","expireReasons","exports","payload","verifyPayload","error","includes","createAnonymousRemoteUser","errorUtils","getCode","HTTP_STATUS","UNAUTHORIZED","message","isAuthHeaderValid","authorization","getDefaultPlugins","logger","authenticate","_user","_password","cb","getForbidden","API_ERROR","BAD_USERNAME_PASSWORD","adduser","allow_access","allow_action","allow_publish","allow_unpublish","handleSpecialUnpublish","action","allowActionCallback","user","pkg","callback","trace","remote","groups","groupAccess","hasPermission","some","group","pkgName","getUnauthorized","isUnpublishMissing","hasGroups","undefined","password","String","Buffer","from"],"sources":["../src/utils.ts"],"sourcesContent":["import buildDebug from 'debug';\nimport _ from 'lodash';\n\nimport { createAnonymousRemoteUser } from '@verdaccio/config';\nimport {\n API_ERROR,\n HTTP_STATUS,\n TOKEN_BASIC,\n TOKEN_BEARER,\n errorUtils,\n pluginUtils,\n} from '@verdaccio/core';\nimport {\n aesDecrypt,\n aesDecryptDeprecated,\n parseBasicPayload,\n verifyPayload,\n} from '@verdaccio/signature';\nimport { AuthPackageAllow, Config, Logger, RemoteUser, Security } from '@verdaccio/types';\n\nimport {\n ActionsAllowed,\n AllowAction,\n AllowActionCallback,\n AuthMiddlewarePayload,\n AuthTokenHeader,\n TokenEncryption,\n} from './types';\n\nconst debug = buildDebug('verdaccio:auth:utils');\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 init');\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 debug('secret length %o', secret.length);\n const isLegacyUnsecure = secret.length > 32;\n debug('is legacy unsecure %o', isLegacyUnsecure);\n if (isLegacyUnsecure) {\n debug('legacy unsecure enabled');\n return aesDecryptDeprecated(convertPayloadToBase64(token), secret).toString('utf-8');\n } else {\n debug('legacy secure enabled');\n return aesDecrypt(token.toString(), secret);\n }\n }\n}\n\nexport function getMiddlewareCredentials(\n security: Security,\n secretKey: string,\n authorizationHeader: string\n): AuthMiddlewarePayload {\n debug('getMiddlewareCredentials init');\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\n/**\n * Return a default configuration for authentication if none is provided.\n * @param logger {Logger}\n * @returns object of default implementations.\n */\nexport function getDefaultPlugins(logger: Logger): pluginUtils.Auth<Config> {\n return {\n authenticate(_user: string, _password: string, cb: pluginUtils.AuthCallback): void {\n debug('triggered default authenticate method');\n cb(errorUtils.getForbidden(API_ERROR.BAD_USERNAME_PASSWORD));\n },\n\n adduser(_user: string, _password: string, cb: pluginUtils.AuthUserCallback): void {\n debug('triggered default adduser method');\n // since adduser is not implemented but optional, continue without error\n // this assumes that the user is added by an external system\n cb(null, true);\n },\n\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 function allow_action(action: ActionsAllowed, logger: 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: @{remote}`);\n const { name, groups } = user;\n debug('allow_action \"%s\": groups %s', action, groups);\n const groupAccess = pkg[action] as string[];\n debug('allow_action \"%s\": groupAccess %s', action, groupAccess);\n const hasPermission = groupAccess.some((group) => {\n return name === group || groups.includes(group);\n });\n debug('package \"%s\" has permission \"%s\"', name, hasPermission);\n logger.trace(\n { pkgName: pkg.name, hasPermission, remote: user.name, groupAccess },\n `[auth/allow_action]: hasPermission? @{hasPermission} for user: @{remote}, package: @{pkgName}`\n );\n\n if (hasPermission) {\n logger.trace({ remote: user.name }, `auth/allow_action: access granted to: @{remote}`);\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: 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 = !pkg[action];\n debug('is unpublish method missing ? %s', isUnpublishMissing);\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"],"mappings":"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","ignoreList":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@verdaccio/auth",
3
- "version": "8.0.0-next-8.3",
3
+ "version": "8.0.0-next-8.5",
4
4
  "description": "logger",
5
5
  "main": "./build/index.js",
6
6
  "types": "./build/index.d.ts",
@@ -29,20 +29,20 @@
29
29
  },
30
30
  "license": "MIT",
31
31
  "dependencies": {
32
- "@verdaccio/config": "8.0.0-next-8.3",
33
- "@verdaccio/core": "8.0.0-next-8.3",
34
- "@verdaccio/loaders": "8.0.0-next-8.3",
35
- "@verdaccio/logger": "8.0.0-next-8.3",
32
+ "@verdaccio/config": "8.0.0-next-8.5",
33
+ "@verdaccio/core": "8.0.0-next-8.5",
34
+ "@verdaccio/loaders": "8.0.0-next-8.4",
36
35
  "@verdaccio/signature": "8.0.0-next-8.1",
37
- "@verdaccio/utils": "8.1.0-next-8.3",
36
+ "@verdaccio/utils": "8.1.0-next-8.5",
38
37
  "debug": "4.3.7",
39
38
  "lodash": "4.17.21",
40
- "verdaccio-htpasswd": "13.0.0-next-8.3"
39
+ "verdaccio-htpasswd": "13.0.0-next-8.5"
41
40
  },
42
41
  "devDependencies": {
43
- "@verdaccio/middleware": "8.0.0-next-8.3",
44
- "@verdaccio/types": "13.0.0-next-8.1",
45
- "express": "4.21.0",
42
+ "@verdaccio/middleware": "8.0.0-next-8.5",
43
+ "@verdaccio/types": "13.0.0-next-8.2",
44
+ "@verdaccio/logger": "8.0.0-next-8.5",
45
+ "express": "4.21.1",
46
46
  "supertest": "7.0.0"
47
47
  },
48
48
  "funding": {
package/src/auth.ts CHANGED
@@ -15,7 +15,6 @@ import {
15
15
  warningUtils,
16
16
  } from '@verdaccio/core';
17
17
  import { asyncLoadPlugin } from '@verdaccio/loaders';
18
- import { logger } from '@verdaccio/logger';
19
18
  import {
20
19
  aesEncrypt,
21
20
  aesEncryptDeprecated,
@@ -28,6 +27,7 @@ import {
28
27
  Callback,
29
28
  Config,
30
29
  JWTSignOptions,
30
+ Logger,
31
31
  PackageAccess,
32
32
  RemoteUser,
33
33
  Security,
@@ -57,11 +57,13 @@ const debug = buildDebug('verdaccio:auth');
57
57
  class Auth implements IAuthMiddleware, TokenEncryption, pluginUtils.IBasicAuth {
58
58
  public config: Config;
59
59
  public secret: string;
60
+ public logger: Logger;
60
61
  public plugins: pluginUtils.Auth<Config>[];
61
62
 
62
- public constructor(config: Config) {
63
+ public constructor(config: Config, logger: Logger) {
63
64
  this.config = config;
64
65
  this.secret = config.secret;
66
+ this.logger = logger;
65
67
  this.plugins = [];
66
68
  if (!this.secret) {
67
69
  throw new TypeError('secret it is required value on initialize the auth class');
@@ -84,7 +86,7 @@ class Auth implements IAuthMiddleware, TokenEncryption, pluginUtils.IBasicAuth {
84
86
  debug('load default auth plugin');
85
87
  const pluginOptions: pluginUtils.PluginOptions = {
86
88
  config: this.config,
87
- logger,
89
+ logger: this.logger,
88
90
  };
89
91
  let authPlugin;
90
92
  try {
@@ -92,9 +94,13 @@ class Auth implements IAuthMiddleware, TokenEncryption, pluginUtils.IBasicAuth {
92
94
  { file: './htpasswd' },
93
95
  pluginOptions as any as pluginUtils.PluginOptions
94
96
  );
97
+ this.logger.info(
98
+ { name: 'verdaccio-htpasswd', pluginCategory: PLUGIN_CATEGORY.AUTHENTICATION },
99
+ 'plugin @{name} successfully loaded (@{pluginCategory})'
100
+ );
95
101
  } catch (error: any) {
96
102
  debug('error on loading auth htpasswd plugin stack: %o', error);
97
- logger.info({}, 'no auth plugin has been found');
103
+ this.logger.info({}, 'no auth plugin has been found');
98
104
  return [];
99
105
  }
100
106
 
@@ -106,7 +112,7 @@ class Auth implements IAuthMiddleware, TokenEncryption, pluginUtils.IBasicAuth {
106
112
  this.config.auth,
107
113
  {
108
114
  config: this.config,
109
- logger,
115
+ logger: this.logger,
110
116
  },
111
117
  (plugin): boolean => {
112
118
  const { authenticate, allow_access, allow_publish } = plugin;
@@ -124,7 +130,7 @@ class Auth implements IAuthMiddleware, TokenEncryption, pluginUtils.IBasicAuth {
124
130
 
125
131
  private _applyDefaultPlugins(): void {
126
132
  // TODO: rename to applyFallbackPluginMethods
127
- this.plugins.push(getDefaultPlugins(logger));
133
+ this.plugins.push(getDefaultPlugins(this.logger));
128
134
  }
129
135
 
130
136
  public changePassword(
@@ -147,7 +153,7 @@ class Auth implements IAuthMiddleware, TokenEncryption, pluginUtils.IBasicAuth {
147
153
  debug('updating password for %o', username);
148
154
  plugin.changePassword!(username, password, newPassword, (err, profile): void => {
149
155
  if (err) {
150
- logger.error(
156
+ this.logger.error(
151
157
  { username, err },
152
158
  `An error has been produced
153
159
  updating the password for @{username}. Error: @{err.message}`
package/src/utils.ts CHANGED
@@ -166,7 +166,9 @@ export function getDefaultPlugins(logger: Logger): pluginUtils.Auth<Config> {
166
166
 
167
167
  adduser(_user: string, _password: string, cb: pluginUtils.AuthUserCallback): void {
168
168
  debug('triggered default adduser method');
169
- return cb(errorUtils.getConflict(API_ERROR.BAD_USERNAME_PASSWORD));
169
+ // since adduser is not implemented but optional, continue without error
170
+ // this assumes that the user is added by an external system
171
+ cb(null, true);
170
172
  },
171
173
 
172
174
  // @ts-ignore
@@ -10,7 +10,7 @@ import {
10
10
  } from '@verdaccio/config';
11
11
  import { getDefaultConfig } from '@verdaccio/config';
12
12
  import { TOKEN_BEARER } from '@verdaccio/core';
13
- import { setup } from '@verdaccio/logger';
13
+ import { logger, setup } from '@verdaccio/logger';
14
14
  import { signPayload } from '@verdaccio/signature';
15
15
  import { Config, RemoteUser, Security } from '@verdaccio/types';
16
16
  import { buildToken, buildUserBuffer } from '@verdaccio/utils';
@@ -52,7 +52,7 @@ describe('Auth utilities', () => {
52
52
  methodNotBeenCalled: string
53
53
  ): Promise<string> {
54
54
  const config: Config = getConfig(configFileName, secret);
55
- const auth: Auth = new Auth(config);
55
+ const auth: Auth = new Auth(config, logger);
56
56
  await auth.init();
57
57
  // @ts-ignore
58
58
  const spy = vi.spyOn(auth, methodToSpy);
@@ -155,7 +155,7 @@ describe('Auth utilities', () => {
155
155
  test.concurrent('should return empty credential corrupted payload', async () => {
156
156
  const secret = 'b2df428b9929d3ace7c598bbf4e496b2';
157
157
  const config: Config = getConfig('security-legacy', secret);
158
- const auth: Auth = new Auth(config);
158
+ const auth: Auth = new Auth(config, logger);
159
159
  await auth.init();
160
160
  // @ts-expect-error
161
161
  const token = auth.aesEncrypt(null);
@@ -11,7 +11,7 @@ import {
11
11
  } from '@verdaccio/config';
12
12
  import { getDefaultConfig } from '@verdaccio/config';
13
13
  import { API_ERROR, CHARACTER_ENCODING, VerdaccioError, errorUtils } from '@verdaccio/core';
14
- import { setup } from '@verdaccio/logger';
14
+ import { logger, setup } from '@verdaccio/logger';
15
15
  import { aesDecrypt, verifyPayload } from '@verdaccio/signature';
16
16
  import { Config, RemoteUser } from '@verdaccio/types';
17
17
  import { getAuthenticatedMessage } from '@verdaccio/utils';
@@ -61,7 +61,7 @@ describe('Auth utilities', () => {
61
61
  methodNotBeenCalled: string
62
62
  ): Promise<string> {
63
63
  const config: Config = getConfig(configFileName, secret);
64
- const auth: Auth = new Auth(config);
64
+ const auth: Auth = new Auth(config, logger);
65
65
  await auth.init();
66
66
  // @ts-ignore
67
67
  const spy = vi.spyOn(auth, methodToSpy);
@@ -123,11 +123,12 @@ describe('Auth utilities', () => {
123
123
  });
124
124
  });
125
125
 
126
- test('add user should fail by default (default)', () => {
126
+ test('add user should not fail by default (default)', () => {
127
127
  const plugin = getDefaultPlugins({ trace: vi.fn() });
128
128
  // @ts-ignore
129
- plugin.adduser('foo', 'bar', (error: any) => {
130
- expect(error).toEqual(errorUtils.getForbidden(API_ERROR.BAD_USERNAME_PASSWORD));
129
+ plugin.adduser('foo', 'bar', (error: any, access: any) => {
130
+ expect(error).toEqual(null);
131
+ expect(access).toEqual(true);
131
132
  });
132
133
  });
133
134
  });
package/test/auth.spec.ts CHANGED
@@ -4,14 +4,7 @@ import supertest from 'supertest';
4
4
  import { describe, expect, test, vi } from 'vitest';
5
5
 
6
6
  import { Config as AppConfig, ROLES, createRemoteUser, getDefaultConfig } from '@verdaccio/config';
7
- import {
8
- API_ERROR,
9
- HEADERS,
10
- HTTP_STATUS,
11
- SUPPORT_ERRORS,
12
- TOKEN_BEARER,
13
- errorUtils,
14
- } from '@verdaccio/core';
7
+ import { HEADERS, HTTP_STATUS, SUPPORT_ERRORS, TOKEN_BEARER, errorUtils } from '@verdaccio/core';
15
8
  import { logger, setup } from '@verdaccio/logger';
16
9
  import { errorReportingMiddleware, final, handleError } from '@verdaccio/middleware';
17
10
  import { Config } from '@verdaccio/types';
@@ -45,7 +38,7 @@ describe('AuthTest', () => {
45
38
  const config: Config = new AppConfig({ ...authProfileConf });
46
39
  config.checkSecretKey('12345');
47
40
 
48
- const auth: Auth = new Auth(config);
41
+ const auth: Auth = new Auth(config, logger);
49
42
  await auth.init();
50
43
  expect(auth).toBeDefined();
51
44
  });
@@ -54,7 +47,7 @@ describe('AuthTest', () => {
54
47
  const config: Config = new AppConfig({ ...authProfileConf, auth: undefined });
55
48
  config.checkSecretKey('12345');
56
49
 
57
- const auth: Auth = new Auth(config);
50
+ const auth: Auth = new Auth(config, logger);
58
51
  await auth.init();
59
52
  expect(auth).toBeDefined();
60
53
  });
@@ -68,7 +61,7 @@ describe('AuthTest', () => {
68
61
  });
69
62
  config.checkSecretKey('12345');
70
63
 
71
- const auth: Auth = new Auth(config);
64
+ const auth: Auth = new Auth(config, logger);
72
65
  await auth.init();
73
66
  expect(auth).toBeDefined();
74
67
  });
@@ -79,7 +72,7 @@ describe('AuthTest', () => {
79
72
  test('should be a success login', async () => {
80
73
  const config: Config = new AppConfig({ ...authProfileConf });
81
74
  config.checkSecretKey('12345');
82
- const auth: Auth = new Auth(config);
75
+ const auth: Auth = new Auth(config, logger);
83
76
  await auth.init();
84
77
  expect(auth).toBeDefined();
85
78
 
@@ -106,7 +99,7 @@ describe('AuthTest', () => {
106
99
  test('should be a fail on login', async () => {
107
100
  const config: Config = new AppConfig(authPluginFailureConf);
108
101
  config.checkSecretKey('12345');
109
- const auth: Auth = new Auth(config);
102
+ const auth: Auth = new Auth(config, logger);
110
103
  await auth.init();
111
104
  expect(auth).toBeDefined();
112
105
 
@@ -125,7 +118,7 @@ describe('AuthTest', () => {
125
118
  test('should skip falsy values', async () => {
126
119
  const config: Config = new AppConfig({ ...authPluginPassThrougConf });
127
120
  config.checkSecretKey('12345');
128
- const auth: Auth = new Auth(config);
121
+ const auth: Auth = new Auth(config, logger);
129
122
  await auth.init();
130
123
  expect(auth).toBeDefined();
131
124
 
@@ -145,7 +138,7 @@ describe('AuthTest', () => {
145
138
  test('should error truthy non-array', async () => {
146
139
  const config: Config = new AppConfig({ ...authPluginPassThrougConf });
147
140
  config.checkSecretKey('12345');
148
- const auth: Auth = new Auth(config);
141
+ const auth: Auth = new Auth(config, logger);
149
142
  await auth.init();
150
143
  expect(auth).toBeDefined();
151
144
 
@@ -163,7 +156,7 @@ describe('AuthTest', () => {
163
156
  test('should skip empty array', async () => {
164
157
  const config: Config = new AppConfig({ ...authPluginPassThrougConf });
165
158
  config.checkSecretKey('12345');
166
- const auth: Auth = new Auth(config);
159
+ const auth: Auth = new Auth(config, logger);
167
160
  await auth.init();
168
161
  expect(auth).toBeDefined();
169
162
 
@@ -180,7 +173,7 @@ describe('AuthTest', () => {
180
173
  test('should accept valid array', async () => {
181
174
  const config: Config = new AppConfig({ ...authPluginPassThrougConf });
182
175
  config.checkSecretKey('12345');
183
- const auth: Auth = new Auth(config);
176
+ const auth: Auth = new Auth(config, logger);
184
177
  await auth.init();
185
178
  expect(auth).toBeDefined();
186
179
 
@@ -208,7 +201,7 @@ describe('AuthTest', () => {
208
201
  },
209
202
  });
210
203
  config.checkSecretKey('12345');
211
- const auth: Auth = new Auth(config);
204
+ const auth: Auth = new Auth(config, logger);
212
205
  await auth.init();
213
206
 
214
207
  return new Promise((resolve) => {
@@ -229,7 +222,7 @@ describe('AuthTest', () => {
229
222
  test('should fail if the plugin does not provide implementation', async () => {
230
223
  const config: Config = new AppConfig({ ...authProfileConf });
231
224
  config.checkSecretKey('12345');
232
- const auth: Auth = new Auth(config);
225
+ const auth: Auth = new Auth(config, logger);
233
226
  await auth.init();
234
227
  expect(auth).toBeDefined();
235
228
  const callback = vi.fn();
@@ -244,7 +237,7 @@ describe('AuthTest', () => {
244
237
  test('should handle plugin does provide implementation', async () => {
245
238
  const config: Config = new AppConfig({ ...authChangePasswordConf });
246
239
  config.checkSecretKey('12345');
247
- const auth: Auth = new Auth(config);
240
+ const auth: Auth = new Auth(config, logger);
248
241
  await auth.init();
249
242
  expect(auth).toBeDefined();
250
243
  const callback = vi.fn();
@@ -259,10 +252,10 @@ describe('AuthTest', () => {
259
252
  describe('no custom allow_access implementation provided', () => {
260
253
  // when allow_access is not implemented, the groups must match
261
254
  // exactly with the packages access group
262
- test('should fails if groups do not match exactly', async () => {
255
+ test('should fail if groups do not match exactly', async () => {
263
256
  const config: Config = new AppConfig({ ...authProfileConf });
264
257
  config.checkSecretKey('12345');
265
- const auth: Auth = new Auth(config);
258
+ const auth: Auth = new Auth(config, logger);
266
259
  await auth.init();
267
260
  expect(auth).toBeDefined();
268
261
 
@@ -284,7 +277,7 @@ describe('AuthTest', () => {
284
277
  test('should success if groups do not match exactly', async () => {
285
278
  const config: Config = new AppConfig({ ...authProfileConf });
286
279
  config.checkSecretKey('12345');
287
- const auth: Auth = new Auth(config);
280
+ const auth: Auth = new Auth(config, logger);
288
281
  await auth.init();
289
282
  expect(auth).toBeDefined();
290
283
 
@@ -308,10 +301,10 @@ describe('AuthTest', () => {
308
301
  describe('no custom allow_publish implementation provided', () => {
309
302
  // when allow_access is not implemented, the groups must match
310
303
  // exactly with the packages access group
311
- test('should fails if groups do not match exactly', async () => {
304
+ test('should fail if groups do not match exactly', async () => {
312
305
  const config: Config = new AppConfig({ ...authProfileConf });
313
306
  config.checkSecretKey('12345');
314
- const auth: Auth = new Auth(config);
307
+ const auth: Auth = new Auth(config, logger);
315
308
  await auth.init();
316
309
  expect(auth).toBeDefined();
317
310
 
@@ -333,7 +326,7 @@ describe('AuthTest', () => {
333
326
  test('should success if groups do match exactly', async () => {
334
327
  const config: Config = new AppConfig({ ...authProfileConf });
335
328
  config.checkSecretKey('12345');
336
- const auth: Auth = new Auth(config);
329
+ const auth: Auth = new Auth(config, logger);
337
330
  await auth.init();
338
331
  expect(auth).toBeDefined();
339
332
 
@@ -354,11 +347,11 @@ describe('AuthTest', () => {
354
347
  });
355
348
  describe('allow_unpublish', () => {
356
349
  describe('no custom allow_unpublish implementation provided', () => {
357
- test('should fails if groups do not match exactly', async () => {
350
+ test('should fail if groups do not match exactly', async () => {
358
351
  const config: Config = new AppConfig({ ...authProfileConf });
359
352
  config.checkSecretKey('12345');
360
353
 
361
- const auth: Auth = new Auth(config);
354
+ const auth: Auth = new Auth(config, logger);
362
355
  await auth.init();
363
356
  expect(auth).toBeDefined();
364
357
 
@@ -392,7 +385,7 @@ describe('AuthTest', () => {
392
385
  },
393
386
  });
394
387
  config.checkSecretKey('12345');
395
- const auth: Auth = new Auth(config);
388
+ const auth: Auth = new Auth(config, logger);
396
389
  await auth.init();
397
390
  expect(auth).toBeDefined();
398
391
 
@@ -415,7 +408,7 @@ describe('AuthTest', () => {
415
408
  const config: Config = new AppConfig({ ...authProfileConf });
416
409
 
417
410
  config.checkSecretKey('12345');
418
- const auth: Auth = new Auth(config);
411
+ const auth: Auth = new Auth(config, logger);
419
412
  await auth.init();
420
413
  expect(auth).toBeDefined();
421
414
 
@@ -439,10 +432,10 @@ describe('AuthTest', () => {
439
432
  describe('error handling', () => {
440
433
  // when allow_access is not implemented, the groups must match
441
434
  // exactly with the packages access group
442
- test('should fails with bad password if adduser is not implemented', async () => {
435
+ test('should not fail if adduser is not implemented', async () => {
443
436
  const config: Config = new AppConfig({ ...authProfileConf });
444
437
  config.checkSecretKey('12345');
445
- const auth: Auth = new Auth(config);
438
+ const auth: Auth = new Auth(config, logger);
446
439
  await auth.init();
447
440
  expect(auth).toBeDefined();
448
441
 
@@ -451,12 +444,21 @@ describe('AuthTest', () => {
451
444
  auth.add_user('juan', 'password', callback);
452
445
 
453
446
  expect(callback).toHaveBeenCalledTimes(1);
454
- expect(callback).toHaveBeenCalledWith(
455
- errorUtils.getConflict(API_ERROR.BAD_USERNAME_PASSWORD)
456
- );
447
+ expect(callback).toHaveBeenCalledWith(null, {
448
+ groups: [
449
+ 'test',
450
+ ROLES.$ALL,
451
+ ROLES.$AUTH,
452
+ ROLES.DEPRECATED_ALL,
453
+ ROLES.DEPRECATED_AUTH,
454
+ ROLES.ALL,
455
+ ],
456
+ name: 'juan',
457
+ real_groups: ['test'],
458
+ });
457
459
  });
458
460
 
459
- test('should fails if adduser fails internally (exception)', async () => {
461
+ test('should fail if adduser fails internally (exception)', async () => {
460
462
  const config: Config = new AppConfig({
461
463
  ...getDefaultConfig(),
462
464
  plugins: path.join(__dirname, './partials/plugin'),
@@ -465,20 +467,20 @@ describe('AuthTest', () => {
465
467
  },
466
468
  });
467
469
  config.checkSecretKey('12345');
468
- const auth: Auth = new Auth(config);
470
+ const auth: Auth = new Auth(config, logger);
469
471
  await auth.init();
470
472
  expect(auth).toBeDefined();
471
473
 
472
474
  const callback = vi.fn();
473
475
 
474
- // note: fail uas username make plugin fails
476
+ // note: username to make plugin fail
475
477
  auth.add_user('fail', 'password', callback);
476
478
 
477
479
  expect(callback).toHaveBeenCalledTimes(1);
478
480
  expect(callback).toHaveBeenCalledWith(new Error('bad username'));
479
481
  });
480
482
 
481
- test('should skip to the next plugin and fails', async () => {
483
+ test('should skip to the next plugin and fail', async () => {
482
484
  const config: Config = new AppConfig({
483
485
  ...getDefaultConfig(),
484
486
  plugins: path.join(__dirname, './partials/plugin'),
@@ -489,19 +491,28 @@ describe('AuthTest', () => {
489
491
  },
490
492
  });
491
493
  config.checkSecretKey('12345');
492
- const auth: Auth = new Auth(config);
494
+ const auth: Auth = new Auth(config, logger);
493
495
  await auth.init();
494
496
  expect(auth).toBeDefined();
495
497
 
496
498
  const callback = vi.fn();
497
499
 
498
- // note: fail uas username make plugin fails
500
+ // note: username to make plugin fail
499
501
  auth.add_user('skip', 'password', callback);
500
502
 
501
503
  expect(callback).toHaveBeenCalledTimes(1);
502
- expect(callback).toHaveBeenCalledWith(
503
- errorUtils.getConflict(API_ERROR.BAD_USERNAME_PASSWORD)
504
- );
504
+ expect(callback).toHaveBeenCalledWith(null, {
505
+ groups: [
506
+ 'test',
507
+ ROLES.$ALL,
508
+ ROLES.$AUTH,
509
+ ROLES.DEPRECATED_ALL,
510
+ ROLES.DEPRECATED_AUTH,
511
+ ROLES.ALL,
512
+ ],
513
+ name: 'skip',
514
+ real_groups: ['test'],
515
+ });
505
516
  });
506
517
  });
507
518
  test('should success if adduser', async () => {
@@ -513,7 +524,7 @@ describe('AuthTest', () => {
513
524
  },
514
525
  });
515
526
  config.checkSecretKey('12345');
516
- const auth: Auth = new Auth(config);
527
+ const auth: Auth = new Auth(config, logger);
517
528
  await auth.init();
518
529
  expect(auth).toBeDefined();
519
530
 
@@ -537,7 +548,7 @@ describe('AuthTest', () => {
537
548
  },
538
549
  });
539
550
  config.checkSecretKey('12345');
540
- const auth: Auth = new Auth(config);
551
+ const auth: Auth = new Auth(config, logger);
541
552
  await auth.init();
542
553
  expect(auth).toBeDefined();
543
554
 
@@ -583,7 +594,7 @@ describe('AuthTest', () => {
583
594
  test('should handle invalid auth token', async () => {
584
595
  const config: Config = new AppConfig({ ...authProfileConf });
585
596
  config.checkSecretKey(secret);
586
- const auth = new Auth(config);
597
+ const auth = new Auth(config, logger);
587
598
  await auth.init();
588
599
  const app = await getServer(auth);
589
600
  return supertest(app)
@@ -595,7 +606,7 @@ describe('AuthTest', () => {
595
606
  test('should handle missing auth header', async () => {
596
607
  const config: Config = new AppConfig({ ...authProfileConf });
597
608
  config.checkSecretKey(secret);
598
- const auth = new Auth(config);
609
+ const auth = new Auth(config, logger);
599
610
  await auth.init();
600
611
  const app = await getServer(auth);
601
612
  return supertest(app).get(`/`).expect(HTTP_STATUS.OK);
@@ -610,7 +621,7 @@ describe('AuthTest', () => {
610
621
  // intended to force key generator (associated with mocks above)
611
622
  // 64 characters secret long
612
623
  config.checkSecretKey('35fabdd29b820d39125e76e6d85cc294');
613
- const auth = new Auth(config);
624
+ const auth = new Auth(config, logger);
614
625
  await auth.init();
615
626
  const token = auth.aesEncrypt(payload) as string;
616
627
  const app = await getServer(auth);
@@ -626,7 +637,7 @@ describe('AuthTest', () => {
626
637
  const config: Config = new AppConfig({ ...authPluginFailureConf });
627
638
  // intended to force key generator (associated with mocks above)
628
639
  config.checkSecretKey(undefined);
629
- const auth = new Auth(config);
640
+ const auth = new Auth(config, logger);
630
641
  await auth.init();
631
642
  const token = auth.aesEncrypt(payload) as string;
632
643
  const app = await getServer(auth);
@@ -646,7 +657,7 @@ describe('AuthTest', () => {
646
657
  ...{ security: { api: { jwt: { sign: { expiresIn: '29d' } } } } },
647
658
  });
648
659
  config.checkSecretKey(secret);
649
- const auth = new Auth(config);
660
+ const auth = new Auth(config, logger);
650
661
  await auth.init();
651
662
  const app = await getServer(auth);
652
663
  const res = await supertest(app)
@@ -668,7 +679,7 @@ describe('AuthTest', () => {
668
679
  ...{ security: { api: { jwt: { sign: { expiresIn: '29d' } } } } },
669
680
  });
670
681
  config.checkSecretKey(secret);
671
- const auth = new Auth(config);
682
+ const auth = new Auth(config, logger);
672
683
  await auth.init();
673
684
  const app = await getServer(auth);
674
685
  const res = await supertest(app).get(`/`).expect(HTTP_STATUS.OK);
@@ -691,7 +702,7 @@ describe('AuthTest', () => {
691
702
  );
692
703
  // intended to force key generator (associated with mocks above)
693
704
  config.checkSecretKey(undefined);
694
- const auth = new Auth(config);
705
+ const auth = new Auth(config, logger);
695
706
  await auth.init();
696
707
  const token = (await auth.jwtEncrypt(
697
708
  createRemoteUser('jwt_user', [ROLES.ALL]),