65 lines
2.1 KiB
TypeScript
65 lines
2.1 KiB
TypeScript
import {
|
|
Controller,
|
|
Get,
|
|
HttpCode,
|
|
Param,
|
|
Post,
|
|
UploadedFile,
|
|
UseInterceptors,
|
|
} from '@nestjs/common';
|
|
import { FileInterceptor } from '@nestjs/platform-express';
|
|
import { AdminUploadsService } from './admin-uploads.service';
|
|
import { CurrentAdmin } from '../auth/guards';
|
|
import type { AuthenticatedAdmin } from '../auth/jwt.strategy';
|
|
import { Body } from '@nestjs/common';
|
|
|
|
/**
|
|
* The subset of multer's file object this controller uses. Declared locally
|
|
* rather than pulling in @types/multer for one interface — multer itself ships
|
|
* with @nestjs/platform-express, but its types do not.
|
|
*/
|
|
interface UploadedMulterFile {
|
|
originalname: string;
|
|
mimetype: string;
|
|
size: number;
|
|
buffer: Buffer;
|
|
}
|
|
|
|
/**
|
|
* Legacy endpoints:
|
|
* POST file/create -> storeWithoutData
|
|
* PUT file/update/{id} -> updateBody (metadata only; not ported — nothing
|
|
* in henza_admin calls it)
|
|
*
|
|
* The multipart field name `file` matches what every legacy uploader posts
|
|
* (MyUpload.vue, SingleUploadInput.vue, UploadInput.vue, PodcastUploadInput.vue).
|
|
*
|
|
* PERMISSIONS. Legacy gated this on nothing at all: `file/create` sat outside
|
|
* any middleware, and henza_server's `auth:api` group is itself commented out
|
|
* (routes/admin.php:12), so the endpoint accepted anonymous uploads. That is a
|
|
* security bug, not a feature, so it is NOT reproduced — these routes require a
|
|
* signed-in admin. No specific rid is demanded, since legacy's permission
|
|
* vocabulary has no media/file entry to port and inventing one would let it
|
|
* drift from the 144 real rids.
|
|
*/
|
|
@Controller('admin/files')
|
|
export class AdminUploadsController {
|
|
constructor(private readonly uploads: AdminUploadsService) {}
|
|
|
|
@Post('create')
|
|
@HttpCode(200)
|
|
@UseInterceptors(FileInterceptor('file'))
|
|
create(
|
|
@UploadedFile() file: UploadedMulterFile | undefined,
|
|
@Body('purpose') purpose: string | undefined,
|
|
@CurrentAdmin() admin: AuthenticatedAdmin,
|
|
) {
|
|
return this.uploads.store(file, purpose, admin.id ?? null);
|
|
}
|
|
|
|
@Get(':id')
|
|
findOne(@Param('id') id: string) {
|
|
return this.uploads.findOne(id);
|
|
}
|
|
}
|