Skip to content

Commit 8479bea

Browse files
committed
chore: merge main into release for new releases
2 parents d273b2f + 74a444e commit 8479bea

File tree

58 files changed

+2049
-438
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+2049
-438
lines changed

apps/api/src/app/s3.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { GetObjectCommand, S3Client } from '@aws-sdk/client-s3';
1+
import { GetObjectCommand, S3Client, type GetObjectCommandOutput } from '@aws-sdk/client-s3';
22
import { Logger } from '@nestjs/common';
33
import '../config/load-env';
44

@@ -126,7 +126,7 @@ export async function getFleetAgent({
126126
os,
127127
}: {
128128
os: 'macos' | 'windows' | 'linux';
129-
}) {
129+
}): Promise<GetObjectCommandOutput['Body']> {
130130
if (!s3Client) {
131131
throw new Error('S3 client not configured');
132132
}

apps/api/src/attachments/upload-attachment.dto.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,4 +69,15 @@ export class UploadAttachmentDto {
6969
@IsString()
7070
@MaxLength(500)
7171
description?: string;
72+
73+
@ApiProperty({
74+
description:
75+
'User ID of the user uploading the attachment (required for API key auth, ignored for JWT auth)',
76+
example: 'usr_abc123def456',
77+
required: false,
78+
})
79+
@IsOptional()
80+
@IsString()
81+
@IsNotEmpty()
82+
userId?: string;
7283
}

apps/api/src/comments/comments.controller.ts

Lines changed: 71 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,14 @@ import {
55
Controller,
66
Delete,
77
Get,
8-
HttpCode,
9-
HttpStatus,
108
Param,
119
Post,
1210
Put,
1311
Query,
1412
UseGuards,
1513
} from '@nestjs/common';
1614
import {
15+
ApiBody,
1716
ApiHeader,
1817
ApiOperation,
1918
ApiParam,
@@ -28,6 +27,7 @@ import type { AuthContext as AuthContextType } from '../auth/types';
2827
import { CommentsService } from './comments.service';
2928
import { CommentResponseDto } from './dto/comment-responses.dto';
3029
import { CreateCommentDto } from './dto/create-comment.dto';
30+
import { DeleteCommentDto } from './dto/delete-comment.dto';
3131
import { UpdateCommentDto } from './dto/update-comment.dto';
3232

3333
@ApiTags('Comments')
@@ -92,13 +92,28 @@ export class CommentsController {
9292
@AuthContext() authContext: AuthContextType,
9393
@Body() createCommentDto: CreateCommentDto,
9494
): Promise<CommentResponseDto> {
95-
if (!authContext.userId) {
96-
throw new BadRequestException('User ID is required');
95+
// For API key auth, userId must be provided in the request body
96+
// For JWT auth, userId comes from the authenticated session
97+
let userId: string;
98+
if (authContext.isApiKey) {
99+
// For API key auth, userId must be provided in the DTO
100+
if (!createCommentDto.userId) {
101+
throw new BadRequestException(
102+
'User ID is required when using API key authentication. Provide userId in the request body.',
103+
);
104+
}
105+
userId = createCommentDto.userId;
106+
} else {
107+
// For JWT auth, use the authenticated user's ID
108+
if (!authContext.userId) {
109+
throw new BadRequestException('User ID is required');
110+
}
111+
userId = authContext.userId;
97112
}
98113

99114
return await this.commentsService.createComment(
100115
organizationId,
101-
authContext.userId,
116+
userId,
102117
createCommentDto,
103118
);
104119
}
@@ -124,14 +139,29 @@ export class CommentsController {
124139
@Param('commentId') commentId: string,
125140
@Body() updateCommentDto: UpdateCommentDto,
126141
): Promise<CommentResponseDto> {
127-
if (!authContext.userId) {
128-
throw new BadRequestException('User ID is required');
142+
// For API key auth, userId must be provided in the request body
143+
// For JWT auth, userId comes from the authenticated session
144+
let userId: string;
145+
if (authContext.isApiKey) {
146+
// For API key auth, userId must be provided in the DTO
147+
if (!updateCommentDto.userId) {
148+
throw new BadRequestException(
149+
'User ID is required when using API key authentication. Provide userId in the request body.',
150+
);
151+
}
152+
userId = updateCommentDto.userId;
153+
} else {
154+
// For JWT auth, use the authenticated user's ID
155+
if (!authContext.userId) {
156+
throw new BadRequestException('User ID is required');
157+
}
158+
userId = authContext.userId;
129159
}
130160

131161
return await this.commentsService.updateComment(
132162
organizationId,
133163
commentId,
134-
authContext.userId,
164+
userId,
135165
updateCommentDto.content,
136166
);
137167
}
@@ -146,6 +176,20 @@ export class CommentsController {
146176
description: 'Unique comment identifier',
147177
example: 'cmt_abc123def456',
148178
})
179+
@ApiBody({
180+
description: 'Delete comment request body',
181+
schema: {
182+
type: 'object',
183+
properties: {
184+
userId: {
185+
type: 'string',
186+
description:
187+
'User ID of the comment author (required for API key auth, ignored for JWT auth)',
188+
example: 'usr_abc123def456',
189+
},
190+
},
191+
},
192+
})
149193
@ApiResponse({
150194
status: 200,
151195
description: 'Comment deleted successfully',
@@ -198,15 +242,31 @@ export class CommentsController {
198242
@OrganizationId() organizationId: string,
199243
@AuthContext() authContext: AuthContextType,
200244
@Param('commentId') commentId: string,
245+
@Body() deleteDto: DeleteCommentDto,
201246
): Promise<{ success: boolean; deletedCommentId: string; message: string }> {
202-
if (!authContext.userId) {
203-
throw new BadRequestException('User ID is required');
247+
// For API key auth, userId must be provided in the request body
248+
// For JWT auth, userId comes from the authenticated session
249+
let userId: string;
250+
if (authContext.isApiKey) {
251+
// For API key auth, userId must be provided in the request body
252+
if (!deleteDto.userId) {
253+
throw new BadRequestException(
254+
'User ID is required when using API key authentication. Provide userId in the request body.',
255+
);
256+
}
257+
userId = deleteDto.userId;
258+
} else {
259+
// For JWT auth, use the authenticated user's ID
260+
if (!authContext.userId) {
261+
throw new BadRequestException('User ID is required');
262+
}
263+
userId = authContext.userId;
204264
}
205265

206266
await this.commentsService.deleteComment(
207267
organizationId,
208268
commentId,
209-
authContext.userId,
269+
userId,
210270
);
211271

212272
return {

apps/api/src/comments/dto/create-comment.dto.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,4 +49,15 @@ export class CreateCommentDto {
4949
@ValidateNested({ each: true })
5050
@Type(() => UploadAttachmentDto)
5151
attachments?: UploadAttachmentDto[];
52+
53+
@ApiProperty({
54+
description:
55+
'User ID of the comment author (required for API key auth, ignored for JWT auth)',
56+
example: 'usr_abc123def456',
57+
required: false,
58+
})
59+
@IsOptional()
60+
@IsString()
61+
@IsNotEmpty()
62+
userId?: string;
5263
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { ApiProperty } from '@nestjs/swagger';
2+
import { IsNotEmpty, IsOptional, IsString } from 'class-validator';
3+
4+
export class DeleteCommentDto {
5+
@ApiProperty({
6+
description:
7+
'User ID of the comment author (required for API key auth, ignored for JWT auth)',
8+
example: 'usr_abc123def456',
9+
required: false,
10+
})
11+
@IsOptional()
12+
@IsString()
13+
@IsNotEmpty()
14+
userId?: string;
15+
}

apps/api/src/comments/dto/update-comment.dto.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { ApiProperty } from '@nestjs/swagger';
2-
import { IsNotEmpty, IsString, MaxLength } from 'class-validator';
2+
import { IsNotEmpty, IsOptional, IsString, MaxLength } from 'class-validator';
33

44
export class UpdateCommentDto {
55
@ApiProperty({
@@ -11,4 +11,15 @@ export class UpdateCommentDto {
1111
@IsNotEmpty()
1212
@MaxLength(2000)
1313
content: string;
14+
15+
@ApiProperty({
16+
description:
17+
'User ID of the comment author (required for API key auth, ignored for JWT auth)',
18+
example: 'usr_abc123def456',
19+
required: false,
20+
})
21+
@IsOptional()
22+
@IsString()
23+
@IsNotEmpty()
24+
userId?: string;
1425
}

0 commit comments

Comments
 (0)