@verdaccio/auth 6.0.0-6-next.29 → 6.0.0-6-next.30

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,30 @@
1
1
  # @verdaccio/auth
2
2
 
3
+ ## 6.0.0-6-next.30
4
+
5
+ ### Minor Changes
6
+
7
+ - 4b29d715: chore: move improvements from v5 to v6
8
+
9
+ Migrate improvements form v5 to v6:
10
+
11
+ - https://github.com/verdaccio/verdaccio/pull/3158
12
+ - https://github.com/verdaccio/verdaccio/pull/3151
13
+ - https://github.com/verdaccio/verdaccio/pull/2271
14
+ - https://github.com/verdaccio/verdaccio/pull/2787
15
+ - https://github.com/verdaccio/verdaccio/pull/2791
16
+ - https://github.com/verdaccio/verdaccio/pull/2205
17
+
18
+ ### Patch Changes
19
+
20
+ - Updated dependencies [4b29d715]
21
+ - @verdaccio/config@6.0.0-6-next.51
22
+ - @verdaccio/core@6.0.0-6-next.51
23
+ - @verdaccio/loaders@6.0.0-6-next.20
24
+ - verdaccio-htpasswd@11.0.0-6-next.21
25
+ - @verdaccio/logger@6.0.0-6-next.19
26
+ - @verdaccio/utils@6.0.0-6-next.19
27
+
3
28
  ## 6.0.0-6-next.29
4
29
 
5
30
  ### Patch Changes
package/build/auth.js CHANGED
@@ -554,7 +554,7 @@ class Auth {
554
554
  } = user;
555
555
  debug('jwt encrypt %o', name);
556
556
  const realGroupsValidated = _lodash.default.isNil(real_groups) ? [] : real_groups;
557
- const groupedGroups = _lodash.default.isNil(groups) ? real_groups : groups.concat(realGroupsValidated);
557
+ const groupedGroups = _lodash.default.isNil(groups) ? real_groups : Array.from(new Set([...groups.concat(realGroupsValidated)]));
558
558
  const payload = {
559
559
  real_groups: realGroupsValidated,
560
560
  name,
package/build/auth.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"auth.js","names":["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","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","adduser","ok","packageName","packageVersion","callback","pkgAllowAccess","name","version","pkg","Object","assign","getMatchedPackagesSpec","packages","allow_unpublish","arguments","isError","apiJWTmiddleware","helpers","createAnonymousRemoteUser","req","res","_next","pause","resume","remote_user","_isRemoteUserValid","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","isUndefined","webUIJWTmiddleware","status","statusCode","send","replace","TOKEN_BEARER","verifyJWTPayload","jwtEncrypt","signOptions","real_groups","realGroupsValidated","groupedGroups","concat","payload","signPayload","aesEncrypt","value"],"sources":["../src/auth.ts"],"sourcesContent":["import buildDebug from 'debug';\nimport { NextFunction, Request, RequestHandler, Response } from 'express';\nimport _ from 'lodash';\nimport { HTPasswd } from 'verdaccio-htpasswd';\n\nimport { createAnonymousRemoteUser, createRemoteUser } from '@verdaccio/config';\nimport {\n API_ERROR,\n SUPPORT_ERRORS,\n TOKEN_BASIC,\n TOKEN_BEARER,\n VerdaccioError,\n errorUtils,\n pluginUtils,\n} from '@verdaccio/core';\nimport { asyncLoadPlugin } from '@verdaccio/loaders';\nimport { logger } from '@verdaccio/logger';\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 { signPayload } from './jwt-token';\nimport { aesEncrypt } from './legacy-token';\nimport { parseBasicPayload } from './token';\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\nexport interface TokenEncryption {\n jwtEncrypt(user: RemoteUser, signOptions: JWTSignOptions): Promise<string>;\n aesEncrypt(buf: string): string | void;\n}\n\nexport interface AESPayload {\n user: string;\n password: string;\n}\nexport interface IAuthMiddleware {\n apiJWTmiddleware(): $NextFunctionVer;\n webUIJWTmiddleware(): $NextFunctionVer;\n}\n\nexport type $RequestExtend = Request & { remote_user?: any; log: Logger };\nexport type $ResponseExtend = Response & { cookies?: any };\nexport type $NextFunctionVer = NextFunction & any;\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 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 );\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 const plugin = plugins.shift() as pluginUtils.Auth<Config>;\n if (typeof plugin.adduser !== 'function') {\n next();\n } else {\n // @ts-expect-error future major (7.x) should remove this section\n if (typeof plugin.adduser === 'undefined' && typeof plugin.add_user === 'function') {\n throw errorUtils.getInternalError(\n 'add_user method not longer supported, rename to adduser'\n );\n }\n\n plugin.adduser(\n user,\n password,\n function (err: VerdaccioError | null, ok?: boolean | string): void {\n if (err) {\n debug('the user %o could not being added. Error: %o', user, err?.message);\n return cb(err);\n }\n if (ok) {\n debug('the user %o has been added', user);\n return self.authenticate(user, password, cb);\n }\n next();\n }\n );\n }\n })();\n }\n\n /**\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 (_.isNil(plugin) || isFunction(plugin.allow_unpublish) === false) {\n debug('allow unpublish for %o plugin does not implement allow_unpublish', packageName);\n continue;\n } else {\n // @ts-ignore\n plugin.allow_unpublish!(user, pkg, (err, ok: boolean): void => {\n if (err) {\n debug(\n 'forbidden publish for %o, it will fallback on unpublish permissions',\n packageName\n );\n return callback(err);\n }\n\n if (_.isNil(ok) === true) {\n debug('bypass unpublish for %o, publish will handle the access', packageName);\n // @ts-ignore\n // eslint-disable-next-line\n return this.allow_publish(...arguments);\n }\n\n if (ok) {\n debug('allowed unpublish for %o', packageName);\n return callback(null, ok);\n }\n });\n }\n }\n }\n\n /**\n * Allow user to publish a package.\n */\n public allow_publish(\n { packageName, packageVersion }: 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 ) as any;\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(): RequestHandler {\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 // @ts-ignore\n return (req: $RequestExtend, res: $ResponseExtend, _next: NextFunction) => {\n req.pause();\n\n const next = function (err?: VerdaccioError): any {\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();\n };\n\n if (this._isRemoteUserValid(req.remote_user)) {\n debug('jwt has a valid authentication header');\n return next();\n }\n\n // in case auth header does not exist we return anonymous function\n 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: Function\n ): void {\n debug('handle JWT api middleware');\n const { scheme, token } = parseAuthTokenHeader(authorization);\n if (scheme.toUpperCase() === TOKEN_BASIC.toUpperCase()) {\n debug('handle basic token');\n // this should happen when client tries to login with an existing user\n const credentials = convertPayloadToBase64(token).toString();\n const { user, password } = parseBasicPayload(credentials) as AESPayload;\n debug('authenticating %o', user);\n this.authenticate(user, password, (err: 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 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(): RequestHandler {\n // @ts-ignore\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) ? real_groups : groups.concat(realGroupsValidated);\n const payload: RemoteUser = {\n real_groups: realGroupsValidated,\n name,\n groups: groupedGroups,\n };\n\n const token: string = await signPayload(payload, this.secret, signOptions);\n\n return token;\n }\n\n /**\n * Encrypt a string.\n */\n public aesEncrypt(value: string): string | void {\n return aesEncrypt(value, this.secret);\n }\n}\n\nexport { Auth };\n"],"mappings":";;;;;;;AAAA;;AAEA;;AACA;;AAEA;;AACA;;AASA;;AACA;;AAWA;;AAEA;;AACA;;AACA;;AACA;;;;AAUA,MAAMA,KAAK,GAAG,IAAAC,cAAA,EAAW,gBAAX,CAAd;;AAoBA,MAAMC,IAAN,CAA+E;EAKtEC,WAAW,CAACC,MAAD,EAAiB;IACjC,KAAKA,MAAL,GAAcA,MAAd;IACA,KAAKC,MAAL,GAAcD,MAAM,CAACC,MAArB;IACA,KAAKC,OAAL,GAAe,EAAf;;IACA,IAAI,CAAC,KAAKD,MAAV,EAAkB;MAChB,MAAM,IAAIE,SAAJ,CAAc,0DAAd,CAAN;IACD;EACF;;EAEgB,MAAJC,IAAI,GAAG;IAClB,IAAIF,OAAO,GAAI,MAAM,KAAKG,UAAL,EAArB;IACAT,KAAK,CAAC,uBAAD,EAA0BM,OAAO,CAACI,MAAlC,CAAL;;IACA,IAAI,CAACJ,OAAD,IAAYA,OAAO,CAACI,MAAR,KAAmB,CAAnC,EAAsC;MACpCJ,OAAO,GAAG,KAAKK,iBAAL,EAAV;IACD;;IACD,KAAKL,OAAL,GAAeA,OAAf;;IAEA,KAAKM,oBAAL;EACD;;EAEOD,iBAAiB,GAAG;IAC1BX,KAAK,CAAC,0BAAD,CAAL;IACA,MAAMa,aAAwC,GAAG;MAC/CT,MAAM,EAAE,KAAKA,MADkC;MAE/CU,MAAM,EAANA;IAF+C,CAAjD;IAIA,IAAIC,UAAJ;;IACA,IAAI;MACFA,UAAU,GAAG,IAAIC,2BAAJ,CACX;QAAEC,IAAI,EAAE;MAAR,CADW,EAEXJ,aAFW,CAAb;IAID,CALD,CAKE,OAAOK,KAAP,EAAmB;MACnBlB,KAAK,CAAC,iDAAD,EAAoDkB,KAApD,CAAL;;MACAJ,cAAA,CAAOK,IAAP,CAAY,EAAZ,EAAgB,+BAAhB;;MACA,OAAO,EAAP;IACD;;IAED,OAAO,CAACJ,UAAD,CAAP;EACD;;EAEuB,MAAVN,UAAU,GAAG;IAAA;;IACzB,OAAO,IAAAW,wBAAA,EACL,KAAKhB,MAAL,CAAYiB,IADP,EAEL;MACEjB,MAAM,EAAE,KAAKA,MADf;MAEEU,MAAM,EAANA;IAFF,CAFK,EAMJQ,MAAD,IAAqB;MACnB,MAAM;QAAEC,YAAF;QAAgBC,YAAhB;QAA8BC;MAA9B,IAAgDH,MAAtD;MAEA,OACE,OAAOC,YAAP,KAAwB,WAAxB,IACA,OAAOC,YAAP,KAAwB,WADxB,IAEA,OAAOC,aAAP,KAAyB,WAH3B;IAKD,CAdI,kBAeL,KAAKrB,MAfA,0EAeL,aAAasB,cAfR,0DAeL,sBAA6BC,YAfxB,CAAP;EAiBD;;EAEOf,oBAAoB,GAAS;IACnC;IACA,KAAKN,OAAL,CAAasB,IAAb,CAAkB,IAAAC,yBAAA,EAAkBf,cAAlB,CAAlB;EACD;;EAEMgB,cAAc,CACnBC,QADmB,EAEnBC,QAFmB,EAGnBC,WAHmB,EAInBC,EAJmB,EAKb;IACN,MAAMC,YAAY,GAAGC,eAAA,CAAEC,MAAF,CAAS,KAAK/B,OAAd,EAAwBgB,MAAD,IAAY,IAAAgB,iBAAA,EAAWhB,MAAM,CAACQ,cAAlB,CAAnC,CAArB;;IAEA,IAAIM,eAAA,CAAEG,OAAF,CAAUJ,YAAV,CAAJ,EAA6B;MAC3B,OAAOD,EAAE,CAACM,gBAAA,CAAWC,gBAAX,CAA4BC,oBAAA,CAAeC,wBAA3C,CAAD,CAAT;IACD;;IAED,KAAK,MAAMrB,MAAX,IAAqBa,YAArB,EAAmC;MACjC,IAAI,IAAAS,YAAA,EAAMtB,MAAN,KAAiB,IAAAgB,iBAAA,EAAWhB,MAAM,CAACQ,cAAlB,MAAsC,KAA3D,EAAkE;QAChE9B,KAAK,CAAC,gEAAD,CAAL;QACA;MACD,CAHD,MAGO;QACLA,KAAK,CAAC,0BAAD,EAA6B+B,QAA7B,CAAL;QACAT,MAAM,CAACQ,cAAP,CAAuBC,QAAvB,EAAiCC,QAAjC,EAA2CC,WAA3C,EAAwD,CAACY,GAAD,EAAMC,OAAN,KAAwB;UAC9E,IAAID,GAAJ,EAAS;YACP/B,cAAA,CAAOI,KAAP,CACE;cAAEa,QAAF;cAAYc;YAAZ,CADF,EAEG;AACf,yEAHY;;YAKA,OAAOX,EAAE,CAACW,GAAD,CAAT;UACD;;UAED7C,KAAK,CAAC,wCAAD,EAA2C+B,QAA3C,CAAL;UACA,OAAOG,EAAE,CAAC,IAAD,EAAOY,OAAP,CAAT;QACD,CAZD;MAaD;IACF;EACF;;EAE2B,MAAfC,eAAe,CAACC,KAAD,EAAgB;IAC1C;IACAC,OAAO,CAACC,GAAR,CAAY,uCAAZ,EAAqDF,KAArD;IACA,OAAOG,OAAO,CAACC,OAAR,EAAP;EACD;;EAEM7B,YAAY,CACjBQ,QADiB,EAEjBC,QAFiB,EAGjBE,EAHiB,EAIX;IACN,MAAM5B,OAAO,GAAG,KAAKA,OAAL,CAAa+C,KAAb,CAAmB,CAAnB,CAAhB;;IACA,CAAC,SAASC,IAAT,GAAsB;MACrB,MAAMhC,MAAM,GAAGhB,OAAO,CAACiD,KAAR,EAAf;;MAEA,IAAI,IAAAjB,iBAAA,EAAWhB,MAAM,CAACC,YAAlB,MAAoC,KAAxC,EAA+C;QAC7C,OAAO+B,IAAI,EAAX;MACD;;MAEDtD,KAAK,CAAC,mBAAD,EAAsB+B,QAAtB,CAAL;MACAT,MAAM,CAACC,YAAP,CAAoBQ,QAApB,EAA8BC,QAA9B,EAAwC,UAAUa,GAAV,EAAsCW,MAAtC,EAAoD;QAC1F,IAAIX,GAAJ,EAAS;UACP7C,KAAK,CAAC,8CAAD,EAAiD+B,QAAjD,EAA2Dc,GAA3D,aAA2DA,GAA3D,uBAA2DA,GAAG,CAAEY,OAAhE,CAAL;UACA,OAAOvB,EAAE,CAACW,GAAD,CAAT;QACD,CAJyF,CAM1F;QACA;QACA;QACA;QACA;QACA;QACA;;;QACA,IAAI,CAAC,CAACW,MAAF,IAAYA,MAAM,CAAC9C,MAAP,KAAkB,CAAlC,EAAqC;UACnC;UACA,IAAI0B,eAAA,CAAEsB,QAAF,CAAWF,MAAX,CAAJ,EAAwB;YACtB,MAAM,IAAIjD,SAAJ,CAAc,+CAAd,CAAN;UACD;;UACD,MAAMoD,YAAqB,GAAGvB,eAAA,CAAEwB,OAAF,CAAUJ,MAAV,CAA9B;;UACA,IAAI,CAACG,YAAL,EAAmB;YACjB,MAAM,IAAIpD,SAAJ,CAAcsD,eAAA,CAAUC,qBAAxB,CAAN;UACD;;UAED9D,KAAK,CAAC,yDAAD,EAA4D+B,QAA5D,EAAsEyB,MAAtE,CAAL;UACA,OAAOtB,EAAE,CAACW,GAAD,EAAM,IAAAkB,wBAAA,EAAiBhC,QAAjB,EAA2ByB,MAA3B,CAAN,CAAT;QACD;;QACDF,IAAI;MACL,CA3BD;IA4BD,CApCD;EAqCD;;EAEMU,QAAQ,CACbC,IADa,EAEbjC,QAFa,EAGbE,EAHa,EAIP;IACN,MAAMgC,IAAI,GAAG,IAAb;IACA,MAAM5D,OAAO,GAAG,KAAKA,OAAL,CAAa+C,KAAb,CAAmB,CAAnB,CAAhB;IACArD,KAAK,CAAC,aAAD,EAAgBiE,IAAhB,CAAL;;IAEA,CAAC,SAASX,IAAT,GAAsB;MACrB,MAAMhC,MAAM,GAAGhB,OAAO,CAACiD,KAAR,EAAf;;MACA,IAAI,OAAOjC,MAAM,CAAC6C,OAAd,KAA0B,UAA9B,EAA0C;QACxCb,IAAI;MACL,CAFD,MAEO;QACL;QACA,IAAI,OAAOhC,MAAM,CAAC6C,OAAd,KAA0B,WAA1B,IAAyC,OAAO7C,MAAM,CAAC0C,QAAd,KAA2B,UAAxE,EAAoF;UAClF,MAAMxB,gBAAA,CAAWC,gBAAX,CACJ,yDADI,CAAN;QAGD;;QAEDnB,MAAM,CAAC6C,OAAP,CACEF,IADF,EAEEjC,QAFF,EAGE,UAAUa,GAAV,EAAsCuB,EAAtC,EAAmE;UACjE,IAAIvB,GAAJ,EAAS;YACP7C,KAAK,CAAC,+CAAD,EAAkDiE,IAAlD,EAAwDpB,GAAxD,aAAwDA,GAAxD,uBAAwDA,GAAG,CAAEY,OAA7D,CAAL;YACA,OAAOvB,EAAE,CAACW,GAAD,CAAT;UACD;;UACD,IAAIuB,EAAJ,EAAQ;YACNpE,KAAK,CAAC,4BAAD,EAA+BiE,IAA/B,CAAL;YACA,OAAOC,IAAI,CAAC3C,YAAL,CAAkB0C,IAAlB,EAAwBjC,QAAxB,EAAkCE,EAAlC,CAAP;UACD;;UACDoB,IAAI;QACL,CAbH;MAeD;IACF,CA5BD;EA6BD;EAED;AACF;AACA;;;EACS9B,YAAY,CACjB;IAAE6C,WAAF;IAAeC;EAAf,CADiB,EAEjBL,IAFiB,EAGjBM,QAHiB,EAIX;IACN,MAAMjE,OAAO,GAAG,KAAKA,OAAL,CAAa+C,KAAb,CAAmB,CAAnB,CAAhB;IACA,MAAMmB,cAA2B,GAAG;MAAEC,IAAI,EAAEJ,WAAR;MAAqBK,OAAO,EAAEJ;IAA9B,CAApC;IACA,MAAMK,GAAG,GAAGC,MAAM,CAACC,MAAP,CACV,EADU,EAEVL,cAFU,EAGV,IAAAM,6BAAA,EAAuBT,WAAvB,EAAoC,KAAKjE,MAAL,CAAY2E,QAAhD,CAHU,CAAZ;IAKA/E,KAAK,CAAC,qBAAD,EAAwBqE,WAAxB,CAAL;;IAEA,CAAC,SAASf,IAAT,GAAsB;MACrB,MAAMhC,MAAiC,GAAGhB,OAAO,CAACiD,KAAR,EAA1C;;MAEA,IAAInB,eAAA,CAAEQ,KAAF,CAAQtB,MAAR,KAAmB,IAAAgB,iBAAA,EAAWhB,MAAM,CAACE,YAAlB,MAAoC,KAA3D,EAAkE;QAChE,OAAO8B,IAAI,EAAX;MACD;;MAEDhC,MAAM,CAACE,YAAP,CAAqByC,IAArB,EAA2BU,GAA3B,EAAgC,UAAU9B,GAAV,EAAsCuB,EAAtC,EAA0D;QACxF,IAAIvB,GAAJ,EAAS;UACP7C,KAAK,CAAC,oCAAD,EAAuCqE,WAAvC,EAAoDxB,GAApD,aAAoDA,GAApD,uBAAoDA,GAAG,CAAEY,OAAzD,CAAL;UACA,OAAOc,QAAQ,CAAC1B,GAAD,CAAf;QACD;;QAED,IAAIuB,EAAJ,EAAQ;UACNpE,KAAK,CAAC,uBAAD,EAA0BqE,WAA1B,CAAL;UACA,OAAOE,QAAQ,CAAC,IAAD,EAAOH,EAAP,CAAf;QACD;;QAEDd,IAAI,GAXoF,CAWhF;MACT,CAZD;IAaD,CApBD;EAqBD;;EAEM0B,eAAe,CACpB;IAAEX,WAAF;IAAeC;EAAf,CADoB,EAEpBL,IAFoB,EAGpBM,QAHoB,EAId;IACN,MAAMI,GAAG,GAAGC,MAAM,CAACC,MAAP,CACV;MAAEJ,IAAI,EAAEJ,WAAR;MAAqBK,OAAO,EAAEJ;IAA9B,CADU,EAEV,IAAAQ,6BAAA,EAAuBT,WAAvB,EAAoC,KAAKjE,MAAL,CAAY2E,QAAhD,CAFU,CAAZ;IAIA/E,KAAK,CAAC,wBAAD,EAA2BqE,WAA3B,CAAL;;IAEA,KAAK,MAAM/C,MAAX,IAAqB,KAAKhB,OAA1B,EAAmC;MACjC,IAAI8B,eAAA,CAAEQ,KAAF,CAAQtB,MAAR,KAAmB,IAAAgB,iBAAA,EAAWhB,MAAM,CAAC0D,eAAlB,MAAuC,KAA9D,EAAqE;QACnEhF,KAAK,CAAC,kEAAD,EAAqEqE,WAArE,CAAL;QACA;MACD,CAHD,MAGO;QACL;QACA/C,MAAM,CAAC0D,eAAP,CAAwBf,IAAxB,EAA8BU,GAA9B,EAAmC,CAAC9B,GAAD,EAAMuB,EAAN,KAA4B;UAC7D,IAAIvB,GAAJ,EAAS;YACP7C,KAAK,CACH,qEADG,EAEHqE,WAFG,CAAL;YAIA,OAAOE,QAAQ,CAAC1B,GAAD,CAAf;UACD;;UAED,IAAIT,eAAA,CAAEQ,KAAF,CAAQwB,EAAR,MAAgB,IAApB,EAA0B;YACxBpE,KAAK,CAAC,yDAAD,EAA4DqE,WAA5D,CAAL,CADwB,CAExB;YACA;;YACA,OAAO,KAAK5C,aAAL,CAAmB,GAAGwD,SAAtB,CAAP;UACD;;UAED,IAAIb,EAAJ,EAAQ;YACNpE,KAAK,CAAC,0BAAD,EAA6BqE,WAA7B,CAAL;YACA,OAAOE,QAAQ,CAAC,IAAD,EAAOH,EAAP,CAAf;UACD;QACF,CApBD;MAqBD;IACF;EACF;EAED;AACF;AACA;;;EACS3C,aAAa,CAClB;IAAE4C,WAAF;IAAeC;EAAf,CADkB,EAElBL,IAFkB,EAGlBM,QAHkB,EAIZ;IACN,MAAMjE,OAAO,GAAG,KAAKA,OAAL,CAAa+C,KAAb,CAAmB,CAAnB,CAAhB;IACA,MAAMsB,GAAG,GAAGC,MAAM,CAACC,MAAP,CACV;MAAEJ,IAAI,EAAEJ,WAAR;MAAqBK,OAAO,EAAEJ;IAA9B,CADU,EAEV,IAAAQ,6BAAA,EAAuBT,WAAvB,EAAoC,KAAKjE,MAAL,CAAY2E,QAAhD,CAFU,CAAZ;IAIA/E,KAAK,CAAC,yCAAD,EAA4CqE,WAA5C,EAAyD/D,OAAO,CAACI,MAAjE,CAAL;;IAEA,CAAC,SAAS4C,IAAT,GAAsB;MACrB,MAAMhC,MAAM,GAAGhB,OAAO,CAACiD,KAAR,EAAf;;MAEA,IAAI,QAAOjC,MAAP,aAAOA,MAAP,uBAAOA,MAAM,CAAEG,aAAf,MAAiC,UAArC,EAAiD;QAC/CzB,KAAK,CAAC,8DAAD,EAAiEqE,WAAjE,CAAL;QACA,OAAOf,IAAI,EAAX;MACD;;MAEDhC,MAAM,CAACG,aAAP,CAAqBwC,IAArB,EAA2BU,GAA3B,EAAgC,CAAC9B,GAAD,EAA6BuB,EAA7B,KAAoD;QAClF,IAAIhC,eAAA,CAAEQ,KAAF,CAAQC,GAAR,MAAiB,KAAjB,IAA0BT,eAAA,CAAE8C,OAAF,CAAUrC,GAAV,CAA9B,EAA8C;UAC5C7C,KAAK,CAAC,0BAAD,EAA6BqE,WAA7B,CAAL;UACA,OAAOE,QAAQ,CAAC1B,GAAD,CAAf;QACD;;QAED,IAAIuB,EAAJ,EAAQ;UACNpE,KAAK,CAAC,wBAAD,EAA2BqE,WAA3B,CAAL;UACA,OAAOE,QAAQ,CAAC,IAAD,EAAOH,EAAP,CAAf;QACD;;QAEDpE,KAAK,CAAC,sCAAD,EAAyCqE,WAAzC,CAAL;QACAf,IAAI,GAZ8E,CAY1E;MACT,CAbD;IAcD,CAtBD;EAuBD;;EAEM6B,gBAAgB,GAAmB;IACxCnF,KAAK,CAAC,gBAAD,CAAL;IACA,MAAMM,OAAO,GAAG,KAAKA,OAAL,CAAa+C,KAAb,CAAmB,CAAnB,CAAhB;IACA,MAAM+B,OAAO,GAAG;MAAEC,yBAAyB,EAAzBA,iCAAF;MAA6BtB,gBAAgB,EAAhBA;IAA7B,CAAhB;;IACA,KAAK,MAAMzC,MAAX,IAAqBhB,OAArB,EAA8B;MAC5B,IAAIgB,MAAM,CAAC6D,gBAAX,EAA6B;QAC3B,OAAO7D,MAAM,CAAC6D,gBAAP,CAAwBC,OAAxB,CAAP;MACD;IACF,CARuC,CAUxC;;;IACA,OAAO,CAACE,GAAD,EAAsBC,GAAtB,EAA4CC,KAA5C,KAAoE;MACzEF,GAAG,CAACG,KAAJ;;MAEA,MAAMnC,IAAI,GAAG,UAAUT,GAAV,EAAqC;QAChDyC,GAAG,CAACI,MAAJ,GADgD,CAEhD;QACA;QACA;QACA;;QACA,IAAI7C,GAAJ,EAAS;UACPyC,GAAG,CAACK,WAAJ,CAAgBzE,KAAhB,GAAwB2B,GAAG,CAACY,OAA5B;QACD;;QAED,OAAO+B,KAAK,EAAZ;MACD,CAXD;;MAaA,IAAI,KAAKI,kBAAL,CAAwBN,GAAG,CAACK,WAA5B,CAAJ,EAA8C;QAC5C3F,KAAK,CAAC,uCAAD,CAAL;QACA,OAAOsD,IAAI,EAAX;MACD,CAnBwE,CAqBzE;;;MACA,MAAMuC,UAAU,GAAG,IAAAR,iCAAA,GAAnB;MACAC,GAAG,CAACK,WAAJ,GAAkBE,UAAlB;MACAN,GAAG,CAACO,MAAJ,CAAWH,WAAX,GAAyBE,UAAzB;MAEA,MAAM;QAAEE;MAAF,IAAoBT,GAAG,CAACU,OAA9B;;MACA,IAAI5D,eAAA,CAAEQ,KAAF,CAAQmD,aAAR,CAAJ,EAA4B;QAC1B/F,KAAK,CAAC,uCAAD,CAAL;QACA,OAAOsD,IAAI,EAAX;MACD;;MAED,IAAI,CAAC,IAAA2C,yBAAA,EAAkBF,aAAlB,CAAL,EAAuC;QACrC/F,KAAK,CAAC,kDAAD,CAAL;QACA,OAAOsD,IAAI,CAACd,gBAAA,CAAW0D,aAAX,CAAyBrC,eAAA,CAAUsC,eAAnC,CAAD,CAAX;MACD;;MACD,MAAM;QAAE9F,MAAF;QAAU+F;MAAV,IAAuB,KAAKhG,MAAlC;;MAEA,IAAI,IAAAiG,mBAAA,EAAYD,QAAZ,CAAJ,EAA2B;QACzBpG,KAAK,CAAC,wCAAD,CAAL;;QACA,KAAKsG,oBAAL,CAA0BhB,GAA1B,EAA+Bc,QAA/B,EAAyC/F,MAAzC,EAAiD0F,aAAjD,EAAgEzC,IAAhE;MACD,CAHD,MAGO;QACLtD,KAAK,CAAC,qCAAD,CAAL;;QACA,KAAKuG,uBAAL,CAA6BjB,GAA7B,EAAkCc,QAAlC,EAA4C/F,MAA5C,EAAoD0F,aAApD,EAAmEzC,IAAnE;MACD;IACF,CA7CD;EA8CD;;EAEOiD,uBAAuB,CAC7BjB,GAD6B,EAE7Bc,QAF6B,EAG7B/F,MAH6B,EAI7B0F,aAJ6B,EAK7BzC,IAL6B,EAMvB;IACNtD,KAAK,CAAC,2BAAD,CAAL;IACA,MAAM;MAAEwG,MAAF;MAAUxD;IAAV,IAAoB,IAAAyD,4BAAA,EAAqBV,aAArB,CAA1B;;IACA,IAAIS,MAAM,CAACE,WAAP,OAAyBC,iBAAA,CAAYD,WAAZ,EAA7B,EAAwD;MACtD1G,KAAK,CAAC,oBAAD,CAAL,CADsD,CAEtD;;MACA,MAAM4G,WAAW,GAAG,IAAAC,8BAAA,EAAuB7D,KAAvB,EAA8B8D,QAA9B,EAApB;MACA,MAAM;QAAE7C,IAAF;QAAQjC;MAAR,IAAqB,IAAA+E,wBAAA,EAAkBH,WAAlB,CAA3B;MACA5G,KAAK,CAAC,mBAAD,EAAsBiE,IAAtB,CAAL;MACA,KAAK1C,YAAL,CAAkB0C,IAAlB,EAAwBjC,QAAxB,EAAkC,CAACa,GAAD,EAA6BoB,IAA7B,KAA4C;QAC5E,IAAI,CAACpB,GAAL,EAAU;UACR7C,KAAK,CAAC,0BAAD,CAAL;UACAsF,GAAG,CAACK,WAAJ,GAAkB1B,IAAlB;UACAX,IAAI;QACL,CAJD,MAIO;UACLtD,KAAK,CAAC,2BAAD,CAAL;UACAsF,GAAG,CAACK,WAAJ,GAAkB,IAAAN,iCAAA,GAAlB;UACA/B,IAAI,CAACT,GAAD,CAAJ;QACD;MACF,CAVD;IAWD,CAjBD,MAiBO;MACL7C,KAAK,CAAC,kBAAD,CAAL;MACA,MAAM4G,WAAgB,GAAG,IAAAI,gCAAA,EAAyBZ,QAAzB,EAAmC/F,MAAnC,EAA2C0F,aAA3C,CAAzB;;MACA,IAAIa,WAAJ,EAAiB;QACf;QACAtB,GAAG,CAACK,WAAJ,GAAkBiB,WAAlB;QACA5G,KAAK,CAAC,0BAAD,CAAL;QACAsD,IAAI;MACL,CALD,MAKO;QACL;QACAtD,KAAK,CAAC,mBAAD,CAAL;QACAsD,IAAI,CAACd,gBAAA,CAAWyE,YAAX,CAAwBpD,eAAA,CAAUqD,qBAAlC,CAAD,CAAJ;MACD;IACF;EACF;;EAEOZ,oBAAoB,CAC1BhB,GAD0B,EAE1Bc,QAF0B,EAG1B/F,MAH0B,EAI1B0F,aAJ0B,EAK1BzC,IAL0B,EAMpB;IACNtD,KAAK,CAAC,8BAAD,CAAL;IACAA,KAAK,CAAC,0BAAD,EAA6B,OAAOK,MAAP,KAAkB,QAA/C,CAAL;IACAL,KAAK,CAAC,iCAAD,EAAoC,OAAO+F,aAAP,KAAyB,QAA7D,CAAL;IACA,MAAMa,WAAgB,GAAG,IAAAI,gCAAA,EAAyBZ,QAAzB,EAAmC/F,MAAnC,EAA2C0F,aAA3C,CAAzB;IACA/F,KAAK,CAAC,+BAAD,EAAkC4G,WAAlC,aAAkCA,WAAlC,uBAAkCA,WAAW,CAAEnC,IAA/C,CAAL;;IACA,IAAImC,WAAJ,EAAiB;MACf,MAAM;QAAE3C,IAAF;QAAQjC;MAAR,IAAqB4E,WAA3B;MACA5G,KAAK,CAAC,mBAAD,EAAsBiE,IAAtB,CAAL;MACA,KAAK1C,YAAL,CAAkB0C,IAAlB,EAAwBjC,QAAxB,EAAkC,CAACa,GAAD,EAAMoB,IAAN,KAAqB;QACrD,IAAI,CAACpB,GAAL,EAAU;UACRyC,GAAG,CAACK,WAAJ,GAAkB1B,IAAlB;UACAjE,KAAK,CAAC,0BAAD,CAAL;UACAsD,IAAI;QACL,CAJD,MAIO;UACLgC,GAAG,CAACK,WAAJ,GAAkB,IAAAN,iCAAA,GAAlB;UACArF,KAAK,CAAC,2BAAD,CAAL;UACAsD,IAAI,CAACT,GAAD,CAAJ;QACD;MACF,CAVD;IAWD,CAdD,MAcO;MACL;MACA7C,KAAK,CAAC,uBAAD,CAAL;MACA,OAAOsD,IAAI,CAACd,gBAAA,CAAW0D,aAAX,CAAyBrC,eAAA,CAAUsC,eAAnC,CAAD,CAAX;IACD;EACF;;EAEOP,kBAAkB,CAACD,WAAD,EAAoC;IAC5D,OAAOvD,eAAA,CAAE+E,WAAF,CAAcxB,WAAd,MAA+B,KAA/B,IAAwCvD,eAAA,CAAE+E,WAAF,CAAcxB,WAAd,aAAcA,WAAd,uBAAcA,WAAW,CAAElB,IAA3B,MAAqC,KAApF;EACD;EAED;AACF;AACA;;;EACS2C,kBAAkB,GAAmB;IAC1C;IACA,OAAO,CAAC9B,GAAD,EAAsBC,GAAtB,EAA4CC,KAA5C,KAA0E;MAC/E,IAAI,KAAKI,kBAAL,CAAwBN,GAAG,CAACK,WAA5B,CAAJ,EAA8C;QAC5C,OAAOH,KAAK,EAAZ;MACD;;MAEDF,GAAG,CAACG,KAAJ;;MACA,MAAMnC,IAAI,GAAIT,GAAD,IAAsC;QACjDyC,GAAG,CAACI,MAAJ;;QACA,IAAI7C,GAAJ,EAAS;UACP;UACA0C,GAAG,CAAC8B,MAAJ,CAAWxE,GAAG,CAACyE,UAAf,EAA2BC,IAA3B,CAAgC1E,GAAG,CAACY,OAApC;QACD;;QAED,OAAO+B,KAAK,EAAZ;MACD,CARD;;MAUA,MAAM;QAAEO;MAAF,IAAoBT,GAAG,CAACU,OAA9B;;MACA,IAAI5D,eAAA,CAAEQ,KAAF,CAAQmD,aAAR,CAAJ,EAA4B;QAC1B,OAAOzC,IAAI,EAAX;MACD;;MAED,IAAI,CAAC,IAAA2C,yBAAA,EAAkBF,aAAlB,CAAL,EAAuC;QACrC,OAAOzC,IAAI,CAACd,gBAAA,CAAW0D,aAAX,CAAyBrC,eAAA,CAAUsC,eAAnC,CAAD,CAAX;MACD;;MAED,MAAMnD,KAAK,GAAG,CAAC+C,aAAa,IAAI,EAAlB,EAAsByB,OAAtB,CAA+B,GAAEC,kBAAa,GAA9C,EAAkD,EAAlD,CAAd;;MACA,IAAI,CAACzE,KAAL,EAAY;QACV,OAAOM,IAAI,EAAX;MACD;;MAED,IAAIsD,WAAJ;;MACA,IAAI;QACFA,WAAW,GAAG,IAAAc,wBAAA,EAAiB1E,KAAjB,EAAwB,KAAK5C,MAAL,CAAYC,MAApC,CAAd;MACD,CAFD,CAEE,OAAOwC,GAAP,EAAiB,CACjB;MACD;;MAED,IAAI,KAAK+C,kBAAL,CAAwBgB,WAAxB,CAAJ,EAA0C;QACxC,MAAM;UAAEnC,IAAF;UAAQjB;QAAR,IAAmBoD,WAAzB;QACAtB,GAAG,CAACK,WAAJ,GAAkB,IAAA5B,wBAAA,EAAiBU,IAAjB,EAAiCjB,MAAjC,CAAlB;MACD,CAHD,MAGO;QACL8B,GAAG,CAACK,WAAJ,GAAkB,IAAAN,iCAAA,GAAlB;MACD;;MAED/B,IAAI;IACL,CA7CD;EA8CD;;EAEsB,MAAVqE,UAAU,CAAC1D,IAAD,EAAmB2D,WAAnB,EAAiE;IACtF,MAAM;MAAEC,WAAF;MAAepD,IAAf;MAAqBjB;IAArB,IAAgCS,IAAtC;IACAjE,KAAK,CAAC,gBAAD,EAAmByE,IAAnB,CAAL;IACA,MAAMqD,mBAAmB,GAAG1F,eAAA,CAAEQ,KAAF,CAAQiF,WAAR,IAAuB,EAAvB,GAA4BA,WAAxD;IACA,MAAME,aAAa,GAAG3F,eAAA,CAAEQ,KAAF,CAAQY,MAAR,IAAkBqE,WAAlB,GAAgCrE,MAAM,CAACwE,MAAP,CAAcF,mBAAd,CAAtD;IACA,MAAMG,OAAmB,GAAG;MAC1BJ,WAAW,EAAEC,mBADa;MAE1BrD,IAF0B;MAG1BjB,MAAM,EAAEuE;IAHkB,CAA5B;IAMA,MAAM/E,KAAa,GAAG,MAAM,IAAAkF,qBAAA,EAAYD,OAAZ,EAAqB,KAAK5H,MAA1B,EAAkCuH,WAAlC,CAA5B;IAEA,OAAO5E,KAAP;EACD;EAED;AACF;AACA;;;EACSmF,UAAU,CAACC,KAAD,EAA+B;IAC9C,OAAO,IAAAD,uBAAA,EAAWC,KAAX,EAAkB,KAAK/H,MAAvB,CAAP;EACD;;AAnhB4E"}
1
+ {"version":3,"file":"auth.js","names":["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","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","adduser","ok","packageName","packageVersion","callback","pkgAllowAccess","name","version","pkg","Object","assign","getMatchedPackagesSpec","packages","allow_unpublish","arguments","isError","apiJWTmiddleware","helpers","createAnonymousRemoteUser","req","res","_next","pause","resume","remote_user","_isRemoteUserValid","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","isUndefined","webUIJWTmiddleware","status","statusCode","send","replace","TOKEN_BEARER","verifyJWTPayload","jwtEncrypt","signOptions","real_groups","realGroupsValidated","groupedGroups","Array","from","Set","concat","payload","signPayload","aesEncrypt","value"],"sources":["../src/auth.ts"],"sourcesContent":["import buildDebug from 'debug';\nimport { NextFunction, Request, RequestHandler, Response } from 'express';\nimport _ from 'lodash';\nimport { HTPasswd } from 'verdaccio-htpasswd';\n\nimport { createAnonymousRemoteUser, createRemoteUser } from '@verdaccio/config';\nimport {\n API_ERROR,\n SUPPORT_ERRORS,\n TOKEN_BASIC,\n TOKEN_BEARER,\n VerdaccioError,\n errorUtils,\n pluginUtils,\n} from '@verdaccio/core';\nimport { asyncLoadPlugin } from '@verdaccio/loaders';\nimport { logger } from '@verdaccio/logger';\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 { signPayload } from './jwt-token';\nimport { aesEncrypt } from './legacy-token';\nimport { parseBasicPayload } from './token';\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\nexport interface TokenEncryption {\n jwtEncrypt(user: RemoteUser, signOptions: JWTSignOptions): Promise<string>;\n aesEncrypt(buf: string): string | void;\n}\n\nexport interface AESPayload {\n user: string;\n password: string;\n}\nexport interface IAuthMiddleware {\n apiJWTmiddleware(): $NextFunctionVer;\n webUIJWTmiddleware(): $NextFunctionVer;\n}\n\nexport type $RequestExtend = Request & { remote_user?: any; log: Logger };\nexport type $ResponseExtend = Response & { cookies?: any };\nexport type $NextFunctionVer = NextFunction & any;\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 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 );\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 const plugin = plugins.shift() as pluginUtils.Auth<Config>;\n if (typeof plugin.adduser !== 'function') {\n next();\n } else {\n // @ts-expect-error future major (7.x) should remove this section\n if (typeof plugin.adduser === 'undefined' && typeof plugin.add_user === 'function') {\n throw errorUtils.getInternalError(\n 'add_user method not longer supported, rename to adduser'\n );\n }\n\n plugin.adduser(\n user,\n password,\n function (err: VerdaccioError | null, ok?: boolean | string): void {\n if (err) {\n debug('the user %o could not being added. Error: %o', user, err?.message);\n return cb(err);\n }\n if (ok) {\n debug('the user %o has been added', user);\n return self.authenticate(user, password, cb);\n }\n next();\n }\n );\n }\n })();\n }\n\n /**\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 (_.isNil(plugin) || isFunction(plugin.allow_unpublish) === false) {\n debug('allow unpublish for %o plugin does not implement allow_unpublish', packageName);\n continue;\n } else {\n // @ts-ignore\n plugin.allow_unpublish!(user, pkg, (err, ok: boolean): void => {\n if (err) {\n debug(\n 'forbidden publish for %o, it will fallback on unpublish permissions',\n packageName\n );\n return callback(err);\n }\n\n if (_.isNil(ok) === true) {\n debug('bypass unpublish for %o, publish will handle the access', packageName);\n // @ts-ignore\n // eslint-disable-next-line\n return this.allow_publish(...arguments);\n }\n\n if (ok) {\n debug('allowed unpublish for %o', packageName);\n return callback(null, ok);\n }\n });\n }\n }\n }\n\n /**\n * Allow user to publish a package.\n */\n public allow_publish(\n { packageName, packageVersion }: 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 ) as any;\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(): RequestHandler {\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 // @ts-ignore\n return (req: $RequestExtend, res: $ResponseExtend, _next: NextFunction) => {\n req.pause();\n\n const next = function (err?: VerdaccioError): any {\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();\n };\n\n if (this._isRemoteUserValid(req.remote_user)) {\n debug('jwt has a valid authentication header');\n return next();\n }\n\n // in case auth header does not exist we return anonymous function\n 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: Function\n ): void {\n debug('handle JWT api middleware');\n const { scheme, token } = parseAuthTokenHeader(authorization);\n if (scheme.toUpperCase() === TOKEN_BASIC.toUpperCase()) {\n debug('handle basic token');\n // this should happen when client tries to login with an existing user\n const credentials = convertPayloadToBase64(token).toString();\n const { user, password } = parseBasicPayload(credentials) as AESPayload;\n debug('authenticating %o', user);\n this.authenticate(user, password, (err: 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 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(): RequestHandler {\n // @ts-ignore\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\n const token: string = await signPayload(payload, this.secret, signOptions);\n\n return token;\n }\n\n /**\n * Encrypt a string.\n */\n public aesEncrypt(value: string): string | void {\n return aesEncrypt(value, this.secret);\n }\n}\n\nexport { Auth };\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@verdaccio/auth",
3
- "version": "6.0.0-6-next.29",
3
+ "version": "6.0.0-6-next.30",
4
4
  "description": "logger",
5
5
  "main": "./build/index.js",
6
6
  "types": "./build/index.d.ts",
@@ -30,16 +30,16 @@
30
30
  },
31
31
  "license": "MIT",
32
32
  "dependencies": {
33
- "@verdaccio/core": "6.0.0-6-next.50",
34
- "@verdaccio/config": "6.0.0-6-next.50",
35
- "@verdaccio/loaders": "6.0.0-6-next.19",
36
- "@verdaccio/logger": "6.0.0-6-next.18",
37
- "@verdaccio/utils": "6.0.0-6-next.18",
33
+ "@verdaccio/core": "6.0.0-6-next.51",
34
+ "@verdaccio/config": "6.0.0-6-next.51",
35
+ "@verdaccio/loaders": "6.0.0-6-next.20",
36
+ "@verdaccio/logger": "6.0.0-6-next.19",
37
+ "@verdaccio/utils": "6.0.0-6-next.19",
38
38
  "debug": "4.3.4",
39
39
  "express": "4.18.2",
40
40
  "jsonwebtoken": "8.5.1",
41
41
  "lodash": "4.17.21",
42
- "verdaccio-htpasswd": "11.0.0-6-next.20"
42
+ "verdaccio-htpasswd": "11.0.0-6-next.21"
43
43
  },
44
44
  "devDependencies": {
45
45
  "@verdaccio/types": "11.0.0-6-next.17"
package/src/auth.ts CHANGED
@@ -574,7 +574,9 @@ class Auth implements IAuthMiddleware, TokenEncryption, pluginUtils.IBasicAuth {
574
574
  const { real_groups, name, groups } = user;
575
575
  debug('jwt encrypt %o', name);
576
576
  const realGroupsValidated = _.isNil(real_groups) ? [] : real_groups;
577
- const groupedGroups = _.isNil(groups) ? real_groups : groups.concat(realGroupsValidated);
577
+ const groupedGroups = _.isNil(groups)
578
+ ? real_groups
579
+ : Array.from(new Set([...groups.concat(realGroupsValidated)]));
578
580
  const payload: RemoteUser = {
579
581
  real_groups: realGroupsValidated,
580
582
  name,
@@ -77,8 +77,8 @@ describe('Auth utilities', () => {
77
77
  const spyNotCalled = jest.spyOn(auth, methodNotBeenCalled);
78
78
  const user: RemoteUser = {
79
79
  name: username,
80
- real_groups: [],
81
- groups: [],
80
+ real_groups: ['test', '$all', '$authenticated', '@all', '@authenticated', 'all'],
81
+ groups: ['company-role1', 'company-role2'],
82
82
  };
83
83
  const token = await getApiToken(auth, config, user, password);
84
84
  expect(spy).toHaveBeenCalled();
@@ -93,7 +93,25 @@ describe('Auth utilities', () => {
93
93
  const payload = verifyPayload(token, secret);
94
94
  expect(payload.name).toBe(user);
95
95
  expect(payload.groups).toBeDefined();
96
+ expect(payload.groups).toEqual([
97
+ 'company-role1',
98
+ 'company-role2',
99
+ 'test',
100
+ '$all',
101
+ '$authenticated',
102
+ '@all',
103
+ '@authenticated',
104
+ 'all',
105
+ ]);
96
106
  expect(payload.real_groups).toBeDefined();
107
+ expect(payload.real_groups).toEqual([
108
+ 'test',
109
+ '$all',
110
+ '$authenticated',
111
+ '@all',
112
+ '@authenticated',
113
+ 'all',
114
+ ]);
97
115
  };
98
116
 
99
117
  const verifyAES = (token: string, user: string, password: string, secret: string) => {
@@ -219,6 +237,30 @@ describe('Auth utilities', () => {
219
237
  });
220
238
  });
221
239
 
240
+ describe('createRemoteUser', () => {
241
+ test('create remote user', () => {
242
+ expect(createRemoteUser('test', [])).toEqual({
243
+ name: 'test',
244
+ real_groups: [],
245
+ groups: ['$all', '$authenticated', '@all', '@authenticated', 'all'],
246
+ });
247
+ });
248
+ test('create remote user with groups', () => {
249
+ expect(createRemoteUser('test', ['group1', 'group2'])).toEqual({
250
+ name: 'test',
251
+ real_groups: ['group1', 'group2'],
252
+ groups: ['group1', 'group2', '$all', '$authenticated', '@all', '@authenticated', 'all'],
253
+ });
254
+ });
255
+ test('create anonymous remote user', () => {
256
+ expect(createAnonymousRemoteUser()).toEqual({
257
+ name: undefined,
258
+ real_groups: [],
259
+ groups: ['$all', '$anonymous', '@all', '@anonymous'],
260
+ });
261
+ });
262
+ });
263
+
222
264
  describe('getApiToken test', () => {
223
265
  test('should sign token with aes and security missing', async () => {
224
266
  const token = await getTokenByConfiguration(
@@ -445,15 +487,13 @@ describe('Auth utilities', () => {
445
487
  security,
446
488
  '12345',
447
489
  buildToken(TOKEN_BEARER, 'fakeToken')
448
- );
490
+ ) as RemoteUser;
449
491
 
450
492
  expect(credentials).toBeDefined();
451
- // @ts-ignore
452
493
  expect(credentials.name).not.toBeDefined();
453
- // @ts-ignore
454
494
  expect(credentials.real_groups).toBeDefined();
455
- // @ts-ignore
456
- expect(credentials.real_groups).toEqual([]);
495
+
496
+ expect(credentials.groups).toEqual(['$all', '$anonymous', '@all', '@anonymous']);
457
497
  });
458
498
 
459
499
  test('should return anonymous whether token and scheme are corrupted', () => {
@@ -485,14 +525,29 @@ describe('Auth utilities', () => {
485
525
  security,
486
526
  secret,
487
527
  buildToken(TOKEN_BEARER, token)
488
- );
528
+ ) as RemoteUser;
489
529
  expect(credentials).toBeDefined();
490
- // @ts-ignore
530
+
491
531
  expect(credentials.name).toEqual(user);
492
- // @ts-ignore
493
532
  expect(credentials.real_groups).toBeDefined();
494
- // @ts-ignore
495
- expect(credentials.real_groups).toEqual([]);
533
+ expect(credentials.real_groups).toEqual([
534
+ 'test',
535
+ '$all',
536
+ '$authenticated',
537
+ '@all',
538
+ '@authenticated',
539
+ 'all',
540
+ ]);
541
+ expect(credentials.groups).toEqual([
542
+ 'company-role1',
543
+ 'company-role2',
544
+ 'test',
545
+ '$all',
546
+ '$authenticated',
547
+ '@all',
548
+ '@authenticated',
549
+ 'all',
550
+ ]);
496
551
  });
497
552
  });
498
553
  });