Skip to content

Conversation

@github-actions
Copy link
Contributor

This is an automated pull request to release the candidate branch into production, which will trigger a deployment.
It was created by the [Production PR] action.

* fix(api): update response and docs for policy & risks endpoints

* fix(api): add API key auth support with userId parameter for comments API

* fix(api): add API key auth support with userId parameter for transfer-ownership and task/attachments endpoints

* fix(api): move userId to request body for comment deletion endpoint

* fix(api): don't expose sensitive fields of user model from /risks endpoint

* fix(api): update error description of transfer-ownership api

---------

Co-authored-by: chasprowebdev <chasgarciaprowebdev@gmail.com>
Co-authored-by: Mariano Fuentes <marfuen98@gmail.com>
@vercel
Copy link

vercel bot commented Dec 17, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (UTC)
app (staging) Ready Ready Preview, Comment Dec 18, 2025 5:11pm
portal (staging) Ready Ready Preview, Comment Dec 18, 2025 5:11pm

@cursor
Copy link

cursor bot commented Dec 17, 2025

PR Summary

Adds JumpCloud employee sync end-to-end, implements OAuth token revocation and connection auth teardown, and updates APIs/DTOs to support API key userId flows with related UI and docs changes.

  • Integrations/Sync:
    • JumpCloud: New manifest, types, variables, and employee sync check; API endpoints POST /v1/integrations/sync/jumpcloud/*; scheduler supports JumpCloud; registry registration.
    • Google Workspace/Rippling: Normalize emails to lowercase and derive managed domains from all users/workers for deactivation logic.
  • Auth/Connections:
    • Add OAuthTokenRevocationService and ConnectionAuthTeardownService; disconnect/delete now revoke tokens, delete stored credentials, and clear active pointers.
    • CredentialRepository.deleteAllByConnection added; module wires new providers.
  • API & DTOs:
    • Comments, task attachments, and org ownership transfer now accept userId in body for API key auth; new DeleteCommentDto; Swagger bodies/responses updated.
    • Risks service includes assignee.user details in queries.
    • S3 getFleetAgent return type clarified.
  • Frontend (People/Policies):
    • People page supports selecting/syncing JumpCloud; queries/hooks extended for JumpCloud provider and status.
    • Policy editor shows AI assistant by default and improves guidance/diff UX.
  • Docs/OpenAPI: Updated for new endpoints, request bodies, and enriched responses (e.g., policies list wrapper with auth info).
  • Misc:
    • UI component minor refactors/typings (diff, sheet, clamp), email templates formatting, analytics helper reflow.
    • Dependency bumps and turbo.json UI mode change.

Written by Cursor Bugbot for commit 74a444e. This will update automatically on new commits. Configure here.

@graphite-app graphite-app bot requested a review from Marfuen December 17, 2025 14:50
@CLAassistant
Copy link

CLAassistant commented Dec 17, 2025

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you all sign our Contributor License Agreement before we can accept your contribution.
2 out of 3 committers have signed the CLA.

✅ carhartlewis
✅ Marfuen
❌ github-actions[bot]
You have signed the CLA already but the status is still pending? Let us recheck it.

},
},
},
});
Copy link

Choose a reason for hiding this comment

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

Bug: Risk detail leaks full assignee user fields

RisksService.findById now uses include: { assignee: { include: { user: true }}}, which returns all scalar User fields (e.g., emailVerified, emailPreferences, isPlatformAdmin) in the API response. This expands exposed data compared to the list endpoint’s limited select and can leak sensitive/internal user attributes.

Fix in Cursor Fix in Web

@graphite-app
Copy link

graphite-app bot commented Dec 17, 2025

Graphite Automations

"Auto-assign PRs to Author" took an action on this PR • (12/17/25)

1 reviewer was added to this PR based on Mariano Fuentes's automation.

Comment on lines 193 to 250
@ApiResponse({
status: 200,
description: 'Comment deleted successfully',
content: {
'application/json': {
schema: {
type: 'object',
properties: {
success: { type: 'boolean', example: true },
deletedCommentId: { type: 'string', example: 'cmt_abc123def456' },
message: {
type: 'string',
example: 'Comment deleted successfully',
},
},
},
},
},
})
@ApiResponse({
status: 401,
description: 'Unauthorized - Invalid authentication',
content: {
'application/json': {
schema: {
type: 'object',
properties: { message: { type: 'string', example: 'Unauthorized' } },
},
},
},
})
@ApiResponse({
status: 404,
description: 'Comment not found',
content: {
'application/json': {
schema: {
type: 'object',
properties: {
message: {
type: 'string',
example: 'Comment with ID cmt_abc123def456 not found',
},
},
},
},
},
})
async deleteComment(
@OrganizationId() organizationId: string,
@AuthContext() authContext: AuthContextType,
@Param('commentId') commentId: string,
@Body() deleteDto: DeleteCommentDto,
): Promise<{ success: boolean; deletedCommentId: string; message: string }> {
if (!authContext.userId) {
throw new BadRequestException('User ID is required');
// For API key auth, userId must be provided in the request body
// For JWT auth, userId comes from the authenticated session
let userId: string;
if (authContext.isApiKey) {
Copy link

Choose a reason for hiding this comment

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

DELETE endpoint now requires a request body, which is non-standard for DELETE requests. The OpenAPI spec marks requestBody as required: true, but the DeleteCommentDto has userId as optional. This creates ambiguity:

  1. For JWT auth users, they must send an empty body {} even though userId is ignored
  2. Many HTTP clients, proxies, and tools have poor support for DELETE with body
  3. Some infrastructure may strip bodies from DELETE requests

Impact: JWT authentication users may get errors if their HTTP client doesn't send a body, or if infrastructure strips the body.

Fix: Consider one of these approaches:

// Option 1: Make body truly optional
@Body() deleteDto?: DeleteCommentDto,
// Then handle undefined case

// Option 2: Use query parameter for API key auth
@Query('userId') userId?: string,

// Option 3: Use custom header
Suggested change
@ApiResponse({
status: 200,
description: 'Comment deleted successfully',
})
@Delete(':commentId')
async deleteComment(
@OrganizationId() organizationId: string,
@AuthContext() authContext: AuthContextType,
@Param('commentId') commentId: string,
@Query('userId') userIdParam?: string,
): Promise<{ success: boolean; deletedCommentId: string; message: string }> {
// For API key auth, userId must be provided in the query parameter
// For JWT auth, userId comes from the authenticated session
let userId: string;
if (authContext.isApiKey) {

Spotted by Graphite Agent

Fix in Graphite


Is this helpful? React 👍 or 👎 to let us know.

* feat(ai): enhance policy assistant prompts for user guidance

* chore(db): update package.json exports to include types for modules

* fix(app): change overflow style in PolicyDetails component

* fix(app): enable AI assistant by default in PolicyDetails component

---------

Co-authored-by: Daniel Fu <itsnotaka@gmail.com>
Co-authored-by: Mariano Fuentes <marfuen98@gmail.com>
...(authContext.userEmail && { email: authContext.userEmail }),
},
};
}
Copy link

Choose a reason for hiding this comment

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

Bug: API key can transfer ownership via userId

transferOwnership no longer enforces session-only auth; under API key auth it trusts a body-provided userId and passes it as currentUserId. Any API key holder who knows an owner’s userId can trigger an ownership transfer, effectively bypassing the prior “session authentication required” gate.

Fix in Cursor Fix in Web

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Bug: PDF view clipped by hidden overflow

The left pane wrapper switched from overflow-y-auto to overflow-hidden, but the PDF/content inside (e.g., PdfViewer’s fixed h-[800px] iframe) can exceed the h-[60vh] container. This causes policy content/PDF to be cut off with no way to scroll, making parts of the document unreachable.

apps/app/src/app/(app)/[orgId]/policies/[policyId]/editor/components/PolicyDetails.tsx#L185-L252

https://github.com/trycompai/comp/blob/3a53acce9230d343c59348e49851c05308952b2f/apps/app/src/app/(app)/[orgId]/policies/[policyId]/editor/components/PolicyDetails.tsx#L185-L252

Fix in Cursor Fix in Web


* feat(jumpcloud): add integration for syncing employees from JumpCloud

* fix(jumpcloud): added rippling back as a valid provider

* fix(jumpcloud): updated help text

* fix(sync): normalize email to lowercase for consistent database operations

* chore(deps): update package versions and bun.lock for consistency
name: gwUser.name.fullName || gwUser.primaryEmail.split('@')[0],
email: normalizedEmail,
name: gwUser.name.fullName || normalizedEmail.split('@')[0],
emailVerified: true, // Google Workspace users are verified
Copy link

Choose a reason for hiding this comment

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

Bug: Email normalization can create duplicate users

Google Workspace and JumpCloud sync now lowercases emails for findUnique and create, but existing User.email values may have been stored with original casing. Because the DB @@unique([email]) is case-sensitive, a previously-created mixed-case email won’t match the new lowercase lookup and a second user record can be created for the same email.

Additional Locations (1)

Fix in Cursor Fix in Web

@Marfuen Marfuen merged commit 8479bea into release Dec 18, 2025
14 of 15 checks passed
@claudfuen
Copy link
Contributor

🎉 This PR is included in version 1.72.0 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants