mirror of
				https://github.com/KevinMidboe/immich.git
				synced 2025-10-29 17:40:28 +00:00 
			
		
		
		
	refactor(server): drop salt column (#1185)
This commit is contained in:
		@@ -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;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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) {
 | 
			
		||||
 
 | 
			
		||||
@@ -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,
 | 
			
		||||
 
 | 
			
		||||
@@ -51,7 +51,6 @@ describe('ImmichJwtService', () => {
 | 
			
		||||
        isAdmin: false,
 | 
			
		||||
        email: 'test@immich.com',
 | 
			
		||||
        password: 'changeme',
 | 
			
		||||
        salt: '123',
 | 
			
		||||
        oauthId: '',
 | 
			
		||||
        profileImagePath: '',
 | 
			
		||||
        shouldChangePassword: false,
 | 
			
		||||
 
 | 
			
		||||
@@ -21,9 +21,6 @@ export class UserEntity {
 | 
			
		||||
  @Column({ default: '', select: false })
 | 
			
		||||
  password?: string;
 | 
			
		||||
 | 
			
		||||
  @Column({ default: '', select: false })
 | 
			
		||||
  salt?: string;
 | 
			
		||||
 | 
			
		||||
  @Column({ default: '' })
 | 
			
		||||
  oauthId!: string;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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 ''`);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user