@verdaccio/api 7.0.0-next-7.7 → 7.0.0-next-7.9

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,31 @@
1
1
  # @verdaccio/api
2
2
 
3
+ ## 7.0.0-next-7.9
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies [c807f0c]
8
+ - @verdaccio/store@7.0.0-next-7.9
9
+ - @verdaccio/core@7.0.0-next-7.9
10
+ - @verdaccio/config@7.0.0-next-7.9
11
+ - @verdaccio/auth@7.0.0-next-7.9
12
+ - @verdaccio/middleware@7.0.0-next-7.9
13
+ - @verdaccio/utils@7.0.0-next-7.9
14
+ - @verdaccio/logger@7.0.0-next-7.9
15
+
16
+ ## 7.0.0-next-7.8
17
+
18
+ ### Patch Changes
19
+
20
+ - 74cd588: fix: bug on change password npm profile
21
+ - @verdaccio/core@7.0.0-next-7.8
22
+ - @verdaccio/config@7.0.0-next-7.8
23
+ - @verdaccio/auth@7.0.0-next-7.8
24
+ - @verdaccio/middleware@7.0.0-next-7.8
25
+ - @verdaccio/store@7.0.0-next-7.8
26
+ - @verdaccio/utils@7.0.0-next-7.8
27
+ - @verdaccio/logger@7.0.0-next-7.8
28
+
3
29
  ## 7.0.0-next-7.7
4
30
 
5
31
  ### Patch Changes
@@ -51,9 +51,12 @@ function _default(route, auth, config) {
51
51
  return next(_core.errorUtils.getCode(_core.HTTP_STATUS.UNAUTHORIZED, _core.API_ERROR.PASSWORD_SHORT));
52
52
  /* eslint new-cap:off */
53
53
  }
54
+ if (_lodash.default.isEmpty(password.old)) {
55
+ return next(_core.errorUtils.getBadRequest('old password is required'));
56
+ }
54
57
  auth.changePassword(name, password.old, password.new, (err, isUpdated) => {
55
58
  if (_lodash.default.isNull(err) === false) {
56
- return next(_core.errorUtils.getCode(err.status, err.message) || _core.errorUtils.getConflict(err.message));
59
+ return next(_core.errorUtils.getForbidden(err.message));
57
60
  }
58
61
  if (isUpdated) {
59
62
  return next(buildProfile(req.remote_user.name));
@@ -1 +1 @@
1
- {"version":3,"file":"profile.js","names":["_lodash","_interopRequireDefault","require","_core","_middleware","obj","__esModule","default","_default","route","auth","config","buildProfile","name","tfa","email","email_verified","created","updated","cidr_whitelist","fullname","get","rateLimit","userRateLimit","req","res","next","_","isNil","remote_user","status","HTTP_STATUS","UNAUTHORIZED","message","API_ERROR","MUST_BE_LOGGED","post","password","body","_config$serverSetting","validatioUtils","validatePassword","new","serverSettings","passwordValidationRegex","errorUtils","getCode","PASSWORD_SHORT","changePassword","old","err","isUpdated","isNull","getConflict","getInternalError","INTERNAL_SERVER_ERROR","SERVICE_UNAVAILABLE","SUPPORT_ERRORS","TFA_DISABLED","INTERNAL_ERROR","APP_ERROR","PROFILE_ERROR"],"sources":["../../src/v1/profile.ts"],"sourcesContent":["import { Response, Router } from 'express';\nimport _ from 'lodash';\n\nimport { Auth } from '@verdaccio/auth';\nimport {\n API_ERROR,\n APP_ERROR,\n HTTP_STATUS,\n SUPPORT_ERRORS,\n errorUtils,\n validatioUtils,\n} from '@verdaccio/core';\nimport { rateLimit } from '@verdaccio/middleware';\nimport { Config } from '@verdaccio/types';\n\nimport { $NextFunctionVer, $RequestExtend } from '../../types/custom';\n\nexport interface Profile {\n tfa: boolean;\n name: string;\n email: string;\n email_verified: boolean;\n created: string;\n updated: string;\n cidr_whitelist: string[] | null;\n fullname: string;\n}\n\nexport default function (route: Router, auth: Auth, config: Config): void {\n function buildProfile(name: string): Profile {\n return {\n tfa: false,\n name,\n email: '',\n email_verified: false,\n created: '',\n updated: '',\n cidr_whitelist: null,\n fullname: '',\n };\n }\n\n route.get(\n '/-/npm/v1/user',\n rateLimit(config?.userRateLimit),\n function (req: $RequestExtend, res: Response, next: $NextFunctionVer): void {\n if (_.isNil(req.remote_user.name) === false) {\n return next(buildProfile(req.remote_user.name));\n }\n\n res.status(HTTP_STATUS.UNAUTHORIZED);\n return next({\n message: API_ERROR.MUST_BE_LOGGED,\n });\n }\n );\n\n route.post(\n '/-/npm/v1/user',\n rateLimit(config?.userRateLimit),\n function (req: $RequestExtend, res: Response, next: $NextFunctionVer): void {\n if (_.isNil(req.remote_user.name)) {\n res.status(HTTP_STATUS.UNAUTHORIZED);\n return next({\n message: API_ERROR.MUST_BE_LOGGED,\n });\n }\n\n const { password, tfa } = req.body;\n const { name } = req.remote_user;\n\n if (_.isNil(password) === false) {\n if (\n validatioUtils.validatePassword(\n password.new,\n config?.serverSettings?.passwordValidationRegex\n ) === false\n ) {\n /* eslint new-cap:off */\n return next(errorUtils.getCode(HTTP_STATUS.UNAUTHORIZED, API_ERROR.PASSWORD_SHORT));\n /* eslint new-cap:off */\n }\n\n auth.changePassword(\n name,\n password.old,\n password.new,\n (err, isUpdated): $NextFunctionVer => {\n if (_.isNull(err) === false) {\n return next(\n errorUtils.getCode(err.status, err.message) || errorUtils.getConflict(err.message)\n );\n }\n\n if (isUpdated) {\n return next(buildProfile(req.remote_user.name));\n }\n return next(errorUtils.getInternalError(API_ERROR.INTERNAL_SERVER_ERROR));\n }\n );\n } else if (_.isNil(tfa) === false) {\n return next(\n errorUtils.getCode(HTTP_STATUS.SERVICE_UNAVAILABLE, SUPPORT_ERRORS.TFA_DISABLED)\n );\n } else {\n return next(errorUtils.getCode(HTTP_STATUS.INTERNAL_ERROR, APP_ERROR.PROFILE_ERROR));\n }\n }\n );\n}\n"],"mappings":";;;;;;AACA,IAAAA,OAAA,GAAAC,sBAAA,CAAAC,OAAA;AAGA,IAAAC,KAAA,GAAAD,OAAA;AAQA,IAAAE,WAAA,GAAAF,OAAA;AAAkD,SAAAD,uBAAAI,GAAA,WAAAA,GAAA,IAAAA,GAAA,CAAAC,UAAA,GAAAD,GAAA,KAAAE,OAAA,EAAAF,GAAA;AAgBnC,SAAAG,SAAUC,KAAa,EAAEC,IAAU,EAAEC,MAAc,EAAQ;EACxE,SAASC,YAAYA,CAACC,IAAY,EAAW;IAC3C,OAAO;MACLC,GAAG,EAAE,KAAK;MACVD,IAAI;MACJE,KAAK,EAAE,EAAE;MACTC,cAAc,EAAE,KAAK;MACrBC,OAAO,EAAE,EAAE;MACXC,OAAO,EAAE,EAAE;MACXC,cAAc,EAAE,IAAI;MACpBC,QAAQ,EAAE;IACZ,CAAC;EACH;EAEAX,KAAK,CAACY,GAAG,CACP,gBAAgB,EAChB,IAAAC,qBAAS,EAACX,MAAM,aAANA,MAAM,uBAANA,MAAM,CAAEY,aAAa,CAAC,EAChC,UAAUC,GAAmB,EAAEC,GAAa,EAAEC,IAAsB,EAAQ;IAC1E,IAAIC,eAAC,CAACC,KAAK,CAACJ,GAAG,CAACK,WAAW,CAAChB,IAAI,CAAC,KAAK,KAAK,EAAE;MAC3C,OAAOa,IAAI,CAACd,YAAY,CAACY,GAAG,CAACK,WAAW,CAAChB,IAAI,CAAC,CAAC;IACjD;IAEAY,GAAG,CAACK,MAAM,CAACC,iBAAW,CAACC,YAAY,CAAC;IACpC,OAAON,IAAI,CAAC;MACVO,OAAO,EAAEC,eAAS,CAACC;IACrB,CAAC,CAAC;EACJ,CACF,CAAC;EAED1B,KAAK,CAAC2B,IAAI,CACR,gBAAgB,EAChB,IAAAd,qBAAS,EAACX,MAAM,aAANA,MAAM,uBAANA,MAAM,CAAEY,aAAa,CAAC,EAChC,UAAUC,GAAmB,EAAEC,GAAa,EAAEC,IAAsB,EAAQ;IAC1E,IAAIC,eAAC,CAACC,KAAK,CAACJ,GAAG,CAACK,WAAW,CAAChB,IAAI,CAAC,EAAE;MACjCY,GAAG,CAACK,MAAM,CAACC,iBAAW,CAACC,YAAY,CAAC;MACpC,OAAON,IAAI,CAAC;QACVO,OAAO,EAAEC,eAAS,CAACC;MACrB,CAAC,CAAC;IACJ;IAEA,MAAM;MAAEE,QAAQ;MAAEvB;IAAI,CAAC,GAAGU,GAAG,CAACc,IAAI;IAClC,MAAM;MAAEzB;IAAK,CAAC,GAAGW,GAAG,CAACK,WAAW;IAEhC,IAAIF,eAAC,CAACC,KAAK,CAACS,QAAQ,CAAC,KAAK,KAAK,EAAE;MAAA,IAAAE,qBAAA;MAC/B,IACEC,oBAAc,CAACC,gBAAgB,CAC7BJ,QAAQ,CAACK,GAAG,EACZ/B,MAAM,aAANA,MAAM,wBAAA4B,qBAAA,GAAN5B,MAAM,CAAEgC,cAAc,cAAAJ,qBAAA,uBAAtBA,qBAAA,CAAwBK,uBAC1B,CAAC,KAAK,KAAK,EACX;QACA;QACA,OAAOlB,IAAI,CAACmB,gBAAU,CAACC,OAAO,CAACf,iBAAW,CAACC,YAAY,EAAEE,eAAS,CAACa,cAAc,CAAC,CAAC;QACnF;MACF;MAEArC,IAAI,CAACsC,cAAc,CACjBnC,IAAI,EACJwB,QAAQ,CAACY,GAAG,EACZZ,QAAQ,CAACK,GAAG,EACZ,CAACQ,GAAG,EAAEC,SAAS,KAAuB;QACpC,IAAIxB,eAAC,CAACyB,MAAM,CAACF,GAAG,CAAC,KAAK,KAAK,EAAE;UAC3B,OAAOxB,IAAI,CACTmB,gBAAU,CAACC,OAAO,CAACI,GAAG,CAACpB,MAAM,EAAEoB,GAAG,CAACjB,OAAO,CAAC,IAAIY,gBAAU,CAACQ,WAAW,CAACH,GAAG,CAACjB,OAAO,CACnF,CAAC;QACH;QAEA,IAAIkB,SAAS,EAAE;UACb,OAAOzB,IAAI,CAACd,YAAY,CAACY,GAAG,CAACK,WAAW,CAAChB,IAAI,CAAC,CAAC;QACjD;QACA,OAAOa,IAAI,CAACmB,gBAAU,CAACS,gBAAgB,CAACpB,eAAS,CAACqB,qBAAqB,CAAC,CAAC;MAC3E,CACF,CAAC;IACH,CAAC,MAAM,IAAI5B,eAAC,CAACC,KAAK,CAACd,GAAG,CAAC,KAAK,KAAK,EAAE;MACjC,OAAOY,IAAI,CACTmB,gBAAU,CAACC,OAAO,CAACf,iBAAW,CAACyB,mBAAmB,EAAEC,oBAAc,CAACC,YAAY,CACjF,CAAC;IACH,CAAC,MAAM;MACL,OAAOhC,IAAI,CAACmB,gBAAU,CAACC,OAAO,CAACf,iBAAW,CAAC4B,cAAc,EAAEC,eAAS,CAACC,aAAa,CAAC,CAAC;IACtF;EACF,CACF,CAAC;AACH"}
1
+ {"version":3,"file":"profile.js","names":["_lodash","_interopRequireDefault","require","_core","_middleware","obj","__esModule","default","_default","route","auth","config","buildProfile","name","tfa","email","email_verified","created","updated","cidr_whitelist","fullname","get","rateLimit","userRateLimit","req","res","next","_","isNil","remote_user","status","HTTP_STATUS","UNAUTHORIZED","message","API_ERROR","MUST_BE_LOGGED","post","password","body","_config$serverSetting","validatioUtils","validatePassword","new","serverSettings","passwordValidationRegex","errorUtils","getCode","PASSWORD_SHORT","isEmpty","old","getBadRequest","changePassword","err","isUpdated","isNull","getForbidden","getInternalError","INTERNAL_SERVER_ERROR","SERVICE_UNAVAILABLE","SUPPORT_ERRORS","TFA_DISABLED","INTERNAL_ERROR","APP_ERROR","PROFILE_ERROR"],"sources":["../../src/v1/profile.ts"],"sourcesContent":["import { Response, Router } from 'express';\nimport _ from 'lodash';\n\nimport { Auth } from '@verdaccio/auth';\nimport {\n API_ERROR,\n APP_ERROR,\n HTTP_STATUS,\n SUPPORT_ERRORS,\n errorUtils,\n validatioUtils,\n} from '@verdaccio/core';\nimport { rateLimit } from '@verdaccio/middleware';\nimport { Config } from '@verdaccio/types';\n\nimport { $NextFunctionVer, $RequestExtend } from '../../types/custom';\n\nexport interface Profile {\n tfa: boolean;\n name: string;\n email: string;\n email_verified: boolean;\n created: string;\n updated: string;\n cidr_whitelist: string[] | null;\n fullname: string;\n}\n\nexport default function (route: Router, auth: Auth, config: Config): void {\n function buildProfile(name: string): Profile {\n return {\n tfa: false,\n name,\n email: '',\n email_verified: false,\n created: '',\n updated: '',\n cidr_whitelist: null,\n fullname: '',\n };\n }\n\n route.get(\n '/-/npm/v1/user',\n rateLimit(config?.userRateLimit),\n function (req: $RequestExtend, res: Response, next: $NextFunctionVer): void {\n if (_.isNil(req.remote_user.name) === false) {\n return next(buildProfile(req.remote_user.name));\n }\n\n res.status(HTTP_STATUS.UNAUTHORIZED);\n return next({\n message: API_ERROR.MUST_BE_LOGGED,\n });\n }\n );\n\n route.post(\n '/-/npm/v1/user',\n rateLimit(config?.userRateLimit),\n function (req: $RequestExtend, res: Response, next: $NextFunctionVer): void {\n if (_.isNil(req.remote_user.name)) {\n res.status(HTTP_STATUS.UNAUTHORIZED);\n return next({\n message: API_ERROR.MUST_BE_LOGGED,\n });\n }\n\n const { password, tfa } = req.body;\n const { name } = req.remote_user;\n\n if (_.isNil(password) === false) {\n if (\n validatioUtils.validatePassword(\n password.new,\n config?.serverSettings?.passwordValidationRegex\n ) === false\n ) {\n /* eslint new-cap:off */\n return next(errorUtils.getCode(HTTP_STATUS.UNAUTHORIZED, API_ERROR.PASSWORD_SHORT));\n /* eslint new-cap:off */\n }\n\n if (_.isEmpty(password.old)) {\n return next(errorUtils.getBadRequest('old password is required'));\n }\n\n auth.changePassword(\n name,\n password.old,\n password.new,\n (err, isUpdated): $NextFunctionVer => {\n if (_.isNull(err) === false) {\n return next(errorUtils.getForbidden(err.message));\n }\n\n if (isUpdated) {\n return next(buildProfile(req.remote_user.name));\n }\n return next(errorUtils.getInternalError(API_ERROR.INTERNAL_SERVER_ERROR));\n }\n );\n } else if (_.isNil(tfa) === false) {\n return next(\n errorUtils.getCode(HTTP_STATUS.SERVICE_UNAVAILABLE, SUPPORT_ERRORS.TFA_DISABLED)\n );\n } else {\n return next(errorUtils.getCode(HTTP_STATUS.INTERNAL_ERROR, APP_ERROR.PROFILE_ERROR));\n }\n }\n );\n}\n"],"mappings":"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"}
package/jest.config.js CHANGED
@@ -1,10 +1,3 @@
1
1
  const config = require('../../jest/config');
2
2
 
3
- module.exports = Object.assign({}, config, {
4
- coverageThreshold: {
5
- global: {
6
- // FIXME: increase to 90
7
- lines: 60,
8
- },
9
- },
10
- });
3
+ module.exports = Object.assign({}, config, {});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@verdaccio/api",
3
- "version": "7.0.0-next-7.7",
3
+ "version": "7.0.0-next-7.9",
4
4
  "description": "loaders logic",
5
5
  "main": "./build/index.js",
6
6
  "types": "build/index.d.ts",
@@ -29,13 +29,13 @@
29
29
  },
30
30
  "license": "MIT",
31
31
  "dependencies": {
32
- "@verdaccio/auth": "7.0.0-next-7.7",
33
- "@verdaccio/config": "7.0.0-next-7.7",
34
- "@verdaccio/core": "7.0.0-next-7.7",
35
- "@verdaccio/logger": "7.0.0-next-7.7",
36
- "@verdaccio/middleware": "7.0.0-next-7.7",
37
- "@verdaccio/store": "7.0.0-next-7.7",
38
- "@verdaccio/utils": "7.0.0-next-7.7",
32
+ "@verdaccio/auth": "7.0.0-next-7.9",
33
+ "@verdaccio/config": "7.0.0-next-7.9",
34
+ "@verdaccio/core": "7.0.0-next-7.9",
35
+ "@verdaccio/logger": "7.0.0-next-7.9",
36
+ "@verdaccio/middleware": "7.0.0-next-7.9",
37
+ "@verdaccio/store": "7.0.0-next-7.9",
38
+ "@verdaccio/utils": "7.0.0-next-7.9",
39
39
  "abortcontroller-polyfill": "1.7.5",
40
40
  "body-parser": "1.20.2",
41
41
  "cookies": "0.9.0",
@@ -46,11 +46,11 @@
46
46
  "semver": "7.5.4"
47
47
  },
48
48
  "devDependencies": {
49
- "@verdaccio/test-helper": "3.0.0-next.1",
49
+ "@verdaccio/test-helper": "3.0.0-next-7.2",
50
50
  "@verdaccio/types": "12.0.0-next.2",
51
51
  "mockdate": "3.0.5",
52
- "nock": "13.4.0",
53
- "supertest": "6.3.3"
52
+ "nock": "13.5.1",
53
+ "supertest": "6.3.4"
54
54
  },
55
55
  "funding": {
56
56
  "type": "opencollective",
package/src/v1/profile.ts CHANGED
@@ -81,15 +81,17 @@ export default function (route: Router, auth: Auth, config: Config): void {
81
81
  /* eslint new-cap:off */
82
82
  }
83
83
 
84
+ if (_.isEmpty(password.old)) {
85
+ return next(errorUtils.getBadRequest('old password is required'));
86
+ }
87
+
84
88
  auth.changePassword(
85
89
  name,
86
90
  password.old,
87
91
  password.new,
88
92
  (err, isUpdated): $NextFunctionVer => {
89
93
  if (_.isNull(err) === false) {
90
- return next(
91
- errorUtils.getCode(err.status, err.message) || errorUtils.getConflict(err.message)
92
- );
94
+ return next(errorUtils.getForbidden(err.message));
93
95
  }
94
96
 
95
97
  if (isUpdated) {
@@ -0,0 +1,27 @@
1
+ auth:
2
+ htpasswd:
3
+ file: ./htpasswd-profile
4
+ web:
5
+ enable: true
6
+ title: verdaccio
7
+
8
+ uplinks:
9
+
10
+ log: { type: stdout, format: pretty, level: trace }
11
+
12
+ packages:
13
+ '@*/*':
14
+ access: $all
15
+ publish: $all
16
+ unpublish: $all
17
+ proxy: npmjs
18
+ 'verdaccio':
19
+ access: $all
20
+ publish: $all
21
+ '**':
22
+ access: $all
23
+ publish: $all
24
+ unpublish: $all
25
+ proxy: npmjs
26
+
27
+ _debug: true
@@ -26,8 +26,8 @@ describe('package', () => {
26
26
  });
27
27
 
28
28
  test.each([
29
- ['foo', 'foo-1.0.0.tgz'],
30
- ['@scope/foo', 'foo-1.0.0.tgz'],
29
+ ['foo2', 'foo2-1.0.0.tgz'],
30
+ ['@scope/foo2', 'foo2-1.0.0.tgz'],
31
31
  ])('should fails if tarball does not exist', async (pkg, fileName) => {
32
32
  await publishVersion(app, pkg, '1.0.1');
33
33
  return await supertest(app)
@@ -0,0 +1,111 @@
1
+ import supertest from 'supertest';
2
+
3
+ import { HEADERS, HEADER_TYPE, HTTP_STATUS, TOKEN_BEARER } from '@verdaccio/core';
4
+ import { buildToken } from '@verdaccio/utils';
5
+
6
+ import { createUser, initializeServer } from './_helper';
7
+
8
+ describe('profile ', () => {
9
+ describe('get profile ', () => {
10
+ test('should return Unauthorized if header token is missing', async () => {
11
+ const app = await initializeServer('profile.yaml');
12
+ return supertest(app)
13
+ .get('/-/npm/v1/user')
14
+ .expect(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON_CHARSET)
15
+ .expect(HTTP_STATUS.UNAUTHORIZED);
16
+ });
17
+
18
+ test('should return user details', async () => {
19
+ const app = await initializeServer('profile.yaml');
20
+ const credentials = { name: 'test', password: 'test' };
21
+ const response = await createUser(app, credentials.name, credentials.password);
22
+ return supertest(app)
23
+ .get('/-/npm/v1/user')
24
+ .set(HEADERS.AUTHORIZATION, buildToken(TOKEN_BEARER, response.body.token))
25
+ .expect(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON_CHARSET)
26
+ .expect(HTTP_STATUS.OK);
27
+ });
28
+ });
29
+ describe('post profile ', () => {
30
+ test('should return Unauthorized if header token is missing', async () => {
31
+ const app = await initializeServer('profile.yaml');
32
+ return supertest(app)
33
+ .post('/-/npm/v1/user')
34
+ .send({})
35
+ .expect(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON_CHARSET)
36
+ .expect(HTTP_STATUS.UNAUTHORIZED);
37
+ });
38
+
39
+ test('should return handle to short new password', async () => {
40
+ const app = await initializeServer('profile.yaml');
41
+ const credentials = { name: 'test', password: 'test' };
42
+ const response = await createUser(app, credentials.name, credentials.password);
43
+ return supertest(app)
44
+ .post('/-/npm/v1/user')
45
+ .send({ password: { new: '_' } })
46
+ .set(HEADERS.AUTHORIZATION, buildToken(TOKEN_BEARER, response.body.token))
47
+ .expect(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON_CHARSET)
48
+ .expect(HTTP_STATUS.UNAUTHORIZED);
49
+ });
50
+
51
+ test('should return handle to missing old password', async () => {
52
+ const app = await initializeServer('profile.yaml');
53
+ const credentials = { name: 'test', password: 'test' };
54
+ const response = await createUser(app, credentials.name, credentials.password);
55
+ return supertest(app)
56
+ .post('/-/npm/v1/user')
57
+ .send({ password: { new: 'fooooo', old: undefined } })
58
+ .set(HEADERS.AUTHORIZATION, buildToken(TOKEN_BEARER, response.body.token))
59
+ .expect(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON_CHARSET)
60
+ .expect(HTTP_STATUS.BAD_REQUEST);
61
+ });
62
+
63
+ test('should return handle to missing password', async () => {
64
+ const app = await initializeServer('profile.yaml');
65
+ const credentials = { name: 'test', password: 'test' };
66
+ const response = await createUser(app, credentials.name, credentials.password);
67
+ return supertest(app)
68
+ .post('/-/npm/v1/user')
69
+ .send({ another: '_' })
70
+ .set(HEADERS.AUTHORIZATION, buildToken(TOKEN_BEARER, response.body.token))
71
+ .expect(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON_CHARSET)
72
+ .expect(HTTP_STATUS.INTERNAL_ERROR);
73
+ });
74
+
75
+ test('should return handle change password', async () => {
76
+ const app = await initializeServer('profile.yaml');
77
+ const credentials = { name: 'test', password: 'test' };
78
+ const response = await createUser(app, credentials.name, credentials.password);
79
+ return supertest(app)
80
+ .post('/-/npm/v1/user')
81
+ .send({ password: { new: 'good password_.%#@$@#$@#', old: 'test' } })
82
+ .set(HEADERS.AUTHORIZATION, buildToken(TOKEN_BEARER, response.body.token))
83
+ .expect(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON_CHARSET)
84
+ .expect(HTTP_STATUS.OK);
85
+ });
86
+
87
+ test('should return handle change password failure', async () => {
88
+ const app = await initializeServer('profile.yaml');
89
+ const credentials = { name: 'test', password: 'test' };
90
+ const response = await createUser(app, credentials.name, credentials.password);
91
+ return supertest(app)
92
+ .post('/-/npm/v1/user')
93
+ .send({ password: { new: 'good password_.%#@$@#$@#', old: 'test_do_not_match' } })
94
+ .set(HEADERS.AUTHORIZATION, buildToken(TOKEN_BEARER, response.body.token))
95
+ .expect(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON_CHARSET)
96
+ .expect(HTTP_STATUS.FORBIDDEN);
97
+ });
98
+
99
+ test('should handle tfa ( two factor auth) disabled', async () => {
100
+ const app = await initializeServer('profile.yaml');
101
+ const credentials = { name: 'test', password: 'test' };
102
+ const response = await createUser(app, credentials.name, credentials.password);
103
+ return supertest(app)
104
+ .post('/-/npm/v1/user')
105
+ .send({ tfa: '_' })
106
+ .set(HEADERS.AUTHORIZATION, buildToken(TOKEN_BEARER, response.body.token))
107
+ .expect(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON_CHARSET)
108
+ .expect(HTTP_STATUS.SERVICE_UNAVAILABLE);
109
+ });
110
+ });
111
+ });