( webhookData: WebhookRecord, oauthProvider: string, requestId: string, logger: Logger )
| 189 | * Returns the access token or throws on failure. |
| 190 | */ |
| 191 | export async function resolveOAuthCredential( |
| 192 | webhookData: WebhookRecord, |
| 193 | oauthProvider: string, |
| 194 | requestId: string, |
| 195 | logger: Logger |
| 196 | ): Promise<string> { |
| 197 | const metadata = webhookData.providerConfig as Record<string, unknown> | null |
| 198 | const credentialId = metadata?.credentialId as string | undefined |
| 199 | const userId = metadata?.userId as string | undefined |
| 200 | const credentialSetId = (webhookData.credentialSetId as string | undefined) ?? undefined |
| 201 | |
| 202 | if (!credentialId && !userId) { |
| 203 | throw new Error(`Missing credential info for webhook ${webhookData.id}`) |
| 204 | } |
| 205 | |
| 206 | if (credentialSetId) { |
| 207 | const [cs] = await db |
| 208 | .select({ organizationId: credentialSet.organizationId }) |
| 209 | .from(credentialSet) |
| 210 | .where(eq(credentialSet.id, credentialSetId)) |
| 211 | .limit(1) |
| 212 | |
| 213 | if (cs?.organizationId) { |
| 214 | const hasAccess = await isOrganizationOnTeamOrEnterprisePlan(cs.organizationId) |
| 215 | if (!hasAccess) { |
| 216 | logger.error( |
| 217 | `[${requestId}] Polling Group plan restriction: Your current plan does not support Polling Groups. Upgrade to Team or Enterprise to use this feature.`, |
| 218 | { |
| 219 | webhookId: webhookData.id, |
| 220 | credentialSetId, |
| 221 | organizationId: cs.organizationId, |
| 222 | } |
| 223 | ) |
| 224 | throw new Error('Polling Group plan restriction') |
| 225 | } |
| 226 | } |
| 227 | } |
| 228 | |
| 229 | let accessToken: string | null = null |
| 230 | |
| 231 | if (credentialId) { |
| 232 | const resolved = await resolveOAuthAccountId(credentialId) |
| 233 | if (!resolved) { |
| 234 | throw new Error( |
| 235 | `Failed to resolve OAuth account for credential ${credentialId}, webhook ${webhookData.id}` |
| 236 | ) |
| 237 | } |
| 238 | const rows = await db.select().from(account).where(eq(account.id, resolved.accountId)).limit(1) |
| 239 | if (!rows.length) { |
| 240 | throw new Error(`Credential ${credentialId} not found for webhook ${webhookData.id}`) |
| 241 | } |
| 242 | const ownerUserId = rows[0].userId |
| 243 | accessToken = await refreshAccessTokenIfNeeded(resolved.accountId, ownerUserId, requestId) |
| 244 | } else if (userId) { |
| 245 | accessToken = await getOAuthToken(userId, oauthProvider) |
| 246 | } |
| 247 | |
| 248 | if (!accessToken) { |
no test coverage detected