From 8d5f95b6c8f8164a829a87b1fa71d769a8bb39b7 Mon Sep 17 00:00:00 2001 From: rubikscraft Date: Wed, 30 Mar 2022 14:10:01 +0200 Subject: [PATCH] make bcrypt strength configurable --- .../syspreferencedefaults.service.ts | 2 ++ .../src/collections/userdb/userdb.module.ts | 2 ++ .../src/collections/userdb/userdb.service.ts | 22 ++++++++++++++----- backend/src/models/dto/syspreferences.dto.ts | 1 + frontend/src/app/i18n/syspref.i18n.ts | 1 + shared/src/dto/syspreferences.dto.ts | 1 + 6 files changed, 24 insertions(+), 5 deletions(-) diff --git a/backend/src/collections/syspreferencesdb/syspreferencedefaults.service.ts b/backend/src/collections/syspreferencesdb/syspreferencedefaults.service.ts index b38a252..0a75fb5 100644 --- a/backend/src/collections/syspreferencesdb/syspreferencedefaults.service.ts +++ b/backend/src/collections/syspreferencesdb/syspreferencedefaults.service.ts @@ -31,6 +31,8 @@ export class SysPreferenceDefaultsService { }, [SysPreference.JwtExpiresIn]: () => this.jwtConfigService.getJwtExpiresIn() ?? '7d', + [SysPreference.BCryptStrength]: () => 12, + [SysPreference.TestString]: () => 'test_string', [SysPreference.TestNumber]: () => 123, [SysPreference.TestBoolean]: () => true, diff --git a/backend/src/collections/userdb/userdb.module.ts b/backend/src/collections/userdb/userdb.module.ts index 0e62c99..8ab2abf 100644 --- a/backend/src/collections/userdb/userdb.module.ts +++ b/backend/src/collections/userdb/userdb.module.ts @@ -6,12 +6,14 @@ import { AuthConfigService } from '../../config/early/auth.config.service'; import { EarlyConfigModule } from '../../config/early/earlyconfig.module'; import { EUserBackend } from '../../models/entities/user.entity'; import { RolesModule } from '../roledb/roledb.module'; +import { SysPreferenceModule } from '../syspreferencesdb/syspreferencedb.module'; import { UsersService } from './userdb.service'; @Module({ imports: [ EarlyConfigModule, RolesModule, + SysPreferenceModule, TypeOrmModule.forFeature([EUserBackend]), ], providers: [UsersService], diff --git a/backend/src/collections/userdb/userdb.service.ts b/backend/src/collections/userdb/userdb.service.ts index 4ed5162..53b2961 100644 --- a/backend/src/collections/userdb/userdb.service.ts +++ b/backend/src/collections/userdb/userdb.service.ts @@ -2,6 +2,7 @@ import { Injectable, Logger } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; import * as bcrypt from 'bcrypt'; import { plainToClass } from 'class-transformer'; +import { SysPreference } from 'picsur-shared/dist/dto/syspreferences.dto'; import { AsyncFailable, Fail, @@ -24,9 +25,7 @@ import { import { EUserBackend } from '../../models/entities/user.entity'; import { GetCols } from '../../models/util/collection'; import { RolesService } from '../roledb/roledb.service'; - -// TODO: make this a configurable value -const BCryptStrength = 12; +import { SysPreferenceService } from '../syspreferencesdb/syspreferencedb.service'; @Injectable() export class UsersService { @@ -36,6 +35,7 @@ export class UsersService { @InjectRepository(EUserBackend) private usersRepository: Repository, private rolesService: RolesService, + private prefService: SysPreferenceService, ) {} // Creation and deletion @@ -49,7 +49,8 @@ export class UsersService { ): AsyncFailable { if (await this.exists(username)) return Fail('User already exists'); - const hashedPassword = await bcrypt.hash(password, BCryptStrength); + const strength = await this.getBCryptStrength(); + const hashedPassword = await bcrypt.hash(password, strength); let user = new EUserBackend(); user.username = username; @@ -153,7 +154,8 @@ export class UsersService { let userToModify = await this.resolve(user); if (HasFailed(userToModify)) return userToModify; - const hashedPassword = await bcrypt.hash(password, BCryptStrength); + const strength = await this.getBCryptStrength(); + const hashedPassword = await bcrypt.hash(password, strength); userToModify.password = hashedPassword; try { @@ -257,4 +259,14 @@ export class UsersService { return filteredRoles; } + + private async getBCryptStrength(): Promise { + const result = await this.prefService.getNumberPreference( + SysPreference.BCryptStrength, + ); + if (HasFailed(result)) { + return 12; + } + return result; + } } diff --git a/backend/src/models/dto/syspreferences.dto.ts b/backend/src/models/dto/syspreferences.dto.ts index 2ce7265..045ee18 100644 --- a/backend/src/models/dto/syspreferences.dto.ts +++ b/backend/src/models/dto/syspreferences.dto.ts @@ -12,6 +12,7 @@ export const SysPreferenceValueTypes: { } = { [SysPreference.JwtSecret]: 'string', [SysPreference.JwtExpiresIn]: 'string', + [SysPreference.BCryptStrength]: 'number', [SysPreference.TestString]: 'string', [SysPreference.TestNumber]: 'number', [SysPreference.TestBoolean]: 'boolean', diff --git a/frontend/src/app/i18n/syspref.i18n.ts b/frontend/src/app/i18n/syspref.i18n.ts index 6ef9ab1..fe0ce2e 100644 --- a/frontend/src/app/i18n/syspref.i18n.ts +++ b/frontend/src/app/i18n/syspref.i18n.ts @@ -5,6 +5,7 @@ export const SysPreferenceFriendlyNames: { } = { [SysPreference.JwtSecret]: 'JWT Secret', [SysPreference.JwtExpiresIn]: 'JWT Expiry Time', + [SysPreference.BCryptStrength]: 'BCrypt Strength', [SysPreference.TestString]: 'Test String', [SysPreference.TestNumber]: 'Test Number', [SysPreference.TestBoolean]: 'Test Boolean', diff --git a/shared/src/dto/syspreferences.dto.ts b/shared/src/dto/syspreferences.dto.ts index 168b832..7166883 100644 --- a/shared/src/dto/syspreferences.dto.ts +++ b/shared/src/dto/syspreferences.dto.ts @@ -2,6 +2,7 @@ export enum SysPreference { JwtSecret = 'jwt_secret', JwtExpiresIn = 'jwt_expires_in', + BCryptStrength = 'bcrypt_strength', TestString = 'test_string', TestNumber = 'test_number', TestBoolean = 'test_boolean',