mirror of
				https://github.com/Unleash/unleash.git
				synced 2025-10-27 11:02:16 +01:00 
			
		
		
		
	feat: Disable password based login (#1046)
This commit will introduce a new setting used to disbaled simple password based authention. The setting itself is an enterprise setting.
This commit is contained in:
		
							parent
							
								
									9e73ed8f47
								
							
						
					
					
						commit
						4fb1bcb524
					
				@ -3,15 +3,31 @@ import { IUnleashServices } from '../../types/services';
 | 
			
		||||
import { IUnleashConfig } from '../../types/option';
 | 
			
		||||
import version from '../../util/version';
 | 
			
		||||
 | 
			
		||||
const Controller = require('../controller');
 | 
			
		||||
import Controller from '../controller';
 | 
			
		||||
import VersionService from '../../services/version-service';
 | 
			
		||||
import SettingService from '../../services/setting-service';
 | 
			
		||||
import {
 | 
			
		||||
    simpleAuthKey,
 | 
			
		||||
    SimpleAuthSettings,
 | 
			
		||||
} from '../../types/settings/simple-auth-settings';
 | 
			
		||||
 | 
			
		||||
class ConfigController extends Controller {
 | 
			
		||||
    private versionService: VersionService;
 | 
			
		||||
 | 
			
		||||
    private settingService: SettingService;
 | 
			
		||||
 | 
			
		||||
    private uiConfig: any;
 | 
			
		||||
 | 
			
		||||
    constructor(
 | 
			
		||||
        config: IUnleashConfig,
 | 
			
		||||
        { versionService }: Pick<IUnleashServices, 'versionService'>,
 | 
			
		||||
        {
 | 
			
		||||
            versionService,
 | 
			
		||||
            settingService,
 | 
			
		||||
        }: Pick<IUnleashServices, 'versionService' | 'settingService'>,
 | 
			
		||||
    ) {
 | 
			
		||||
        super(config);
 | 
			
		||||
        this.versionService = versionService;
 | 
			
		||||
        this.settingService = settingService;
 | 
			
		||||
        const authenticationType =
 | 
			
		||||
            config.authentication && config.authentication.type;
 | 
			
		||||
        this.uiConfig = {
 | 
			
		||||
@ -26,13 +42,12 @@ class ConfigController extends Controller {
 | 
			
		||||
 | 
			
		||||
    async getUIConfig(req: Request, res: Response): Promise<void> {
 | 
			
		||||
        const config = this.uiConfig;
 | 
			
		||||
        if (this.versionService) {
 | 
			
		||||
            const versionInfo = this.versionService.getVersionInfo();
 | 
			
		||||
            res.json({ ...config, versionInfo });
 | 
			
		||||
        } else {
 | 
			
		||||
            res.json(config);
 | 
			
		||||
        }
 | 
			
		||||
        const simpleAuthSettings =
 | 
			
		||||
            await this.settingService.get<SimpleAuthSettings>(simpleAuthKey);
 | 
			
		||||
 | 
			
		||||
        const versionInfo = this.versionService.getVersionInfo();
 | 
			
		||||
        const disablePasswordAuth = simpleAuthSettings?.disabled;
 | 
			
		||||
        res.json({ ...config, versionInfo, disablePasswordAuth });
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
export default ConfigController;
 | 
			
		||||
module.exports = ConfigController;
 | 
			
		||||
 | 
			
		||||
@ -24,6 +24,7 @@ import { IAuthRequest } from './routes/unleash-types';
 | 
			
		||||
import * as permissions from './types/permissions';
 | 
			
		||||
import * as eventType from './types/events';
 | 
			
		||||
import { RoleName } from './types/model';
 | 
			
		||||
import { SimpleAuthSettings } from './types/settings/simple-auth-settings';
 | 
			
		||||
 | 
			
		||||
async function createApp(
 | 
			
		||||
    config: IUnleashConfig,
 | 
			
		||||
@ -177,4 +178,5 @@ export type {
 | 
			
		||||
    IUser,
 | 
			
		||||
    IUnleashServices,
 | 
			
		||||
    IAuthRequest,
 | 
			
		||||
    SimpleAuthSettings,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -47,15 +47,16 @@ export const createServices = (
 | 
			
		||||
    const tagTypeService = new TagTypeService(stores, config);
 | 
			
		||||
    const addonService = new AddonService(stores, config, tagTypeService);
 | 
			
		||||
    const sessionService = new SessionService(stores, config);
 | 
			
		||||
    const settingService = new SettingService(stores, config);
 | 
			
		||||
    const userService = new UserService(stores, config, {
 | 
			
		||||
        accessService,
 | 
			
		||||
        resetTokenService,
 | 
			
		||||
        emailService,
 | 
			
		||||
        sessionService,
 | 
			
		||||
        settingService,
 | 
			
		||||
    });
 | 
			
		||||
    const versionService = new VersionService(stores, config);
 | 
			
		||||
    const healthService = new HealthService(stores, config);
 | 
			
		||||
    const settingService = new SettingService(stores, config);
 | 
			
		||||
    const userFeedbackService = new UserFeedbackService(stores, config);
 | 
			
		||||
    const featureToggleServiceV2 = new FeatureToggleServiceV2(stores, config);
 | 
			
		||||
    const environmentService = new EnvironmentService(stores, config);
 | 
			
		||||
 | 
			
		||||
@ -16,7 +16,7 @@ export default class SettingService {
 | 
			
		||||
        this.settingStore = settingStore;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async get(id: string): Promise<object> {
 | 
			
		||||
    async get<T>(id: string): Promise<T> {
 | 
			
		||||
        return this.settingStore.get(id);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -11,6 +11,8 @@ import SessionService from './session-service';
 | 
			
		||||
import FakeSessionStore from '../../test/fixtures/fake-session-store';
 | 
			
		||||
import User from '../types/user';
 | 
			
		||||
import FakeResetTokenStore from '../../test/fixtures/fake-reset-token-store';
 | 
			
		||||
import SettingService from './setting-service';
 | 
			
		||||
import FakeSettingStore from '../../test/fixtures/fake-setting-store';
 | 
			
		||||
 | 
			
		||||
const config: IUnleashConfig = createTestConfig();
 | 
			
		||||
 | 
			
		||||
@ -28,12 +30,17 @@ test('Should create new user', async () => {
 | 
			
		||||
    const sessionStore = new FakeSessionStore();
 | 
			
		||||
    const sessionService = new SessionService({ sessionStore }, config);
 | 
			
		||||
    const emailService = new EmailService(config.email, config.getLogger);
 | 
			
		||||
    const settingService = new SettingService(
 | 
			
		||||
        { settingStore: new FakeSettingStore() },
 | 
			
		||||
        config,
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    const service = new UserService({ userStore, eventStore }, config, {
 | 
			
		||||
        accessService,
 | 
			
		||||
        resetTokenService,
 | 
			
		||||
        emailService,
 | 
			
		||||
        sessionService,
 | 
			
		||||
        settingService,
 | 
			
		||||
    });
 | 
			
		||||
    const user = await service.createUser(
 | 
			
		||||
        {
 | 
			
		||||
@ -63,12 +70,17 @@ test('Should create default user', async () => {
 | 
			
		||||
    const emailService = new EmailService(config.email, config.getLogger);
 | 
			
		||||
    const sessionStore = new FakeSessionStore();
 | 
			
		||||
    const sessionService = new SessionService({ sessionStore }, config);
 | 
			
		||||
    const settingService = new SettingService(
 | 
			
		||||
        { settingStore: new FakeSettingStore() },
 | 
			
		||||
        config,
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    const service = new UserService({ userStore, eventStore }, config, {
 | 
			
		||||
        accessService,
 | 
			
		||||
        resetTokenService,
 | 
			
		||||
        emailService,
 | 
			
		||||
        sessionService,
 | 
			
		||||
        settingService,
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    await service.initAdminUser();
 | 
			
		||||
@ -90,12 +102,17 @@ test('Should be a valid password', async () => {
 | 
			
		||||
    const emailService = new EmailService(config.email, config.getLogger);
 | 
			
		||||
    const sessionStore = new FakeSessionStore();
 | 
			
		||||
    const sessionService = new SessionService({ sessionStore }, config);
 | 
			
		||||
    const settingService = new SettingService(
 | 
			
		||||
        { settingStore: new FakeSettingStore() },
 | 
			
		||||
        config,
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    const service = new UserService({ userStore, eventStore }, config, {
 | 
			
		||||
        accessService,
 | 
			
		||||
        resetTokenService,
 | 
			
		||||
        emailService,
 | 
			
		||||
        sessionService,
 | 
			
		||||
        settingService,
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    const valid = service.validatePassword('this is a strong password!');
 | 
			
		||||
@ -115,12 +132,17 @@ test('Password must be at least 10 chars', async () => {
 | 
			
		||||
    const emailService = new EmailService(config.email, config.getLogger);
 | 
			
		||||
    const sessionStore = new FakeSessionStore();
 | 
			
		||||
    const sessionService = new SessionService({ sessionStore }, config);
 | 
			
		||||
    const settingService = new SettingService(
 | 
			
		||||
        { settingStore: new FakeSettingStore() },
 | 
			
		||||
        config,
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    const service = new UserService({ userStore, eventStore }, config, {
 | 
			
		||||
        accessService,
 | 
			
		||||
        resetTokenService,
 | 
			
		||||
        emailService,
 | 
			
		||||
        sessionService,
 | 
			
		||||
        settingService,
 | 
			
		||||
    });
 | 
			
		||||
    expect(() => service.validatePassword('admin')).toThrow(
 | 
			
		||||
        'The password must be at least 10 characters long.',
 | 
			
		||||
@ -142,12 +164,17 @@ test('The password must contain at least one uppercase letter.', async () => {
 | 
			
		||||
    const emailService = new EmailService(config.email, config.getLogger);
 | 
			
		||||
    const sessionStore = new FakeSessionStore();
 | 
			
		||||
    const sessionService = new SessionService({ sessionStore }, config);
 | 
			
		||||
    const settingService = new SettingService(
 | 
			
		||||
        { settingStore: new FakeSettingStore() },
 | 
			
		||||
        config,
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    const service = new UserService({ userStore, eventStore }, config, {
 | 
			
		||||
        accessService,
 | 
			
		||||
        resetTokenService,
 | 
			
		||||
        emailService,
 | 
			
		||||
        sessionService,
 | 
			
		||||
        settingService,
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    expect(() => service.validatePassword('qwertyabcde')).toThrowError(
 | 
			
		||||
@ -171,12 +198,17 @@ test('The password must contain at least one number', async () => {
 | 
			
		||||
    const emailService = new EmailService(config.email, config.getLogger);
 | 
			
		||||
    const sessionStore = new FakeSessionStore();
 | 
			
		||||
    const sessionService = new SessionService({ sessionStore }, config);
 | 
			
		||||
    const settingService = new SettingService(
 | 
			
		||||
        { settingStore: new FakeSettingStore() },
 | 
			
		||||
        config,
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    const service = new UserService({ userStore, eventStore }, config, {
 | 
			
		||||
        accessService,
 | 
			
		||||
        resetTokenService,
 | 
			
		||||
        emailService,
 | 
			
		||||
        sessionService,
 | 
			
		||||
        settingService,
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    expect(() => service.validatePassword('qwertyabcdE')).toThrowError(
 | 
			
		||||
@ -199,12 +231,17 @@ test('The password must contain at least one special character', async () => {
 | 
			
		||||
    const emailService = new EmailService(config.email, config.getLogger);
 | 
			
		||||
    const sessionStore = new FakeSessionStore();
 | 
			
		||||
    const sessionService = new SessionService({ sessionStore }, config);
 | 
			
		||||
    const settingService = new SettingService(
 | 
			
		||||
        { settingStore: new FakeSettingStore() },
 | 
			
		||||
        config,
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    const service = new UserService({ userStore, eventStore }, config, {
 | 
			
		||||
        accessService,
 | 
			
		||||
        resetTokenService,
 | 
			
		||||
        emailService,
 | 
			
		||||
        sessionService,
 | 
			
		||||
        settingService,
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    expect(() => service.validatePassword('qwertyabcdE2')).toThrowError(
 | 
			
		||||
@ -227,12 +264,17 @@ test('Should be a valid password with special chars', async () => {
 | 
			
		||||
    const emailService = new EmailService(config.email, config.getLogger);
 | 
			
		||||
    const sessionStore = new FakeSessionStore();
 | 
			
		||||
    const sessionService = new SessionService({ sessionStore }, config);
 | 
			
		||||
    const settingService = new SettingService(
 | 
			
		||||
        { settingStore: new FakeSettingStore() },
 | 
			
		||||
        config,
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    const service = new UserService({ userStore, eventStore }, config, {
 | 
			
		||||
        accessService,
 | 
			
		||||
        resetTokenService,
 | 
			
		||||
        emailService,
 | 
			
		||||
        sessionService,
 | 
			
		||||
        settingService,
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    const valid = service.validatePassword('this is a strong password!');
 | 
			
		||||
 | 
			
		||||
@ -21,6 +21,9 @@ import { USER_UPDATED, USER_CREATED, USER_DELETED } from '../types/events';
 | 
			
		||||
import { IEventStore } from '../types/stores/event-store';
 | 
			
		||||
import { IUserSearch, IUserStore } from '../types/stores/user-store';
 | 
			
		||||
import { RoleName } from '../types/model';
 | 
			
		||||
import SettingService from './setting-service';
 | 
			
		||||
import { SimpleAuthSettings } from '../server-impl';
 | 
			
		||||
import { simpleAuthKey } from '../types/settings/simple-auth-settings';
 | 
			
		||||
 | 
			
		||||
const systemUser = new User({ id: -1, username: 'system' });
 | 
			
		||||
 | 
			
		||||
@ -77,6 +80,8 @@ class UserService {
 | 
			
		||||
 | 
			
		||||
    private emailService: EmailService;
 | 
			
		||||
 | 
			
		||||
    private settingService: SettingService;
 | 
			
		||||
 | 
			
		||||
    constructor(
 | 
			
		||||
        stores: Pick<IUnleashStores, 'userStore' | 'eventStore'>,
 | 
			
		||||
        {
 | 
			
		||||
@ -88,6 +93,7 @@ class UserService {
 | 
			
		||||
            resetTokenService: ResetTokenService;
 | 
			
		||||
            emailService: EmailService;
 | 
			
		||||
            sessionService: SessionService;
 | 
			
		||||
            settingService: SettingService;
 | 
			
		||||
        },
 | 
			
		||||
    ) {
 | 
			
		||||
        this.logger = getLogger('service/user-service.js');
 | 
			
		||||
@ -97,6 +103,7 @@ class UserService {
 | 
			
		||||
        this.resetTokenService = services.resetTokenService;
 | 
			
		||||
        this.emailService = services.emailService;
 | 
			
		||||
        this.sessionService = services.sessionService;
 | 
			
		||||
        this.settingService = services.settingService;
 | 
			
		||||
        if (authentication && authentication.createAdminUser) {
 | 
			
		||||
            process.nextTick(() => this.initAdminUser());
 | 
			
		||||
        }
 | 
			
		||||
@ -241,6 +248,16 @@ class UserService {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async loginUser(usernameOrEmail: string, password: string): Promise<IUser> {
 | 
			
		||||
        const settings = await this.settingService.get<SimpleAuthSettings>(
 | 
			
		||||
            simpleAuthKey,
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        if (settings && settings.disabled) {
 | 
			
		||||
            throw new Error(
 | 
			
		||||
                'Logging in with username/password has been disabled.',
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const idQuery = isEmail(usernameOrEmail)
 | 
			
		||||
            ? { email: usernameOrEmail }
 | 
			
		||||
            : { username: usernameOrEmail };
 | 
			
		||||
 | 
			
		||||
@ -2,6 +2,7 @@ interface IBaseOptions {
 | 
			
		||||
    type: string;
 | 
			
		||||
    path: string;
 | 
			
		||||
    message: string;
 | 
			
		||||
    defaultHidden?: boolean;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
interface IOptions extends IBaseOptions {
 | 
			
		||||
@ -15,13 +16,22 @@ class AuthenticationRequired {
 | 
			
		||||
 | 
			
		||||
    private message: string;
 | 
			
		||||
 | 
			
		||||
    private defaultHidden: boolean;
 | 
			
		||||
 | 
			
		||||
    private options?: IBaseOptions[];
 | 
			
		||||
 | 
			
		||||
    constructor({ type, path, message, options }: IOptions) {
 | 
			
		||||
    constructor({
 | 
			
		||||
        type,
 | 
			
		||||
        path,
 | 
			
		||||
        message,
 | 
			
		||||
        options,
 | 
			
		||||
        defaultHidden = false,
 | 
			
		||||
    }: IOptions) {
 | 
			
		||||
        this.type = type;
 | 
			
		||||
        this.path = path;
 | 
			
		||||
        this.message = message;
 | 
			
		||||
        this.options = options;
 | 
			
		||||
        this.defaultHidden = defaultHidden;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										4
									
								
								src/lib/types/settings/simple-auth-settings.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								src/lib/types/settings/simple-auth-settings.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,4 @@
 | 
			
		||||
export const simpleAuthKey = 'unleash.auth.simple';
 | 
			
		||||
export interface SimpleAuthSettings {
 | 
			
		||||
    disabled: boolean;
 | 
			
		||||
}
 | 
			
		||||
@ -6,6 +6,6 @@ export interface ISettingInsert {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface ISettingStore extends Store<any, string> {
 | 
			
		||||
    insert(name: string, content: any): Promise<void>;
 | 
			
		||||
    insert<T>(name: string, content: T): Promise<void>;
 | 
			
		||||
    updateRow(name: string, content: any): Promise<void>;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										37
									
								
								src/test/e2e/api/admin/config.e2e.test.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								src/test/e2e/api/admin/config.e2e.test.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,37 @@
 | 
			
		||||
import dbInit, { ITestDb } from '../../helpers/database-init';
 | 
			
		||||
import { setupApp } from '../../helpers/test-helper';
 | 
			
		||||
import getLogger from '../../../fixtures/no-logger';
 | 
			
		||||
import { simpleAuthKey } from '../../../../lib/types/settings/simple-auth-settings';
 | 
			
		||||
 | 
			
		||||
let db: ITestDb;
 | 
			
		||||
let app;
 | 
			
		||||
 | 
			
		||||
beforeAll(async () => {
 | 
			
		||||
    db = await dbInit('config_api_serial', getLogger);
 | 
			
		||||
    app = await setupApp(db.stores);
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
afterAll(async () => {
 | 
			
		||||
    await app.destroy();
 | 
			
		||||
    await db.destroy();
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
test('gets ui config', async () => {
 | 
			
		||||
    const { body } = await app.request
 | 
			
		||||
        .get('/api/admin/ui-config')
 | 
			
		||||
        .expect('Content-Type', /json/)
 | 
			
		||||
        .expect(200);
 | 
			
		||||
 | 
			
		||||
    expect(body.unleashUrl).toBe('http://localhost:4242');
 | 
			
		||||
    expect(body.version).toBeDefined();
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
test('gets ui config with disablePasswordAuth', async () => {
 | 
			
		||||
    await db.stores.settingStore.insert(simpleAuthKey, { disabled: true });
 | 
			
		||||
    const { body } = await app.request
 | 
			
		||||
        .get('/api/admin/ui-config')
 | 
			
		||||
        .expect('Content-Type', /json/)
 | 
			
		||||
        .expect(200);
 | 
			
		||||
 | 
			
		||||
    expect(body.disablePasswordAuth).toBe(true);
 | 
			
		||||
});
 | 
			
		||||
@ -13,6 +13,8 @@ import { EmailService } from '../../../../lib/services/email-service';
 | 
			
		||||
import SessionStore from '../../../../lib/db/session-store';
 | 
			
		||||
import SessionService from '../../../../lib/services/session-service';
 | 
			
		||||
import { RoleName } from '../../../../lib/types/model';
 | 
			
		||||
import SettingService from '../../../../lib/services/setting-service';
 | 
			
		||||
import FakeSettingStore from '../../../fixtures/fake-setting-store';
 | 
			
		||||
 | 
			
		||||
let app;
 | 
			
		||||
let stores;
 | 
			
		||||
@ -53,11 +55,16 @@ beforeAll(async () => {
 | 
			
		||||
        config.getLogger,
 | 
			
		||||
    );
 | 
			
		||||
    const sessionService = new SessionService({ sessionStore }, config);
 | 
			
		||||
    const settingService = new SettingService(
 | 
			
		||||
        { settingStore: new FakeSettingStore() },
 | 
			
		||||
        config,
 | 
			
		||||
    );
 | 
			
		||||
    userService = new UserService(stores, config, {
 | 
			
		||||
        accessService,
 | 
			
		||||
        resetTokenService,
 | 
			
		||||
        emailService,
 | 
			
		||||
        sessionService,
 | 
			
		||||
        settingService,
 | 
			
		||||
    });
 | 
			
		||||
    resetTokenService = new ResetTokenService(stores, config);
 | 
			
		||||
    const adminRole = await accessService.getRootRole(RoleName.ADMIN);
 | 
			
		||||
 | 
			
		||||
@ -9,6 +9,8 @@ import { createTestConfig } from '../../config/test-config';
 | 
			
		||||
import SessionService from '../../../lib/services/session-service';
 | 
			
		||||
import InvalidTokenError from '../../../lib/error/invalid-token-error';
 | 
			
		||||
import { IUser } from '../../../lib/types/user';
 | 
			
		||||
import SettingService from '../../../lib/services/setting-service';
 | 
			
		||||
import FakeSettingStore from '../../fixtures/fake-setting-store';
 | 
			
		||||
 | 
			
		||||
const config: IUnleashConfig = createTestConfig();
 | 
			
		||||
 | 
			
		||||
@ -28,12 +30,17 @@ beforeAll(async () => {
 | 
			
		||||
    resetTokenService = new ResetTokenService(stores, config);
 | 
			
		||||
    sessionService = new SessionService(stores, config);
 | 
			
		||||
    const emailService = new EmailService(undefined, config.getLogger);
 | 
			
		||||
    const settingService = new SettingService(
 | 
			
		||||
        { settingStore: new FakeSettingStore() },
 | 
			
		||||
        config,
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    userService = new UserService(stores, config, {
 | 
			
		||||
        accessService,
 | 
			
		||||
        resetTokenService,
 | 
			
		||||
        emailService,
 | 
			
		||||
        sessionService,
 | 
			
		||||
        settingService,
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    adminUser = await userService.createUser({
 | 
			
		||||
 | 
			
		||||
@ -10,6 +10,8 @@ import SessionService from '../../../lib/services/session-service';
 | 
			
		||||
import NotFoundError from '../../../lib/error/notfound-error';
 | 
			
		||||
import { IRole } from '../../../lib/types/stores/access-store';
 | 
			
		||||
import { RoleName } from '../../../lib/types/model';
 | 
			
		||||
import SettingService from '../../../lib/services/setting-service';
 | 
			
		||||
import { simpleAuthKey } from '../../../lib/types/settings/simple-auth-settings';
 | 
			
		||||
 | 
			
		||||
let db;
 | 
			
		||||
let stores;
 | 
			
		||||
@ -27,12 +29,14 @@ beforeAll(async () => {
 | 
			
		||||
    const resetTokenService = new ResetTokenService(stores, config);
 | 
			
		||||
    const emailService = new EmailService(undefined, config.getLogger);
 | 
			
		||||
    sessionService = new SessionService(stores, config);
 | 
			
		||||
    const settingService = new SettingService(stores, config);
 | 
			
		||||
 | 
			
		||||
    userService = new UserService(stores, config, {
 | 
			
		||||
        accessService,
 | 
			
		||||
        resetTokenService,
 | 
			
		||||
        emailService,
 | 
			
		||||
        sessionService,
 | 
			
		||||
        settingService,
 | 
			
		||||
    });
 | 
			
		||||
    userStore = stores.userStore;
 | 
			
		||||
    const rootRoles = await accessService.getRootRoles();
 | 
			
		||||
@ -93,6 +97,22 @@ test('should create user with password', async () => {
 | 
			
		||||
    expect(user.username).toBe('test');
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
test('should not login user if simple auth is disabled', async () => {
 | 
			
		||||
    await db.stores.settingStore.insert(simpleAuthKey, { disabled: true });
 | 
			
		||||
 | 
			
		||||
    await userService.createUser({
 | 
			
		||||
        username: 'test_no_pass',
 | 
			
		||||
        password: 'A very strange P4ssw0rd_',
 | 
			
		||||
        rootRole: adminRole.id,
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    await expect(async () => {
 | 
			
		||||
        await userService.loginUser('test_no_pass', 'A very strange P4ssw0rd_');
 | 
			
		||||
    }).rejects.toThrowError(
 | 
			
		||||
        'Logging in with username/password has been disabled.',
 | 
			
		||||
    );
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
test('should login for user _without_ password', async () => {
 | 
			
		||||
    const email = 'some@test.com';
 | 
			
		||||
    await userService.createUser({
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										3
									
								
								src/test/fixtures/fake-setting-store.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								src/test/fixtures/fake-setting-store.ts
									
									
									
									
										vendored
									
									
								
							@ -1,5 +1,4 @@
 | 
			
		||||
import { ISettingStore } from '../../lib/types/stores/settings-store';
 | 
			
		||||
import NotFoundError from '../../lib/error/notfound-error';
 | 
			
		||||
 | 
			
		||||
export default class FakeSettingStore implements ISettingStore {
 | 
			
		||||
    settings: Map<string, any> = new Map();
 | 
			
		||||
@ -23,7 +22,7 @@ export default class FakeSettingStore implements ISettingStore {
 | 
			
		||||
        if (setting) {
 | 
			
		||||
            return setting;
 | 
			
		||||
        }
 | 
			
		||||
        throw new NotFoundError(`Could not find setting with key ${key}`);
 | 
			
		||||
        return undefined;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async getAll(): Promise<any[]> {
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user