Allow creation of space

* other fixes and cleanups
This commit is contained in:
Philipinho
2024-06-24 20:06:57 +01:00
parent 562abb0413
commit f2a193ac8d
22 changed files with 289 additions and 32 deletions

View File

@ -3,7 +3,6 @@ import { TextAlign } from '@tiptap/extension-text-align';
import { TaskList } from '@tiptap/extension-task-list';
import { TaskItem } from '@tiptap/extension-task-item';
import { Underline } from '@tiptap/extension-underline';
import { Link } from '@tiptap/extension-link';
import { Superscript } from '@tiptap/extension-superscript';
import SubScript from '@tiptap/extension-subscript';
import { Highlight } from '@tiptap/extension-highlight';
@ -17,6 +16,7 @@ import {
Details,
DetailsContent,
DetailsSummary,
LinkExtension,
MathBlock,
MathInline,
Table,
@ -37,7 +37,7 @@ export const tiptapExtensions = [
TaskList,
TaskItem,
Underline,
Link,
LinkExtension,
Superscript,
SubScript,
Highlight,

View File

@ -2,7 +2,7 @@ import { IsOptional, IsString, MaxLength, MinLength } from 'class-validator';
export class CreateSpaceDto {
@MinLength(2)
@MaxLength(64)
@MaxLength(50)
@IsString()
name: string;
@ -11,7 +11,7 @@ export class CreateSpaceDto {
description?: string;
@MinLength(2)
@MaxLength(64)
@MaxLength(50)
@IsString()
slug: string;
}

View File

@ -6,14 +6,54 @@ import {
import { CreateSpaceDto } from '../dto/create-space.dto';
import { PaginationOptions } from '@docmost/db/pagination/pagination-options';
import { SpaceRepo } from '@docmost/db/repos/space/space.repo';
import { KyselyTransaction } from '@docmost/db/types/kysely.types';
import { Space } from '@docmost/db/types/entity.types';
import { KyselyDB, KyselyTransaction } from '@docmost/db/types/kysely.types';
import { Space, User } from '@docmost/db/types/entity.types';
import { PaginationResult } from '@docmost/db/pagination/pagination';
import { UpdateSpaceDto } from '../dto/update-space.dto';
import { executeTx } from '@docmost/db/utils';
import { InjectKysely } from 'nestjs-kysely';
import { SpaceMemberService } from './space-member.service';
import { SpaceRole } from '../../../common/helpers/types/permission';
@Injectable()
export class SpaceService {
constructor(private spaceRepo: SpaceRepo) {}
constructor(
private spaceRepo: SpaceRepo,
private spaceMemberService: SpaceMemberService,
@InjectKysely() private readonly db: KyselyDB,
) {}
async createSpace(
authUser: User,
workspaceId: string,
createSpaceDto: CreateSpaceDto,
trx?: KyselyTransaction,
): Promise<Space> {
let space = null;
await executeTx(
this.db,
async (trx) => {
space = await this.create(
authUser.id,
workspaceId,
createSpaceDto,
trx,
);
await this.spaceMemberService.addUserToSpace(
authUser.id,
space.id,
SpaceRole.ADMIN,
workspaceId,
trx,
);
},
trx,
);
return { ...space, memberCount: 1 };
}
async create(
userId: string,
@ -28,7 +68,7 @@ export class SpaceService {
);
if (slugExists) {
throw new BadRequestException(
'Slug exists. Please use a unique space slug',
'Space slug exists. Please use a unique space slug',
);
}

View File

@ -28,6 +28,12 @@ import {
import { UpdateSpaceDto } from './dto/update-space.dto';
import { findHighestUserSpaceRole } from '@docmost/db/repos/space/utils';
import { SpaceMemberRepo } from '@docmost/db/repos/space/space-member.repo';
import {
WorkspaceCaslAction,
WorkspaceCaslSubject,
} from '../casl/interfaces/workspace-ability.type';
import WorkspaceAbilityFactory from '../casl/abilities/workspace-ability.factory';
import { CreateSpaceDto } from './dto/create-space.dto';
@UseGuards(JwtAuthGuard)
@Controller('spaces')
@ -37,6 +43,7 @@ export class SpaceController {
private readonly spaceMemberService: SpaceMemberService,
private readonly spaceMemberRepo: SpaceMemberRepo,
private readonly spaceAbility: SpaceAbilityFactory,
private readonly workspaceAbility: WorkspaceAbilityFactory,
) {}
@HttpCode(HttpStatus.OK)
@ -86,6 +93,22 @@ export class SpaceController {
return { ...space, membership };
}
@HttpCode(HttpStatus.OK)
@Post('create')
createGroup(
@Body() createSpaceDto: CreateSpaceDto,
@AuthUser() user: User,
@AuthWorkspace() workspace: Workspace,
) {
const ability = this.workspaceAbility.createForUser(user, workspace);
if (
ability.cannot(WorkspaceCaslAction.Manage, WorkspaceCaslSubject.Space)
) {
throw new ForbiddenException();
}
return this.spaceService.createSpace(user, workspace.id, createSpaceDto);
}
@HttpCode(HttpStatus.OK)
@Post('update')
async updateGroup(

View File

@ -33,7 +33,7 @@ export class SpaceRepo {
if (isValidUUID(spaceId)) {
query = query.where('id', '=', spaceId);
} else {
query = query.where('slug', '=', spaceId);
query = query.where(sql`LOWER(slug)`, '=', sql`LOWER(${spaceId})`);
}
return query.executeTakeFirst();
}