feat(credential-groups): add seventeen OAuth providers
Summary
- Adds 17 OAuth providers to Credential Groups: Airtable, Asana, Attio, Box, Cal.com, ClickUp, DocuSign, Dropbox, HubSpot, Linear, LinkedIn, monday.com, Notion, Pipedrive, Salesforce, WordPress.com, Zoom
- Adds
createUserInfoManagedOAuthConnector, so a provider contributes aparserather than its own connector factory - Fixes
tokenTypebeing compared against exactlyBearer— RFC 6749 §7.1 makes it case-insensitive, and several providers send lowercasebearer, which was rejected as an incomplete authorization - Adds
ManagedOAuthScopeResolutionfor providers that report granted scopes somewhere other than the token response. Better Auth derivestokens.scopesfrom the token response'sscopefield, so a provider that omits it yields an empty list and the scope check rejects a grant the user actually approved - Adds
scopelessfor Notion, ClickUp and Cal.com, which authorize with an empty scope list and previously tripped the "no scope policy" guard before the flow could start - Surfaces which providers this deployment has an OAuth client for, so the picker no longer offers an account type that fails on click
- Adds a search field to the account-type picker, now that the list is 21 rows
Every verifyIdentity is written fresh rather than reusing the connector layer's getUserInfo: that one exists to satisfy Better Auth's email_is_missing guard, so it substitutes a synthetic address when the provider returns none and asserts emailVerified: true in places the provider never verified. Managed enrollment binds a credential to an invited person, so it reports only what the provider proves. LinkedIn now reads the real email_verified claim.
Two deliberate omissions:
- Spotify — its user profile endpoint returns an email the provider documents as unverified, so it cannot satisfy the invitation binding
- Zoho Desk — its data-center Desk base is persisted as a marker inside the credential's scope string, and managed credentials store granted scopes as an array. Adding it now would silently fall back to the default host for every non-US data center; that marker needs plumbing through the managed-credential path first
Type of Change
- New feature
Testing
Tested manually. bun run type-check, bun run lint, and all 37 audits pass; 2202 tests across the credential-group, connector, contract and hook suites pass.
Per-provider OAuth walkthroughs still need a live run — the empty granted-scope case in particular only reproduces against a real provider.
Checklist
- Code follows project style guidelines
- Self-reviewed my changes
- Tests added/updated and passing
- No new warnings introduced
- I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)