mirror of
https://github.com/verdaccio/verdaccio.git
synced 2025-01-06 22:40:26 -05:00
124e5f2de7
* migrate htpasswd package * update versions * Update htpasswd.passwords.test.ts
123 lines
4.1 KiB
TypeScript
123 lines
4.1 KiB
TypeScript
import bcrypt from 'bcryptjs';
|
|
import crypto from 'crypto';
|
|
import path from 'path';
|
|
import { beforeEach, describe, expect, test, vi } from 'vitest';
|
|
|
|
import { Config, parseConfigFile } from '@verdaccio/config';
|
|
import { pluginUtils } from '@verdaccio/core';
|
|
|
|
import HTPasswd, { DEFAULT_SLOW_VERIFY_MS, HTPasswdConfig } from '../src/htpasswd';
|
|
|
|
const options = {
|
|
logger: { warn: vi.fn(), info: vi.fn() },
|
|
config: new Config(parseConfigFile(path.join(__dirname, './__fixtures__/config.yaml'))),
|
|
} as any as pluginUtils.PluginOptions;
|
|
|
|
const config = {
|
|
file: './htpasswd',
|
|
max_users: 1000,
|
|
} as HTPasswdConfig;
|
|
|
|
describe('HTPasswd', () => {
|
|
let wrapper;
|
|
|
|
beforeEach(() => {
|
|
wrapper = new HTPasswd(config, options);
|
|
vi.resetModules();
|
|
vi.clearAllMocks();
|
|
|
|
// @ts-ignore
|
|
crypto.randomBytes = vi.fn(() => {
|
|
return {
|
|
toString: (): string => '$6',
|
|
};
|
|
});
|
|
});
|
|
|
|
describe('constructor()', () => {
|
|
const error = vi.fn();
|
|
const warn = vi.fn();
|
|
const info = vi.fn();
|
|
const emptyPluginOptions = {
|
|
config: {
|
|
configPath: '',
|
|
},
|
|
logger: { warn, info, error },
|
|
} as any as pluginUtils.PluginOptions;
|
|
|
|
test('should ensure file path configuration exists', () => {
|
|
expect(function () {
|
|
new HTPasswd({} as HTPasswdConfig, emptyPluginOptions);
|
|
}).toThrow(/should specify "file" in config/);
|
|
});
|
|
|
|
test('should switch to bcrypt if incorrect algorithm is set', () => {
|
|
let invalidConfig = { algorithm: 'invalid', ...config } as HTPasswdConfig;
|
|
new HTPasswd(invalidConfig, emptyPluginOptions);
|
|
expect(warn).toHaveBeenCalledWith(
|
|
'The algorithm selected %s is invalid, switching to to default one "bcrypt", password validation can be affected',
|
|
'invalid'
|
|
);
|
|
expect(info).toHaveBeenCalled();
|
|
});
|
|
});
|
|
|
|
describe('authenticate()', () => {
|
|
test.each([
|
|
{ username: 'test1111', password: 'test1111' },
|
|
{ username: 'username', password: 'password' },
|
|
{ username: 'bcrypt', password: 'password' },
|
|
])('it should authenticate user $username with given credentials', ({ username, password }) => {
|
|
return new Promise((done) => {
|
|
const generateCallback = (username) => (error, userGroups) => {
|
|
expect(error).toBeNull();
|
|
expect(userGroups).toContain(username);
|
|
done();
|
|
};
|
|
wrapper.adduser(username, password, () => {
|
|
wrapper.authenticate(username, password, generateCallback(username));
|
|
});
|
|
});
|
|
});
|
|
|
|
test.each([
|
|
{ username: 'test1111', password: 'test1111' },
|
|
{ username: 'username', password: 'password' },
|
|
{ username: 'bcrypt', password: 'password' },
|
|
])('it should not authenticate use $username with given credentials', ({ username }) => {
|
|
return new Promise((done) => {
|
|
const generateCallback = () => (error) => {
|
|
expect(error).toBeNull();
|
|
// expect(userGroups).toBeFalsy();
|
|
done();
|
|
};
|
|
wrapper.authenticate(username, 'somerandompassword', generateCallback());
|
|
});
|
|
});
|
|
|
|
// TODO: flakes on CI
|
|
test.skip('it should warn on slow password verification', () => {
|
|
return new Promise((done) => {
|
|
// @ts-ignore
|
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
bcrypt.compare = vi.fn((_passwd, _hash) => {
|
|
return new Promise((resolve) => setTimeout(resolve, DEFAULT_SLOW_VERIFY_MS + 1)).then(
|
|
() => true
|
|
);
|
|
});
|
|
const callback = (a, b): void => {
|
|
expect(a).toBeNull();
|
|
expect(b).toContain('bcrypt');
|
|
const mockWarn = options.logger.warn as any;
|
|
expect(mockWarn.mock.calls.length).toBe(1);
|
|
const [{ user, durationMs }, message] = mockWarn.mock.calls[0];
|
|
expect(user).toEqual('bcrypt');
|
|
expect(durationMs).toBeGreaterThan(DEFAULT_SLOW_VERIFY_MS);
|
|
expect(message).toEqual('Password for user "@{user}" took @{durationMs}ms to verify');
|
|
done(true);
|
|
};
|
|
wrapper.authenticate('bcrypt', 'password', callback);
|
|
});
|
|
});
|
|
});
|
|
});
|