refactor(server): use new storage providers (#5433)
This commit is contained in:
40
packages/backend/server/src/modules/users/controller.ts
Normal file
40
packages/backend/server/src/modules/users/controller.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
import {
|
||||
Controller,
|
||||
ForbiddenException,
|
||||
Get,
|
||||
NotFoundException,
|
||||
Param,
|
||||
Res,
|
||||
} from '@nestjs/common';
|
||||
import type { Response } from 'express';
|
||||
|
||||
import { AvatarStorage } from '../storage';
|
||||
|
||||
@Controller('/api/avatars')
|
||||
export class UserAvatarController {
|
||||
constructor(private readonly storage: AvatarStorage) {}
|
||||
|
||||
@Get('/:id')
|
||||
async getAvatar(@Res() res: Response, @Param('id') id: string) {
|
||||
if (this.storage.provider.type !== 'fs') {
|
||||
throw new ForbiddenException(
|
||||
'Only available when avatar storage provider set to fs.'
|
||||
);
|
||||
}
|
||||
|
||||
const { body, metadata } = await this.storage.get(id);
|
||||
|
||||
if (!body) {
|
||||
throw new NotFoundException(`Avatar ${id} not found.`);
|
||||
}
|
||||
|
||||
// metadata should always exists if body is not null
|
||||
if (metadata) {
|
||||
res.setHeader('content-type', metadata.contentType);
|
||||
res.setHeader('last-modified', metadata.lastModified.toISOString());
|
||||
res.setHeader('content-length', metadata.contentLength);
|
||||
}
|
||||
|
||||
body.pipe(res);
|
||||
}
|
||||
}
|
||||
@@ -3,12 +3,14 @@ import { Module } from '@nestjs/common';
|
||||
import { FeatureModule } from '../features';
|
||||
import { QuotaModule } from '../quota';
|
||||
import { StorageModule } from '../storage';
|
||||
import { UserAvatarController } from './controller';
|
||||
import { UserResolver } from './resolver';
|
||||
import { UsersService } from './users';
|
||||
|
||||
@Module({
|
||||
imports: [StorageModule, FeatureModule, QuotaModule],
|
||||
providers: [UserResolver, UsersService],
|
||||
controllers: [UserAvatarController],
|
||||
exports: [UsersService],
|
||||
})
|
||||
export class UsersModule {}
|
||||
|
||||
@@ -17,6 +17,7 @@ import type { User } from '@prisma/client';
|
||||
import { GraphQLError } from 'graphql';
|
||||
import GraphQLUpload from 'graphql-upload/GraphQLUpload.mjs';
|
||||
|
||||
import { EventEmitter } from '../../event';
|
||||
import { PrismaService } from '../../prisma/service';
|
||||
import { CloudThrottlerGuard, Throttle } from '../../throttler';
|
||||
import type { FileUpload } from '../../types';
|
||||
@@ -24,7 +25,7 @@ import { Auth, CurrentUser, Public, Publicable } from '../auth/guard';
|
||||
import { AuthService } from '../auth/service';
|
||||
import { FeatureManagementService } from '../features';
|
||||
import { QuotaService } from '../quota';
|
||||
import { StorageService } from '../storage/storage.service';
|
||||
import { AvatarStorage } from '../storage';
|
||||
import { DeleteAccount, RemoveAvatar, UserQuotaType, UserType } from './types';
|
||||
import { UsersService } from './users';
|
||||
|
||||
@@ -39,10 +40,11 @@ export class UserResolver {
|
||||
constructor(
|
||||
private readonly auth: AuthService,
|
||||
private readonly prisma: PrismaService,
|
||||
private readonly storage: StorageService,
|
||||
private readonly storage: AvatarStorage,
|
||||
private readonly users: UsersService,
|
||||
private readonly feature: FeatureManagementService,
|
||||
private readonly quota: QuotaService
|
||||
private readonly quota: QuotaService,
|
||||
private readonly event: EventEmitter
|
||||
) {}
|
||||
|
||||
@Throttle({
|
||||
@@ -147,10 +149,20 @@ export class UserResolver {
|
||||
if (!user) {
|
||||
throw new BadRequestException(`User not found`);
|
||||
}
|
||||
const url = await this.storage.uploadFile(`${user.id}-avatar`, avatar);
|
||||
|
||||
const link = await this.storage.put(
|
||||
`${user.id}-avatar`,
|
||||
avatar.createReadStream(),
|
||||
{
|
||||
contentType: avatar.mimetype,
|
||||
}
|
||||
);
|
||||
|
||||
return this.prisma.user.update({
|
||||
where: { id: user.id },
|
||||
data: { avatarUrl: url },
|
||||
data: {
|
||||
avatarUrl: link,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@@ -183,7 +195,8 @@ export class UserResolver {
|
||||
})
|
||||
@Mutation(() => DeleteAccount)
|
||||
async deleteAccount(@CurrentUser() user: UserType): Promise<DeleteAccount> {
|
||||
await this.users.deleteUser(user.id);
|
||||
const deletedUser = await this.users.deleteUser(user.id);
|
||||
this.event.emit('user.deleted', deletedUser);
|
||||
return { success: true };
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user