@verdaccio/auth 6.0.0-6-next.26 → 6.0.0-6-next.28
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 +87 -0
- package/build/auth.d.ts +18 -33
- package/build/auth.js +53 -47
- package/build/auth.js.map +1 -1
- package/build/index.d.ts +1 -1
- package/build/index.js +1 -15
- package/build/index.js.map +1 -1
- package/build/utils.d.ts +10 -5
- package/build/utils.js +8 -2
- package/build/utils.js.map +1 -1
- package/package.json +9 -9
- package/src/auth.ts +117 -126
- package/src/index.ts +1 -1
- package/src/utils.ts +12 -13
- package/test/auth-utils.spec.ts +4 -3
- package/test/auth.spec.ts +65 -30
- package/test/helper/plugin.ts +14 -3
- package/test/partials/plugin/verdaccio-fail/fail.js +11 -0
- package/test/partials/plugin/verdaccio-fail/package.json +5 -0
- package/test/partials/plugin/verdaccio-fail-invalid-method/fail.js +11 -0
- package/test/partials/plugin/verdaccio-fail-invalid-method/package.json +5 -0
- package/test/partials/plugin/verdaccio-passthroug/package.json +5 -0
- package/test/partials/plugin/{authenticate.passthroug.js → verdaccio-passthroug/passthroug.js} +0 -0
- package/test/partials/plugin/verdaccio-success/package.json +5 -0
- package/test/partials/plugin/{authenticate.success.js → verdaccio-success/success.js} +0 -0
- package/tsconfig.build.json +3 -3
- package/tsconfig.json +6 -6
- package/test/partials/plugin/authenticate.fail.js +0 -11
package/build/utils.js
CHANGED
|
@@ -158,14 +158,20 @@ function verifyJWTPayload(token, secret) {
|
|
|
158
158
|
function isAuthHeaderValid(authorization) {
|
|
159
159
|
return authorization.split(' ').length === 2;
|
|
160
160
|
}
|
|
161
|
+
/**
|
|
162
|
+
* Return a default configuration for authentication if none is provided.
|
|
163
|
+
* @param logger {Logger}
|
|
164
|
+
* @returns object of default implementations.
|
|
165
|
+
*/
|
|
166
|
+
|
|
161
167
|
|
|
162
168
|
function getDefaultPlugins(logger) {
|
|
163
169
|
return {
|
|
164
|
-
authenticate(
|
|
170
|
+
authenticate(_user, _password, cb) {
|
|
165
171
|
cb(_core.errorUtils.getForbidden(_core.API_ERROR.BAD_USERNAME_PASSWORD));
|
|
166
172
|
},
|
|
167
173
|
|
|
168
|
-
adduser(
|
|
174
|
+
adduser(_user, _password, cb) {
|
|
169
175
|
return cb(_core.errorUtils.getConflict(_core.API_ERROR.BAD_USERNAME_PASSWORD));
|
|
170
176
|
},
|
|
171
177
|
|
package/build/utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","names":["debug","buildDebug","parseAuthTokenHeader","authorizationHeader","parts","split","scheme","token","parseAESCredentials","secret","toUpperCase","TOKEN_BASIC","credentials","convertPayloadToBase64","toString","TOKEN_BEARER","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","payload","verifyPayload","error","includes","createAnonymousRemoteUser","errorUtils","getCode","HTTP_STATUS","UNAUTHORIZED","message","isAuthHeaderValid","authorization","length","getDefaultPlugins","logger","authenticate","user","password","cb","getForbidden","API_ERROR","BAD_USERNAME_PASSWORD","adduser","getConflict","allow_access","allow_action","allow_publish","allow_unpublish","handleSpecialUnpublish","action","allowActionCallback","pkg","callback","trace","remote","groups","groupAccess","hasPermission","some","group","pkgName","getUnauthorized","isUnpublishMissing","hasGroups","undefined","String","Buffer","from"],"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 VerdaccioError,\n errorUtils,\n} from '@verdaccio/core';\nimport {\n AuthPackageAllow,\n Callback,\n Config,\n IPluginAuth,\n RemoteUser,\n Security,\n} from '@verdaccio/types';\n\nimport { AESPayload, TokenEncryption } from './auth';\nimport { verifyPayload } from './jwt-token';\nimport { aesDecrypt } from './legacy-token';\nimport { parseBasicPayload } from './token';\n\nconst debug = buildDebug('verdaccio:auth:utils');\n\nexport type BasicPayload = AESPayload | void;\nexport type AuthMiddlewarePayload = RemoteUser | BasicPayload;\n\nexport interface AuthTokenHeader {\n scheme: string;\n token: string;\n}\nexport type AllowActionCallbackResponse = boolean | undefined;\nexport type AllowActionCallback = (\n error: VerdaccioError | null,\n allowed?: AllowActionCallbackResponse\n) => void;\n\nexport type AllowAction = (\n user: RemoteUser,\n pkg: AuthPackageAllow,\n callback: AllowActionCallback\n) => void;\n\n/**\n * Split authentication header eg: Bearer [secret_token]\n * @param authorizationHeader auth token\n */\nexport function parseAuthTokenHeader(authorizationHeader: string): AuthTokenHeader {\n const parts = authorizationHeader.split(' ');\n const [scheme, token] = parts;\n\n return { scheme, token };\n}\n\nexport function parseAESCredentials(authorizationHeader: string, secret: string) {\n debug('parseAESCredentials');\n const { scheme, token } = parseAuthTokenHeader(authorizationHeader);\n\n // basic is deprecated and should not be enforced\n // basic is currently being used for functional test\n if (scheme.toUpperCase() === TOKEN_BASIC.toUpperCase()) {\n debug('legacy header basic');\n const credentials = convertPayloadToBase64(token).toString();\n\n return credentials;\n } else if (scheme.toUpperCase() === TOKEN_BEARER.toUpperCase()) {\n debug('legacy header bearer');\n const credentials = aesDecrypt(token, secret);\n\n return credentials;\n }\n}\n\nexport function getMiddlewareCredentials(\n security: Security,\n secretKey: string,\n authorizationHeader: string\n): AuthMiddlewarePayload {\n debug('getMiddlewareCredentials');\n // comment out for debugging purposes\n if (isAESLegacy(security)) {\n debug('is legacy');\n const credentials = parseAESCredentials(authorizationHeader, secretKey);\n if (!credentials) {\n debug('parse legacy credentials failed');\n return;\n }\n\n const parsedCredentials = parseBasicPayload(credentials);\n if (!parsedCredentials) {\n debug('parse legacy basic payload credentials failed');\n return;\n }\n\n return parsedCredentials;\n }\n const { scheme, token } = parseAuthTokenHeader(authorizationHeader);\n\n debug('is jwt');\n if (_.isString(token) && scheme.toUpperCase() === TOKEN_BEARER.toUpperCase()) {\n return verifyJWTPayload(token, secretKey);\n }\n}\n\nexport function isAESLegacy(security: Security): boolean {\n const { legacy, jwt } = security.api;\n\n return _.isNil(legacy) === false && _.isNil(jwt) && legacy === true;\n}\n\nexport async function getApiToken(\n auth: TokenEncryption,\n config: Config,\n remoteUser: RemoteUser,\n aesPassword: string\n): Promise<string | void> {\n debug('get api token');\n const { security } = config;\n\n if (isAESLegacy(security)) {\n debug('security legacy enabled');\n // fallback all goes to AES encryption\n return await new Promise((resolve): void => {\n resolve(auth.aesEncrypt(buildUser(remoteUser.name as string, aesPassword)));\n });\n }\n const { jwt } = security.api;\n\n if (jwt?.sign) {\n return await auth.jwtEncrypt(remoteUser, jwt.sign);\n }\n return await new Promise((resolve): void => {\n resolve(auth.aesEncrypt(buildUser(remoteUser.name as string, aesPassword)));\n });\n}\n\nexport const expireReasons: string[] = ['JsonWebTokenError', 'TokenExpiredError'];\n\nexport function verifyJWTPayload(token: string, secret: string): RemoteUser {\n try {\n const payload: RemoteUser = verifyPayload(token, secret);\n\n return payload;\n } catch (error: any) {\n // #168 this check should be removed as soon AES encrypt is removed.\n if (expireReasons.includes(error.name)) {\n // it might be possible the jwt configuration is enabled and\n // old tokens fails still remains in usage, thus\n // we return an anonymous user to force log in.\n return createAnonymousRemoteUser();\n }\n throw errorUtils.getCode(HTTP_STATUS.UNAUTHORIZED, error.message);\n }\n}\n\nexport function isAuthHeaderValid(authorization: string): boolean {\n return authorization.split(' ').length === 2;\n}\n\nexport function getDefaultPlugins(logger: any): IPluginAuth<Config> {\n return {\n authenticate(user: string, password: string, cb: Callback): void {\n cb(errorUtils.getForbidden(API_ERROR.BAD_USERNAME_PASSWORD));\n },\n\n adduser(user: string, password: string, cb: Callback): void {\n return cb(errorUtils.getConflict(API_ERROR.BAD_USERNAME_PASSWORD));\n },\n\n // FIXME: allow_action and allow_publish should be in the @verdaccio/types\n // @ts-ignore\n allow_access: allow_action('access', logger),\n // @ts-ignore\n allow_publish: allow_action('publish', logger),\n allow_unpublish: handleSpecialUnpublish(logger),\n };\n}\n\nexport type ActionsAllowed = 'publish' | 'unpublish' | 'access';\n\nexport function allow_action(action: ActionsAllowed, logger): AllowAction {\n return function allowActionCallback(\n user: RemoteUser,\n pkg: AuthPackageAllow,\n callback: AllowActionCallback\n ): void {\n logger.trace({ remote: user.name }, `[auth/allow_action]: user: @{remote}`);\n const { name, groups } = user;\n const groupAccess = pkg[action] as string[];\n const hasPermission = groupAccess.some((group) => name === group || groups.includes(group));\n logger.trace(\n { pkgName: pkg.name, hasPermission, remote: user.name, groupAccess },\n `[auth/allow_action]: hasPermission? @{hasPermission} for user: @{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): any {\n return function (user: RemoteUser, pkg: AuthPackageAllow, callback: AllowActionCallback): void {\n const action = 'unpublish';\n // verify whether the unpublish prop has been defined\n const isUnpublishMissing: boolean = _.isNil(pkg[action]);\n const hasGroups: boolean = isUnpublishMissing ? false : (pkg[action] as string[]).length > 0;\n logger.trace(\n { user: user.name, name: pkg.name, hasGroups },\n `fallback unpublish for @{name} has groups: @{hasGroups} for @{user}`\n );\n\n if (isUnpublishMissing || hasGroups === false) {\n return callback(null, undefined);\n }\n\n logger.trace(\n { user: user.name, name: pkg.name, action, hasGroups },\n `allow_action for @{action} for @{name} has groups: @{hasGroups} for @{user}`\n );\n return allow_action(action, logger)(user, pkg, callback);\n };\n}\n\nexport function buildUser(name: string, password: string): string {\n return String(`${name}:${password}`);\n}\n\nexport function convertPayloadToBase64(payload: string): Buffer {\n return Buffer.from(payload, 'base64');\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"utils.js","names":["debug","buildDebug","parseAuthTokenHeader","authorizationHeader","parts","split","scheme","token","parseAESCredentials","secret","toUpperCase","TOKEN_BASIC","credentials","convertPayloadToBase64","toString","TOKEN_BEARER","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","payload","verifyPayload","error","includes","createAnonymousRemoteUser","errorUtils","getCode","HTTP_STATUS","UNAUTHORIZED","message","isAuthHeaderValid","authorization","length","getDefaultPlugins","logger","authenticate","_user","_password","cb","getForbidden","API_ERROR","BAD_USERNAME_PASSWORD","adduser","getConflict","allow_access","allow_action","allow_publish","allow_unpublish","handleSpecialUnpublish","action","allowActionCallback","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 VerdaccioError,\n errorUtils,\n pluginUtils,\n} from '@verdaccio/core';\nimport { AuthPackageAllow, Config, Logger, RemoteUser, Security } from '@verdaccio/types';\n\nimport { AESPayload, TokenEncryption } from './auth';\nimport { verifyPayload } from './jwt-token';\nimport { aesDecrypt } from './legacy-token';\nimport { parseBasicPayload } from './token';\n\nconst debug = buildDebug('verdaccio:auth:utils');\n\nexport type BasicPayload = AESPayload | void;\nexport type AuthMiddlewarePayload = RemoteUser | BasicPayload;\n\nexport interface AuthTokenHeader {\n scheme: string;\n token: string;\n}\nexport type AllowActionCallbackResponse = boolean | undefined;\nexport type AllowActionCallback = (\n error: VerdaccioError | null,\n allowed?: AllowActionCallbackResponse\n) => void;\n\nexport type AllowAction = (\n user: RemoteUser,\n pkg: AuthPackageAllow,\n callback: AllowActionCallback\n) => void;\n\n/**\n * Split authentication header eg: Bearer [secret_token]\n * @param authorizationHeader auth token\n */\nexport function parseAuthTokenHeader(authorizationHeader: string): AuthTokenHeader {\n const parts = authorizationHeader.split(' ');\n const [scheme, token] = parts;\n\n return { scheme, token };\n}\n\nexport function parseAESCredentials(authorizationHeader: string, secret: string) {\n debug('parseAESCredentials');\n const { scheme, token } = parseAuthTokenHeader(authorizationHeader);\n\n // basic is deprecated and should not be enforced\n // basic is currently being used for functional test\n if (scheme.toUpperCase() === TOKEN_BASIC.toUpperCase()) {\n debug('legacy header basic');\n const credentials = convertPayloadToBase64(token).toString();\n\n return credentials;\n } else if (scheme.toUpperCase() === TOKEN_BEARER.toUpperCase()) {\n debug('legacy header bearer');\n const credentials = aesDecrypt(token, secret);\n\n return credentials;\n }\n}\n\nexport function getMiddlewareCredentials(\n security: Security,\n secretKey: string,\n authorizationHeader: string\n): AuthMiddlewarePayload {\n debug('getMiddlewareCredentials');\n // comment out for debugging purposes\n if (isAESLegacy(security)) {\n debug('is legacy');\n const credentials = parseAESCredentials(authorizationHeader, secretKey);\n if (!credentials) {\n debug('parse legacy credentials failed');\n return;\n }\n\n const parsedCredentials = parseBasicPayload(credentials);\n if (!parsedCredentials) {\n debug('parse legacy basic payload credentials failed');\n return;\n }\n\n return parsedCredentials;\n }\n const { scheme, token } = parseAuthTokenHeader(authorizationHeader);\n\n debug('is jwt');\n if (_.isString(token) && scheme.toUpperCase() === TOKEN_BEARER.toUpperCase()) {\n return verifyJWTPayload(token, secretKey);\n }\n}\n\nexport function isAESLegacy(security: Security): boolean {\n const { legacy, jwt } = security.api;\n\n return _.isNil(legacy) === false && _.isNil(jwt) && legacy === true;\n}\n\nexport async function getApiToken(\n auth: TokenEncryption,\n config: Config,\n remoteUser: RemoteUser,\n aesPassword: string\n): Promise<string | void> {\n debug('get api token');\n const { security } = config;\n\n if (isAESLegacy(security)) {\n debug('security legacy enabled');\n // fallback all goes to AES encryption\n return await new Promise((resolve): void => {\n resolve(auth.aesEncrypt(buildUser(remoteUser.name as string, aesPassword)));\n });\n }\n const { jwt } = security.api;\n\n if (jwt?.sign) {\n return await auth.jwtEncrypt(remoteUser, jwt.sign);\n }\n return await new Promise((resolve): void => {\n resolve(auth.aesEncrypt(buildUser(remoteUser.name as string, aesPassword)));\n });\n}\n\nexport const expireReasons: string[] = ['JsonWebTokenError', 'TokenExpiredError'];\n\nexport function verifyJWTPayload(token: string, secret: string): RemoteUser {\n try {\n const payload: RemoteUser = verifyPayload(token, secret);\n\n return payload;\n } catch (error: any) {\n // #168 this check should be removed as soon AES encrypt is removed.\n if (expireReasons.includes(error.name)) {\n // it might be possible the jwt configuration is enabled and\n // old tokens fails still remains in usage, thus\n // we return an anonymous user to force log in.\n return createAnonymousRemoteUser();\n }\n throw errorUtils.getCode(HTTP_STATUS.UNAUTHORIZED, error.message);\n }\n}\n\nexport function isAuthHeaderValid(authorization: string): boolean {\n return authorization.split(' ').length === 2;\n}\n\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 cb(errorUtils.getForbidden(API_ERROR.BAD_USERNAME_PASSWORD));\n },\n\n adduser(_user: string, _password: string, cb: pluginUtils.AuthUserCallback): void {\n return cb(errorUtils.getConflict(API_ERROR.BAD_USERNAME_PASSWORD));\n },\n\n // FIXME: allow_action and allow_publish should be in the @verdaccio/types\n // @ts-ignore\n allow_access: allow_action('access', logger),\n // @ts-ignore\n allow_publish: allow_action('publish', logger),\n allow_unpublish: handleSpecialUnpublish(logger),\n };\n}\n\nexport type ActionsAllowed = 'publish' | 'unpublish' | 'access';\n\nexport function allow_action(action: ActionsAllowed, logger: 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 const groupAccess = pkg[action] as string[];\n const hasPermission = groupAccess.some((group) => name === group || groups.includes(group));\n logger.trace(\n { pkgName: pkg.name, hasPermission, remote: user.name, groupAccess },\n `[auth/allow_action]: hasPermission? @{hasPermission} for user: @{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 = _.isNil(pkg[action]);\n const hasGroups: boolean = isUnpublishMissing ? false : (pkg[action] as string[]).length > 0;\n logger.trace(\n { user: user.name, name: pkg.name, hasGroups },\n `fallback unpublish for @{name} has groups: @{hasGroups} for @{user}`\n );\n\n if (isUnpublishMissing || hasGroups === false) {\n return callback(null, undefined);\n }\n\n logger.trace(\n { user: user.name, name: pkg.name, action, hasGroups },\n `allow_action for @{action} for @{name} has groups: @{hasGroups} for @{user}`\n );\n return allow_action(action, logger)(user, pkg, callback);\n };\n}\n\nexport function buildUser(name: string, password: string): string {\n return String(`${name}:${password}`);\n}\n\nexport function convertPayloadToBase64(payload: string): Buffer {\n return Buffer.from(payload, 'base64');\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@verdaccio/auth",
|
|
3
|
-
"version": "6.0.0-6-next.
|
|
3
|
+
"version": "6.0.0-6-next.28",
|
|
4
4
|
"description": "logger",
|
|
5
5
|
"main": "./build/index.js",
|
|
6
|
-
"types": "build/index.d.ts",
|
|
6
|
+
"types": "./build/index.d.ts",
|
|
7
7
|
"author": {
|
|
8
8
|
"name": "Juan Picado",
|
|
9
9
|
"email": "juanpicado19@gmail.com"
|
|
@@ -30,19 +30,19 @@
|
|
|
30
30
|
},
|
|
31
31
|
"license": "MIT",
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@verdaccio/core": "6.0.0-6-next.
|
|
34
|
-
"@verdaccio/config": "6.0.0-6-next.
|
|
35
|
-
"@verdaccio/loaders": "6.0.0-6-next.
|
|
36
|
-
"@verdaccio/logger": "6.0.0-6-next.
|
|
37
|
-
"@verdaccio/utils": "6.0.0-6-next.
|
|
33
|
+
"@verdaccio/core": "6.0.0-6-next.49",
|
|
34
|
+
"@verdaccio/config": "6.0.0-6-next.49",
|
|
35
|
+
"@verdaccio/loaders": "6.0.0-6-next.18",
|
|
36
|
+
"@verdaccio/logger": "6.0.0-6-next.17",
|
|
37
|
+
"@verdaccio/utils": "6.0.0-6-next.17",
|
|
38
38
|
"debug": "4.3.4",
|
|
39
39
|
"express": "4.18.1",
|
|
40
40
|
"jsonwebtoken": "8.5.1",
|
|
41
41
|
"lodash": "4.17.21",
|
|
42
|
-
"verdaccio-htpasswd": "11.0.0-6-next.
|
|
42
|
+
"verdaccio-htpasswd": "11.0.0-6-next.19"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
|
-
"@verdaccio/types": "11.0.0-6-next.
|
|
45
|
+
"@verdaccio/types": "11.0.0-6-next.17"
|
|
46
46
|
},
|
|
47
47
|
"funding": {
|
|
48
48
|
"type": "opencollective",
|
package/src/auth.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import buildDebug from 'debug';
|
|
2
|
-
import { NextFunction, Request, Response } from 'express';
|
|
2
|
+
import { NextFunction, Request, RequestHandler, Response } from 'express';
|
|
3
3
|
import _ from 'lodash';
|
|
4
|
-
import { HTPasswd
|
|
4
|
+
import { HTPasswd } from 'verdaccio-htpasswd';
|
|
5
5
|
|
|
6
6
|
import { createAnonymousRemoteUser, createRemoteUser } from '@verdaccio/config';
|
|
7
7
|
import {
|
|
@@ -11,18 +11,17 @@ import {
|
|
|
11
11
|
TOKEN_BEARER,
|
|
12
12
|
VerdaccioError,
|
|
13
13
|
errorUtils,
|
|
14
|
+
pluginUtils,
|
|
14
15
|
} from '@verdaccio/core';
|
|
15
|
-
import {
|
|
16
|
+
import { asyncLoadPlugin } from '@verdaccio/loaders';
|
|
17
|
+
import { logger } from '@verdaccio/logger';
|
|
16
18
|
import {
|
|
17
19
|
AllowAccess,
|
|
18
|
-
AuthPluginPackage,
|
|
19
20
|
Callback,
|
|
20
21
|
Config,
|
|
21
|
-
IPluginAuth,
|
|
22
22
|
JWTSignOptions,
|
|
23
23
|
Logger,
|
|
24
24
|
PackageAccess,
|
|
25
|
-
PluginOptions,
|
|
26
25
|
RemoteUser,
|
|
27
26
|
Security,
|
|
28
27
|
} from '@verdaccio/types';
|
|
@@ -41,20 +40,8 @@ import {
|
|
|
41
40
|
verifyJWTPayload,
|
|
42
41
|
} from './utils';
|
|
43
42
|
|
|
44
|
-
/* eslint-disable @typescript-eslint/no-var-requires */
|
|
45
|
-
const LoggerApi = require('@verdaccio/logger');
|
|
46
|
-
|
|
47
43
|
const debug = buildDebug('verdaccio:auth');
|
|
48
44
|
|
|
49
|
-
export interface IBasicAuth<T> {
|
|
50
|
-
config: T & Config;
|
|
51
|
-
authenticate(user: string, password: string, cb: Callback): void;
|
|
52
|
-
invalidateToken?(token: string): Promise<void>;
|
|
53
|
-
changePassword(user: string, password: string, newPassword: string, cb: Callback): void;
|
|
54
|
-
allow_access(pkg: AuthPluginPackage, user: RemoteUser, callback: Callback): void;
|
|
55
|
-
add_user(user: string, password: string, cb: Callback): any;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
45
|
export interface TokenEncryption {
|
|
59
46
|
jwtEncrypt(user: RemoteUser, signOptions: JWTSignOptions): Promise<string>;
|
|
60
47
|
aesEncrypt(buf: string): string | void;
|
|
@@ -64,84 +51,84 @@ export interface AESPayload {
|
|
|
64
51
|
user: string;
|
|
65
52
|
password: string;
|
|
66
53
|
}
|
|
67
|
-
|
|
68
|
-
export type $RequestExtend = Request & { remote_user?: any; log: Logger };
|
|
69
|
-
export type $ResponseExtend = Response & { cookies?: any };
|
|
70
|
-
export type $NextFunctionVer = NextFunction & any;
|
|
71
|
-
|
|
72
54
|
export interface IAuthMiddleware {
|
|
73
55
|
apiJWTmiddleware(): $NextFunctionVer;
|
|
74
56
|
webUIJWTmiddleware(): $NextFunctionVer;
|
|
75
57
|
}
|
|
76
58
|
|
|
77
|
-
export
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
secret: string;
|
|
81
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
82
|
-
plugins: any[];
|
|
83
|
-
allow_unpublish(pkg: AuthPluginPackage, user: RemoteUser, callback: Callback): void;
|
|
84
|
-
invalidateToken(token: string): Promise<void>;
|
|
85
|
-
}
|
|
59
|
+
export type $RequestExtend = Request & { remote_user?: any; log: Logger };
|
|
60
|
+
export type $ResponseExtend = Response & { cookies?: any };
|
|
61
|
+
export type $NextFunctionVer = NextFunction & any;
|
|
86
62
|
|
|
87
|
-
class Auth implements
|
|
63
|
+
class Auth implements IAuthMiddleware, TokenEncryption, pluginUtils.IBasicAuth {
|
|
88
64
|
public config: Config;
|
|
89
|
-
public logger: Logger;
|
|
90
65
|
public secret: string;
|
|
91
|
-
public plugins:
|
|
66
|
+
public plugins: pluginUtils.Auth<Config>[];
|
|
92
67
|
|
|
93
68
|
public constructor(config: Config) {
|
|
94
69
|
this.config = config;
|
|
95
|
-
this.logger = LoggerApi.logger.child({ sub: 'auth' });
|
|
96
70
|
this.secret = config.secret;
|
|
71
|
+
this.plugins = [];
|
|
97
72
|
if (!this.secret) {
|
|
98
73
|
throw new TypeError('secret it is required value on initialize the auth class');
|
|
99
74
|
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
public async init() {
|
|
78
|
+
let plugins = (await this.loadPlugin()) as pluginUtils.Auth<unknown>[];
|
|
79
|
+
debug('auth plugins found %s', plugins.length);
|
|
80
|
+
if (!plugins || plugins.length === 0) {
|
|
81
|
+
plugins = this.loadDefaultPlugin();
|
|
82
|
+
}
|
|
83
|
+
this.plugins = plugins;
|
|
100
84
|
|
|
101
|
-
this.plugins =
|
|
102
|
-
_.isNil(config?.auth) === false ? this._loadPlugin(config) : this.loadDefaultPlugin(config);
|
|
103
85
|
this._applyDefaultPlugins();
|
|
104
86
|
}
|
|
105
87
|
|
|
106
|
-
private loadDefaultPlugin(
|
|
107
|
-
|
|
108
|
-
const pluginOptions: PluginOptions
|
|
109
|
-
config,
|
|
110
|
-
logger
|
|
88
|
+
private loadDefaultPlugin() {
|
|
89
|
+
debug('load default auth plugin');
|
|
90
|
+
const pluginOptions: pluginUtils.PluginOptions = {
|
|
91
|
+
config: this.config,
|
|
92
|
+
logger,
|
|
111
93
|
};
|
|
112
94
|
let authPlugin;
|
|
113
95
|
try {
|
|
114
|
-
authPlugin = new HTPasswd(
|
|
96
|
+
authPlugin = new HTPasswd(
|
|
97
|
+
{ file: './htpasswd' },
|
|
98
|
+
pluginOptions as any as pluginUtils.PluginOptions
|
|
99
|
+
);
|
|
115
100
|
} catch (error: any) {
|
|
116
101
|
debug('error on loading auth htpasswd plugin stack: %o', error);
|
|
102
|
+
logger.info({}, 'no auth plugin has been found');
|
|
117
103
|
return [];
|
|
118
104
|
}
|
|
119
105
|
|
|
120
106
|
return [authPlugin];
|
|
121
107
|
}
|
|
122
108
|
|
|
123
|
-
private
|
|
124
|
-
|
|
125
|
-
config,
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
config.auth,
|
|
132
|
-
pluginOptions,
|
|
133
|
-
(plugin: IPluginAuth<Config>): boolean => {
|
|
109
|
+
private async loadPlugin() {
|
|
110
|
+
return asyncLoadPlugin<pluginUtils.Auth<unknown>>(
|
|
111
|
+
this.config.auth,
|
|
112
|
+
{
|
|
113
|
+
config: this.config,
|
|
114
|
+
logger,
|
|
115
|
+
},
|
|
116
|
+
(plugin): boolean => {
|
|
134
117
|
const { authenticate, allow_access, allow_publish } = plugin;
|
|
135
118
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
119
|
+
return (
|
|
120
|
+
typeof authenticate !== 'undefined' ||
|
|
121
|
+
typeof allow_access !== 'undefined' ||
|
|
122
|
+
typeof allow_publish !== 'undefined'
|
|
123
|
+
);
|
|
124
|
+
},
|
|
125
|
+
this.config?.serverSettings?.pluginPrefix
|
|
139
126
|
);
|
|
140
127
|
}
|
|
141
128
|
|
|
142
129
|
private _applyDefaultPlugins(): void {
|
|
143
130
|
// TODO: rename to applyFallbackPluginMethods
|
|
144
|
-
this.plugins.push(getDefaultPlugins(
|
|
131
|
+
this.plugins.push(getDefaultPlugins(logger));
|
|
145
132
|
}
|
|
146
133
|
|
|
147
134
|
public changePassword(
|
|
@@ -164,7 +151,7 @@ class Auth implements IAuth {
|
|
|
164
151
|
debug('updating password for %o', username);
|
|
165
152
|
plugin.changePassword!(username, password, newPassword, (err, profile): void => {
|
|
166
153
|
if (err) {
|
|
167
|
-
|
|
154
|
+
logger.error(
|
|
168
155
|
{ username, err },
|
|
169
156
|
`An error has been produced
|
|
170
157
|
updating the password for @{username}. Error: @{err.message}`
|
|
@@ -185,17 +172,21 @@ class Auth implements IAuth {
|
|
|
185
172
|
return Promise.resolve();
|
|
186
173
|
}
|
|
187
174
|
|
|
188
|
-
public authenticate(
|
|
175
|
+
public authenticate(
|
|
176
|
+
username: string,
|
|
177
|
+
password: string,
|
|
178
|
+
cb: (error: VerdaccioError | null, user?: RemoteUser) => void
|
|
179
|
+
): void {
|
|
189
180
|
const plugins = this.plugins.slice(0);
|
|
190
181
|
(function next(): void {
|
|
191
|
-
const plugin = plugins.shift() as
|
|
182
|
+
const plugin = plugins.shift() as pluginUtils.Auth<Config>;
|
|
192
183
|
|
|
193
184
|
if (isFunction(plugin.authenticate) === false) {
|
|
194
185
|
return next();
|
|
195
186
|
}
|
|
196
187
|
|
|
197
188
|
debug('authenticating %o', username);
|
|
198
|
-
plugin.authenticate(username, password, function (err, groups): void {
|
|
189
|
+
plugin.authenticate(username, password, function (err: VerdaccioError | null, groups): void {
|
|
199
190
|
if (err) {
|
|
200
191
|
debug('authenticating for user %o failed. Error: %o', username, err?.message);
|
|
201
192
|
return cb(err);
|
|
@@ -226,37 +217,42 @@ class Auth implements IAuth {
|
|
|
226
217
|
})();
|
|
227
218
|
}
|
|
228
219
|
|
|
229
|
-
public add_user(
|
|
220
|
+
public add_user(
|
|
221
|
+
user: string,
|
|
222
|
+
password: string,
|
|
223
|
+
cb: (error: VerdaccioError | null, user?: RemoteUser) => void
|
|
224
|
+
): void {
|
|
230
225
|
const self = this;
|
|
231
226
|
const plugins = this.plugins.slice(0);
|
|
232
227
|
debug('add user %o', user);
|
|
233
228
|
|
|
234
229
|
(function next(): void {
|
|
235
|
-
const plugin = plugins.shift() as
|
|
236
|
-
|
|
237
|
-
if (isFunction(plugin[method]) === false) {
|
|
238
|
-
method = 'add_user';
|
|
239
|
-
self.logger.warn(
|
|
240
|
-
'the plugin method add_user in the auth plugin is deprecated and will' +
|
|
241
|
-
' be removed in next major release, notify to the plugin author'
|
|
242
|
-
);
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
if (isFunction(plugin[method]) === false) {
|
|
230
|
+
const plugin = plugins.shift() as pluginUtils.Auth<Config>;
|
|
231
|
+
if (typeof plugin.adduser !== 'function') {
|
|
246
232
|
next();
|
|
247
233
|
} else {
|
|
248
|
-
//
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
234
|
+
// @ts-expect-error future major (7.x) should remove this section
|
|
235
|
+
if (typeof plugin.adduser === 'undefined' && typeof plugin.add_user === 'function') {
|
|
236
|
+
throw errorUtils.getInternalError(
|
|
237
|
+
'add_user method not longer supported, rename to adduser'
|
|
238
|
+
);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
plugin.adduser(
|
|
242
|
+
user,
|
|
243
|
+
password,
|
|
244
|
+
function (err: VerdaccioError | null, ok?: boolean | string): void {
|
|
245
|
+
if (err) {
|
|
246
|
+
debug('the user %o could not being added. Error: %o', user, err?.message);
|
|
247
|
+
return cb(err);
|
|
248
|
+
}
|
|
249
|
+
if (ok) {
|
|
250
|
+
debug('the user %o has been added', user);
|
|
251
|
+
return self.authenticate(user, password, cb);
|
|
252
|
+
}
|
|
253
|
+
next();
|
|
257
254
|
}
|
|
258
|
-
|
|
259
|
-
});
|
|
255
|
+
);
|
|
260
256
|
}
|
|
261
257
|
})();
|
|
262
258
|
}
|
|
@@ -265,27 +261,27 @@ class Auth implements IAuth {
|
|
|
265
261
|
* Allow user to access a package.
|
|
266
262
|
*/
|
|
267
263
|
public allow_access(
|
|
268
|
-
{ packageName, packageVersion }: AuthPluginPackage,
|
|
264
|
+
{ packageName, packageVersion }: pluginUtils.AuthPluginPackage,
|
|
269
265
|
user: RemoteUser,
|
|
270
|
-
callback:
|
|
266
|
+
callback: pluginUtils.AccessCallback
|
|
271
267
|
): void {
|
|
272
268
|
const plugins = this.plugins.slice(0);
|
|
273
|
-
const
|
|
269
|
+
const pkgAllowAccess: AllowAccess = { name: packageName, version: packageVersion };
|
|
274
270
|
const pkg = Object.assign(
|
|
275
271
|
{},
|
|
276
|
-
|
|
272
|
+
pkgAllowAccess,
|
|
277
273
|
getMatchedPackagesSpec(packageName, this.config.packages)
|
|
278
274
|
) as AllowAccess & PackageAccess;
|
|
279
275
|
debug('allow access for %o', packageName);
|
|
280
276
|
|
|
281
277
|
(function next(): void {
|
|
282
|
-
const plugin:
|
|
278
|
+
const plugin: pluginUtils.Auth<unknown> = plugins.shift() as pluginUtils.Auth<unknown>;
|
|
283
279
|
|
|
284
280
|
if (_.isNil(plugin) || isFunction(plugin.allow_access) === false) {
|
|
285
281
|
return next();
|
|
286
282
|
}
|
|
287
283
|
|
|
288
|
-
plugin.allow_access!(user, pkg, function (err, ok
|
|
284
|
+
plugin.allow_access!(user, pkg, function (err: VerdaccioError | null, ok?: boolean): void {
|
|
289
285
|
if (err) {
|
|
290
286
|
debug('forbidden access for %o. Error: %o', packageName, err?.message);
|
|
291
287
|
return callback(err);
|
|
@@ -302,7 +298,7 @@ class Auth implements IAuth {
|
|
|
302
298
|
}
|
|
303
299
|
|
|
304
300
|
public allow_unpublish(
|
|
305
|
-
{ packageName, packageVersion }: AuthPluginPackage,
|
|
301
|
+
{ packageName, packageVersion }: pluginUtils.AuthPluginPackage,
|
|
306
302
|
user: RemoteUser,
|
|
307
303
|
callback: Callback
|
|
308
304
|
): void {
|
|
@@ -347,7 +343,7 @@ class Auth implements IAuth {
|
|
|
347
343
|
* Allow user to publish a package.
|
|
348
344
|
*/
|
|
349
345
|
public allow_publish(
|
|
350
|
-
{ packageName, packageVersion }: AuthPluginPackage,
|
|
346
|
+
{ packageName, packageVersion }: pluginUtils.AuthPluginPackage,
|
|
351
347
|
user: RemoteUser,
|
|
352
348
|
callback: Callback
|
|
353
349
|
): void {
|
|
@@ -355,42 +351,35 @@ class Auth implements IAuth {
|
|
|
355
351
|
const pkg = Object.assign(
|
|
356
352
|
{ name: packageName, version: packageVersion },
|
|
357
353
|
getMatchedPackagesSpec(packageName, this.config.packages)
|
|
358
|
-
);
|
|
354
|
+
) as any;
|
|
359
355
|
debug('allow publish for %o init | plugins: %o', packageName, plugins.length);
|
|
360
356
|
|
|
361
357
|
(function next(): void {
|
|
362
358
|
const plugin = plugins.shift();
|
|
363
359
|
|
|
364
|
-
if (
|
|
360
|
+
if (typeof plugin?.allow_publish !== 'function') {
|
|
365
361
|
debug('allow publish for %o plugin does not implement allow_publish', packageName);
|
|
366
362
|
return next();
|
|
367
363
|
}
|
|
368
364
|
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
// @ts-ignore
|
|
375
|
-
(err: VerdaccioError, ok: boolean): void => {
|
|
376
|
-
if (_.isNil(err) === false && _.isError(err)) {
|
|
377
|
-
debug('forbidden publish for %o', packageName);
|
|
378
|
-
return callback(err);
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
if (ok) {
|
|
382
|
-
debug('allowed publish for %o', packageName);
|
|
383
|
-
return callback(null, ok);
|
|
384
|
-
}
|
|
365
|
+
plugin.allow_publish(user, pkg, (err: VerdaccioError | null, ok?: boolean): void => {
|
|
366
|
+
if (_.isNil(err) === false && _.isError(err)) {
|
|
367
|
+
debug('forbidden publish for %o', packageName);
|
|
368
|
+
return callback(err);
|
|
369
|
+
}
|
|
385
370
|
|
|
386
|
-
|
|
387
|
-
|
|
371
|
+
if (ok) {
|
|
372
|
+
debug('allowed publish for %o', packageName);
|
|
373
|
+
return callback(null, ok);
|
|
388
374
|
}
|
|
389
|
-
|
|
375
|
+
|
|
376
|
+
debug('allow publish skip validation for %o', packageName);
|
|
377
|
+
next(); // cb(null, false) causes next plugin to roll
|
|
378
|
+
});
|
|
390
379
|
})();
|
|
391
380
|
}
|
|
392
381
|
|
|
393
|
-
public apiJWTmiddleware():
|
|
382
|
+
public apiJWTmiddleware(): RequestHandler {
|
|
394
383
|
debug('jwt middleware');
|
|
395
384
|
const plugins = this.plugins.slice(0);
|
|
396
385
|
const helpers = { createAnonymousRemoteUser, createRemoteUser };
|
|
@@ -400,10 +389,11 @@ class Auth implements IAuth {
|
|
|
400
389
|
}
|
|
401
390
|
}
|
|
402
391
|
|
|
403
|
-
|
|
392
|
+
// @ts-ignore
|
|
393
|
+
return (req: $RequestExtend, res: $ResponseExtend, _next: NextFunction) => {
|
|
404
394
|
req.pause();
|
|
405
395
|
|
|
406
|
-
const next = function (err
|
|
396
|
+
const next = function (err?: VerdaccioError): any {
|
|
407
397
|
req.resume();
|
|
408
398
|
// uncomment this to reject users with bad auth headers
|
|
409
399
|
// return _next.apply(null, arguments)
|
|
@@ -412,6 +402,7 @@ class Auth implements IAuth {
|
|
|
412
402
|
if (err) {
|
|
413
403
|
req.remote_user.error = err.message;
|
|
414
404
|
}
|
|
405
|
+
|
|
415
406
|
return _next();
|
|
416
407
|
};
|
|
417
408
|
|
|
@@ -462,7 +453,7 @@ class Auth implements IAuth {
|
|
|
462
453
|
const credentials = convertPayloadToBase64(token).toString();
|
|
463
454
|
const { user, password } = parseBasicPayload(credentials) as AESPayload;
|
|
464
455
|
debug('authenticating %o', user);
|
|
465
|
-
this.authenticate(user, password, (err, user): void => {
|
|
456
|
+
this.authenticate(user, password, (err: VerdaccioError | null, user): void => {
|
|
466
457
|
if (!err) {
|
|
467
458
|
debug('generating a remote user');
|
|
468
459
|
req.remote_user = user;
|
|
@@ -522,14 +513,15 @@ class Auth implements IAuth {
|
|
|
522
513
|
}
|
|
523
514
|
}
|
|
524
515
|
|
|
525
|
-
private _isRemoteUserValid(remote_user
|
|
526
|
-
return _.isUndefined(remote_user) === false && _.isUndefined(remote_user
|
|
516
|
+
private _isRemoteUserValid(remote_user?: RemoteUser): boolean {
|
|
517
|
+
return _.isUndefined(remote_user) === false && _.isUndefined(remote_user?.name) === false;
|
|
527
518
|
}
|
|
528
519
|
|
|
529
520
|
/**
|
|
530
521
|
* JWT middleware for WebUI
|
|
531
522
|
*/
|
|
532
|
-
public webUIJWTmiddleware():
|
|
523
|
+
public webUIJWTmiddleware(): RequestHandler {
|
|
524
|
+
// @ts-ignore
|
|
533
525
|
return (req: $RequestExtend, res: $ResponseExtend, _next: NextFunction): void => {
|
|
534
526
|
if (this._isRemoteUserValid(req.remote_user)) {
|
|
535
527
|
return _next();
|
|
@@ -560,7 +552,7 @@ class Auth implements IAuth {
|
|
|
560
552
|
return next();
|
|
561
553
|
}
|
|
562
554
|
|
|
563
|
-
let credentials;
|
|
555
|
+
let credentials: RemoteUser | undefined;
|
|
564
556
|
try {
|
|
565
557
|
credentials = verifyJWTPayload(token, this.config.secret);
|
|
566
558
|
} catch (err: any) {
|
|
@@ -568,9 +560,8 @@ class Auth implements IAuth {
|
|
|
568
560
|
}
|
|
569
561
|
|
|
570
562
|
if (this._isRemoteUserValid(credentials)) {
|
|
571
|
-
const { name, groups } = credentials;
|
|
572
|
-
|
|
573
|
-
req.remote_user = createRemoteUser(name, groups);
|
|
563
|
+
const { name, groups } = credentials as RemoteUser;
|
|
564
|
+
req.remote_user = createRemoteUser(name as string, groups);
|
|
574
565
|
} else {
|
|
575
566
|
req.remote_user = createAnonymousRemoteUser();
|
|
576
567
|
}
|
package/src/index.ts
CHANGED
package/src/utils.ts
CHANGED
|
@@ -9,15 +9,9 @@ import {
|
|
|
9
9
|
TOKEN_BEARER,
|
|
10
10
|
VerdaccioError,
|
|
11
11
|
errorUtils,
|
|
12
|
+
pluginUtils,
|
|
12
13
|
} from '@verdaccio/core';
|
|
13
|
-
import {
|
|
14
|
-
AuthPackageAllow,
|
|
15
|
-
Callback,
|
|
16
|
-
Config,
|
|
17
|
-
IPluginAuth,
|
|
18
|
-
RemoteUser,
|
|
19
|
-
Security,
|
|
20
|
-
} from '@verdaccio/types';
|
|
14
|
+
import { AuthPackageAllow, Config, Logger, RemoteUser, Security } from '@verdaccio/types';
|
|
21
15
|
|
|
22
16
|
import { AESPayload, TokenEncryption } from './auth';
|
|
23
17
|
import { verifyPayload } from './jwt-token';
|
|
@@ -161,13 +155,18 @@ export function isAuthHeaderValid(authorization: string): boolean {
|
|
|
161
155
|
return authorization.split(' ').length === 2;
|
|
162
156
|
}
|
|
163
157
|
|
|
164
|
-
|
|
158
|
+
/**
|
|
159
|
+
* Return a default configuration for authentication if none is provided.
|
|
160
|
+
* @param logger {Logger}
|
|
161
|
+
* @returns object of default implementations.
|
|
162
|
+
*/
|
|
163
|
+
export function getDefaultPlugins(logger: Logger): pluginUtils.Auth<Config> {
|
|
165
164
|
return {
|
|
166
|
-
authenticate(
|
|
165
|
+
authenticate(_user: string, _password: string, cb: pluginUtils.AuthCallback): void {
|
|
167
166
|
cb(errorUtils.getForbidden(API_ERROR.BAD_USERNAME_PASSWORD));
|
|
168
167
|
},
|
|
169
168
|
|
|
170
|
-
adduser(
|
|
169
|
+
adduser(_user: string, _password: string, cb: pluginUtils.AuthUserCallback): void {
|
|
171
170
|
return cb(errorUtils.getConflict(API_ERROR.BAD_USERNAME_PASSWORD));
|
|
172
171
|
},
|
|
173
172
|
|
|
@@ -182,7 +181,7 @@ export function getDefaultPlugins(logger: any): IPluginAuth<Config> {
|
|
|
182
181
|
|
|
183
182
|
export type ActionsAllowed = 'publish' | 'unpublish' | 'access';
|
|
184
183
|
|
|
185
|
-
export function allow_action(action: ActionsAllowed, logger): AllowAction {
|
|
184
|
+
export function allow_action(action: ActionsAllowed, logger: Logger): AllowAction {
|
|
186
185
|
return function allowActionCallback(
|
|
187
186
|
user: RemoteUser,
|
|
188
187
|
pkg: AuthPackageAllow,
|
|
@@ -217,7 +216,7 @@ export function allow_action(action: ActionsAllowed, logger): AllowAction {
|
|
|
217
216
|
/**
|
|
218
217
|
*
|
|
219
218
|
*/
|
|
220
|
-
export function handleSpecialUnpublish(logger): any {
|
|
219
|
+
export function handleSpecialUnpublish(logger: Logger): any {
|
|
221
220
|
return function (user: RemoteUser, pkg: AuthPackageAllow, callback: AllowActionCallback): void {
|
|
222
221
|
const action = 'unpublish';
|
|
223
222
|
// verify whether the unpublish prop has been defined
|