diff --git a/app/w/[id]/components/workflow-block/components/sub-block/components/credential-selector.tsx b/app/w/[id]/components/workflow-block/components/sub-block/components/credential-selector.tsx
index 565093319..c543c832d 100644
--- a/app/w/[id]/components/workflow-block/components/sub-block/components/credential-selector.tsx
+++ b/app/w/[id]/components/workflow-block/components/sub-block/components/credential-selector.tsx
@@ -21,6 +21,7 @@ import {
getProviderIdFromServiceId,
getServiceByProviderAndId,
getServiceIdFromScopes,
+ parseProvider,
} from '@/lib/oauth'
import { saveToStorage } from '@/stores/workflows/persistence'
@@ -168,26 +169,62 @@ export function CredentialSelector({
// Get provider icon
const getProviderIcon = (providerName: OAuthProvider) => {
- const providerConfig = OAUTH_PROVIDERS[providerName]
- if (providerConfig) {
- return providerConfig.icon({ className: 'h-4 w-4' })
+ const { baseProvider } = parseProvider(providerName)
+ const baseProviderConfig = OAUTH_PROVIDERS[baseProvider]
+
+ if (!baseProviderConfig) {
+ return
}
- return
+
+ // For compound providers, find the specific service
+ if (providerName.includes('-')) {
+ for (const service of Object.values(baseProviderConfig.services)) {
+ if (service.providerId === providerName) {
+ return service.icon({ className: 'h-4 w-4' })
+ }
+ }
+ }
+
+ // Fallback to base provider icon
+ return baseProviderConfig.icon({ className: 'h-4 w-4' })
}
// Get provider name
const getProviderName = (providerName: OAuthProvider) => {
const effectiveServiceId = getServiceId()
try {
+ // First try to get the service by provider and service ID
const service = getServiceByProviderAndId(providerName, effectiveServiceId)
return service.name
} catch (error) {
- // Fallback to provider name if service not found
- const providerConfig = OAUTH_PROVIDERS[providerName]
- if (providerConfig) {
- return providerConfig.name
+ // If that fails, try to get the service by parsing the provider
+ try {
+ const { baseProvider } = parseProvider(providerName)
+ const baseProviderConfig = OAUTH_PROVIDERS[baseProvider]
+
+ // For compound providers like 'google-sheets', try to find the specific service
+ if (providerName.includes('-')) {
+ const serviceKey = providerName.split('-')[1] || ''
+ for (const [key, service] of Object.entries(baseProviderConfig?.services || {})) {
+ if (key === serviceKey || key === providerName || service.providerId === providerName) {
+ return service.name
+ }
+ }
+ }
+
+ // Fallback to provider name if service not found
+ if (baseProviderConfig) {
+ return baseProviderConfig.name
+ }
+ } catch (parseError) {
+ // Ignore parse error and continue to final fallback
}
+
+ // Final fallback: capitalize the provider name
return providerName
+ .split('-')
+ .map((part) => part.charAt(0).toUpperCase() + part.slice(1))
+ .join(' ')
}
}
@@ -209,8 +246,8 @@ export function CredentialSelector({
) : (
-
- {label}
+ {getProviderIcon(provider)}
+ {label}
)}
@@ -228,7 +265,7 @@ export function CredentialSelector({
) : (
-
No credentials found.
+
No credentials found.
Connect a new account to continue.
@@ -255,7 +292,7 @@ export function CredentialSelector({
-
+ {getProviderIcon(provider)}
Connect {getProviderName(provider)} account
diff --git a/components/ui/oauth-required-modal.tsx b/components/ui/oauth-required-modal.tsx
index ed5100bfc..589c3cacb 100644
--- a/components/ui/oauth-required-modal.tsx
+++ b/components/ui/oauth-required-modal.tsx
@@ -16,6 +16,7 @@ import {
OAuthProvider,
getProviderIdFromServiceId,
getServiceIdFromScopes,
+ parseProvider,
} from '@/lib/oauth'
import { saveToStorage } from '@/stores/workflows/persistence'
@@ -60,10 +61,25 @@ export function OAuthRequiredModal({
requiredScopes = [],
serviceId,
}: OAuthRequiredModalProps) {
- // Get provider configuration
- const providerConfig = OAUTH_PROVIDERS[provider]
- const providerName = providerConfig?.name || provider
- const ProviderIcon = providerConfig?.icon || (() => null)
+ // Get provider configuration and service
+ const effectiveServiceId = serviceId || getServiceIdFromScopes(provider, requiredScopes)
+ const { baseProvider } = parseProvider(provider)
+ const baseProviderConfig = OAUTH_PROVIDERS[baseProvider]
+
+ // Default to base provider name and icon
+ let providerName = baseProviderConfig?.name || provider
+ let ProviderIcon = baseProviderConfig?.icon || (() => null)
+
+ // Try to find the specific service
+ if (baseProviderConfig) {
+ for (const service of Object.values(baseProviderConfig.services)) {
+ if (service.id === effectiveServiceId || service.providerId === provider) {
+ providerName = service.name
+ ProviderIcon = service.icon
+ break
+ }
+ }
+ }
// Filter out userinfo scopes as they're not relevant to show to users
const displayScopes = requiredScopes.filter(
@@ -73,7 +89,6 @@ export function OAuthRequiredModal({
const handleRedirectToSettings = () => {
try {
// Determine the appropriate serviceId and providerId
- const effectiveServiceId = serviceId || getServiceIdFromScopes(provider, requiredScopes)
const providerId = getProviderIdFromServiceId(effectiveServiceId)
// Store information about the required connection
@@ -98,7 +113,6 @@ export function OAuthRequiredModal({
const handleConnectDirectly = async () => {
try {
// Determine the appropriate serviceId and providerId
- const effectiveServiceId = serviceId || getServiceIdFromScopes(provider, requiredScopes)
const providerId = getProviderIdFromServiceId(effectiveServiceId)
// Store information about the required connection
diff --git a/lib/oauth.ts b/lib/oauth.ts
index 6c1fe5af7..2c0aa6ec0 100644
--- a/lib/oauth.ts
+++ b/lib/oauth.ts
@@ -39,6 +39,7 @@ export interface OAuthServiceConfig {
description: string
providerId: string
icon: (props: { className?: string }) => ReactNode
+ baseProviderIcon: (props: { className?: string }) => ReactNode
scopes: string[]
}
@@ -55,6 +56,7 @@ export const OAUTH_PROVIDERS: Record = {
description: 'Automate email workflows and enhance communication efficiency.',
providerId: 'google-email',
icon: (props) => GmailIcon(props),
+ baseProviderIcon: (props) => GoogleIcon(props),
scopes: [
'https://www.googleapis.com/auth/gmail.send',
'https://www.googleapis.com/auth/gmail.readonly',
@@ -66,6 +68,7 @@ export const OAUTH_PROVIDERS: Record = {
description: 'Streamline file organization and document workflows.',
providerId: 'google-drive',
icon: (props) => GoogleDriveIcon(props),
+ baseProviderIcon: (props) => GoogleIcon(props),
scopes: ['https://www.googleapis.com/auth/drive'],
},
'google-docs': {
@@ -74,6 +77,7 @@ export const OAUTH_PROVIDERS: Record = {
description: 'Create, read, and edit Google Documents programmatically.',
providerId: 'google-docs',
icon: (props) => GoogleDocsIcon(props),
+ baseProviderIcon: (props) => GoogleIcon(props),
scopes: ['https://www.googleapis.com/auth/documents'],
},
'google-sheets': {
@@ -82,6 +86,7 @@ export const OAUTH_PROVIDERS: Record = {
description: 'Manage and analyze data with Google Sheets integration.',
providerId: 'google-sheets',
icon: (props) => GoogleSheetsIcon(props),
+ baseProviderIcon: (props) => GoogleIcon(props),
scopes: ['https://www.googleapis.com/auth/spreadsheets'],
},
'google-calendar': {
@@ -90,6 +95,7 @@ export const OAUTH_PROVIDERS: Record = {
description: 'Schedule and manage events with Google Calendar.',
providerId: 'google-calendar',
icon: (props) => GoogleCalendarIcon(props),
+ baseProviderIcon: (props) => GoogleIcon(props),
scopes: ['https://www.googleapis.com/auth/calendar'],
},
},
@@ -106,6 +112,7 @@ export const OAUTH_PROVIDERS: Record = {
description: 'Manage repositories, issues, and pull requests.',
providerId: 'github-repo',
icon: (props) => GithubIcon(props),
+ baseProviderIcon: (props) => GithubIcon(props),
scopes: ['repo', 'user'],
},
'github-workflow': {
@@ -114,6 +121,7 @@ export const OAUTH_PROVIDERS: Record = {
description: 'Trigger and manage GitHub Actions workflows.',
providerId: 'github-workflow',
icon: (props) => GithubIcon(props),
+ baseProviderIcon: (props) => GithubIcon(props),
scopes: ['repo', 'workflow'],
},
},
@@ -130,6 +138,7 @@ export const OAUTH_PROVIDERS: Record = {
description: 'Post tweets and interact with the X API.',
providerId: 'x',
icon: (props) => xIcon(props),
+ baseProviderIcon: (props) => xIcon(props),
scopes: [],
},
},
@@ -146,6 +155,7 @@ export const OAUTH_PROVIDERS: Record = {
description: 'Connect to your Supabase projects and manage data.',
providerId: 'supabase',
icon: (props) => SupabaseIcon(props),
+ baseProviderIcon: (props) => SupabaseIcon(props),
scopes: ['database.read', 'database.write', 'projects.read'],
},
},