mirror of
https://github.com/CaramelFur/Picsur.git
synced 2026-01-27 09:29:05 +01:00
Add custom decorator
This commit is contained in:
@@ -2,11 +2,9 @@ import { Module } from '@nestjs/common';
|
||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||
import { AuthModule } from './routes/auth/auth.module';
|
||||
import { UserEntity } from './collections/userdb/user.entity';
|
||||
import { UsersModule } from './collections/userdb/userdb.module';
|
||||
import { ImageModule } from './routes/image/imageroute.module';
|
||||
import Config from './env';
|
||||
import { ImageEntity } from './collections/imagedb/image.entity';
|
||||
import { SafeImagesModule } from './lib/safeimages/safeimages.module';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
@@ -22,9 +20,7 @@ import { SafeImagesModule } from './lib/safeimages/safeimages.module';
|
||||
entities: [UserEntity, ImageEntity],
|
||||
}),
|
||||
AuthModule,
|
||||
UsersModule,
|
||||
ImageModule,
|
||||
SafeImagesModule,
|
||||
],
|
||||
})
|
||||
export class AppModule {}
|
||||
|
||||
38
src/decorators/multipart.decorator.ts
Normal file
38
src/decorators/multipart.decorator.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
import {
|
||||
BadRequestException,
|
||||
createParamDecorator,
|
||||
ExecutionContext,
|
||||
} from '@nestjs/common';
|
||||
import { FastifyRequest } from 'fastify';
|
||||
import { Multipart } from 'fastify-multipart';
|
||||
import { request } from 'http';
|
||||
import Config from 'src/env';
|
||||
|
||||
export interface MPFile {
|
||||
fieldname: string;
|
||||
}
|
||||
|
||||
export const PostFile = createParamDecorator(
|
||||
async (data: unknown, ctx: ExecutionContext) => {
|
||||
const req: FastifyRequest = ctx.switchToHttp().getRequest();
|
||||
|
||||
if (!req.isMultipart()) throw new BadRequestException('Invalid file');
|
||||
|
||||
const file = await req.file({
|
||||
limits: { fileSize: Config.limits.maxFileSize, files: 1 },
|
||||
});
|
||||
if (file === undefined) throw new BadRequestException('Invalid file');
|
||||
|
||||
const allFields: Multipart[] = Object.values(file.fields).filter(
|
||||
(entry) => entry,
|
||||
) as any;
|
||||
|
||||
const files = allFields.filter((entry) => entry.file !== undefined);
|
||||
|
||||
if (files.length !== 1) throw new BadRequestException('Invalid file');
|
||||
|
||||
return await files[0].toBuffer();
|
||||
},
|
||||
);
|
||||
|
||||
// TODO: Make better multipart decoder
|
||||
@@ -1,7 +1,7 @@
|
||||
const Config = {
|
||||
database: {
|
||||
host: process.env.DB_HOST ?? 'localhost',
|
||||
port: parseInt(process.env.DB_PORT) ?? 5432,
|
||||
port: process.env.DB_PORT ? parseInt(process.env.DB_PORT) : 5432,
|
||||
username: process.env.DB_USERNAME ?? 'imagur',
|
||||
password: process.env.DB_PASSWORD ?? 'imagur',
|
||||
database: process.env.DB_DATABASE ?? 'imagur',
|
||||
@@ -14,6 +14,11 @@ const Config = {
|
||||
secret: process.env.JWT_SECRET ?? 'CHANGE_ME',
|
||||
expiresIn: process.env.JWT_EXPIRES_IN ?? '1d',
|
||||
},
|
||||
limits: {
|
||||
maxFileSize: process.env.MAX_FILE_SIZE
|
||||
? parseInt(process.env.MAX_FILE_SIZE)
|
||||
: 128000000,
|
||||
},
|
||||
};
|
||||
|
||||
export default Config;
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { ImageDBModule } from 'src/collections/imagedb/imagedb.module';
|
||||
import { SafeImagesService } from './safeimages.service';
|
||||
|
||||
@Module({
|
||||
imports: [ImageDBModule],
|
||||
providers: [SafeImagesService],
|
||||
exports: [SafeImagesService],
|
||||
})
|
||||
export class SafeImagesModule {}
|
||||
10
src/managers/imagemanager/imagemanager.module.ts
Normal file
10
src/managers/imagemanager/imagemanager.module.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { ImageDBModule } from 'src/collections/imagedb/imagedb.module';
|
||||
import { ImageManagerService } from './imagemanager.service';
|
||||
|
||||
@Module({
|
||||
imports: [ImageDBModule],
|
||||
providers: [ImageManagerService],
|
||||
exports: [ImageManagerService],
|
||||
})
|
||||
export class ImageManagerModule {}
|
||||
@@ -6,7 +6,7 @@ import { FullMime, MimesService } from 'src/collections/imagedb/mimes.service';
|
||||
import { AsyncFailable, Fail, HasFailed } from 'src/types/failable';
|
||||
|
||||
@Injectable()
|
||||
export class SafeImagesService {
|
||||
export class ImageManagerService {
|
||||
constructor(
|
||||
private readonly imagesService: ImageDBService,
|
||||
private readonly mimesService: MimesService,
|
||||
@@ -10,13 +10,13 @@ import {
|
||||
Res,
|
||||
} from '@nestjs/common';
|
||||
import { FastifyReply, FastifyRequest } from 'fastify';
|
||||
import { Multipart } from 'fastify-multipart';
|
||||
import { PostFile } from 'src/decorators/multipart.decorator';
|
||||
import { ImageManagerService } from 'src/managers/imagemanager/imagemanager.service';
|
||||
import { HasFailed } from 'src/types/failable';
|
||||
import { SafeImagesService } from 'src/lib/safeimages/safeimages.service';
|
||||
|
||||
@Controller()
|
||||
export class ImageController {
|
||||
constructor(private readonly imagesService: SafeImagesService) {}
|
||||
constructor(private readonly imagesService: ImageManagerService) {}
|
||||
|
||||
@Get('i/:hash')
|
||||
async getImage(
|
||||
@@ -35,27 +35,11 @@ export class ImageController {
|
||||
}
|
||||
|
||||
@Post('i')
|
||||
async uploadImage(@Req() req: FastifyRequest) {
|
||||
if (!req.isMultipart())
|
||||
throw new BadRequestException('Not a multipart request');
|
||||
|
||||
const file = await req.file({ limits: {} });
|
||||
if (file === undefined) throw new BadRequestException('No file uploaded');
|
||||
|
||||
const allFields: Multipart[] = Object.values(file.fields).filter(
|
||||
(entry) => entry,
|
||||
) as any;
|
||||
|
||||
const options = allFields.filter((entry) => entry.file === undefined);
|
||||
const files = allFields.filter((entry) => entry.file !== undefined);
|
||||
|
||||
if (files.length !== 1) throw new BadRequestException('Invalid file');
|
||||
|
||||
const image = await files[0].toBuffer();
|
||||
|
||||
const hash = await this.imagesService.uploadImage(image);
|
||||
if (HasFailed(hash))
|
||||
async uploadImage(@Req() req: FastifyRequest, @PostFile() file: Buffer) {
|
||||
const hash = await this.imagesService.uploadImage(file);
|
||||
if (HasFailed(hash)) {
|
||||
throw new InternalServerErrorException('Failed to upload image');
|
||||
}
|
||||
|
||||
return { hash };
|
||||
}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { SafeImagesModule } from 'src/lib/safeimages/safeimages.module';
|
||||
import { ImageManagerModule } from 'src/managers/imagemanager/imagemanager.module';
|
||||
|
||||
import { ImageController } from './imageroute.controller';
|
||||
|
||||
@Module({
|
||||
imports: [SafeImagesModule],
|
||||
imports: [ImageManagerModule],
|
||||
controllers: [ImageController],
|
||||
})
|
||||
export class ImageModule {}
|
||||
|
||||
Reference in New Issue
Block a user