mirror of
https://github.com/verdaccio/verdaccio.git
synced 2024-12-16 21:56:25 -05:00
e93d6a30a4
* migrate web package to vitest * migrate node-api to vitest * migrate file-locking vitest * migrate cli * remove jest from npm packages * Create weak-cherries-serve.md * update ci
260 lines
8.8 KiB
TypeScript
260 lines
8.8 KiB
TypeScript
import _ from 'lodash';
|
|
import path from 'path';
|
|
import { describe, expect, test, vi } from 'vitest';
|
|
|
|
import {
|
|
Config as AppConfig,
|
|
createAnonymousRemoteUser,
|
|
createRemoteUser,
|
|
parseConfigFile,
|
|
} from '@verdaccio/config';
|
|
import { getDefaultConfig } from '@verdaccio/config';
|
|
import { TOKEN_BEARER } from '@verdaccio/core';
|
|
import { logger, setup } from '@verdaccio/logger';
|
|
import { signPayload } from '@verdaccio/signature';
|
|
import { Config, RemoteUser, Security } from '@verdaccio/types';
|
|
import { buildToken, buildUserBuffer } from '@verdaccio/utils';
|
|
|
|
import { Auth, getApiToken, getMiddlewareCredentials, verifyJWTPayload } from '../src';
|
|
|
|
setup({});
|
|
|
|
const parseConfigurationFile = (conf) => {
|
|
const { name, ext } = path.parse(conf);
|
|
const format = ext.startsWith('.') ? ext.substring(1) : 'yaml';
|
|
|
|
return path.join(__dirname, `./partials/config/${format}/security/${name}.${format}`);
|
|
};
|
|
|
|
describe('Auth utilities', () => {
|
|
vi.setConfig({ testTimeout: 20000 });
|
|
|
|
const parseConfigurationSecurityFile = (name) => {
|
|
return parseConfigurationFile(`security/${name}`);
|
|
};
|
|
|
|
function getConfig(configFileName: string, secret: string) {
|
|
const conf = parseConfigFile(parseConfigurationSecurityFile(configFileName));
|
|
// @ts-ignore
|
|
const secConf = _.merge(getDefaultConfig(), conf);
|
|
secConf.secret = secret;
|
|
const config: Config = new AppConfig(secConf);
|
|
|
|
return config;
|
|
}
|
|
|
|
async function getTokenByConfiguration(
|
|
configFileName: string,
|
|
username: string,
|
|
password: string,
|
|
secret = '12345',
|
|
methodToSpy: string,
|
|
methodNotBeenCalled: string
|
|
): Promise<string> {
|
|
const config: Config = getConfig(configFileName, secret);
|
|
const auth: Auth = new Auth(config, logger);
|
|
await auth.init();
|
|
// @ts-ignore
|
|
const spy = vi.spyOn(auth, methodToSpy);
|
|
// @ts-ignore
|
|
const spyNotCalled = vi.spyOn(auth, methodNotBeenCalled);
|
|
const user: RemoteUser = {
|
|
name: username,
|
|
real_groups: ['test', '$all', '$authenticated', '@all', '@authenticated', 'all'],
|
|
groups: ['company-role1', 'company-role2'],
|
|
};
|
|
const token = await getApiToken(auth, config, user, password);
|
|
expect(spy).toHaveBeenCalled();
|
|
expect(spy).toHaveBeenCalledTimes(1);
|
|
expect(spyNotCalled).not.toHaveBeenCalled();
|
|
expect(token).toBeDefined();
|
|
|
|
return token as string;
|
|
}
|
|
|
|
describe('getMiddlewareCredentials test', () => {
|
|
describe('should get AES credentials', () => {
|
|
test.concurrent('should unpack aes token and credentials bearer auth', async () => {
|
|
const secret = 'b2df428b9929d3ace7c598bbf4e496b2';
|
|
const user = 'test';
|
|
const pass = 'test';
|
|
const token = await getTokenByConfiguration(
|
|
'security-legacy',
|
|
user,
|
|
pass,
|
|
secret,
|
|
'aesEncrypt',
|
|
'jwtEncrypt'
|
|
);
|
|
const config: Config = getConfig('security-legacy', secret);
|
|
const security: Security = config.security;
|
|
const credentials = getMiddlewareCredentials(security, secret, `Bearer ${token}`);
|
|
expect(credentials).toBeDefined();
|
|
// @ts-ignore
|
|
expect(credentials.user).toEqual(user);
|
|
// @ts-ignore
|
|
expect(credentials.password).toEqual(pass);
|
|
});
|
|
|
|
test.concurrent('should unpack aes token and credentials basic auth', async () => {
|
|
const secret = 'b2df428b9929d3ace7c598bbf4e496b2';
|
|
const user = 'test';
|
|
const pass = 'test';
|
|
// basic authentication need send user as base64
|
|
const token = buildUserBuffer(user, pass).toString('base64');
|
|
const config: Config = getConfig('security-legacy', secret);
|
|
const security: Security = config.security;
|
|
const credentials = getMiddlewareCredentials(security, secret, `Basic ${token}`);
|
|
expect(credentials).toBeDefined();
|
|
// @ts-ignore
|
|
expect(credentials.user).toEqual(user);
|
|
// @ts-ignore
|
|
expect(credentials.password).toEqual(pass);
|
|
});
|
|
|
|
test.concurrent('should return empty credential wrong secret key', async () => {
|
|
const secret = 'b2df428b9929d3ace7c598bbf4e496b2';
|
|
const token = await getTokenByConfiguration(
|
|
'security-legacy',
|
|
'test',
|
|
'test',
|
|
secret,
|
|
'aesEncrypt',
|
|
'jwtEncrypt'
|
|
);
|
|
const config: Config = getConfig('security-legacy', secret);
|
|
const security: Security = config.security;
|
|
const credentials = getMiddlewareCredentials(
|
|
security,
|
|
'b2df428b9929d3ace7c598bbf4e496_BAD_TOKEN',
|
|
buildToken(TOKEN_BEARER, token)
|
|
);
|
|
expect(credentials).not.toBeDefined();
|
|
});
|
|
|
|
test.concurrent('should return empty credential wrong scheme', async () => {
|
|
const secret = 'b2df428b9929d3ace7c598bbf4e496b2';
|
|
const token = await getTokenByConfiguration(
|
|
'security-legacy',
|
|
'test',
|
|
'test',
|
|
secret,
|
|
'aesEncrypt',
|
|
'jwtEncrypt'
|
|
);
|
|
const config: Config = getConfig('security-legacy', secret);
|
|
const security: Security = config.security;
|
|
const credentials = getMiddlewareCredentials(
|
|
security,
|
|
secret,
|
|
buildToken('BAD_SCHEME', token)
|
|
);
|
|
expect(credentials).not.toBeDefined();
|
|
});
|
|
|
|
test.concurrent('should return empty credential corrupted payload', async () => {
|
|
const secret = 'b2df428b9929d3ace7c598bbf4e496b2';
|
|
const config: Config = getConfig('security-legacy', secret);
|
|
const auth: Auth = new Auth(config, logger);
|
|
await auth.init();
|
|
// @ts-expect-error
|
|
const token = auth.aesEncrypt(null);
|
|
const security: Security = config.security;
|
|
const credentials = getMiddlewareCredentials(
|
|
security,
|
|
secret,
|
|
buildToken(TOKEN_BEARER, token as string)
|
|
);
|
|
expect(credentials).not.toBeDefined();
|
|
});
|
|
});
|
|
|
|
describe('verifyJWTPayload', () => {
|
|
test('should fail on verify the token and return anonymous users', () => {
|
|
expect(verifyJWTPayload('fakeToken', 'b2df428b9929d3ace7c598bbf4e496b2')).toEqual(
|
|
createAnonymousRemoteUser()
|
|
);
|
|
});
|
|
|
|
test('should verify the token and return a remote user', async () => {
|
|
const remoteUser = createRemoteUser('foo', []);
|
|
const token = await signPayload(remoteUser, '12345');
|
|
const verifiedToken = verifyJWTPayload(token, '12345');
|
|
expect(verifiedToken.groups).toEqual(remoteUser.groups);
|
|
expect(verifiedToken.name).toEqual(remoteUser.name);
|
|
});
|
|
});
|
|
|
|
describe('should get JWT credentials', () => {
|
|
test('should return anonymous whether token is corrupted', () => {
|
|
const config: Config = getConfig('security-jwt', '12345');
|
|
const security: Security = config.security;
|
|
const credentials = getMiddlewareCredentials(
|
|
security,
|
|
'12345',
|
|
buildToken(TOKEN_BEARER, 'fakeToken')
|
|
) as RemoteUser;
|
|
|
|
expect(credentials).toBeDefined();
|
|
expect(credentials.name).not.toBeDefined();
|
|
expect(credentials.real_groups).toBeDefined();
|
|
|
|
expect(credentials.groups).toEqual(['$all', '$anonymous', '@all', '@anonymous']);
|
|
});
|
|
|
|
test('should return anonymous whether token and scheme are corrupted', () => {
|
|
const config: Config = getConfig('security-jwt', '12345');
|
|
const security: Security = config.security;
|
|
const credentials = getMiddlewareCredentials(
|
|
security,
|
|
'12345',
|
|
buildToken('FakeScheme', 'fakeToken')
|
|
);
|
|
|
|
expect(credentials).not.toBeDefined();
|
|
});
|
|
|
|
test('should verify successfully a JWT token', async () => {
|
|
const secret = 'b2df428b9929d3ace7c598bbf4e496b2';
|
|
const user = 'test';
|
|
const config: Config = getConfig('security-jwt', secret);
|
|
const token = await getTokenByConfiguration(
|
|
'security-jwt',
|
|
user,
|
|
'secretTest',
|
|
secret,
|
|
'jwtEncrypt',
|
|
'aesEncrypt'
|
|
);
|
|
const security: Security = config.security;
|
|
const credentials = getMiddlewareCredentials(
|
|
security,
|
|
secret,
|
|
buildToken(TOKEN_BEARER, token)
|
|
) as RemoteUser;
|
|
expect(credentials).toBeDefined();
|
|
|
|
expect(credentials.name).toEqual(user);
|
|
expect(credentials.real_groups).toBeDefined();
|
|
expect(credentials.real_groups).toEqual([
|
|
'test',
|
|
'$all',
|
|
'$authenticated',
|
|
'@all',
|
|
'@authenticated',
|
|
'all',
|
|
]);
|
|
expect(credentials.groups).toEqual([
|
|
'company-role1',
|
|
'company-role2',
|
|
'test',
|
|
'$all',
|
|
'$authenticated',
|
|
'@all',
|
|
'@authenticated',
|
|
'all',
|
|
]);
|
|
});
|
|
});
|
|
});
|
|
});
|