This commit is contained in:
Bastian Wagner
2026-07-31 21:25:31 +02:00
parent 4ef35b3755
commit e6757ab9dc
5 changed files with 0 additions and 209 deletions

View File

@@ -1,6 +1,5 @@
import { Module } from '@nestjs/common'; import { Module } from '@nestjs/common';
import { UsersModule } from './users/users.module'; import { UsersModule } from './users/users.module';
import { FilesModule } from './files/files.module';
import { AuthModule } from './auth/auth.module'; import { AuthModule } from './auth/auth.module';
import databaseConfig from './config/database.config'; import databaseConfig from './config/database.config';
import authConfig from './config/auth.config'; import authConfig from './config/auth.config';
@@ -68,7 +67,6 @@ import { PenaltyModule } from './penalty/penalty.module';
exclude: ['*/api*'], exclude: ['*/api*'],
}), }),
UsersModule, UsersModule,
FilesModule,
AuthModule, AuthModule,
ForgotModule, ForgotModule,
MailModule, MailModule,

View File

@@ -1,30 +0,0 @@
import {
Column,
Entity,
PrimaryGeneratedColumn,
AfterLoad,
AfterInsert,
} from 'typeorm';
import { ApiProperty } from '@nestjs/swagger';
import { Allow } from 'class-validator';
import { EntityHelper } from 'src/utils/entity-helper';
import appConfig from '../../config/app.config';
@Entity({ name: 'file' })
export class FileEntity extends EntityHelper {
@ApiProperty({ example: 'cbcfa8b8-3a25-4adb-a9c6-e325f0d0f3ae' })
@PrimaryGeneratedColumn('uuid')
id: string;
@Allow()
@Column()
path: string;
@AfterLoad()
@AfterInsert()
updatePath() {
if (this.path.indexOf('/') === 0) {
this.path = appConfig().backendDomain + this.path;
}
}
}

View File

@@ -1,48 +0,0 @@
import {
Controller,
Get,
Param,
Post,
Response,
UploadedFile,
UseGuards,
UseInterceptors,
} from '@nestjs/common';
import { FileInterceptor } from '@nestjs/platform-express';
import { ApiBearerAuth, ApiBody, ApiConsumes, ApiTags } from '@nestjs/swagger';
import { AuthGuard } from '@nestjs/passport';
import { FilesService } from './files.service';
@ApiTags('Files')
@Controller({
path: 'files',
version: '1',
})
export class FilesController {
constructor(private readonly filesService: FilesService) {}
@ApiBearerAuth()
@UseGuards(AuthGuard('jwt'))
@Post('upload')
@ApiConsumes('multipart/form-data')
@ApiBody({
schema: {
type: 'object',
properties: {
file: {
type: 'string',
format: 'binary',
},
},
},
})
@UseInterceptors(FileInterceptor('file'))
async uploadFile(@UploadedFile() file) {
return this.filesService.uploadFile(file);
}
@Get(':path')
download(@Param('path') path, @Response() response) {
return response.sendFile(path, { root: './files' });
}
}

View File

@@ -1,90 +0,0 @@
import { HttpException, HttpStatus, Module } from '@nestjs/common';
import { FilesController } from './files.controller';
import { MulterModule } from '@nestjs/platform-express';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { diskStorage } from 'multer';
import { randomStringGenerator } from '@nestjs/common/utils/random-string-generator.util';
import * as AWS from 'aws-sdk';
import * as multerS3 from 'multer-s3';
import { TypeOrmModule } from '@nestjs/typeorm';
import { FileEntity } from './entities/file.entity';
import { FilesService } from './files.service';
@Module({
imports: [
TypeOrmModule.forFeature([FileEntity]),
MulterModule.registerAsync({
imports: [ConfigModule],
inject: [ConfigService],
useFactory: (configService: ConfigService) => {
const storages = {
local: () =>
diskStorage({
destination: './files',
filename: (request, file, callback) => {
callback(
null,
`${randomStringGenerator()}.${file.originalname
.split('.')
.pop()
.toLowerCase()}`,
);
},
}),
s3: () => {
const s3 = new AWS.S3();
AWS.config.update({
accessKeyId: configService.get('file.accessKeyId'),
secretAccessKey: configService.get('file.secretAccessKey'),
region: configService.get('file.awsS3Region'),
});
return multerS3({
s3: s3,
bucket: configService.get('file.awsDefaultS3Bucket'),
acl: 'public-read',
contentType: multerS3.AUTO_CONTENT_TYPE,
key: (request, file, callback) => {
callback(
null,
`${randomStringGenerator()}.${file.originalname
.split('.')
.pop()
.toLowerCase()}`,
);
},
});
},
};
return {
fileFilter: (request, file, callback) => {
if (!file.originalname.match(/\.(jpg|jpeg|png|gif)$/i)) {
return callback(
new HttpException(
{
status: HttpStatus.UNPROCESSABLE_ENTITY,
errors: {
file: `cantUploadFileType`,
},
},
HttpStatus.UNPROCESSABLE_ENTITY,
),
false,
);
}
callback(null, true);
},
storage: storages[configService.get('file.driver')](),
limits: {
fileSize: configService.get('file.maxFileSize'),
},
};
},
}),
],
controllers: [FilesController],
providers: [ConfigModule, ConfigService, FilesService],
})
export class FilesModule {}

View File

@@ -1,39 +0,0 @@
import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { InjectRepository } from '@nestjs/typeorm';
import { FileEntity } from './entities/file.entity';
import { Repository } from 'typeorm';
@Injectable()
export class FilesService {
constructor(
private readonly configService: ConfigService,
@InjectRepository(FileEntity)
private fileRepository: Repository<FileEntity>,
) {}
async uploadFile(file): Promise<FileEntity> {
if (!file) {
throw new HttpException(
{
status: HttpStatus.UNPROCESSABLE_ENTITY,
errors: {
file: 'selectFile',
},
},
HttpStatus.UNPROCESSABLE_ENTITY,
);
}
const path = {
local: `/${this.configService.get('app.apiPrefix')}/v1/${file.path}`,
s3: file.location,
};
return this.fileRepository.save(
this.fileRepository.create({
path: path[this.configService.get('file.driver')],
}),
);
}
}