mirror of
https://github.com/docmost/docmost.git
synced 2025-11-13 08:52:39 +10:00
88 lines
2.5 KiB
TypeScript
88 lines
2.5 KiB
TypeScript
import {
|
|
BadRequestException,
|
|
Controller,
|
|
ForbiddenException,
|
|
HttpCode,
|
|
HttpStatus,
|
|
Logger,
|
|
Post,
|
|
Req,
|
|
UseGuards,
|
|
UseInterceptors,
|
|
} from '@nestjs/common';
|
|
import SpaceAbilityFactory from '../../core/casl/abilities/space-ability.factory';
|
|
import { JwtAuthGuard } from '../../common/guards/jwt-auth.guard';
|
|
import { AuthUser } from '../../common/decorators/auth-user.decorator';
|
|
import { User, Workspace } from '@docmost/db/types/entity.types';
|
|
import {
|
|
SpaceCaslAction,
|
|
SpaceCaslSubject,
|
|
} from '../../core/casl/interfaces/space-ability.type';
|
|
import { FileInterceptor } from '../../common/interceptors/file.interceptor';
|
|
import * as bytes from 'bytes';
|
|
import * as path from 'path';
|
|
import { MAX_FILE_SIZE } from '../../core/attachment/attachment.constants';
|
|
import { ImportService } from './import.service';
|
|
import { AuthWorkspace } from '../../common/decorators/auth-workspace.decorator';
|
|
|
|
@Controller()
|
|
export class ImportController {
|
|
private readonly logger = new Logger(ImportController.name);
|
|
|
|
constructor(
|
|
private readonly importService: ImportService,
|
|
private readonly spaceAbility: SpaceAbilityFactory,
|
|
) {}
|
|
|
|
@UseInterceptors(FileInterceptor)
|
|
@UseGuards(JwtAuthGuard)
|
|
@HttpCode(HttpStatus.OK)
|
|
@Post('pages/import')
|
|
async importPage(
|
|
@Req() req: any,
|
|
@AuthUser() user: User,
|
|
@AuthWorkspace() workspace: Workspace,
|
|
) {
|
|
const validFileExtensions = ['.md', '.html'];
|
|
|
|
const maxFileSize = bytes(MAX_FILE_SIZE);
|
|
|
|
let file = null;
|
|
try {
|
|
file = await req.file({
|
|
limits: { fileSize: maxFileSize, fields: 3, files: 1 },
|
|
});
|
|
} catch (err: any) {
|
|
this.logger.error(err.message);
|
|
if (err?.statusCode === 413) {
|
|
throw new BadRequestException(
|
|
`File too large. Exceeds the ${MAX_FILE_SIZE} limit`,
|
|
);
|
|
}
|
|
}
|
|
|
|
if (!file) {
|
|
throw new BadRequestException('Failed to upload file');
|
|
}
|
|
|
|
if (
|
|
!validFileExtensions.includes(path.extname(file.filename).toLowerCase())
|
|
) {
|
|
throw new BadRequestException('Invalid import file type.');
|
|
}
|
|
|
|
const spaceId = file.fields?.spaceId?.value;
|
|
|
|
if (!spaceId) {
|
|
throw new BadRequestException('spaceId or format not found');
|
|
}
|
|
|
|
const ability = await this.spaceAbility.createForUser(user, spaceId);
|
|
if (ability.cannot(SpaceCaslAction.Edit, SpaceCaslSubject.Page)) {
|
|
throw new ForbiddenException();
|
|
}
|
|
|
|
return this.importService.importPage(file, user.id, spaceId, workspace.id);
|
|
}
|
|
}
|