1
0
mirror of https://github.com/verdaccio/verdaccio.git synced 2024-11-17 07:45:52 +01:00
verdaccio/packages/api/test/integration/user.spec.ts

238 lines
6.9 KiB
TypeScript
Raw Normal View History

import supertest from 'supertest';
import { initializeServer } from './_helper';
import { HTTP_STATUS, API_ERROR } from '@verdaccio/commons-api';
import {HEADERS, HEADER_TYPE, API_MESSAGE} from '@verdaccio/dev-commons';
import {$RequestExtend, $ResponseExtend} from "@verdaccio/dev-types";
import {getBadRequest, getConflict, getUnauthorized} from "@verdaccio/commons-api/lib";
import _ from "lodash";
const mockApiJWTmiddleware = jest.fn(() =>
(req: $RequestExtend, res: $ResponseExtend, _next): void => {
req.remote_user = { name: 'test', groups: [], real_groups: []};
_next();
}
);
const mockAuthenticate = jest.fn(() => (_name, _password, callback): void => {
return callback(null, ['all']);
}
);
const mockAddUser = jest.fn(() => (_name, _password, callback): void => {
return callback(getConflict(API_ERROR.USERNAME_ALREADY_REGISTERED));
}
);
jest.mock('@verdaccio/auth', () => ({
getApiToken: () => 'token',
Auth: class {
apiJWTmiddleware() {
return mockApiJWTmiddleware();
}
allow_access (_d, f_, cb) {
cb(null, true);
}
add_user (name, password, callback) {
mockAddUser()(name, password, callback);
}
authenticate (_name, _password, callback) {
mockAuthenticate()(_name, _password, callback);
}
}
}));
describe('user', () => {
const credentials = { name: 'test', password: 'test' };
test('should test add a new user', async (done) => {
mockApiJWTmiddleware.mockImplementationOnce(() =>
(req: $RequestExtend, res: $ResponseExtend, _next): void => {
req.remote_user = { name: undefined};
_next();
}
);
mockAddUser.mockImplementationOnce(() => (_name, _password, callback): void => {
return callback(null, true);
}
);
supertest(await initializeServer('user.yaml'))
.put(`/-/user/org.couchdb.user:newUser`)
.send({
name: 'newUser',
password: 'newUser'
})
.expect(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON_CHARSET)
.expect(HTTP_STATUS.CREATED)
.end(function(err, res) {
if (err) {
return done(err);
}
expect(res.body.ok).toBeDefined();
expect(res.body.token).toBeDefined();
const token = res.body.token;
expect(typeof token).toBe('string');
expect(res.body.ok).toMatch(`user 'newUser' created`);
done();
});
});
test('should test fails on add a existing user with login', async (done) => {
mockApiJWTmiddleware.mockImplementationOnce(() =>
(req: $RequestExtend, res: $ResponseExtend, _next): void => {
req.remote_user = { name: undefined};
_next();
}
);
supertest(await initializeServer('user.yaml'))
.put('/-/user/org.couchdb.user:jotaNew')
.send(credentials)
.expect(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON_CHARSET)
.expect(HTTP_STATUS.CONFLICT)
.end(function(err, res) {
if (err) {
return done(err);
}
expect(res.body.error).toBeDefined();
expect(res.body.error).toMatch(API_ERROR.USERNAME_ALREADY_REGISTERED);
done();
});
});
test('should log in as existing user', async (done) => {
supertest(await initializeServer('user.yaml'))
.put(`/-/user/org.couchdb.user:${credentials.name}`)
.send(credentials)
.expect(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON_CHARSET)
.expect(HTTP_STATUS.CREATED)
.end((err, res) => {
if (err) {
return done(err);
}
expect(res.body).toBeTruthy();
expect(res.body.ok).toMatch(`you are authenticated as \'${credentials.name}\'`);
done();
});
});
test('should test fails add a new user with missing name', async (done) => {
mockApiJWTmiddleware.mockImplementationOnce(() =>
(req: $RequestExtend, res: $ResponseExtend, _next): void => {
req.remote_user = { name: undefined };
_next();
}
);
mockAddUser.mockImplementationOnce(() => (_name, _password, callback): void => {
return callback(getBadRequest(API_ERROR.USERNAME_PASSWORD_REQUIRED));
}
);
const credentialsShort = _.cloneDeep(credentials);
delete credentialsShort.name;
supertest(await initializeServer('user.yaml'))
.put(`/-/user/org.couchdb.user:${credentials.name}`)
.send(credentialsShort)
.expect(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON_CHARSET)
.expect(HTTP_STATUS.BAD_REQUEST)
.end(function(err, res) {
if (err) {
return done(err);
}
expect(res.body.error).toBeDefined();
expect(res.body.error).toMatch(API_ERROR.USERNAME_PASSWORD_REQUIRED);
done();
});
});
test('should test fails add a new user with missing password', async (done) => {
mockApiJWTmiddleware.mockImplementationOnce(() =>
(req: $RequestExtend, res: $ResponseExtend, _next): void => {
req.remote_user = { name: undefined};
_next();
}
);
const credentialsShort = _.cloneDeep(credentials);
delete credentialsShort.password;
supertest(await initializeServer('user.yaml'))
.put(`/-/user/org.couchdb.user:${credentials.name}`)
.send(credentialsShort)
.expect(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON_CHARSET)
.expect(HTTP_STATUS.BAD_REQUEST)
.end(function(err, res) {
if (err) {
return done(err);
}
expect(res.body.error).toBeDefined();
// FIXME: message is not 100% accurate
// eslint-disable-next-line new-cap
expect(res.body.error).toMatch(API_ERROR.PASSWORD_SHORT());
done();
});
});
test('should test fails add a new user with wrong password', async (done) => {
mockApiJWTmiddleware.mockImplementationOnce(() =>
(req: $RequestExtend, res: $ResponseExtend, _next): void => {
req.remote_user = { name: 'test'};
_next();
}
);
mockAuthenticate.mockImplementationOnce(() => (_name, _password, callback): void => {
return callback(getUnauthorized(API_ERROR.BAD_USERNAME_PASSWORD));
}
);
const credentialsShort = _.cloneDeep(credentials);
credentialsShort.password = 'failPassword';
supertest(await initializeServer('user.yaml'))
.put('/-/user/org.couchdb.user:test')
.send(credentialsShort)
.expect(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON_CHARSET)
.expect(HTTP_STATUS.UNAUTHORIZED)
.end(function(err, res) {
if (err) {
return done(err);
}
expect(res.body.error).toBeDefined();
expect(res.body.error).toMatch(API_ERROR.BAD_USERNAME_PASSWORD);
done();
});
});
test('should be able to logout an user', async (done) => {
mockApiJWTmiddleware.mockImplementationOnce(() =>
(req: $RequestExtend, res: $ResponseExtend, _next): void => {
req.remote_user = { name: 'test'};
_next();
}
);
mockAuthenticate.mockImplementationOnce(() => (_name, _password, callback): void => {
return callback(getUnauthorized(API_ERROR.BAD_USERNAME_PASSWORD));
}
);
const credentialsShort = _.cloneDeep(credentials);
credentialsShort.password = 'failPassword';
supertest(await initializeServer('user.yaml'))
.delete('/-/user/token/someSecretToken')
.send(credentialsShort)
.expect(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON_CHARSET)
.expect(HTTP_STATUS.OK)
.end(function(err, res) {
if (err) {
return done(err);
}
expect(res.body.ok).toMatch(API_MESSAGE.LOGGED_OUT);
done();
});
});
});