@verdaccio/web 9.0.0-next-9.13 → 9.0.0-next-9.14

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/build/api/user.js CHANGED
@@ -18,12 +18,13 @@ function addUserAuthApi(auth, config, storage) {
18
18
  if (err) {
19
19
  const errorCode = err.message ? _verdaccio_core.HTTP_STATUS.UNAUTHORIZED : _verdaccio_core.HTTP_STATUS.INTERNAL_ERROR;
20
20
  debug$1("error authenticate %o", errorCode);
21
- next(_verdaccio_core.errorUtils.getCode(errorCode, err.message));
21
+ if (errorCode === _verdaccio_core.HTTP_STATUS.UNAUTHORIZED) res.set(_verdaccio_core.HEADERS.WWW_AUTH, _verdaccio_core.TOKEN_BEARER);
22
+ return next(_verdaccio_core.errorUtils.getCode(errorCode, err.message));
22
23
  } else {
23
24
  req.remote_user = user;
24
25
  const jWTSignOptions = config.security.web.sign;
25
26
  res.set(_verdaccio_core.HEADERS.CACHE_CONTROL, _verdaccio_core.HEADERS.NO_CACHE);
26
- next({
27
+ return next({
27
28
  token: await auth.jwtEncrypt(user, jWTSignOptions),
28
29
  username: req.remote_user.name
29
30
  });
@@ -1 +1 @@
1
- {"version":3,"file":"user.js","names":[],"sources":["../../src/api/user.ts"],"sourcesContent":["import buildDebug from 'debug';\nimport type { Request, Response } from 'express';\nimport { Router } from 'express';\nimport { isNil } from 'lodash-es';\n\nimport { type Auth, getApiToken } from '@verdaccio/auth';\nimport type { VerdaccioError } from '@verdaccio/core';\nimport {\n API_ERROR,\n APP_ERROR,\n HEADERS,\n HTTP_STATUS,\n cryptoUtils,\n errorUtils,\n validationUtils,\n} from '@verdaccio/core';\nimport { WebUrls, rateLimit } from '@verdaccio/middleware';\nimport type { Config, JWTSignOptions, RemoteUser } from '@verdaccio/types';\n\nimport type { $NextFunctionVer } from './package';\n\nconst debug = buildDebug('verdaccio:web:api:user');\n\nconst WEB_LOGIN_SESSION_ID = 'web-login-sessionId';\n\nfunction addUserAuthApi(auth: Auth, config: Config, storage: Storage): Router {\n const route = Router(); /* eslint new-cap: 0 */\n route.post(\n WebUrls.user_login,\n rateLimit(config?.userRateLimit),\n function (req: Request, res: Response, next: $NextFunctionVer): void {\n const { username, password } = req.body;\n debug('authenticate %o', username);\n auth.authenticate(\n username,\n password,\n async (err: VerdaccioError | null, user?: RemoteUser): Promise<void> => {\n if (err) {\n const errorCode = err.message ? HTTP_STATUS.UNAUTHORIZED : HTTP_STATUS.INTERNAL_ERROR;\n debug('error authenticate %o', errorCode);\n next(errorUtils.getCode(errorCode, err.message));\n } else {\n req.remote_user = user as RemoteUser;\n const jWTSignOptions: JWTSignOptions = config.security.web.sign;\n res.set(HEADERS.CACHE_CONTROL, HEADERS.NO_CACHE);\n next({\n token: await auth.jwtEncrypt(user as RemoteUser, jWTSignOptions),\n username: req.remote_user.name,\n });\n }\n }\n );\n }\n );\n\n if (config?.flags?.createUser === true) {\n route.put(\n WebUrls.user_signup,\n rateLimit(config?.userRateLimit),\n function (req: Request, res: Response, next: $NextFunctionVer): void {\n const { name, password, email, sessionId } = req.body;\n debug('login or adduser');\n\n // TOOD: reuse with login.ts file\n if (typeof sessionId !== 'string' || sessionId.length !== 36) {\n debug('sessionId is invalid length: %o', sessionId.length);\n return next(errorUtils.getCode(HTTP_STATUS.BAD_REQUEST, API_ERROR.SESSION_ID_INVALID));\n }\n\n if (!name || !password || !email) {\n return next(errorUtils.getCode(HTTP_STATUS.BAD_REQUEST, API_ERROR.BAD_DATA));\n }\n\n auth.add_user(name, password, async function (err, user): Promise<void> {\n if (err) {\n if (err.status >= HTTP_STATUS.BAD_REQUEST && err.status < HTTP_STATUS.INTERNAL_ERROR) {\n debug('adduser: error on create user');\n // With npm registering is the same as logging in,\n // and npm accepts only an 409 error.\n // So, changing status code here.\n return next(\n errorUtils.getCode(err.status, err.message) || errorUtils.getConflict(err.message)\n );\n }\n return next(err);\n }\n\n const tokens = await storage.readTokens({ user: sessionId });\n debug('tokens found for sessionId %o: %o', sessionId, tokens.length);\n if (tokens && tokens.length === 1 && tokens[0].key === WEB_LOGIN_SESSION_ID) {\n if (tokens[0].token.length === 0) {\n debug('waiting for authentication');\n // Poll again after short delay\n // TODO: make this configurable (default 5 seconds)\n res.status(HTTP_STATUS.ACCEPTED);\n res.set(HEADERS.RETRY_AFTER, '5');\n res.json({});\n return;\n }\n\n // session token can only be used once\n debug('deleting session token');\n await storage.deleteToken(sessionId, tokens[0].key);\n\n // Check if token has expired\n // TODO: make this configurable (default 2 minutes)\n const tokenCreatedDate = new Date(tokens[0].created);\n const minutesAgo = new Date(Date.now() - 2 * 60 * 1000);\n if (tokenCreatedDate < minutesAgo) {\n debug('session token expired');\n return next(errorUtils.getUnauthorized(API_ERROR.SESSION_TOKEN_EXPIRED));\n }\n\n debug('session token is valid, login successful');\n res.status(HTTP_STATUS.OK);\n res.json({ token: tokens[0].token });\n return;\n }\n\n const token =\n name && password\n ? await getApiToken(auth, config, user as RemoteUser, password)\n : undefined;\n if (token) {\n debug('adduser: new token %o', cryptoUtils.mask(token as string, 4));\n return next({ token, username: name });\n }\n return next(errorUtils.getUnauthorized());\n });\n }\n );\n }\n\n if (config?.flags?.changePassword === true) {\n route.put(\n WebUrls.reset_password,\n rateLimit(config?.userRateLimit),\n function (req: Request, res: Response, next: $NextFunctionVer): void {\n if (isNil(req.remote_user.name)) {\n res.status(HTTP_STATUS.UNAUTHORIZED);\n return next({\n // FUTURE: update to a more meaningful message\n message: API_ERROR.MUST_BE_LOGGED,\n });\n }\n\n const { password } = req.body;\n const { name } = req.remote_user;\n\n if (\n validationUtils.validatePassword(\n password.new,\n config?.server?.passwordValidationRegex\n ) === false\n ) {\n return next(errorUtils.getCode(HTTP_STATUS.BAD_REQUEST, APP_ERROR.PASSWORD_VALIDATION));\n }\n\n auth.changePassword(name as string, password.old, password.new, (err, isUpdated): void => {\n if (isNil(err) && isUpdated) {\n next({\n ok: true,\n });\n } else {\n return next(errorUtils.getInternalError(API_ERROR.INTERNAL_SERVER_ERROR));\n }\n });\n }\n );\n }\n\n return route;\n}\n\nexport default addUserAuthApi;\n"],"mappings":"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"}
1
+ {"version":3,"file":"user.js","names":[],"sources":["../../src/api/user.ts"],"sourcesContent":["import buildDebug from 'debug';\nimport type { Request, Response } from 'express';\nimport { Router } from 'express';\nimport { isNil } from 'lodash-es';\n\nimport { type Auth, getApiToken } from '@verdaccio/auth';\nimport type { VerdaccioError } from '@verdaccio/core';\nimport {\n API_ERROR,\n APP_ERROR,\n HEADERS,\n HTTP_STATUS,\n TOKEN_BEARER,\n cryptoUtils,\n errorUtils,\n validationUtils,\n} from '@verdaccio/core';\nimport { WebUrls, rateLimit } from '@verdaccio/middleware';\nimport type { Config, JWTSignOptions, RemoteUser } from '@verdaccio/types';\n\nimport type { $NextFunctionVer } from './package';\n\nconst debug = buildDebug('verdaccio:web:api:user');\n\nconst WEB_LOGIN_SESSION_ID = 'web-login-sessionId';\n\nfunction addUserAuthApi(auth: Auth, config: Config, storage: Storage): Router {\n const route = Router(); /* eslint new-cap: 0 */\n route.post(\n WebUrls.user_login,\n rateLimit(config?.userRateLimit),\n function (req: Request, res: Response, next: $NextFunctionVer): void {\n const { username, password } = req.body;\n debug('authenticate %o', username);\n auth.authenticate(\n username,\n password,\n async (err: VerdaccioError | null, user?: RemoteUser): Promise<void> => {\n if (err) {\n const errorCode = err.message ? HTTP_STATUS.UNAUTHORIZED : HTTP_STATUS.INTERNAL_ERROR;\n debug('error authenticate %o', errorCode);\n // Prevent the final middleware from adding WWW-Authenticate header,\n // which triggers the browser's native basic auth popup instead of\n // letting the WebUI handle the error in JavaScript.\n if (errorCode === HTTP_STATUS.UNAUTHORIZED) {\n res.set(HEADERS.WWW_AUTH, TOKEN_BEARER);\n }\n return next(errorUtils.getCode(errorCode, err.message));\n } else {\n req.remote_user = user as RemoteUser;\n const jWTSignOptions: JWTSignOptions = config.security.web.sign;\n res.set(HEADERS.CACHE_CONTROL, HEADERS.NO_CACHE);\n return next({\n token: await auth.jwtEncrypt(user as RemoteUser, jWTSignOptions),\n username: req.remote_user.name,\n });\n }\n }\n );\n }\n );\n\n if (config?.flags?.createUser === true) {\n route.put(\n WebUrls.user_signup,\n rateLimit(config?.userRateLimit),\n function (req: Request, res: Response, next: $NextFunctionVer): void {\n const { name, password, email, sessionId } = req.body;\n debug('login or adduser');\n\n // TOOD: reuse with login.ts file\n if (typeof sessionId !== 'string' || sessionId.length !== 36) {\n debug('sessionId is invalid length: %o', sessionId.length);\n return next(errorUtils.getCode(HTTP_STATUS.BAD_REQUEST, API_ERROR.SESSION_ID_INVALID));\n }\n\n if (!name || !password || !email) {\n return next(errorUtils.getCode(HTTP_STATUS.BAD_REQUEST, API_ERROR.BAD_DATA));\n }\n\n auth.add_user(name, password, async function (err, user): Promise<void> {\n if (err) {\n if (err.status >= HTTP_STATUS.BAD_REQUEST && err.status < HTTP_STATUS.INTERNAL_ERROR) {\n debug('adduser: error on create user');\n // With npm registering is the same as logging in,\n // and npm accepts only an 409 error.\n // So, changing status code here.\n return next(\n errorUtils.getCode(err.status, err.message) || errorUtils.getConflict(err.message)\n );\n }\n return next(err);\n }\n\n const tokens = await storage.readTokens({ user: sessionId });\n debug('tokens found for sessionId %o: %o', sessionId, tokens.length);\n if (tokens && tokens.length === 1 && tokens[0].key === WEB_LOGIN_SESSION_ID) {\n if (tokens[0].token.length === 0) {\n debug('waiting for authentication');\n // Poll again after short delay\n // TODO: make this configurable (default 5 seconds)\n res.status(HTTP_STATUS.ACCEPTED);\n res.set(HEADERS.RETRY_AFTER, '5');\n res.json({});\n return;\n }\n\n // session token can only be used once\n debug('deleting session token');\n await storage.deleteToken(sessionId, tokens[0].key);\n\n // Check if token has expired\n // TODO: make this configurable (default 2 minutes)\n const tokenCreatedDate = new Date(tokens[0].created);\n const minutesAgo = new Date(Date.now() - 2 * 60 * 1000);\n if (tokenCreatedDate < minutesAgo) {\n debug('session token expired');\n return next(errorUtils.getUnauthorized(API_ERROR.SESSION_TOKEN_EXPIRED));\n }\n\n debug('session token is valid, login successful');\n res.status(HTTP_STATUS.OK);\n res.json({ token: tokens[0].token });\n return;\n }\n\n const token =\n name && password\n ? await getApiToken(auth, config, user as RemoteUser, password)\n : undefined;\n if (token) {\n debug('adduser: new token %o', cryptoUtils.mask(token as string, 4));\n return next({ token, username: name });\n }\n return next(errorUtils.getUnauthorized());\n });\n }\n );\n }\n\n if (config?.flags?.changePassword === true) {\n route.put(\n WebUrls.reset_password,\n rateLimit(config?.userRateLimit),\n function (req: Request, res: Response, next: $NextFunctionVer): void {\n if (isNil(req.remote_user.name)) {\n res.status(HTTP_STATUS.UNAUTHORIZED);\n return next({\n // FUTURE: update to a more meaningful message\n message: API_ERROR.MUST_BE_LOGGED,\n });\n }\n\n const { password } = req.body;\n const { name } = req.remote_user;\n\n if (\n validationUtils.validatePassword(\n password.new,\n config?.server?.passwordValidationRegex\n ) === false\n ) {\n return next(errorUtils.getCode(HTTP_STATUS.BAD_REQUEST, APP_ERROR.PASSWORD_VALIDATION));\n }\n\n auth.changePassword(name as string, password.old, password.new, (err, isUpdated): void => {\n if (isNil(err) && isUpdated) {\n next({\n ok: true,\n });\n } else {\n return next(errorUtils.getInternalError(API_ERROR.INTERNAL_SERVER_ERROR));\n }\n });\n }\n );\n }\n\n return route;\n}\n\nexport default addUserAuthApi;\n"],"mappings":";;;;;;;;;AAsBA,IAAM,WAAA,GAAA,MAAA,SAAmB,yBAAyB;AAElD,IAAM,uBAAuB;AAE7B,SAAS,eAAe,MAAY,QAAgB,SAA0B;CAC5E,MAAM,SAAA,GAAA,QAAA,SAAgB;AACtB,OAAM,KACJ,sBAAA,QAAQ,aAAA,GAAA,sBAAA,WACE,QAAQ,cAAc,EAChC,SAAU,KAAc,KAAe,MAA8B;EACnE,MAAM,EAAE,UAAU,aAAa,IAAI;AACnC,UAAM,mBAAmB,SAAS;AAClC,OAAK,aACH,UACA,UACA,OAAO,KAA4B,SAAqC;AACtE,OAAI,KAAK;IACP,MAAM,YAAY,IAAI,UAAU,gBAAA,YAAY,eAAe,gBAAA,YAAY;AACvE,YAAM,yBAAyB,UAAU;AAIzC,QAAI,cAAc,gBAAA,YAAY,aAC5B,KAAI,IAAI,gBAAA,QAAQ,UAAU,gBAAA,aAAa;AAEzC,WAAO,KAAK,gBAAA,WAAW,QAAQ,WAAW,IAAI,QAAQ,CAAC;UAClD;AACL,QAAI,cAAc;IAClB,MAAM,iBAAiC,OAAO,SAAS,IAAI;AAC3D,QAAI,IAAI,gBAAA,QAAQ,eAAe,gBAAA,QAAQ,SAAS;AAChD,WAAO,KAAK;KACV,OAAO,MAAM,KAAK,WAAW,MAAoB,eAAe;KAChE,UAAU,IAAI,YAAY;KAC3B,CAAC;;IAGP;GAEJ;AAED,KAAI,QAAQ,OAAO,eAAe,KAChC,OAAM,IACJ,sBAAA,QAAQ,cAAA,GAAA,sBAAA,WACE,QAAQ,cAAc,EAChC,SAAU,KAAc,KAAe,MAA8B;EACnE,MAAM,EAAE,MAAM,UAAU,OAAO,cAAc,IAAI;AACjD,UAAM,mBAAmB;AAGzB,MAAI,OAAO,cAAc,YAAY,UAAU,WAAW,IAAI;AAC5D,WAAM,mCAAmC,UAAU,OAAO;AAC1D,UAAO,KAAK,gBAAA,WAAW,QAAQ,gBAAA,YAAY,aAAa,gBAAA,UAAU,mBAAmB,CAAC;;AAGxF,MAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,MACzB,QAAO,KAAK,gBAAA,WAAW,QAAQ,gBAAA,YAAY,aAAa,gBAAA,UAAU,SAAS,CAAC;AAG9E,OAAK,SAAS,MAAM,UAAU,eAAgB,KAAK,MAAqB;AACtE,OAAI,KAAK;AACP,QAAI,IAAI,UAAU,gBAAA,YAAY,eAAe,IAAI,SAAS,gBAAA,YAAY,gBAAgB;AACpF,aAAM,gCAAgC;AAItC,YAAO,KACL,gBAAA,WAAW,QAAQ,IAAI,QAAQ,IAAI,QAAQ,IAAI,gBAAA,WAAW,YAAY,IAAI,QAAQ,CACnF;;AAEH,WAAO,KAAK,IAAI;;GAGlB,MAAM,SAAS,MAAM,QAAQ,WAAW,EAAE,MAAM,WAAW,CAAC;AAC5D,WAAM,qCAAqC,WAAW,OAAO,OAAO;AACpE,OAAI,UAAU,OAAO,WAAW,KAAK,OAAO,GAAG,QAAQ,sBAAsB;AAC3E,QAAI,OAAO,GAAG,MAAM,WAAW,GAAG;AAChC,aAAM,6BAA6B;AAGnC,SAAI,OAAO,gBAAA,YAAY,SAAS;AAChC,SAAI,IAAI,gBAAA,QAAQ,aAAa,IAAI;AACjC,SAAI,KAAK,EAAE,CAAC;AACZ;;AAIF,YAAM,yBAAyB;AAC/B,UAAM,QAAQ,YAAY,WAAW,OAAO,GAAG,IAAI;AAMnD,QAFyB,IAAI,KAAK,OAAO,GAAG,QAAQ,mBACjC,IAAI,KAAK,KAAK,KAAK,GAAG,MAAS,IAAK,EACpB;AACjC,aAAM,wBAAwB;AAC9B,YAAO,KAAK,gBAAA,WAAW,gBAAgB,gBAAA,UAAU,sBAAsB,CAAC;;AAG1E,YAAM,2CAA2C;AACjD,QAAI,OAAO,gBAAA,YAAY,GAAG;AAC1B,QAAI,KAAK,EAAE,OAAO,OAAO,GAAG,OAAO,CAAC;AACpC;;GAGF,MAAM,QACJ,QAAQ,WACJ,OAAA,GAAA,gBAAA,aAAkB,MAAM,QAAQ,MAAoB,SAAS,GAC7D,KAAA;AACN,OAAI,OAAO;AACT,YAAM,yBAAyB,gBAAA,YAAY,KAAK,OAAiB,EAAE,CAAC;AACpE,WAAO,KAAK;KAAE;KAAO,UAAU;KAAM,CAAC;;AAExC,UAAO,KAAK,gBAAA,WAAW,iBAAiB,CAAC;IACzC;GAEL;AAGH,KAAI,QAAQ,OAAO,mBAAmB,KACpC,OAAM,IACJ,sBAAA,QAAQ,iBAAA,GAAA,sBAAA,WACE,QAAQ,cAAc,EAChC,SAAU,KAAc,KAAe,MAA8B;AACnE,OAAA,GAAA,UAAA,OAAU,IAAI,YAAY,KAAK,EAAE;AAC/B,OAAI,OAAO,gBAAA,YAAY,aAAa;AACpC,UAAO,KAAK,EAEV,SAAS,gBAAA,UAAU,gBACpB,CAAC;;EAGJ,MAAM,EAAE,aAAa,IAAI;EACzB,MAAM,EAAE,SAAS,IAAI;AAErB,MACE,gBAAA,gBAAgB,iBACd,SAAS,KACT,QAAQ,QAAQ,wBACjB,KAAK,MAEN,QAAO,KAAK,gBAAA,WAAW,QAAQ,gBAAA,YAAY,aAAa,gBAAA,UAAU,oBAAoB,CAAC;AAGzF,OAAK,eAAe,MAAgB,SAAS,KAAK,SAAS,MAAM,KAAK,cAAoB;AACxF,QAAA,GAAA,UAAA,OAAU,IAAI,IAAI,UAChB,MAAK,EACH,IAAI,MACL,CAAC;OAEF,QAAO,KAAK,gBAAA,WAAW,iBAAiB,gBAAA,UAAU,sBAAsB,CAAC;IAE3E;GAEL;AAGH,QAAO"}
@@ -1,7 +1,7 @@
1
1
  import buildDebug from "debug";
2
2
  import { Router } from "express";
3
3
  import { isNil } from "lodash-es";
4
- import { API_ERROR, APP_ERROR, HEADERS, HTTP_STATUS, cryptoUtils, errorUtils, validationUtils } from "@verdaccio/core";
4
+ import { API_ERROR, APP_ERROR, HEADERS, HTTP_STATUS, TOKEN_BEARER, cryptoUtils, errorUtils, validationUtils } from "@verdaccio/core";
5
5
  import { WebUrls, rateLimit } from "@verdaccio/middleware";
6
6
  import { getApiToken } from "@verdaccio/auth";
7
7
  //#region src/api/user.ts
@@ -16,12 +16,13 @@ function addUserAuthApi(auth, config, storage) {
16
16
  if (err) {
17
17
  const errorCode = err.message ? HTTP_STATUS.UNAUTHORIZED : HTTP_STATUS.INTERNAL_ERROR;
18
18
  debug("error authenticate %o", errorCode);
19
- next(errorUtils.getCode(errorCode, err.message));
19
+ if (errorCode === HTTP_STATUS.UNAUTHORIZED) res.set(HEADERS.WWW_AUTH, TOKEN_BEARER);
20
+ return next(errorUtils.getCode(errorCode, err.message));
20
21
  } else {
21
22
  req.remote_user = user;
22
23
  const jWTSignOptions = config.security.web.sign;
23
24
  res.set(HEADERS.CACHE_CONTROL, HEADERS.NO_CACHE);
24
- next({
25
+ return next({
25
26
  token: await auth.jwtEncrypt(user, jWTSignOptions),
26
27
  username: req.remote_user.name
27
28
  });
@@ -1 +1 @@
1
- {"version":3,"file":"user.mjs","names":[],"sources":["../../src/api/user.ts"],"sourcesContent":["import buildDebug from 'debug';\nimport type { Request, Response } from 'express';\nimport { Router } from 'express';\nimport { isNil } from 'lodash-es';\n\nimport { type Auth, getApiToken } from '@verdaccio/auth';\nimport type { VerdaccioError } from '@verdaccio/core';\nimport {\n API_ERROR,\n APP_ERROR,\n HEADERS,\n HTTP_STATUS,\n cryptoUtils,\n errorUtils,\n validationUtils,\n} from '@verdaccio/core';\nimport { WebUrls, rateLimit } from '@verdaccio/middleware';\nimport type { Config, JWTSignOptions, RemoteUser } from '@verdaccio/types';\n\nimport type { $NextFunctionVer } from './package';\n\nconst debug = buildDebug('verdaccio:web:api:user');\n\nconst WEB_LOGIN_SESSION_ID = 'web-login-sessionId';\n\nfunction addUserAuthApi(auth: Auth, config: Config, storage: Storage): Router {\n const route = Router(); /* eslint new-cap: 0 */\n route.post(\n WebUrls.user_login,\n rateLimit(config?.userRateLimit),\n function (req: Request, res: Response, next: $NextFunctionVer): void {\n const { username, password } = req.body;\n debug('authenticate %o', username);\n auth.authenticate(\n username,\n password,\n async (err: VerdaccioError | null, user?: RemoteUser): Promise<void> => {\n if (err) {\n const errorCode = err.message ? HTTP_STATUS.UNAUTHORIZED : HTTP_STATUS.INTERNAL_ERROR;\n debug('error authenticate %o', errorCode);\n next(errorUtils.getCode(errorCode, err.message));\n } else {\n req.remote_user = user as RemoteUser;\n const jWTSignOptions: JWTSignOptions = config.security.web.sign;\n res.set(HEADERS.CACHE_CONTROL, HEADERS.NO_CACHE);\n next({\n token: await auth.jwtEncrypt(user as RemoteUser, jWTSignOptions),\n username: req.remote_user.name,\n });\n }\n }\n );\n }\n );\n\n if (config?.flags?.createUser === true) {\n route.put(\n WebUrls.user_signup,\n rateLimit(config?.userRateLimit),\n function (req: Request, res: Response, next: $NextFunctionVer): void {\n const { name, password, email, sessionId } = req.body;\n debug('login or adduser');\n\n // TOOD: reuse with login.ts file\n if (typeof sessionId !== 'string' || sessionId.length !== 36) {\n debug('sessionId is invalid length: %o', sessionId.length);\n return next(errorUtils.getCode(HTTP_STATUS.BAD_REQUEST, API_ERROR.SESSION_ID_INVALID));\n }\n\n if (!name || !password || !email) {\n return next(errorUtils.getCode(HTTP_STATUS.BAD_REQUEST, API_ERROR.BAD_DATA));\n }\n\n auth.add_user(name, password, async function (err, user): Promise<void> {\n if (err) {\n if (err.status >= HTTP_STATUS.BAD_REQUEST && err.status < HTTP_STATUS.INTERNAL_ERROR) {\n debug('adduser: error on create user');\n // With npm registering is the same as logging in,\n // and npm accepts only an 409 error.\n // So, changing status code here.\n return next(\n errorUtils.getCode(err.status, err.message) || errorUtils.getConflict(err.message)\n );\n }\n return next(err);\n }\n\n const tokens = await storage.readTokens({ user: sessionId });\n debug('tokens found for sessionId %o: %o', sessionId, tokens.length);\n if (tokens && tokens.length === 1 && tokens[0].key === WEB_LOGIN_SESSION_ID) {\n if (tokens[0].token.length === 0) {\n debug('waiting for authentication');\n // Poll again after short delay\n // TODO: make this configurable (default 5 seconds)\n res.status(HTTP_STATUS.ACCEPTED);\n res.set(HEADERS.RETRY_AFTER, '5');\n res.json({});\n return;\n }\n\n // session token can only be used once\n debug('deleting session token');\n await storage.deleteToken(sessionId, tokens[0].key);\n\n // Check if token has expired\n // TODO: make this configurable (default 2 minutes)\n const tokenCreatedDate = new Date(tokens[0].created);\n const minutesAgo = new Date(Date.now() - 2 * 60 * 1000);\n if (tokenCreatedDate < minutesAgo) {\n debug('session token expired');\n return next(errorUtils.getUnauthorized(API_ERROR.SESSION_TOKEN_EXPIRED));\n }\n\n debug('session token is valid, login successful');\n res.status(HTTP_STATUS.OK);\n res.json({ token: tokens[0].token });\n return;\n }\n\n const token =\n name && password\n ? await getApiToken(auth, config, user as RemoteUser, password)\n : undefined;\n if (token) {\n debug('adduser: new token %o', cryptoUtils.mask(token as string, 4));\n return next({ token, username: name });\n }\n return next(errorUtils.getUnauthorized());\n });\n }\n );\n }\n\n if (config?.flags?.changePassword === true) {\n route.put(\n WebUrls.reset_password,\n rateLimit(config?.userRateLimit),\n function (req: Request, res: Response, next: $NextFunctionVer): void {\n if (isNil(req.remote_user.name)) {\n res.status(HTTP_STATUS.UNAUTHORIZED);\n return next({\n // FUTURE: update to a more meaningful message\n message: API_ERROR.MUST_BE_LOGGED,\n });\n }\n\n const { password } = req.body;\n const { name } = req.remote_user;\n\n if (\n validationUtils.validatePassword(\n password.new,\n config?.server?.passwordValidationRegex\n ) === false\n ) {\n return next(errorUtils.getCode(HTTP_STATUS.BAD_REQUEST, APP_ERROR.PASSWORD_VALIDATION));\n }\n\n auth.changePassword(name as string, password.old, password.new, (err, isUpdated): void => {\n if (isNil(err) && isUpdated) {\n next({\n ok: true,\n });\n } else {\n return next(errorUtils.getInternalError(API_ERROR.INTERNAL_SERVER_ERROR));\n }\n });\n }\n );\n }\n\n return route;\n}\n\nexport default addUserAuthApi;\n"],"mappings":"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"}
1
+ {"version":3,"file":"user.mjs","names":[],"sources":["../../src/api/user.ts"],"sourcesContent":["import buildDebug from 'debug';\nimport type { Request, Response } from 'express';\nimport { Router } from 'express';\nimport { isNil } from 'lodash-es';\n\nimport { type Auth, getApiToken } from '@verdaccio/auth';\nimport type { VerdaccioError } from '@verdaccio/core';\nimport {\n API_ERROR,\n APP_ERROR,\n HEADERS,\n HTTP_STATUS,\n TOKEN_BEARER,\n cryptoUtils,\n errorUtils,\n validationUtils,\n} from '@verdaccio/core';\nimport { WebUrls, rateLimit } from '@verdaccio/middleware';\nimport type { Config, JWTSignOptions, RemoteUser } from '@verdaccio/types';\n\nimport type { $NextFunctionVer } from './package';\n\nconst debug = buildDebug('verdaccio:web:api:user');\n\nconst WEB_LOGIN_SESSION_ID = 'web-login-sessionId';\n\nfunction addUserAuthApi(auth: Auth, config: Config, storage: Storage): Router {\n const route = Router(); /* eslint new-cap: 0 */\n route.post(\n WebUrls.user_login,\n rateLimit(config?.userRateLimit),\n function (req: Request, res: Response, next: $NextFunctionVer): void {\n const { username, password } = req.body;\n debug('authenticate %o', username);\n auth.authenticate(\n username,\n password,\n async (err: VerdaccioError | null, user?: RemoteUser): Promise<void> => {\n if (err) {\n const errorCode = err.message ? HTTP_STATUS.UNAUTHORIZED : HTTP_STATUS.INTERNAL_ERROR;\n debug('error authenticate %o', errorCode);\n // Prevent the final middleware from adding WWW-Authenticate header,\n // which triggers the browser's native basic auth popup instead of\n // letting the WebUI handle the error in JavaScript.\n if (errorCode === HTTP_STATUS.UNAUTHORIZED) {\n res.set(HEADERS.WWW_AUTH, TOKEN_BEARER);\n }\n return next(errorUtils.getCode(errorCode, err.message));\n } else {\n req.remote_user = user as RemoteUser;\n const jWTSignOptions: JWTSignOptions = config.security.web.sign;\n res.set(HEADERS.CACHE_CONTROL, HEADERS.NO_CACHE);\n return next({\n token: await auth.jwtEncrypt(user as RemoteUser, jWTSignOptions),\n username: req.remote_user.name,\n });\n }\n }\n );\n }\n );\n\n if (config?.flags?.createUser === true) {\n route.put(\n WebUrls.user_signup,\n rateLimit(config?.userRateLimit),\n function (req: Request, res: Response, next: $NextFunctionVer): void {\n const { name, password, email, sessionId } = req.body;\n debug('login or adduser');\n\n // TOOD: reuse with login.ts file\n if (typeof sessionId !== 'string' || sessionId.length !== 36) {\n debug('sessionId is invalid length: %o', sessionId.length);\n return next(errorUtils.getCode(HTTP_STATUS.BAD_REQUEST, API_ERROR.SESSION_ID_INVALID));\n }\n\n if (!name || !password || !email) {\n return next(errorUtils.getCode(HTTP_STATUS.BAD_REQUEST, API_ERROR.BAD_DATA));\n }\n\n auth.add_user(name, password, async function (err, user): Promise<void> {\n if (err) {\n if (err.status >= HTTP_STATUS.BAD_REQUEST && err.status < HTTP_STATUS.INTERNAL_ERROR) {\n debug('adduser: error on create user');\n // With npm registering is the same as logging in,\n // and npm accepts only an 409 error.\n // So, changing status code here.\n return next(\n errorUtils.getCode(err.status, err.message) || errorUtils.getConflict(err.message)\n );\n }\n return next(err);\n }\n\n const tokens = await storage.readTokens({ user: sessionId });\n debug('tokens found for sessionId %o: %o', sessionId, tokens.length);\n if (tokens && tokens.length === 1 && tokens[0].key === WEB_LOGIN_SESSION_ID) {\n if (tokens[0].token.length === 0) {\n debug('waiting for authentication');\n // Poll again after short delay\n // TODO: make this configurable (default 5 seconds)\n res.status(HTTP_STATUS.ACCEPTED);\n res.set(HEADERS.RETRY_AFTER, '5');\n res.json({});\n return;\n }\n\n // session token can only be used once\n debug('deleting session token');\n await storage.deleteToken(sessionId, tokens[0].key);\n\n // Check if token has expired\n // TODO: make this configurable (default 2 minutes)\n const tokenCreatedDate = new Date(tokens[0].created);\n const minutesAgo = new Date(Date.now() - 2 * 60 * 1000);\n if (tokenCreatedDate < minutesAgo) {\n debug('session token expired');\n return next(errorUtils.getUnauthorized(API_ERROR.SESSION_TOKEN_EXPIRED));\n }\n\n debug('session token is valid, login successful');\n res.status(HTTP_STATUS.OK);\n res.json({ token: tokens[0].token });\n return;\n }\n\n const token =\n name && password\n ? await getApiToken(auth, config, user as RemoteUser, password)\n : undefined;\n if (token) {\n debug('adduser: new token %o', cryptoUtils.mask(token as string, 4));\n return next({ token, username: name });\n }\n return next(errorUtils.getUnauthorized());\n });\n }\n );\n }\n\n if (config?.flags?.changePassword === true) {\n route.put(\n WebUrls.reset_password,\n rateLimit(config?.userRateLimit),\n function (req: Request, res: Response, next: $NextFunctionVer): void {\n if (isNil(req.remote_user.name)) {\n res.status(HTTP_STATUS.UNAUTHORIZED);\n return next({\n // FUTURE: update to a more meaningful message\n message: API_ERROR.MUST_BE_LOGGED,\n });\n }\n\n const { password } = req.body;\n const { name } = req.remote_user;\n\n if (\n validationUtils.validatePassword(\n password.new,\n config?.server?.passwordValidationRegex\n ) === false\n ) {\n return next(errorUtils.getCode(HTTP_STATUS.BAD_REQUEST, APP_ERROR.PASSWORD_VALIDATION));\n }\n\n auth.changePassword(name as string, password.old, password.new, (err, isUpdated): void => {\n if (isNil(err) && isUpdated) {\n next({\n ok: true,\n });\n } else {\n return next(errorUtils.getInternalError(API_ERROR.INTERNAL_SERVER_ERROR));\n }\n });\n }\n );\n }\n\n return route;\n}\n\nexport default addUserAuthApi;\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@verdaccio/web",
3
- "version": "9.0.0-next-9.13",
3
+ "version": "9.0.0-next-9.14",
4
4
  "description": "Verdaccio Web Middleware",
5
5
  "main": "./build/index.js",
6
6
  "types": "build/index.d.ts",
@@ -28,22 +28,22 @@
28
28
  },
29
29
  "license": "MIT",
30
30
  "dependencies": {
31
- "@verdaccio/auth": "9.0.0-next-9.13",
32
- "@verdaccio/config": "9.0.0-next-9.13",
33
- "@verdaccio/core": "9.0.0-next-9.13",
34
- "@verdaccio/loaders": "9.0.0-next-9.13",
35
- "@verdaccio/logger": "9.0.0-next-9.13",
36
- "@verdaccio/middleware": "9.0.0-next-9.13",
37
- "@verdaccio/store": "9.0.0-next-9.13",
38
- "@verdaccio/tarball": "14.0.0-next-9.13",
39
- "@verdaccio/ui-theme": "9.0.0-next-9.13",
31
+ "@verdaccio/auth": "9.0.0-next-9.14",
32
+ "@verdaccio/config": "9.0.0-next-9.14",
33
+ "@verdaccio/core": "9.0.0-next-9.14",
34
+ "@verdaccio/loaders": "9.0.0-next-9.14",
35
+ "@verdaccio/logger": "9.0.0-next-9.14",
36
+ "@verdaccio/middleware": "9.0.0-next-9.14",
37
+ "@verdaccio/store": "9.0.0-next-9.14",
38
+ "@verdaccio/tarball": "14.0.0-next-9.14",
39
+ "@verdaccio/ui-theme": "9.0.0-next-9.14",
40
40
  "debug": "4.4.3",
41
41
  "express": "5.2.1",
42
42
  "lodash-es": "4.17.23"
43
43
  },
44
44
  "devDependencies": {
45
- "@verdaccio/api": "9.0.0-next-9.13",
46
- "@verdaccio/test-helper": "5.0.0-next-9.13",
45
+ "@verdaccio/api": "9.0.0-next-9.14",
46
+ "@verdaccio/test-helper": "5.0.0-next-9.14",
47
47
  "@verdaccio/types": "14.0.0-next-9.5",
48
48
  "@types/lodash-es": "4.17.12",
49
49
  "jsdom": "28.1.0",