more fix and update
This commit is contained in:
@@ -1,7 +1,8 @@
|
||||
import { Body, Controller, Get, Headers, Param, Post, Query, Res } from '@nestjs/common';
|
||||
import { ApiBearerAuth, ApiBody, ApiOperation, ApiParam, ApiQuery, ApiResponse, ApiTags } from '@nestjs/swagger';
|
||||
import { BadRequestException, Body, Controller, ForbiddenException, Get, Headers, Param, Post, Query, Res, UploadedFile, UseInterceptors } from '@nestjs/common';
|
||||
import { FileInterceptor } from '@nestjs/platform-express';
|
||||
import { JwtService } from '@nestjs/jwt';
|
||||
import { GetObjectCommand, S3Client } from '@aws-sdk/client-s3';
|
||||
import { ApiBearerAuth, ApiBody, ApiConsumes, ApiOperation, ApiParam, ApiQuery, ApiResponse, ApiTags } from '@nestjs/swagger';
|
||||
import { GetObjectCommand, PutObjectCommand, S3Client } from '@aws-sdk/client-s3';
|
||||
import { firstValueFrom } from 'rxjs';
|
||||
import { CoreGrpcService } from '../core-grpc.service';
|
||||
import { getAuthorizedUserId } from '../document-access';
|
||||
@@ -44,6 +45,49 @@ export class MediaController {
|
||||
return getAuthorizedUserId(this.jwt, this.core, authorization);
|
||||
}
|
||||
|
||||
@Post('upload')
|
||||
@ApiConsumes('multipart/form-data')
|
||||
@ApiOperation({ summary: 'Загрузить файл через API', description: 'Принимает файл по uploadToken из upload-url ответа. Обходит прямой доступ браузера к MinIO.' })
|
||||
@ApiResponse({ status: 201, description: 'Файл загружен' })
|
||||
@UseInterceptors(FileInterceptor('file', { limits: { fileSize: 50 * 1024 * 1024 } }))
|
||||
async uploadObject(
|
||||
@Headers('x-upload-token') uploadToken: string | undefined,
|
||||
@UploadedFile() file: { buffer: Buffer; mimetype: string } | undefined
|
||||
) {
|
||||
if (!uploadToken) {
|
||||
throw new BadRequestException('Не передан uploadToken');
|
||||
}
|
||||
if (!file) {
|
||||
throw new BadRequestException('Файл не передан');
|
||||
}
|
||||
|
||||
let payload: { purpose?: string; storageKey?: string; contentType?: string };
|
||||
try {
|
||||
payload = await this.jwt.verifyAsync(uploadToken, {
|
||||
secret: process.env.JWT_ACCESS_SECRET ?? 'docker-access-secret',
|
||||
issuer: 'id.lendry.ru'
|
||||
});
|
||||
} catch {
|
||||
throw new ForbiddenException('Ссылка загрузки недействительна или истекла');
|
||||
}
|
||||
|
||||
if (payload.purpose !== 'media-upload' || !payload.storageKey) {
|
||||
throw new ForbiddenException('Ссылка загрузки недействительна');
|
||||
}
|
||||
|
||||
const bucket = process.env.MINIO_BUCKET ?? 'lendry-id';
|
||||
await this.getS3Client().send(
|
||||
new PutObjectCommand({
|
||||
Bucket: bucket,
|
||||
Key: payload.storageKey,
|
||||
Body: file.buffer,
|
||||
ContentType: file.mimetype || payload.contentType || 'application/octet-stream'
|
||||
})
|
||||
);
|
||||
|
||||
return { ok: true, storageKey: payload.storageKey };
|
||||
}
|
||||
|
||||
@Post('avatars/upload-url')
|
||||
@ApiBearerAuth()
|
||||
@ApiOperation({ summary: 'Получить URL для загрузки аватара', description: 'Возвращает presigned URL MinIO для загрузки изображения аватара.' })
|
||||
|
||||
Reference in New Issue
Block a user