Files
docmost/apps/server/src/integrations/import/import.controller.ts
2024-07-21 20:48:33 +01:00

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);
}
}