Skip to content

Commit d01a7d9

Browse files
feat: 워크스페이스 합류 구현
1 parent b5a6ada commit d01a7d9

File tree

3 files changed

+51
-3
lines changed

3 files changed

+51
-3
lines changed

apps/backend/src/auth/token/token.service.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,12 @@ export class TokenService {
3232
});
3333
}
3434

35+
verifyInviteToken(token: string): { workspaceId: string; role: string } {
36+
return this.jwtService.verify(token, {
37+
secret: process.env.JWT_SECRET,
38+
});
39+
}
40+
3541
// 후에 DB 로직 (지금은 refreshToken이 DB로 관리 X)
3642
// 추가될 때를 위해 일단 비동기 선언
3743
async refreshAccessToken(refreshToken: string): Promise<string> {

apps/backend/src/workspace/workspace.controller.ts

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
HttpCode,
1010
HttpStatus,
1111
Param,
12+
Query,
1213
} from '@nestjs/common';
1314
import { ApiBody, ApiOperation, ApiResponse } from '@nestjs/swagger';
1415
import { WorkspaceService } from './workspace.service';
@@ -22,8 +23,9 @@ import { CreateWorkspaceInviteUrlDto } from './dtos/createWorkspaceInviteUrl.dto
2223
export enum WorkspaceResponseMessage {
2324
WORKSPACE_CREATED = '워크스페이스를 생성했습니다.',
2425
WORKSPACE_DELETED = '워크스페이스를 삭제했습니다.',
25-
WORKSPACES_RETURNED = '사용자가 참여하고 있는 모든 워크스페이스들을 가져왔습니다',
26-
WORKSPACE_INVITED = '워크스페이스 게스트 초대 링크가 생성되었습니다',
26+
WORKSPACES_RETURNED = '사용자가 참여하고 있는 모든 워크스페이스들을 가져왔습니다.',
27+
WORKSPACE_INVITED = '워크스페이스 게스트 초대 링크가 생성되었습니다.',
28+
WORKSPACE_JOINED = '워크스페이스에 게스트로 등록되었습니다.',
2729
}
2830

2931
@Controller('workspace')
@@ -106,8 +108,24 @@ export class WorkspaceController {
106108
const inviteUrl = await this.workspaceService.generateInviteUrl(userId, id);
107109

108110
return {
109-
message: '초대 URL이 생성되었습니다.',
111+
message: WorkspaceResponseMessage.WORKSPACE_INVITED,
110112
inviteUrl,
111113
};
112114
}
115+
116+
@ApiResponse({
117+
type: MessageResponseDto,
118+
})
119+
@ApiOperation({
120+
summary: '워크스페이스초대 링크에 접속해 권한을 업데이트합니다.',
121+
})
122+
@Get('/join')
123+
@UseGuards(JwtAuthGuard) // 로그인 인증
124+
@HttpCode(HttpStatus.OK)
125+
async joinWorkspace(@Request() req, @Query('token') token: string) {
126+
const userId = req.user.sub; // 인증된 사용자 ID
127+
await this.workspaceService.processInviteToken(userId, token);
128+
129+
return { message: WorkspaceResponseMessage.WORKSPACE_INVITED };
130+
}
113131
}

apps/backend/src/workspace/workspace.service.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,4 +121,28 @@ export class WorkspaceService {
121121
// TODO: 하드코딩 -> 바꿔야할듯?
122122
return `https://octodocs.local/api/workspace/join?token=${token}`;
123123
}
124+
125+
async processInviteToken(userId: number, token: string): Promise<void> {
126+
// 토큰 검증 및 디코딩
127+
const decodedToken = this.tokenService.verifyInviteToken(token);
128+
const { workspaceId, role } = decodedToken;
129+
130+
// 현재 사용자를 초대받은 역할로 등록
131+
const existingRole = await this.roleRepository.findOneBy({
132+
workspaceId: parseInt(workspaceId),
133+
userId,
134+
});
135+
136+
// 이미 워크스페이스에 등록된 경우
137+
if (existingRole) {
138+
throw new Error('이미 워크스페이스에 가입된 사용자입니다.');
139+
}
140+
141+
// 새로운 역할 생성
142+
await this.roleRepository.save({
143+
workspaceId: parseInt(workspaceId),
144+
userId: userId,
145+
role: role,
146+
});
147+
}
124148
}

0 commit comments

Comments
 (0)