Skip to content

Commit 2c67d3d

Browse files
committed
simplify code
1 parent 223d1e8 commit 2c67d3d

File tree

14 files changed

+85
-119
lines changed

14 files changed

+85
-119
lines changed

apps/sim/app/api/auth/oauth/disconnect/route.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,6 @@ export async function POST(request: NextRequest) {
8282
id: credentialSetMember.id,
8383
credentialSetId: credentialSetMember.credentialSetId,
8484
providerId: credentialSet.providerId,
85-
type: credentialSet.type,
8685
})
8786
.from(credentialSetMember)
8887
.innerJoin(credentialSet, eq(credentialSetMember.credentialSetId, credentialSet.id))
@@ -94,12 +93,12 @@ export async function POST(request: NextRequest) {
9493
)
9594

9695
for (const membership of userMemberships) {
97-
// Only sync if the credential set matches this provider or is 'all' type
96+
// Only sync if the credential set matches this provider
97+
// Credential sets store OAuth provider IDs like 'google-email' or 'outlook'
9898
const matchesProvider =
99-
membership.type === 'all' ||
10099
membership.providerId === provider ||
101100
membership.providerId === providerId ||
102-
(membership.providerId && provider.startsWith(membership.providerId))
101+
membership.providerId?.startsWith(`${provider}-`)
103102

104103
if (matchesProvider) {
105104
try {

apps/sim/app/api/credential-sets/[id]/invite/route.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ export async function POST(req: NextRequest, { params }: { params: Promise<{ id:
121121
.where(eq(organization.id, result.set.organizationId))
122122
.limit(1)
123123

124-
const provider = (result.set.providerId as 'gmail' | 'outlook') || 'gmail'
124+
const provider = (result.set.providerId as 'google-email' | 'outlook') || 'google-email'
125125
const emailHtml = await renderPollingGroupInvitationEmail({
126126
inviterName: inviter?.name || 'A team member',
127127
organizationName: org?.name || 'your organization',

apps/sim/app/api/credential-sets/[id]/members/route.ts

Lines changed: 12 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ async function getCredentialSetWithAccess(credentialSetId: string, userId: strin
1313
.select({
1414
id: credentialSet.id,
1515
organizationId: credentialSet.organizationId,
16-
type: credentialSet.type,
1716
providerId: credentialSet.providerId,
1817
})
1918
.from(credentialSet)
@@ -62,34 +61,22 @@ export async function GET(req: NextRequest, { params }: { params: Promise<{ id:
6261
.leftJoin(user, eq(credentialSetMember.userId, user.id))
6362
.where(eq(credentialSetMember.credentialSetId, id))
6463

65-
// Get credentials for all active members
64+
// Get credentials for all active members filtered by the polling group's provider
6665
const activeMembers = members.filter((m) => m.status === 'active')
6766
const memberUserIds = activeMembers.map((m) => m.userId)
6867

6968
let credentials: { userId: string; providerId: string; accountId: string }[] = []
70-
if (memberUserIds.length > 0) {
71-
// If credential set is for a specific provider, filter by that provider
72-
if (result.set.type === 'specific' && result.set.providerId) {
73-
credentials = await db
74-
.select({
75-
userId: account.userId,
76-
providerId: account.providerId,
77-
accountId: account.accountId,
78-
})
79-
.from(account)
80-
.where(
81-
and(inArray(account.userId, memberUserIds), eq(account.providerId, result.set.providerId))
82-
)
83-
} else {
84-
credentials = await db
85-
.select({
86-
userId: account.userId,
87-
providerId: account.providerId,
88-
accountId: account.accountId,
89-
})
90-
.from(account)
91-
.where(inArray(account.userId, memberUserIds))
92-
}
69+
if (memberUserIds.length > 0 && result.set.providerId) {
70+
credentials = await db
71+
.select({
72+
userId: account.userId,
73+
providerId: account.providerId,
74+
accountId: account.accountId,
75+
})
76+
.from(account)
77+
.where(
78+
and(inArray(account.userId, memberUserIds), eq(account.providerId, result.set.providerId))
79+
)
9380
}
9481

9582
// Group credentials by userId

apps/sim/app/api/credential-sets/[id]/route.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ async function getCredentialSetWithAccess(credentialSetId: string, userId: strin
2020
organizationId: credentialSet.organizationId,
2121
name: credentialSet.name,
2222
description: credentialSet.description,
23-
type: credentialSet.type,
2423
providerId: credentialSet.providerId,
2524
createdBy: credentialSet.createdBy,
2625
createdAt: credentialSet.createdAt,

apps/sim/app/api/credential-sets/route.ts

Lines changed: 8 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,12 @@ import { getSession } from '@/lib/auth'
88

99
const logger = createLogger('CredentialSets')
1010

11-
const createCredentialSetSchema = z
12-
.object({
13-
organizationId: z.string().min(1),
14-
name: z.string().trim().min(1).max(100),
15-
description: z.string().max(500).optional(),
16-
type: z.enum(['all', 'specific']).default('all'),
17-
providerId: z.string().min(1).optional(),
18-
})
19-
.refine((data) => data.type !== 'specific' || data.providerId, {
20-
message: 'providerId is required when type is specific',
21-
path: ['providerId'],
22-
})
11+
const createCredentialSetSchema = z.object({
12+
organizationId: z.string().min(1),
13+
name: z.string().trim().min(1).max(100),
14+
description: z.string().max(500).optional(),
15+
providerId: z.enum(['google-email', 'outlook']),
16+
})
2317

2418
export async function GET(req: Request) {
2519
const session = await getSession()
@@ -50,7 +44,6 @@ export async function GET(req: Request) {
5044
id: credentialSet.id,
5145
name: credentialSet.name,
5246
description: credentialSet.description,
53-
type: credentialSet.type,
5447
providerId: credentialSet.providerId,
5548
createdBy: credentialSet.createdBy,
5649
createdAt: credentialSet.createdAt,
@@ -94,8 +87,7 @@ export async function POST(req: Request) {
9487

9588
try {
9689
const body = await req.json()
97-
const { organizationId, name, description, type, providerId } =
98-
createCredentialSetSchema.parse(body)
90+
const { organizationId, name, description, providerId } = createCredentialSetSchema.parse(body)
9991

10092
const membership = await db
10193
.select({ id: member.id, role: member.role })
@@ -139,8 +131,7 @@ export async function POST(req: Request) {
139131
organizationId,
140132
name,
141133
description: description || null,
142-
type,
143-
providerId: type === 'specific' ? providerId : null,
134+
providerId,
144135
createdBy: session.user.id,
145136
createdAt: now,
146137
updatedAt: now,

apps/sim/app/credential-account/[token]/page.tsx

Lines changed: 11 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { useParams, useRouter } from 'next/navigation'
66
import { Button } from '@/components/emcn'
77
import { GmailIcon, OutlookIcon } from '@/components/icons'
88
import { client, useSession } from '@/lib/auth/auth-client'
9+
import { getProviderDisplayName, isPollingProvider } from '@/lib/credential-sets/providers'
910

1011
interface InvitationInfo {
1112
credentialSetName: string
@@ -16,18 +17,6 @@ interface InvitationInfo {
1617

1718
type AcceptedState = 'connecting' | 'already-connected'
1819

19-
/**
20-
* Maps credential set provider IDs to OAuth provider IDs
21-
* The credential set stores 'gmail' but the OAuth provider is 'google-email'
22-
*/
23-
function getOAuthProviderId(credentialSetProviderId: string): string {
24-
if (credentialSetProviderId === 'gmail') {
25-
return 'google-email'
26-
}
27-
// outlook is the same in both
28-
return credentialSetProviderId
29-
}
30-
3120
export default function CredentialAccountInvitePage() {
3221
const params = useParams()
3322
const router = useRouter()
@@ -87,16 +76,17 @@ export default function CredentialAccountInvitePage() {
8776

8877
// Check if user already has this provider connected
8978
let isAlreadyConnected = false
90-
if (credentialSetProviderId) {
91-
const oauthProviderId = getOAuthProviderId(credentialSetProviderId)
79+
if (credentialSetProviderId && isPollingProvider(credentialSetProviderId)) {
9280
try {
9381
const connectionsRes = await fetch('/api/auth/oauth/connections')
9482
if (connectionsRes.ok) {
9583
const connectionsData = await connectionsRes.json()
9684
const connections = connectionsData.connections || []
9785
isAlreadyConnected = connections.some(
9886
(conn: { provider: string; accounts?: { id: string }[] }) =>
99-
conn.provider === oauthProviderId && conn.accounts && conn.accounts.length > 0
87+
conn.provider === credentialSetProviderId &&
88+
conn.accounts &&
89+
conn.accounts.length > 0
10090
)
10191
}
10292
} catch {
@@ -110,16 +100,15 @@ export default function CredentialAccountInvitePage() {
110100
setTimeout(() => {
111101
router.push('/workspace')
112102
}, 2000)
113-
} else if (credentialSetProviderId === 'gmail' || credentialSetProviderId === 'outlook') {
103+
} else if (credentialSetProviderId && isPollingProvider(credentialSetProviderId)) {
114104
// Not connected - start OAuth flow
115105
setAcceptedState('connecting')
116106

117107
// Small delay to show success message before redirect
118108
setTimeout(async () => {
119109
try {
120-
const oauthProviderId = getOAuthProviderId(credentialSetProviderId)
121110
await client.oauth2.link({
122-
providerId: oauthProviderId,
111+
providerId: credentialSetProviderId,
123112
callbackURL: `${window.location.origin}/workspace`,
124113
})
125114
} catch (oauthError) {
@@ -165,15 +154,12 @@ export default function CredentialAccountInvitePage() {
165154
const ProviderIcon =
166155
invitation?.providerId === 'outlook'
167156
? OutlookIcon
168-
: invitation?.providerId === 'gmail'
157+
: invitation?.providerId === 'google-email'
169158
? GmailIcon
170159
: Mail
171-
const providerName =
172-
invitation?.providerId === 'outlook'
173-
? 'Outlook'
174-
: invitation?.providerId === 'gmail'
175-
? 'Gmail'
176-
: 'email'
160+
const providerName = invitation?.providerId
161+
? getProviderDisplayName(invitation.providerId)
162+
: 'email'
177163

178164
if (acceptedState === 'already-connected') {
179165
return (

apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/credential-selector/credential-selector.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { createLogger } from '@sim/logger'
55
import { ExternalLink, Users } from 'lucide-react'
66
import { Button, Combobox } from '@/components/emcn/components'
77
import { getSubscriptionStatus } from '@/lib/billing/client'
8+
import { getPollingProviderFromOAuth } from '@/lib/credential-sets/providers'
89
import {
910
getCanonicalScopesForProvider,
1011
getProviderIdFromServiceId,
@@ -215,9 +216,10 @@ export function CredentialSelector({
215216
}, [])
216217

217218
const { comboboxOptions, comboboxGroups } = useMemo(() => {
218-
const filteredCredentialSets = credentialSets.filter(
219-
(cs) => cs.type === 'all' || cs.providerId === effectiveProviderId
220-
)
219+
const pollingProviderId = getPollingProviderFromOAuth(effectiveProviderId)
220+
const filteredCredentialSets = pollingProviderId
221+
? credentialSets.filter((cs) => cs.providerId === pollingProviderId)
222+
: []
221223

222224
if (canUseCredentialSets && filteredCredentialSets.length > 0) {
223225
const groups = []

apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/settings-modal/components/credential-sets/credential-sets.tsx

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,10 @@ import { GmailIcon, OutlookIcon } from '@/components/icons'
2121
import { Skeleton } from '@/components/ui'
2222
import { useSession } from '@/lib/auth/auth-client'
2323
import { getSubscriptionStatus } from '@/lib/billing/client'
24+
import { getProviderDisplayName, type PollingProvider } from '@/lib/credential-sets/providers'
2425
import { getUserRole } from '@/lib/workspaces/organization'
2526
import {
2627
type CredentialSet,
27-
type CredentialSetType,
2828
useAcceptCredentialSetInvitation,
2929
useCreateCredentialSet,
3030
useCreateCredentialSetInvitation,
@@ -79,7 +79,7 @@ export function CredentialSets() {
7979
const [viewingSet, setViewingSet] = useState<CredentialSet | null>(null)
8080
const [newSetName, setNewSetName] = useState('')
8181
const [newSetDescription, setNewSetDescription] = useState('')
82-
const [newSetProvider, setNewSetProvider] = useState<'gmail' | 'outlook'>('gmail')
82+
const [newSetProvider, setNewSetProvider] = useState<PollingProvider>('google-email')
8383
const [createError, setCreateError] = useState<string | null>(null)
8484
const [inviteEmails, setInviteEmails] = useState('')
8585
const [isDragging, setIsDragging] = useState(false)
@@ -92,12 +92,6 @@ export function CredentialSets() {
9292
const removeMember = useRemoveCredentialSetMember()
9393
const leaveCredentialSet = useLeaveCredentialSet()
9494

95-
const getProviderName = useCallback((providerId: string) => {
96-
if (providerId === 'gmail') return 'Gmail'
97-
if (providerId === 'outlook') return 'Outlook'
98-
return providerId
99-
}, [])
100-
10195
const extractEmailsFromText = useCallback((text: string): string[] => {
10296
// Match email patterns in text
10397
const emailRegex = /[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/g
@@ -211,13 +205,12 @@ export function CredentialSets() {
211205
organizationId: activeOrganization.id,
212206
name: newSetName.trim(),
213207
description: newSetDescription.trim() || undefined,
214-
type: 'specific' as CredentialSetType,
215208
providerId: newSetProvider,
216209
})
217210
setShowCreateModal(false)
218211
setNewSetName('')
219212
setNewSetDescription('')
220-
setNewSetProvider('gmail')
213+
setNewSetProvider('google-email')
221214
} catch (error) {
222215
logger.error('Failed to create polling group', error)
223216
if (error instanceof Error) {
@@ -258,7 +251,7 @@ export function CredentialSets() {
258251
setShowCreateModal(false)
259252
setNewSetName('')
260253
setNewSetDescription('')
261-
setNewSetProvider('gmail')
254+
setNewSetProvider('google-email')
262255
setCreateError(null)
263256
}, [])
264257

@@ -292,7 +285,7 @@ export function CredentialSets() {
292285
{viewingSet.name}
293286
</span>
294287
<span className='text-[12px] text-[var(--text-secondary)]'>
295-
{getProviderName(viewingSet.providerId || '')}
288+
{getProviderDisplayName(viewingSet.providerId || '')}
296289
</span>
297290
</div>
298291
</div>
@@ -569,7 +562,7 @@ export function CredentialSets() {
569562
</span>
570563
<span className='text-[12px] text-[var(--text-secondary)]'>
571564
{set.memberCount} member{set.memberCount !== 1 ? 's' : ''}
572-
{set.providerId && <> · {getProviderName(set.providerId)}</>}
565+
{set.providerId && <> · {getProviderDisplayName(set.providerId)}</>}
573566
</span>
574567
</div>
575568
<Button
@@ -616,8 +609,8 @@ export function CredentialSets() {
616609
<Label>Email Provider</Label>
617610
<div className='flex gap-[8px]'>
618611
<Button
619-
variant={newSetProvider === 'gmail' ? 'active' : 'default'}
620-
onClick={() => setNewSetProvider('gmail')}
612+
variant={newSetProvider === 'google-email' ? 'active' : 'default'}
613+
onClick={() => setNewSetProvider('google-email')}
621614
className='flex-1'
622615
>
623616
<GmailIcon className='mr-[6px] h-[16px] w-[16px]' />
@@ -633,8 +626,8 @@ export function CredentialSets() {
633626
</Button>
634627
</div>
635628
<p className='mt-[4px] text-[11px] text-[var(--text-tertiary)]'>
636-
Members will connect their {newSetProvider === 'gmail' ? 'Gmail' : 'Outlook'}{' '}
637-
account for email polling
629+
Members will connect their {getProviderDisplayName(newSetProvider)} account for
630+
email polling
638631
</p>
639632
</div>
640633
{createError && <p className='text-[12px] text-[var(--text-error)]'>{createError}</p>}

apps/sim/components/emails/invitations/polling-group-invitation-email.tsx

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { Link, Text } from '@react-email/components'
2-
import { createLogger } from '@sim/logger'
32
import { baseStyles } from '@/components/emails/_styles'
43
import { EmailLayout } from '@/components/emails/components'
54
import { getBrandConfig } from '@/lib/branding/branding'
@@ -8,21 +7,19 @@ interface PollingGroupInvitationEmailProps {
87
inviterName?: string
98
organizationName?: string
109
pollingGroupName?: string
11-
provider?: 'gmail' | 'outlook'
10+
provider?: 'google-email' | 'outlook'
1211
inviteLink?: string
1312
}
1413

15-
const logger = createLogger('PollingGroupInvitationEmail')
16-
1714
export function PollingGroupInvitationEmail({
1815
inviterName = 'A team member',
1916
organizationName = 'an organization',
2017
pollingGroupName = 'a polling group',
21-
provider = 'gmail',
18+
provider = 'google-email',
2219
inviteLink = '',
2320
}: PollingGroupInvitationEmailProps) {
2421
const brand = getBrandConfig()
25-
const providerName = provider === 'gmail' ? 'Gmail' : 'Outlook'
22+
const providerName = provider === 'google-email' ? 'Gmail' : 'Outlook'
2623

2724
return (
2825
<EmailLayout preview={`You've been invited to join ${pollingGroupName} on ${brand.name}`}>

apps/sim/components/emails/render.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ export async function renderPollingGroupInvitationEmail(params: {
189189
inviterName: string
190190
organizationName: string
191191
pollingGroupName: string
192-
provider: 'gmail' | 'outlook'
192+
provider: 'google-email' | 'outlook'
193193
inviteLink: string
194194
}): Promise<string> {
195195
return await render(

0 commit comments

Comments
 (0)