mirror of
https://github.com/verdaccio/verdaccio.git
synced 2024-11-13 03:35:52 +01:00
c264f944fb
* fix: unpublish and add or remove star colision The issue was the npm star use a similar payload, but we did not check properly the shape of the payload, this fix and allow unpublish correctly. Improve unit testing for publishing and unpublishing Add new code documentation for future changes. * chore: update secrets baseline * chore: add missing type this will requires update types in the future
138 lines
5.0 KiB
TypeScript
138 lines
5.0 KiB
TypeScript
import request from 'supertest';
|
|
import path from 'path';
|
|
import rimraf from 'rimraf';
|
|
|
|
import endPointAPI from '../../../../src/api';
|
|
|
|
import {HEADERS, HTTP_STATUS, HEADER_TYPE, TOKEN_BEARER, TOKEN_BASIC, API_ERROR} from '../../../../src/lib/constants';
|
|
import {mockServer} from '../../__helper/mock';
|
|
import {DOMAIN_SERVERS} from '../../../functional/config.functional';
|
|
import {buildToken} from '../../../../src/lib/utils';
|
|
import {addUser, getPackage, loginUserToken} from '../../__helper/api';
|
|
import {setup} from '../../../../src/lib/logger';
|
|
import configDefault from '../../partials/config';
|
|
import {buildUserBuffer} from '../../../../src/lib/auth-utils';
|
|
|
|
setup([]);
|
|
const credentials = { name: 'JotaJWT', password: 'secretPass' };
|
|
|
|
const FORBIDDEN_VUE = 'authorization required to access package vue';
|
|
|
|
describe('endpoint user auth JWT unit test', () => {
|
|
jest.setTimeout(20000);
|
|
let app;
|
|
let mockRegistry;
|
|
const FAKE_TOKEN: string = buildToken(TOKEN_BEARER, 'fake');
|
|
|
|
beforeAll(function(done) {
|
|
const store = path.join(__dirname, '../../partials/store/test-jwt-storage');
|
|
const mockServerPort = 55546;
|
|
rimraf(store, async () => {
|
|
const configForTest = configDefault({
|
|
storage: store,
|
|
uplinks: {
|
|
npmjs: {
|
|
url: `http://${DOMAIN_SERVERS}:${mockServerPort}`
|
|
}
|
|
},
|
|
self_path: store,
|
|
auth: {
|
|
htpasswd: {
|
|
file: './test-jwt-storage/.htpasswd_jwt_auth'
|
|
}
|
|
},
|
|
logs: [
|
|
{ type: 'stdout', format: 'pretty', level: 'warn' }
|
|
]
|
|
}, 'api-jwt/jwt.yaml');
|
|
|
|
app = await endPointAPI(configForTest);
|
|
mockRegistry = await mockServer(mockServerPort).init();
|
|
done();
|
|
});
|
|
});
|
|
|
|
afterAll(function(done) {
|
|
mockRegistry[0].stop();
|
|
done();
|
|
});
|
|
|
|
test('should test add a new user with JWT enabled', async (done) => {
|
|
const [err, res] = await addUser(request(app), credentials.name, credentials);
|
|
expect(err).toBeNull();
|
|
expect(res.body.ok).toBeDefined();
|
|
expect(res.body.token).toBeDefined();
|
|
|
|
const { token } = res.body;
|
|
expect(typeof token).toBe('string');
|
|
expect(res.body.ok).toMatch(`user '${credentials.name}' created`);
|
|
|
|
// testing JWT auth headers with token
|
|
// we need it here, because token is required
|
|
const [err1, resp1] = await getPackage(request(app), token, 'vue');
|
|
expect(err1).toBeNull();
|
|
expect(resp1.body).toBeDefined();
|
|
expect(resp1.body.name).toMatch('vue');
|
|
|
|
const [err2, resp2] = await getPackage(request(app), FAKE_TOKEN, 'vue', HTTP_STATUS.UNAUTHORIZED);
|
|
expect(err2).toBeNull();
|
|
expect(resp2.statusCode).toBe(HTTP_STATUS.UNAUTHORIZED);
|
|
expect(resp2.body.error).toMatch(FORBIDDEN_VUE);
|
|
done();
|
|
});
|
|
|
|
test('should emulate npm login when user already exist', async (done) => {
|
|
const credentials = { name: 'jwtUser2', password: 'secretPass' };
|
|
// creates an user
|
|
await addUser(request(app), credentials.name, credentials);
|
|
// it should fails conflict 409
|
|
await addUser(request(app), credentials.name, credentials, HTTP_STATUS.CONFLICT);
|
|
|
|
// npm will try to sign in sending credentials via basic auth header
|
|
const token = buildUserBuffer(credentials.name, credentials.password).toString('base64');
|
|
// put should exist in request
|
|
// @ts-ignore
|
|
request(app).put(`/-/user/org.couchdb.user:${credentials.name}/-rev/undefined`)
|
|
.send(credentials)
|
|
.set(HEADERS.AUTHORIZATION, buildToken(TOKEN_BASIC, token))
|
|
.expect(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON_CHARSET)
|
|
.expect(HTTP_STATUS.CREATED)
|
|
.end(function(err, res) {
|
|
expect(err).toBeNull();
|
|
expect(res.body.ok).toBeDefined();
|
|
expect(res.body.token).toBeDefined();
|
|
|
|
done();
|
|
});
|
|
});
|
|
|
|
test('should fails on try to access with corrupted token', async (done) => {
|
|
const [err2, resp2] = await getPackage(request(app), FAKE_TOKEN, 'vue', HTTP_STATUS.UNAUTHORIZED);
|
|
expect(err2).toBeNull();
|
|
expect(resp2.statusCode).toBe(HTTP_STATUS.UNAUTHORIZED);
|
|
expect(resp2.body.error).toMatch(FORBIDDEN_VUE);
|
|
done();
|
|
});
|
|
|
|
test('should fails on login if user credentials are invalid even if jwt valid token is provided', async (done) => {
|
|
const credentials = { name: 'newFailsUser', password: 'secretPass' };
|
|
const [err, res] = await addUser(request(app), credentials.name, credentials);
|
|
expect(err).toBeNull();
|
|
expect(res.body.ok).toBeDefined();
|
|
expect(res.body.token).toBeDefined();
|
|
|
|
const { token } = res.body;
|
|
expect(typeof token).toBe('string');
|
|
expect(res.body.ok).toMatch(`user '${credentials.name}' created`);
|
|
|
|
// we login when token is valid
|
|
const newCredentials = { name: 'newFailsUser', password: 'BAD_PASSWORD' };
|
|
const [err2, resp2] = await loginUserToken(request(app), newCredentials.name, newCredentials, token, HTTP_STATUS.UNAUTHORIZED);
|
|
expect(err2).toBeNull();
|
|
expect(resp2.statusCode).toBe(HTTP_STATUS.UNAUTHORIZED);
|
|
expect(resp2.body.error).toMatch(API_ERROR.BAD_USERNAME_PASSWORD);
|
|
|
|
done();
|
|
});
|
|
});
|