mirror of
https://github.com/verdaccio/verdaccio.git
synced 2024-12-16 21:56:25 -05:00
fix: profile v1 endpoint and tests
This commit is contained in:
parent
5e896b5fd0
commit
a183446000
3 changed files with 144 additions and 4 deletions
|
@ -2,7 +2,7 @@ import { Response, Router } from 'express';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
|
|
||||||
import { Auth } from '@verdaccio/auth';
|
import { Auth } from '@verdaccio/auth';
|
||||||
import { validatioUtils } from '@verdaccio/core';
|
import { errorUtils, validatioUtils } from '@verdaccio/core';
|
||||||
import { rateLimit } from '@verdaccio/middleware';
|
import { rateLimit } from '@verdaccio/middleware';
|
||||||
import { ConfigYaml } from '@verdaccio/types';
|
import { ConfigYaml } from '@verdaccio/types';
|
||||||
|
|
||||||
|
@ -71,15 +71,17 @@ export default function (router: Router, auth: Auth, config: ConfigYaml) {
|
||||||
/* eslint new-cap:off */
|
/* eslint new-cap:off */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_.isEmpty(password.old)) {
|
||||||
|
return next(errorUtils.getBadRequest('old password is required'));
|
||||||
|
}
|
||||||
|
|
||||||
auth.changePassword(
|
auth.changePassword(
|
||||||
name,
|
name,
|
||||||
password.old,
|
password.old,
|
||||||
password.new,
|
password.new,
|
||||||
(err, isUpdated): $NextFunctionVer => {
|
(err, isUpdated): $NextFunctionVer => {
|
||||||
if (_.isNull(err) === false) {
|
if (_.isNull(err) === false) {
|
||||||
return next(
|
return next(errorUtils.getForbidden(err.message));
|
||||||
ErrorCode.getCode(err.status, err.message) || ErrorCode.getConflict(err.message)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isUpdated) {
|
if (isUpdated) {
|
||||||
|
|
27
test/unit/modules/api/config/profile.yaml
Normal file
27
test/unit/modules/api/config/profile.yaml
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
auth:
|
||||||
|
htpasswd:
|
||||||
|
file: ./htpasswd-profile
|
||||||
|
web:
|
||||||
|
enable: true
|
||||||
|
title: verdaccio
|
||||||
|
|
||||||
|
uplinks:
|
||||||
|
|
||||||
|
log: { type: stdout, format: pretty, level: trace }
|
||||||
|
|
||||||
|
packages:
|
||||||
|
'@*/*':
|
||||||
|
access: $all
|
||||||
|
publish: $all
|
||||||
|
unpublish: $all
|
||||||
|
proxy: npmjs
|
||||||
|
'verdaccio':
|
||||||
|
access: $all
|
||||||
|
publish: $all
|
||||||
|
'**':
|
||||||
|
access: $all
|
||||||
|
publish: $all
|
||||||
|
unpublish: $all
|
||||||
|
proxy: npmjs
|
||||||
|
|
||||||
|
_debug: true
|
111
test/unit/modules/api/profile.spec.ts
Normal file
111
test/unit/modules/api/profile.spec.ts
Normal file
|
@ -0,0 +1,111 @@
|
||||||
|
import supertest from 'supertest';
|
||||||
|
|
||||||
|
import { HEADERS, HEADER_TYPE, HTTP_STATUS, TOKEN_BEARER } from '@verdaccio/core';
|
||||||
|
import { buildToken } from '@verdaccio/utils';
|
||||||
|
|
||||||
|
import { createUser, initializeServer } from './_helper';
|
||||||
|
|
||||||
|
describe('profile ', () => {
|
||||||
|
describe('get profile ', () => {
|
||||||
|
test('should return Unauthorized if header token is missing', async () => {
|
||||||
|
const app = await initializeServer('profile.yaml');
|
||||||
|
return supertest(app)
|
||||||
|
.get('/-/npm/v1/user')
|
||||||
|
.expect(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON_CHARSET)
|
||||||
|
.expect(HTTP_STATUS.UNAUTHORIZED);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should return user details', async () => {
|
||||||
|
const app = await initializeServer('profile.yaml');
|
||||||
|
const credentials = { name: 'test', password: 'test' };
|
||||||
|
const response = await createUser(app, credentials.name, credentials.password);
|
||||||
|
return supertest(app)
|
||||||
|
.get('/-/npm/v1/user')
|
||||||
|
.set(HEADERS.AUTHORIZATION, buildToken(TOKEN_BEARER, response.body.token))
|
||||||
|
.expect(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON_CHARSET)
|
||||||
|
.expect(HTTP_STATUS.OK);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
describe('post profile ', () => {
|
||||||
|
test('should return Unauthorized if header token is missing', async () => {
|
||||||
|
const app = await initializeServer('profile.yaml');
|
||||||
|
return supertest(app)
|
||||||
|
.post('/-/npm/v1/user')
|
||||||
|
.send({})
|
||||||
|
.expect(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON_CHARSET)
|
||||||
|
.expect(HTTP_STATUS.UNAUTHORIZED);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should return handle to short new password', async () => {
|
||||||
|
const app = await initializeServer('profile.yaml');
|
||||||
|
const credentials = { name: 'test', password: 'test' };
|
||||||
|
const response = await createUser(app, credentials.name, credentials.password);
|
||||||
|
return supertest(app)
|
||||||
|
.post('/-/npm/v1/user')
|
||||||
|
.send({ password: { new: '_' } })
|
||||||
|
.set(HEADERS.AUTHORIZATION, buildToken(TOKEN_BEARER, response.body.token))
|
||||||
|
.expect(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON_CHARSET)
|
||||||
|
.expect(HTTP_STATUS.UNAUTHORIZED);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should return handle to missing old password', async () => {
|
||||||
|
const app = await initializeServer('profile.yaml');
|
||||||
|
const credentials = { name: 'test', password: 'test' };
|
||||||
|
const response = await createUser(app, credentials.name, credentials.password);
|
||||||
|
return supertest(app)
|
||||||
|
.post('/-/npm/v1/user')
|
||||||
|
.send({ password: { new: 'fooooo', old: undefined } })
|
||||||
|
.set(HEADERS.AUTHORIZATION, buildToken(TOKEN_BEARER, response.body.token))
|
||||||
|
.expect(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON_CHARSET)
|
||||||
|
.expect(HTTP_STATUS.BAD_REQUEST);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should return handle to missing password', async () => {
|
||||||
|
const app = await initializeServer('profile.yaml');
|
||||||
|
const credentials = { name: 'test', password: 'test' };
|
||||||
|
const response = await createUser(app, credentials.name, credentials.password);
|
||||||
|
return supertest(app)
|
||||||
|
.post('/-/npm/v1/user')
|
||||||
|
.send({ another: '_' })
|
||||||
|
.set(HEADERS.AUTHORIZATION, buildToken(TOKEN_BEARER, response.body.token))
|
||||||
|
.expect(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON_CHARSET)
|
||||||
|
.expect(HTTP_STATUS.INTERNAL_ERROR);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should return handle change password', async () => {
|
||||||
|
const app = await initializeServer('profile.yaml');
|
||||||
|
const credentials = { name: 'test', password: 'test' };
|
||||||
|
const response = await createUser(app, credentials.name, credentials.password);
|
||||||
|
return supertest(app)
|
||||||
|
.post('/-/npm/v1/user')
|
||||||
|
.send({ password: { new: 'good password_.%#@$@#$@#', old: 'test' } })
|
||||||
|
.set(HEADERS.AUTHORIZATION, buildToken(TOKEN_BEARER, response.body.token))
|
||||||
|
.expect(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON_CHARSET)
|
||||||
|
.expect(HTTP_STATUS.OK);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should return handle change password failure', async () => {
|
||||||
|
const app = await initializeServer('profile.yaml');
|
||||||
|
const credentials = { name: 'test', password: 'test' };
|
||||||
|
const response = await createUser(app, credentials.name, credentials.password);
|
||||||
|
return supertest(app)
|
||||||
|
.post('/-/npm/v1/user')
|
||||||
|
.send({ password: { new: 'good password_.%#@$@#$@#', old: 'test_do_not_match' } })
|
||||||
|
.set(HEADERS.AUTHORIZATION, buildToken(TOKEN_BEARER, response.body.token))
|
||||||
|
.expect(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON_CHARSET)
|
||||||
|
.expect(HTTP_STATUS.FORBIDDEN);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should handle tfa ( two factor auth) disabled', async () => {
|
||||||
|
const app = await initializeServer('profile.yaml');
|
||||||
|
const credentials = { name: 'test', password: 'test' };
|
||||||
|
const response = await createUser(app, credentials.name, credentials.password);
|
||||||
|
return supertest(app)
|
||||||
|
.post('/-/npm/v1/user')
|
||||||
|
.send({ tfa: '_' })
|
||||||
|
.set(HEADERS.AUTHORIZATION, buildToken(TOKEN_BEARER, response.body.token))
|
||||||
|
.expect(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON_CHARSET)
|
||||||
|
.expect(HTTP_STATUS.SERVICE_UNAVAILABLE);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
Loading…
Reference in a new issue