diff --git a/server/src/domain/user/user.core.ts b/server/src/domain/user/user.core.ts index 1b3e872256..915830fd09 100644 --- a/server/src/domain/user/user.core.ts +++ b/server/src/domain/user/user.core.ts @@ -116,6 +116,14 @@ export class UserCore { return createReadStream(user.profileImagePath); } + async getUserProfileImageHash(user: UserEntity): Promise { + if (!user.profileImageHash) { + throw new NotFoundException('User does not have a profile image'); + } + return user.profileImageHash; + + + async getList(filter?: UserListFilter): Promise { return this.userRepository.getList(filter); } diff --git a/server/src/domain/user/user.service.ts b/server/src/domain/user/user.service.ts index d668151957..a45cde019c 100644 --- a/server/src/domain/user/user.service.ts +++ b/server/src/domain/user/user.service.ts @@ -120,6 +120,14 @@ export class UserService { return this.userCore.getUserProfileImage(user); } + async getUserProfileImageHash(userId: string): Promise { + const user = await this.userCore.get(userId); + if (!user) { + throw new NotFoundException('User not found'); + } + return this.userCore.getUserProfileImageHash(user); + } + async resetAdminPassword(ask: (admin: UserResponseDto) => Promise) { const admin = await this.userCore.getAdmin(); if (!admin) { diff --git a/server/src/immich/controllers/user.controller.ts b/server/src/immich/controllers/user.controller.ts index 52b00898e1..9c3b9cdeaa 100644 --- a/server/src/immich/controllers/user.controller.ts +++ b/server/src/immich/controllers/user.controller.ts @@ -98,10 +98,11 @@ export class UserController { } @Get('/profile-image/:userId') - @Header('Cache-Control', 'private, max-age=86400, no-transform') + @Header('Cache-Control', 'private, no-cache, no-transform') async getProfileImage(@Param() { userId }: UserIdDto, @Response({ passthrough: true }) res: Res): Promise { const readableStream = await this.service.getUserProfileImage(userId); res.header('Content-Type', 'image/jpeg'); + res.header('ETag', await this.service.getUserProfileImageHash(userId)); return new StreamableFile(readableStream); } } diff --git a/server/src/infra/entities/user.entity.ts b/server/src/infra/entities/user.entity.ts index 7cdac1f824..495b279609 100644 --- a/server/src/infra/entities/user.entity.ts +++ b/server/src/infra/entities/user.entity.ts @@ -42,6 +42,9 @@ export class UserEntity { @Column({ default: '' }) profileImagePath!: string; + @Column({ default: '' }) + profileImageHash!: string; + @Column({ default: true }) shouldChangePassword!: boolean;