* Make JwtGuard better

* Fix auth decorators
This commit is contained in:
Philipinho
2024-02-28 03:07:24 +00:00
parent 40251aef7d
commit cdcb4e87d0
14 changed files with 155 additions and 136 deletions

View File

@ -24,6 +24,10 @@ export class AuthenticationExtension implements Extension {
const userId = jwtPayload.sub; const userId = jwtPayload.sub;
const user = await this.userService.findById(userId); const user = await this.userService.findById(userId);
if (!user) {
throw new UnauthorizedException();
}
//TODO: Check if the page exists and verify user permissions for page. //TODO: Check if the page exists and verify user permissions for page.
// if all fails, abort connection // if all fails, abort connection

View File

@ -7,8 +7,7 @@ import * as Y from 'yjs';
import { PageService } from '../../core/page/services/page.service'; import { PageService } from '../../core/page/services/page.service';
import { Injectable } from '@nestjs/common'; import { Injectable } from '@nestjs/common';
import { TiptapTransformer } from '@hocuspocus/transformer'; import { TiptapTransformer } from '@hocuspocus/transformer';
import { jsonToHtml, jsonToText, tiptapExtensions } from '../collaboration.util'; import { jsonToText, tiptapExtensions } from '../collaboration.util';
import { generateText } from '@tiptap/core'
@Injectable() @Injectable()
export class PersistenceExtension implements Extension { export class PersistenceExtension implements Extension {
@ -67,7 +66,6 @@ export class PersistenceExtension implements Extension {
const ydocState = Buffer.from(Y.encodeStateAsUpdate(document)); const ydocState = Buffer.from(Y.encodeStateAsUpdate(document));
const textContent = jsonToText(tiptapJson); const textContent = jsonToText(tiptapJson);
console.log(jsonToText(tiptapJson));
try { try {
await this.pageService.updateState( await this.pageService.updateState(

View File

@ -12,9 +12,12 @@ import {
import { AttachmentService } from './attachment.service'; import { AttachmentService } from './attachment.service';
import { FastifyReply, FastifyRequest } from 'fastify'; import { FastifyReply, FastifyRequest } from 'fastify';
import { AttachmentInterceptor } from './attachment.interceptor'; import { AttachmentInterceptor } from './attachment.interceptor';
import { JwtUser } from '../../decorators/jwt-user.decorator'; import { JwtGuard } from '../auth/guards/jwt.guard';
import { JwtGuard } from '../auth/guards/JwtGuard';
import * as bytes from 'bytes'; import * as bytes from 'bytes';
import { AuthUser } from '../../decorators/auth-user.decorator';
import { User } from '../user/entities/user.entity';
import { CurrentWorkspace } from '../../decorators/current-workspace.decorator';
import { Workspace } from '../workspace/entities/workspace.entity';
@Controller('attachments') @Controller('attachments')
export class AttachmentController { export class AttachmentController {
@ -25,9 +28,9 @@ export class AttachmentController {
@Post('upload/avatar') @Post('upload/avatar')
@UseInterceptors(AttachmentInterceptor) @UseInterceptors(AttachmentInterceptor)
async uploadAvatar( async uploadAvatar(
@JwtUser() jwtUser,
@Req() req: FastifyRequest, @Req() req: FastifyRequest,
@Res() res: FastifyReply, @Res() res: FastifyReply,
@AuthUser() user: User,
) { ) {
const maxFileSize = bytes('5MB'); const maxFileSize = bytes('5MB');
@ -38,7 +41,7 @@ export class AttachmentController {
const fileResponse = await this.attachmentService.uploadAvatar( const fileResponse = await this.attachmentService.uploadAvatar(
file, file,
jwtUser.id, user.id,
); );
return res.send(fileResponse); return res.send(fileResponse);
@ -52,9 +55,10 @@ export class AttachmentController {
@Post('upload/workspace-logo') @Post('upload/workspace-logo')
@UseInterceptors(AttachmentInterceptor) @UseInterceptors(AttachmentInterceptor)
async uploadWorkspaceLogo( async uploadWorkspaceLogo(
@JwtUser() jwtUser,
@Req() req: FastifyRequest, @Req() req: FastifyRequest,
@Res() res: FastifyReply, @Res() res: FastifyReply,
@AuthUser() user: User,
@CurrentWorkspace() workspace: Workspace,
) { ) {
const maxFileSize = bytes('5MB'); const maxFileSize = bytes('5MB');
@ -63,13 +67,10 @@ export class AttachmentController {
limits: { fileSize: maxFileSize, fields: 1, files: 1 }, limits: { fileSize: maxFileSize, fields: 1, files: 1 },
}); });
// TODO FIX
const workspaceId = '123';
const fileResponse = await this.attachmentService.uploadWorkspaceLogo( const fileResponse = await this.attachmentService.uploadWorkspaceLogo(
file, file,
workspaceId, workspace.id,
jwtUser.id, user.id,
); );
return res.send(fileResponse); return res.send(fileResponse);
@ -83,9 +84,10 @@ export class AttachmentController {
@Post('upload/file') @Post('upload/file')
@UseInterceptors(AttachmentInterceptor) @UseInterceptors(AttachmentInterceptor)
async uploadFile( async uploadFile(
@JwtUser() jwtUser,
@Req() req: FastifyRequest, @Req() req: FastifyRequest,
@Res() res: FastifyReply, @Res() res: FastifyReply,
@AuthUser() user: User,
@CurrentWorkspace() workspace: Workspace,
) { ) {
const maxFileSize = bytes('20MB'); const maxFileSize = bytes('20MB');
@ -94,12 +96,10 @@ export class AttachmentController {
limits: { fileSize: maxFileSize, fields: 1, files: 1 }, limits: { fileSize: maxFileSize, fields: 1, files: 1 },
}); });
const workspaceId = '123';
const fileResponse = await this.attachmentService.uploadWorkspaceLogo( const fileResponse = await this.attachmentService.uploadWorkspaceLogo(
file, file,
workspaceId, workspace.id,
jwtUser.id, user.id,
); );
return res.send(fileResponse); return res.send(fileResponse);

View File

@ -0,0 +1,37 @@
import {
CanActivate,
ExecutionContext,
Injectable,
UnauthorizedException,
} from '@nestjs/common';
import { TokenService } from '../services/token.service';
import { UserService } from '../../user/user.service';
@Injectable()
export class JwtGuard implements CanActivate {
constructor(
private tokenService: TokenService,
private userService: UserService,
) {}
async canActivate(context: ExecutionContext): Promise<boolean> {
const request = context.switchToHttp().getRequest();
const token: string = await this.tokenService.extractTokenFromHeader(
request,
);
if (!token) {
throw new UnauthorizedException('Invalid jwt token');
}
try {
const payload = await this.tokenService.verifyJwt(token);
//fetch user and current workspace data from db
request['user'] = await this.userService.getUserInstance(payload.sub);
} catch (error) {
throw new UnauthorizedException('Could not verify jwt token');
}
return true;
}
}

View File

@ -4,39 +4,33 @@ import {
Body, Body,
HttpCode, HttpCode,
HttpStatus, HttpStatus,
Req,
UseGuards, UseGuards,
} from '@nestjs/common'; } from '@nestjs/common';
import { CommentService } from './comment.service'; import { CommentService } from './comment.service';
import { CreateCommentDto } from './dto/create-comment.dto'; import { CreateCommentDto } from './dto/create-comment.dto';
import { UpdateCommentDto } from './dto/update-comment.dto'; import { UpdateCommentDto } from './dto/update-comment.dto';
import { FastifyRequest } from 'fastify'; import { JwtGuard } from '../auth/guards/jwt.guard';
import { JwtGuard } from '../auth/guards/JwtGuard';
import { CommentsInput, SingleCommentInput } from './dto/comments.input'; import { CommentsInput, SingleCommentInput } from './dto/comments.input';
import { ResolveCommentDto } from './dto/resolve-comment.dto'; import { ResolveCommentDto } from './dto/resolve-comment.dto';
import { WorkspaceService } from '../workspace/services/workspace.service'; import { WorkspaceService } from '../workspace/services/workspace.service';
import { AuthUser } from '../../decorators/auth-user.decorator';
import { User } from '../user/entities/user.entity';
import { CurrentWorkspace } from '../../decorators/current-workspace.decorator';
import { Workspace } from '../workspace/entities/workspace.entity';
@UseGuards(JwtGuard) @UseGuards(JwtGuard)
@Controller('comments') @Controller('comments')
export class CommentController { export class CommentController {
constructor( constructor(private readonly commentService: CommentService) {}
private readonly commentService: CommentService,
private readonly workspaceService: WorkspaceService,
) {}
@HttpCode(HttpStatus.CREATED) @HttpCode(HttpStatus.CREATED)
@Post('create') @Post('create')
async create( async create(
@Req() req: FastifyRequest,
@Body() createCommentDto: CreateCommentDto, @Body() createCommentDto: CreateCommentDto,
@AuthUser() user: User,
@CurrentWorkspace() workspace: Workspace,
) { ) {
const jwtPayload = req['user']; return this.commentService.create(user.id, workspace.id, createCommentDto);
const userId = jwtPayload.sub;
const workspaceId = (
await this.workspaceService.getUserCurrentWorkspace(jwtPayload.sub)
).id;
return this.commentService.create(userId, workspaceId, createCommentDto);
} }
@HttpCode(HttpStatus.OK) @HttpCode(HttpStatus.OK)
@ -60,11 +54,10 @@ export class CommentController {
@HttpCode(HttpStatus.OK) @HttpCode(HttpStatus.OK)
@Post('resolve') @Post('resolve')
resolve( resolve(
@Req() req: FastifyRequest,
@Body() resolveCommentDto: ResolveCommentDto, @Body() resolveCommentDto: ResolveCommentDto,
@AuthUser() user: User,
) { ) {
const userId = req['user'].sub; return this.commentService.resolveComment(user.id, resolveCommentDto);
return this.commentService.resolveComment(userId, resolveCommentDto);
} }
@HttpCode(HttpStatus.OK) @HttpCode(HttpStatus.OK)

View File

@ -4,17 +4,11 @@ import { CommentController } from './comment.controller';
import { CommentRepository } from './repositories/comment.repository'; import { CommentRepository } from './repositories/comment.repository';
import { TypeOrmModule } from '@nestjs/typeorm'; import { TypeOrmModule } from '@nestjs/typeorm';
import { AuthModule } from '../auth/auth.module'; import { AuthModule } from '../auth/auth.module';
import { WorkspaceModule } from '../workspace/workspace.module';
import { Comment } from './entities/comment.entity'; import { Comment } from './entities/comment.entity';
import { PageModule } from '../page/page.module'; import { PageModule } from '../page/page.module';
@Module({ @Module({
imports: [ imports: [TypeOrmModule.forFeature([Comment]), AuthModule, PageModule],
TypeOrmModule.forFeature([Comment]),
AuthModule,
WorkspaceModule,
PageModule,
],
controllers: [CommentController], controllers: [CommentController],
providers: [CommentService, CommentRepository], providers: [CommentService, CommentRepository],
exports: [CommentService, CommentRepository], exports: [CommentService, CommentRepository],

View File

@ -10,7 +10,6 @@ import { PageService } from './services/page.service';
import { CreatePageDto } from './dto/create-page.dto'; import { CreatePageDto } from './dto/create-page.dto';
import { UpdatePageDto } from './dto/update-page.dto'; import { UpdatePageDto } from './dto/update-page.dto';
import { JwtGuard } from '../auth/guards/jwt.guard'; import { JwtGuard } from '../auth/guards/jwt.guard';
import { WorkspaceService } from '../workspace/services/workspace.service';
import { MovePageDto } from './dto/move-page.dto'; import { MovePageDto } from './dto/move-page.dto';
import { PageDetailsDto } from './dto/page-details.dto'; import { PageDetailsDto } from './dto/page-details.dto';
import { DeletePageDto } from './dto/delete-page.dto'; import { DeletePageDto } from './dto/delete-page.dto';
@ -18,7 +17,10 @@ import { PageOrderingService } from './services/page-ordering.service';
import { PageHistoryService } from './services/page-history.service'; import { PageHistoryService } from './services/page-history.service';
import { HistoryDetailsDto } from './dto/history-details.dto'; import { HistoryDetailsDto } from './dto/history-details.dto';
import { PageHistoryDto } from './dto/page-history.dto'; import { PageHistoryDto } from './dto/page-history.dto';
import { JwtUser } from '../../decorators/jwt-user.decorator'; import { AuthUser } from '../../decorators/auth-user.decorator';
import { User } from '../user/entities/user.entity';
import { CurrentWorkspace } from '../../decorators/current-workspace.decorator';
import { Workspace } from '../workspace/entities/workspace.entity';
@UseGuards(JwtGuard) @UseGuards(JwtGuard)
@Controller('pages') @Controller('pages')
@ -27,7 +29,6 @@ export class PageController {
private readonly pageService: PageService, private readonly pageService: PageService,
private readonly pageOrderService: PageOrderingService, private readonly pageOrderService: PageOrderingService,
private readonly pageHistoryService: PageHistoryService, private readonly pageHistoryService: PageHistoryService,
private readonly workspaceService: WorkspaceService,
) {} ) {}
@HttpCode(HttpStatus.OK) @HttpCode(HttpStatus.OK)
@ -38,17 +39,18 @@ export class PageController {
@HttpCode(HttpStatus.CREATED) @HttpCode(HttpStatus.CREATED)
@Post('create') @Post('create')
async create(@JwtUser() jwtUser, @Body() createPageDto: CreatePageDto) { async create(
const workspaceId = ( @Body() createPageDto: CreatePageDto,
await this.workspaceService.getUserCurrentWorkspace(jwtUser.id) @AuthUser() user: User,
).id; @CurrentWorkspace() workspace: Workspace,
return this.pageService.create(jwtUser.id, workspaceId, createPageDto); ) {
return this.pageService.create(user.id, workspace.id, createPageDto);
} }
@HttpCode(HttpStatus.OK) @HttpCode(HttpStatus.OK)
@Post('update') @Post('update')
async update(@JwtUser() jwtUser, @Body() updatePageDto: UpdatePageDto) { async update(@Body() updatePageDto: UpdatePageDto, @AuthUser() user: User) {
return this.pageService.update(updatePageDto.id, updatePageDto, jwtUser.id); return this.pageService.update(updatePageDto.id, updatePageDto, user.id);
} }
@HttpCode(HttpStatus.OK) @HttpCode(HttpStatus.OK)

View File

@ -7,36 +7,29 @@ import {
Query, Query,
UseGuards, UseGuards,
} from '@nestjs/common'; } from '@nestjs/common';
import { JwtUser } from '../../decorators/jwt-user.decorator'; import { JwtGuard } from '../auth/guards/jwt.guard';
import { WorkspaceService } from '../workspace/services/workspace.service';
import { JwtGuard } from '../auth/guards/JwtGuard';
import { SearchService } from './search.service'; import { SearchService } from './search.service';
import { SearchDTO } from './dto/search.dto'; import { SearchDTO } from './dto/search.dto';
import { CurrentWorkspace } from '../../decorators/current-workspace.decorator';
import { Workspace } from '../workspace/entities/workspace.entity';
@UseGuards(JwtGuard) @UseGuards(JwtGuard)
@Controller('search') @Controller('search')
export class SearchController { export class SearchController {
constructor( constructor(private readonly searchService: SearchService) {}
private readonly searchService: SearchService,
private readonly workspaceService: WorkspaceService,
) {}
@HttpCode(HttpStatus.OK) @HttpCode(HttpStatus.OK)
@Post() @Post()
async pageSearch( async pageSearch(
@Query('type') type: string, @Query('type') type: string,
@Body() searchDto: SearchDTO, @Body() searchDto: SearchDTO,
@JwtUser() jwtUser, @CurrentWorkspace() workspace: Workspace,
) { ) {
const workspaceId = (
await this.workspaceService.getUserCurrentWorkspace(jwtUser.id)
).id;
if (!type || type === 'page') { if (!type || type === 'page') {
return this.searchService.searchPage( return this.searchService.searchPage(
searchDto.query, searchDto.query,
searchDto, searchDto,
workspaceId, workspace.id,
); );
} }
return; return;

View File

@ -2,11 +2,10 @@ import { Module } from '@nestjs/common';
import { SearchController } from './search.controller'; import { SearchController } from './search.controller';
import { SearchService } from './search.service'; import { SearchService } from './search.service';
import { AuthModule } from '../auth/auth.module'; import { AuthModule } from '../auth/auth.module';
import { WorkspaceModule } from '../workspace/workspace.module';
import { PageModule } from '../page/page.module'; import { PageModule } from '../page/page.module';
@Module({ @Module({
imports: [AuthModule, WorkspaceModule, PageModule], imports: [AuthModule, PageModule],
controllers: [SearchController], controllers: [SearchController],
providers: [SearchService], providers: [SearchService],
}) })

View File

@ -3,12 +3,14 @@ import {
HttpCode, HttpCode,
HttpStatus, HttpStatus,
Post, Post,
Req,
UseGuards, UseGuards,
} from '@nestjs/common'; } from '@nestjs/common';
import { FastifyRequest } from 'fastify';
import { JwtGuard } from '../auth/guards/jwt.guard'; import { JwtGuard } from '../auth/guards/jwt.guard';
import { SpaceService } from './space.service'; import { SpaceService } from './space.service';
import { AuthUser } from '../../decorators/auth-user.decorator';
import { User } from '../user/entities/user.entity';
import { CurrentWorkspace } from '../../decorators/current-workspace.decorator';
import { Workspace } from '../workspace/entities/workspace.entity';
@UseGuards(JwtGuard) @UseGuards(JwtGuard)
@Controller('spaces') @Controller('spaces')
@ -18,5 +20,10 @@ export class SpaceController {
// get all spaces user is a member of // get all spaces user is a member of
@HttpCode(HttpStatus.OK) @HttpCode(HttpStatus.OK)
@Post('/') @Post('/')
async getUserSpaces(@Req() req: FastifyRequest) {} async getUserSpaces(
@AuthUser() user: User,
@CurrentWorkspace() workspace: Workspace,
) {
return this.spaceService.getUserSpacesInWorkspace(user.id, workspace.id);
}
} }

View File

@ -4,17 +4,16 @@ import {
UseGuards, UseGuards,
HttpCode, HttpCode,
HttpStatus, HttpStatus,
Req,
UnauthorizedException, UnauthorizedException,
Post, Post,
Body, Body,
} from '@nestjs/common'; } from '@nestjs/common';
import { UserService } from './user.service'; import { UserService } from './user.service';
import { JwtGuard } from '../auth/guards/jwt.guard'; import { JwtGuard } from '../auth/guards/jwt.guard';
import { FastifyRequest } from 'fastify';
import { User } from './entities/user.entity'; import { User } from './entities/user.entity';
import { Workspace } from '../workspace/entities/workspace.entity'; import { Workspace } from '../workspace/entities/workspace.entity';
import { UpdateUserDto } from './dto/update-user.dto'; import { UpdateUserDto } from './dto/update-user.dto';
import { AuthUser } from '../../decorators/auth-user.decorator';
@UseGuards(JwtGuard) @UseGuards(JwtGuard)
@Controller('user') @Controller('user')
@ -23,9 +22,8 @@ export class UserController {
@HttpCode(HttpStatus.OK) @HttpCode(HttpStatus.OK)
@Get('me') @Get('me')
async getUser(@Req() req: FastifyRequest) { async getUser(@AuthUser() authUser: User) {
const jwtPayload = req['user']; const user: User = await this.userService.findById(authUser.id);
const user: User = await this.userService.findById(jwtPayload.sub);
if (!user) { if (!user) {
throw new UnauthorizedException('Invalid user'); throw new UnauthorizedException('Invalid user');
@ -36,11 +34,9 @@ export class UserController {
@HttpCode(HttpStatus.OK) @HttpCode(HttpStatus.OK)
@Get('info') @Get('info')
async getUserInfo(@Req() req: FastifyRequest) { async getUserInfo(@AuthUser() user: User) {
const jwtPayload = req['user'];
const data: { workspace: Workspace; user: User } = const data: { workspace: Workspace; user: User } =
await this.userService.getUserInstance(jwtPayload.sub); await this.userService.getUserInstance(user.id);
return data; return data;
} }
@ -48,11 +44,9 @@ export class UserController {
@HttpCode(HttpStatus.OK) @HttpCode(HttpStatus.OK)
@Post('update') @Post('update')
async updateUser( async updateUser(
@Req() req: FastifyRequest,
@Body() updateUserDto: UpdateUserDto, @Body() updateUserDto: UpdateUserDto,
@AuthUser() user: User,
) { ) {
const jwtPayload = req['user']; return this.userService.update(user.id, updateUserDto);
return this.userService.update(jwtPayload.sub, updateUserDto);
} }
} }

View File

@ -6,11 +6,9 @@ import {
HttpCode, HttpCode,
HttpStatus, HttpStatus,
Post, Post,
Req,
UseGuards, UseGuards,
} from '@nestjs/common'; } from '@nestjs/common';
import { WorkspaceService } from '../services/workspace.service'; import { WorkspaceService } from '../services/workspace.service';
import { FastifyRequest } from 'fastify';
import { JwtGuard } from '../../auth/guards/jwt.guard'; import { JwtGuard } from '../../auth/guards/jwt.guard';
import { UpdateWorkspaceDto } from '../dto/update-workspace.dto'; import { UpdateWorkspaceDto } from '../dto/update-workspace.dto';
import { CreateWorkspaceDto } from '../dto/create-workspace.dto'; import { CreateWorkspaceDto } from '../dto/create-workspace.dto';
@ -18,46 +16,32 @@ import { DeleteWorkspaceDto } from '../dto/delete-workspace.dto';
import { UpdateWorkspaceUserRoleDto } from '../dto/update-workspace-user-role.dto'; import { UpdateWorkspaceUserRoleDto } from '../dto/update-workspace-user-role.dto';
import { RemoveWorkspaceUserDto } from '../dto/remove-workspace-user.dto'; import { RemoveWorkspaceUserDto } from '../dto/remove-workspace-user.dto';
import { AddWorkspaceUserDto } from '../dto/add-workspace-user.dto'; import { AddWorkspaceUserDto } from '../dto/add-workspace-user.dto';
import { AuthUser } from '../../../decorators/auth-user.decorator';
import { User } from '../../user/entities/user.entity';
import { CurrentWorkspace } from '../../../decorators/current-workspace.decorator';
import { Workspace } from '../entities/workspace.entity';
@UseGuards(JwtGuard) @UseGuards(JwtGuard)
@Controller('workspace') @Controller('workspace')
export class WorkspaceController { export class WorkspaceController {
constructor(private readonly workspaceService: WorkspaceService) {} constructor(private readonly workspaceService: WorkspaceService) {}
@HttpCode(HttpStatus.OK)
@Post('test')
async test(
@Req() req: FastifyRequest,
//@Body() createWorkspaceDto: CreateWorkspaceDto,
) {
//const jwtPayload = req['user'];
// const userId = jwtPayload.sub;
// return this.workspaceService.createOrJoinWorkspace();
}
@HttpCode(HttpStatus.OK) @HttpCode(HttpStatus.OK)
@Post('create') @Post('create')
async createWorkspace( async createWorkspace(
@Req() req: FastifyRequest,
@Body() createWorkspaceDto: CreateWorkspaceDto, @Body() createWorkspaceDto: CreateWorkspaceDto,
@AuthUser() user: User,
) { ) {
const jwtPayload = req['user']; return this.workspaceService.create(user.id, createWorkspaceDto);
const userId = jwtPayload.sub;
return this.workspaceService.create(userId, createWorkspaceDto);
} }
@HttpCode(HttpStatus.OK) @HttpCode(HttpStatus.OK)
@Post('update') @Post('update')
async updateWorkspace( async updateWorkspace(
@Req() req: FastifyRequest,
@Body() updateWorkspaceDto: UpdateWorkspaceDto, @Body() updateWorkspaceDto: UpdateWorkspaceDto,
@CurrentWorkspace() workspace: Workspace,
) { ) {
const jwtPayload = req['user']; return this.workspaceService.update(workspace.id, updateWorkspaceDto);
const workspaceId = (
await this.workspaceService.getUserCurrentWorkspace(jwtPayload.sub)
).id;
return this.workspaceService.update(workspaceId, updateWorkspaceDto);
} }
@HttpCode(HttpStatus.OK) @HttpCode(HttpStatus.OK)
@ -68,29 +52,19 @@ export class WorkspaceController {
@HttpCode(HttpStatus.OK) @HttpCode(HttpStatus.OK)
@Get('members') @Get('members')
async getWorkspaceMembers(@Req() req: FastifyRequest) { async getWorkspaceMembers(@CurrentWorkspace() workspace: Workspace) {
const jwtPayload = req['user']; return this.workspaceService.getWorkspaceUsers(workspace.id);
const workspaceId = (
await this.workspaceService.getUserCurrentWorkspace(jwtPayload.sub)
).id;
return this.workspaceService.getWorkspaceUsers(workspaceId);
} }
@HttpCode(HttpStatus.OK) @HttpCode(HttpStatus.OK)
@Post('members/add') @Post('members/add')
async addWorkspaceMember( async addWorkspaceMember(
@Req() req: FastifyRequest,
@Body() addWorkspaceUserDto: AddWorkspaceUserDto, @Body() addWorkspaceUserDto: AddWorkspaceUserDto,
@CurrentWorkspace() workspace: Workspace,
) { ) {
const jwtPayload = req['user'];
const workspaceId = (
await this.workspaceService.getUserCurrentWorkspace(jwtPayload.sub)
).id;
return this.workspaceService.addUserToWorkspace( return this.workspaceService.addUserToWorkspace(
addWorkspaceUserDto.userId, addWorkspaceUserDto.userId,
workspaceId, workspace.id,
addWorkspaceUserDto.role, addWorkspaceUserDto.role,
); );
} }
@ -98,34 +72,24 @@ export class WorkspaceController {
@HttpCode(HttpStatus.OK) @HttpCode(HttpStatus.OK)
@Delete('members/delete') @Delete('members/delete')
async removeWorkspaceMember( async removeWorkspaceMember(
@Req() req: FastifyRequest,
@Body() removeWorkspaceUserDto: RemoveWorkspaceUserDto, @Body() removeWorkspaceUserDto: RemoveWorkspaceUserDto,
@CurrentWorkspace() workspace: Workspace,
) { ) {
const jwtPayload = req['user'];
const workspaceId = (
await this.workspaceService.getUserCurrentWorkspace(jwtPayload.sub)
).id;
return this.workspaceService.removeUserFromWorkspace( return this.workspaceService.removeUserFromWorkspace(
removeWorkspaceUserDto.userId, removeWorkspaceUserDto.userId,
workspaceId, workspace.id,
); );
} }
@HttpCode(HttpStatus.OK) @HttpCode(HttpStatus.OK)
@Post('members/role') @Post('members/role')
async updateWorkspaceMemberRole( async updateWorkspaceMemberRole(
@Req() req: FastifyRequest,
@Body() workspaceUserRoleDto: UpdateWorkspaceUserRoleDto, @Body() workspaceUserRoleDto: UpdateWorkspaceUserRoleDto,
@CurrentWorkspace() workspace: Workspace,
) { ) {
const jwtPayload = req['user'];
const workspaceId = (
await this.workspaceService.getUserCurrentWorkspace(jwtPayload.sub)
).id;
return this.workspaceService.updateWorkspaceUserRole( return this.workspaceService.updateWorkspaceUserRole(
workspaceUserRoleDto, workspaceUserRoleDto,
workspaceId, workspace.id,
); );
} }
} }

View File

@ -0,0 +1,17 @@
import {
createParamDecorator,
ExecutionContext,
UnauthorizedException,
} from '@nestjs/common';
export const AuthUser = createParamDecorator(
(data: unknown, ctx: ExecutionContext) => {
const request = ctx.switchToHttp().getRequest();
if (!request['user'] || !request['user'].user) {
throw new UnauthorizedException();
}
return request['user'] ? request['user'].user : undefined;
},
);

View File

@ -0,0 +1,17 @@
import {
createParamDecorator,
ExecutionContext,
UnauthorizedException,
} from '@nestjs/common';
export const CurrentWorkspace = createParamDecorator(
(data: unknown, ctx: ExecutionContext) => {
const request = ctx.switchToHttp().getRequest();
if (!request['user'] || !request['user'].workspace) {
throw new UnauthorizedException();
}
return request['user'] ? request['user'].workspace : undefined;
},
);