fix(server): invalidate old user avatar when updated (#7285)

fix CLOUD-41
This commit is contained in:
forehalo
2024-06-20 12:25:10 +00:00
parent a557fd3277
commit aa124638bc
6 changed files with 127 additions and 4 deletions

View File

@@ -7,7 +7,10 @@ export type StorageConfig<Ext = unknown> = {
} & Ext;
export interface StorageStartupConfigurations {
avatar: StorageConfig<{ publicLinkFactory: (key: string) => string }>;
avatar: StorageConfig<{
publicLinkFactory: (key: string) => string;
keyInPublicLink: (link: string) => string;
}>;
blob: StorageConfig;
}
@@ -22,6 +25,7 @@ defineStartupConfig('storages', {
provider: 'fs',
bucket: 'avatars',
publicLinkFactory: key => `/api/avatars/${key}`,
keyInPublicLink: link => link.split('/').pop() as string,
},
blob: {
provider: 'fs',

View File

@@ -42,8 +42,8 @@ export class AvatarStorage {
return this.provider.get(key);
}
delete(key: string) {
return this.provider.delete(key);
delete(link: string) {
return this.provider.delete(this.storageConfig.keyInPublicLink(link));
}
@OnEvent('user.deleted')

View File

@@ -2,8 +2,10 @@ import { Controller, Get, Param, Res } from '@nestjs/common';
import type { Response } from 'express';
import { ActionForbidden, UserAvatarNotFound } from '../../fundamentals';
import { Public } from '../auth/guard';
import { AvatarStorage } from '../storage';
@Public()
@Controller('/api/avatars')
export class UserAvatarController {
constructor(private readonly storage: AvatarStorage) {}

View File

@@ -91,18 +91,26 @@ export class UserResolver {
@Args({ name: 'avatar', type: () => GraphQLUpload })
avatar: FileUpload
) {
if (!avatar.mimetype.startsWith('image/')) {
throw new Error('Invalid file type');
}
if (!user) {
throw new UserNotFound();
}
const avatarUrl = await this.storage.put(
`${user.id}-avatar`,
`${user.id}-avatar-${Date.now()}`,
avatar.createReadStream(),
{
contentType: avatar.mimetype,
}
);
if (user.avatarUrl) {
await this.storage.delete(user.avatarUrl);
}
return this.users.updateUser(user.id, { avatarUrl });
}