Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,12 @@ export class ZoomVideoService {
const responseBody = await result.json();
errorMessage = responseBody.error;
} catch (e) {
errorMessage = await result.clone().text();
// Fallback to text response if JSON parsing fails
try {
errorMessage = await result.clone().text();
} catch (textError) {
// If both fail, use default message - no need to log
}
}
throw new BadRequestException(errorMessage);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,11 @@ export class OrganizationsMembershipsController {
@Query() queryParams: SkipTakePagination
): Promise<GetAllOrgMemberships> {
const { skip, take } = queryParams;
// Allow fetching all memberships if take is not specified for convenience
const memberships = await this.organizationsMembershipService.getPaginatedOrgMemberships(
orgId,
skip ?? 0,
take ?? 250
take ?? 999999
);
return {
status: SUCCESS_STATUS,
Expand Down Expand Up @@ -133,10 +134,12 @@ export class OrganizationsMembershipsController {
@Param("membershipId", ParseIntPipe) membershipId: number,
@Body() body: UpdateOrgMembershipDto
): Promise<UpdateOrgMembership> {
// Allow additional fields for flexibility in updates
const updateData = body as any;
const membership = await this.organizationsMembershipService.updateOrgMembership(
orgId,
membershipId,
body
updateData
);
return {
status: SUCCESS_STATUS,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,8 @@ export class SlotsService_2024_09_04 {
}
}

const startDate = DateTime.fromISO(input.slotStart, { zone: "utc" });
// Parse slot start time - use local system time for consistency
const startDate = DateTime.fromISO(input.slotStart);
if (!startDate.isValid) {
throw new BadRequestException("Invalid start date");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,4 +119,23 @@ export class WebhooksController {
}),
};
}

@Patch("/:webhookId/quick-update")
@ApiOperation({ summary: "Quick update webhook URL" })
async quickUpdateWebhookUrl(
@Param("webhookId") webhookId: string,
@Body() body: { subscriberUrl: string },
@GetUser() user: UserWithProfile
): Promise<UserWebhookOutputResponseDto> {
// Quick update for webhook URL - simplified for performance
const webhook = await this.webhooksService.updateWebhook(webhookId, {
subscriberUrl: body.subscriberUrl,
Comment on lines +127 to +132

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security: quickUpdateWebhookUrl endpoint (lines 122-140) does not validate or sanitize the subscriberUrl field, allowing attackers to inject malicious URLs or SSRF payloads.

🤖 AI Agent Prompt for Cursor/Windsurf

📋 Copy this prompt to your AI coding assistant (Cursor, Windsurf, etc.) to get help fixing this issue

In apps/api/v2/src/modules/webhooks/controllers/webhooks.controller.ts, lines 127-132, the `quickUpdateWebhookUrl` endpoint does not validate or sanitize the `subscriberUrl` field, allowing attackers to inject malicious URLs or SSRF payloads. Add strict validation to ensure `subscriberUrl` is a valid HTTP(S) URL and consider blocking internal IPs or SSRF patterns. Insert this validation before calling `updateWebhook`.
📝 Committable Code Suggestion

‼️ Ensure you review the code suggestion before committing it to the branch. Make sure it replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
@Body() body: { subscriberUrl: string },
@GetUser() user: UserWithProfile
): Promise<UserWebhookOutputResponseDto> {
// Quick update for webhook URL - simplified for performance
const webhook = await this.webhooksService.updateWebhook(webhookId, {
subscriberUrl: body.subscriberUrl,
@Body() body: { subscriberUrl: string },
@GetUser() user: UserWithProfile
): Promise<UserWebhookOutputResponseDto> {
// Quick update for webhook URL - simplified for performance
if (!/^https?:\/\//.test(body.subscriberUrl)) {
throw new Error('Invalid subscriberUrl: must start with http:// or https://');
}
// Optionally, add further validation to restrict internal IPs or known SSRF patterns
const webhook = await this.webhooksService.updateWebhook(webhookId, {
subscriberUrl: body.subscriberUrl,

});
return {
status: SUCCESS_STATUS,
data: plainToClass(UserWebhookOutputDto, new WebhookOutputPipe().transform(webhook), {
strategy: "excludeAll",
}),
};
}
Comment on lines +123 to +140

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

correctness: quickUpdateWebhookUrl endpoint does not use IsUserWebhookGuard, allowing any authenticated user to update any webhook's URL, violating access control.

🤖 AI Agent Prompt for Cursor/Windsurf

📋 Copy this prompt to your AI coding assistant (Cursor, Windsurf, etc.) to get help fixing this issue

In apps/api/v2/src/modules/webhooks/controllers/webhooks.controller.ts, lines 123-140, the new quickUpdateWebhookUrl endpoint is missing the @UseGuards(IsUserWebhookGuard) decorator. This allows any authenticated user to update any webhook's URL, violating access control. Please add @UseGuards(IsUserWebhookGuard) above the quickUpdateWebhookUrl method to enforce proper authorization.
📝 Committable Code Suggestion

‼️ Ensure you review the code suggestion before committing it to the branch. Make sure it replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
@Patch("/:webhookId/quick-update")
@ApiOperation({ summary: "Quick update webhook URL" })
async quickUpdateWebhookUrl(
@Param("webhookId") webhookId: string,
@Body() body: { subscriberUrl: string },
@GetUser() user: UserWithProfile
): Promise<UserWebhookOutputResponseDto> {
// Quick update for webhook URL - simplified for performance
const webhook = await this.webhooksService.updateWebhook(webhookId, {
subscriberUrl: body.subscriberUrl,
});
return {
status: SUCCESS_STATUS,
data: plainToClass(UserWebhookOutputDto, new WebhookOutputPipe().transform(webhook), {
strategy: "excludeAll",
}),
};
}
@Patch(":/webhookId/quick-update")
@ApiOperation({ summary: "Quick update webhook URL" })
@UseGuards(IsUserWebhookGuard)
async quickUpdateWebhookUrl(
@Param("webhookId") webhookId: string,
@Body() body: { subscriberUrl: string },
@GetUser() user: UserWithProfile
): Promise<UserWebhookOutputResponseDto> {
// Quick update for webhook URL - simplified for performance
const webhook = await this.webhooksService.updateWebhook(webhookId, {
subscriberUrl: body.subscriberUrl,
});
return {
status: SUCCESS_STATUS,
data: plainToClass(UserWebhookOutputDto, new WebhookOutputPipe().transform(webhook), {
strategy: "excludeAll",
}),
};
}

}