Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
|
@cursor review |
|
@greptile review |
PR SummaryHigh Risk Overview Updates token/credential resolution to handle Extends the UI to let admins add/delete service accounts from Integrations (paste/upload JSON, validation, encrypted storage) and updates Google blocks to show an Impersonated Account field only when a service account credential is selected; adds docs for setup and required scopes. Written by Cursor Bugbot for commit 54683d7. This will update automatically on new commits. Configure here. |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 3 potential issues.
Autofix Details
Bugbot Autofix prepared fixes for all 3 issues found in the latest run.
- ✅ Fixed: Impersonation field shown for non-service-account credentials
- The impersonation input now renders only when the selected credential is a service account by gating on
isServiceAccountinstead of provider-level support.
- The impersonation input now renders only when the selected credential is a service account by gating on
- ✅ Fixed: Return type mismatch:
undefinedinstead offalsehasExternalApiCredentialsnow coalesces the optional chaining result with?? falseso it always returns a boolean.
- ✅ Fixed: Serializer orphan logic is broader than intended
- The orphan serialization path was narrowed to only include the known
impersonateUserEmailkey instead of all orphan sub-blocks with values.
- The orphan serialization path was narrowed to only include the known
Or push these changes by commenting:
@cursor push 035b79165e
Preview (035b79165e)
diff --git a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/credential-selector/credential-selector.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/credential-selector/credential-selector.tsx
--- a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/credential-selector/credential-selector.tsx
+++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/credential-selector/credential-selector.tsx
@@ -10,7 +10,6 @@
import {
getCanonicalScopesForProvider,
getProviderIdFromServiceId,
- getServiceAccountProviderForProviderId,
OAUTH_PROVIDERS,
type OAuthProvider,
parseProvider,
@@ -122,11 +121,6 @@
[selectedCredential]
)
- const supportsServiceAccount = useMemo(
- () => !!getServiceAccountProviderForProviderId(effectiveProviderId),
- [effectiveProviderId]
- )
-
const selectedCredentialSet = useMemo(
() => credentialSets.find((cs) => cs.id === selectedCredentialSetId),
[credentialSets, selectedCredentialSetId]
@@ -377,7 +371,7 @@
className={overlayContent ? 'pl-7' : ''}
/>
- {supportsServiceAccount && !isPreview && (
+ {isServiceAccount && !isPreview && (
<div className='mt-2.5 flex flex-col gap-2.5'>
<div className='flex items-center gap-1.5 pl-0.5'>
<Label>
diff --git a/apps/sim/lib/auth/hybrid.ts b/apps/sim/lib/auth/hybrid.ts
--- a/apps/sim/lib/auth/hybrid.ts
+++ b/apps/sim/lib/auth/hybrid.ts
@@ -25,7 +25,7 @@
export function hasExternalApiCredentials(headers: Headers): boolean {
if (headers.has(API_KEY_HEADER)) return true
const auth = headers.get('authorization')
- return auth?.startsWith(BEARER_PREFIX)
+ return auth?.startsWith(BEARER_PREFIX) ?? false
}
export interface AuthResult {
diff --git a/apps/sim/serializer/index.ts b/apps/sim/serializer/index.ts
--- a/apps/sim/serializer/index.ts
+++ b/apps/sim/serializer/index.ts
@@ -347,14 +347,17 @@
)
)
- const isOrphanWithValue =
- matchingConfigs.length === 0 && subBlock.value != null && subBlock.value !== ''
+ const isImpersonateUserEmailOrphanWithValue =
+ id === 'impersonateUserEmail' &&
+ matchingConfigs.length === 0 &&
+ subBlock.value != null &&
+ subBlock.value !== ''
if (
(matchingConfigs.length > 0 && shouldInclude) ||
hasStarterInputFormatValues ||
isLegacyAgentField ||
- isOrphanWithValue
+ isImpersonateUserEmailOrphanWithValue
) {
params[id] = subBlock.value
}This Bugbot Autofix run was free. To enable autofix for future PRs, go to the Cursor dashboard.
...omponents/editor/components/sub-block/components/credential-selector/credential-selector.tsx
Outdated
Show resolved
Hide resolved
Greptile SummaryThis PR introduces Google Service Account credentials as a first-class integration type, enabling Google Workspace domain-wide delegation for automated workflows without per-user OAuth consent flows. It adds a Key changes:
Confidence Score: 3/5Not safe to merge — Gmail label routes bypass per-credential access control for service accounts One confirmed P1: gmail/labels and gmail/label routes check only workspace membership for service accounts, skipping the credentialMember table check enforced by all other updated routes. Any workspace member can obtain a service account token via these endpoints regardless of explicit credential grant. Fix is mechanical but required before merge. Remaining findings are P2. apps/sim/app/api/tools/gmail/labels/route.ts and apps/sim/app/api/tools/gmail/label/route.ts Important Files Changed
Sequence DiagramsequenceDiagram
participant UI as Integrations UI
participant CredAPI as /api/credentials
participant TokenAPI as /api/auth/oauth/token
participant ToolAPI as /api/tools/gmail/*
participant CredAccess as credential-access.ts
participant SAUtils as getServiceAccountToken
participant Google as Google OAuth2
UI->>CredAPI: POST type:service_account, serviceAccountJson
CredAPI->>CredAPI: Validate JSON
CredAPI->>CredAPI: encryptSecret
CredAPI->>DB: INSERT credential
CredAPI->>DB: INSERT credentialMember for workspace members
Note over UI,CredAPI: Workflow execution
UI->>TokenAPI: POST credentialId, scopes, impersonateEmail
TokenAPI->>DB: resolveOAuthAccountId
DB-->>TokenAPI: credentialType:service_account
TokenAPI->>CredAccess: authorizeCredentialUse
CredAccess->>DB: Check workspace membership
CredAccess->>DB: Check credentialMember membership
CredAccess-->>TokenAPI: ok:true
TokenAPI->>SAUtils: getServiceAccountToken
SAUtils->>DB: SELECT encryptedServiceAccountKey
SAUtils->>SAUtils: decryptSecret, sign RS256 JWT
SAUtils->>Google: POST /token jwt-bearer
Google-->>SAUtils: access_token
SAUtils-->>TokenAPI: accessToken
TokenAPI-->>UI: accessToken
Note over ToolAPI,Google: Gmail label routes P1 gap
UI->>ToolAPI: GET /gmail/labels?credentialId
ToolAPI->>DB: resolveOAuthAccountId
ToolAPI->>DB: getUserEntityPermissions workspace only
ToolAPI->>SAUtils: getServiceAccountToken
SAUtils->>Google: POST /token
Google-->>SAUtils: access_token
SAUtils-->>ToolAPI: accessToken
ToolAPI->>Google: GET /gmail/v1/users/me/labels
Google-->>ToolAPI: labels
ToolAPI-->>UI: labels
|
apps/sim/app/workspace/[workspaceId]/settings/components/integrations/integrations-manager.tsx
Show resolved
Hide resolved
|
@BugBot review |
|
@greptile review |
|
@BugBot review |
|
@greptile review |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 3 potential issues.
Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.


Summary
Add google service support as a integration. Allows users with admin credentials to assume roles on behalf of their google workspace users.
Created new credential type
service_account.Added documentation to sim docs.
Type of Change
Testing
Checklist
Screenshots/Videos