瀏覽代碼

refactor(server): drop salt column (#1185)

Jason Rasmussen 2 年之前
父節點
當前提交
4e860b024b

+ 1 - 3
server/apps/cli/src/commands/reset-admin-password.command.ts

@@ -21,8 +21,7 @@ export class ResetAdminPasswordCommand extends CommandRunner {
     let { password } = await this.inquirer.ask<{ password: string }>('prompt-password', undefined);
     password = password || randomBytes(24).toString('base64').replace(/\W/g, '');
 
-    const salt = await bcrypt.genSalt();
-    const hashedPassword = await bcrypt.hash(password, salt);
+    const hashedPassword = await bcrypt.hash(password, 10);
 
     const user = await this.userRepository.findOne({ where: { isAdmin: true } });
     if (!user) {
@@ -30,7 +29,6 @@ export class ResetAdminPasswordCommand extends CommandRunner {
       return;
     }
 
-    user.salt = salt;
     user.password = hashedPassword;
     user.shouldChangePassword = true;
 

+ 5 - 15
server/apps/immich/src/api-v1/user/user.core.ts

@@ -7,24 +7,18 @@ import {
   NotFoundException,
   UnauthorizedException,
 } from '@nestjs/common';
-import { genSalt, hash } from 'bcrypt';
+import { hash } from 'bcrypt';
 import { createReadStream, constants, ReadStream } from 'fs';
 import fs from 'fs/promises';
 import { AuthUserDto } from '../../decorators/auth-user.decorator';
 import { CreateAdminDto, CreateUserDto, CreateUserOAuthDto } from './dto/create-user.dto';
 import { IUserRepository, UserListFilter } from './user-repository';
 
+const SALT_ROUNDS = 10;
+
 export class UserCore {
   constructor(private userRepository: IUserRepository) {}
 
-  private async generateSalt(): Promise<string> {
-    return genSalt();
-  }
-
-  private async hashPassword(password: string, salt: string): Promise<string> {
-    return hash(password, salt);
-  }
-
   async updateUser(authUser: AuthUserDto, id: string, dto: Partial<UserEntity>): Promise<UserEntity> {
     if (!(authUser.isAdmin || authUser.id === id)) {
       throw new ForbiddenException('You are not allowed to update this user');
@@ -36,9 +30,7 @@ export class UserCore {
 
     try {
       if (dto.password) {
-        const salt = await this.generateSalt();
-        dto.salt = salt;
-        dto.password = await this.hashPassword(dto.password, salt);
+        dto.password = await hash(dto.password, SALT_ROUNDS);
       }
       return this.userRepository.update(id, dto);
     } catch (e) {
@@ -63,9 +55,7 @@ export class UserCore {
     try {
       const payload: Partial<UserEntity> = { ...createUserDto };
       if (payload.password) {
-        const salt = await this.generateSalt();
-        payload.salt = salt;
-        payload.password = await this.hashPassword(payload.password, salt);
+        payload.password = await hash(payload.password, SALT_ROUNDS);
       }
       return this.userRepository.create(payload);
     } catch (e) {

+ 0 - 3
server/apps/immich/src/api-v1/user/user.service.spec.ts

@@ -27,7 +27,6 @@ describe('UserService', () => {
     id: adminUserAuth.id,
     email: 'admin@test.com',
     password: 'admin_password',
-    salt: 'admin_salt',
     firstName: 'admin_first_name',
     lastName: 'admin_last_name',
     isAdmin: true,
@@ -42,7 +41,6 @@ describe('UserService', () => {
     id: immichUserAuth.id,
     email: 'immich@test.com',
     password: 'immich_password',
-    salt: 'immich_salt',
     firstName: 'immich_first_name',
     lastName: 'immich_last_name',
     isAdmin: false,
@@ -57,7 +55,6 @@ describe('UserService', () => {
     id: immichUserAuth.id,
     email: 'immich@test.com',
     password: 'immich_password',
-    salt: 'immich_salt',
     firstName: 'updated_immich_first_name',
     lastName: 'updated_immich_last_name',
     isAdmin: false,

+ 0 - 1
server/apps/immich/src/modules/immich-jwt/immich-jwt.service.spec.ts

@@ -51,7 +51,6 @@ describe('ImmichJwtService', () => {
         isAdmin: false,
         email: 'test@immich.com',
         password: 'changeme',
-        salt: '123',
         oauthId: '',
         profileImagePath: '',
         shouldChangePassword: false,

+ 0 - 3
server/libs/database/src/entities/user.entity.ts

@@ -21,9 +21,6 @@ export class UserEntity {
   @Column({ default: '', select: false })
   password?: string;
 
-  @Column({ default: '', select: false })
-  salt?: string;
-
   @Column({ default: '' })
   oauthId!: string;
 

+ 14 - 0
server/libs/database/src/migrations/1672109862870-DropSaltColumn.ts

@@ -0,0 +1,14 @@
+import { MigrationInterface, QueryRunner } from "typeorm";
+
+export class DropSaltColumn1672109862870 implements MigrationInterface {
+    name = 'DropSaltColumn1672109862870'
+
+    public async up(queryRunner: QueryRunner): Promise<void> {
+        await queryRunner.query(`ALTER TABLE "users" DROP COLUMN "salt"`);
+    }
+
+    public async down(queryRunner: QueryRunner): Promise<void> {
+        await queryRunner.query(`ALTER TABLE "users" ADD "salt" character varying NOT NULL DEFAULT ''`);
+    }
+
+}