0
Fork 0
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:
Juan Picado 2024-02-03 12:07:15 +01:00
parent 5e896b5fd0
commit a183446000
3 changed files with 144 additions and 4 deletions

View file

@ -2,7 +2,7 @@ import { Response, Router } from 'express';
import _ from 'lodash';
import { Auth } from '@verdaccio/auth';
import { validatioUtils } from '@verdaccio/core';
import { errorUtils, validatioUtils } from '@verdaccio/core';
import { rateLimit } from '@verdaccio/middleware';
import { ConfigYaml } from '@verdaccio/types';
@ -71,15 +71,17 @@ export default function (router: Router, auth: Auth, config: ConfigYaml) {
/* eslint new-cap:off */
}
if (_.isEmpty(password.old)) {
return next(errorUtils.getBadRequest('old password is required'));
}
auth.changePassword(
name,
password.old,
password.new,
(err, isUpdated): $NextFunctionVer => {
if (_.isNull(err) === false) {
return next(
ErrorCode.getCode(err.status, err.message) || ErrorCode.getConflict(err.message)
);
return next(errorUtils.getForbidden(err.message));
}
if (isUpdated) {

View 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

View 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);
});
});
});