MCPcopy Index your code
hub / github.com/simstudioai/sim / generateOAuthLink

Function generateOAuthLink

apps/sim/lib/copilot/tools/handlers/oauth.ts:76–143  ·  view source on GitHub ↗

* Resolves a human-friendly provider name to a providerId and returns a * browser-initiated authorize URL the user opens to connect the service. * * Steps: resolve provider → return the Sim `/api/auth/oauth2/authorize` URL. * That endpoint (not this server-side handler) creates the credential dr

(
  workspaceId: string | undefined,
  workflowId: string | undefined,
  chatId: string | undefined,
  providerName: string,
  baseUrl: string
)

Source from the content-addressed store, hash-verified

74 * passes.
75 */
76async function generateOAuthLink(
77 workspaceId: string | undefined,
78 workflowId: string | undefined,
79 chatId: string | undefined,
80 providerName: string,
81 baseUrl: string
82): Promise<{ url: string; providerId: string; serviceName: string }> {
83 if (!workspaceId) {
84 throw new Error('workspaceId is required to generate an OAuth link')
85 }
86
87 const allServices = getAllOAuthServices()
88 const normalizedInput = providerName.toLowerCase().trim()
89
90 const matched =
91 allServices.find((s) => s.providerId === normalizedInput) ||
92 allServices.find((s) => s.name.toLowerCase() === normalizedInput) ||
93 allServices.find(
94 (s) =>
95 s.name.toLowerCase().includes(normalizedInput) ||
96 normalizedInput.includes(s.name.toLowerCase())
97 ) ||
98 allServices.find(
99 (s) => s.providerId.includes(normalizedInput) || normalizedInput.includes(s.providerId)
100 )
101
102 if (!matched) {
103 const available = allServices.map((s) => s.name).join(', ')
104 throw new Error(`Provider "${providerName}" not found. Available providers: ${available}`)
105 }
106
107 const { providerId, name: serviceName } = matched
108 const callbackURL =
109 workflowId && workspaceId
110 ? `${baseUrl}/workspace/${workspaceId}/w/${workflowId}`
111 : chatId && workspaceId
112 ? `${baseUrl}/workspace/${workspaceId}/chat/${chatId}`
113 : `${baseUrl}/workspace/${workspaceId}`
114
115 if (providerId === 'trello') {
116 return { url: `${baseUrl}/api/auth/trello/authorize`, providerId, serviceName }
117 }
118 if (providerId === 'shopify') {
119 const returnUrl = encodeURIComponent(callbackURL)
120 return {
121 url: `${baseUrl}/api/auth/shopify/authorize?returnUrl=${returnUrl}`,
122 providerId,
123 serviceName,
124 }
125 }
126
127 // Hand back a browser-initiated authorize URL rather than calling
128 // oAuth2LinkAccount here. Generating the link server-side would set Better
129 // Auth's signed `state` cookie on this server-to-server response instead of the
130 // user's browser, so the OAuth callback would fail with `state_mismatch`. The
131 // authorize endpoint runs the link inside the user's browser, planting the
132 // cookie correctly while keeping the callback's state check enabled.
133 //

Callers 1

executeOAuthGetAuthLinkFunction · 0.85

Calls 4

getAllOAuthServicesFunction · 0.90
joinMethod · 0.80
setMethod · 0.65
toStringMethod · 0.45

Tested by

no test coverage detected