files
This commit is contained in:
@@ -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,
|
||||||
|
|||||||
@@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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' });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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 {}
|
|
||||||
@@ -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')],
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user