mirror of
https://github.com/better-auth/better-auth.git
synced 2026-05-23 15:42:09 -05:00
feat: add patreon social provider (#6245)
Co-authored-by: benkingcode <ben@lionfeet.com> Co-authored-by: Kinfe123 <kinfishtech@gmail.com>
This commit is contained in:
@@ -138,12 +138,13 @@ Better Auth provides pre-configured helper functions for popular OAuth providers
|
||||
- **Microsoft Entra ID (Azure AD)** - `microsoftEntraId(options)`
|
||||
- **Okta** - `okta(options)`
|
||||
- **Slack** - `slack(options)`
|
||||
- **Patreon** - `patreon(options)`
|
||||
|
||||
### Example: Using Pre-configured Providers
|
||||
|
||||
```ts title="auth.ts"
|
||||
import { betterAuth } from "better-auth"
|
||||
import { genericOAuth, auth0, hubspot, keycloak, line, microsoftEntraId, okta, slack } from "better-auth/plugins"
|
||||
import { genericOAuth, auth0, hubspot, keycloak, line, microsoftEntraId, okta, slack, patreon } from "better-auth/plugins"
|
||||
|
||||
export const auth = betterAuth({
|
||||
plugins: [
|
||||
@@ -189,6 +190,10 @@ export const auth = betterAuth({
|
||||
clientId: process.env.SLACK_CLIENT_ID,
|
||||
clientSecret: process.env.SLACK_CLIENT_SECRET,
|
||||
}),
|
||||
patreon({
|
||||
clientId: process.env.PATREON_CLIENT_ID,
|
||||
clientSecret: process.env.PATREON_CLIENT_SECRET,
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
@@ -204,6 +209,7 @@ Each provider helper accepts common OAuth options (extending `BaseOAuthProviderO
|
||||
- **Microsoft Entra ID**: Requires `tenantId` (can be a GUID, `"common"`, `"organizations"`, or `"consumers"`)
|
||||
- **Okta**: Requires `issuer` (e.g., `https://dev-xxxxx.okta.com/oauth2/default`)
|
||||
- **Slack**: No additional required fields
|
||||
- **Patreon**: No additional required fields
|
||||
|
||||
All providers support the same optional fields:
|
||||
- `scopes?: string[]` - Array of OAuth scopes to request
|
||||
|
||||
@@ -32,4 +32,5 @@ export {
|
||||
microsoftEntraId,
|
||||
} from "./microsoft-entra-id";
|
||||
export { type OktaOptions, okta } from "./okta";
|
||||
export { type PatreonOptions, patreon } from "./patreon";
|
||||
export { type SlackOptions, slack } from "./slack";
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
import type { OAuth2Tokens, OAuth2UserInfo } from "@better-auth/core/oauth2";
|
||||
import { betterFetch } from "@better-fetch/fetch";
|
||||
import type { BaseOAuthProviderOptions, GenericOAuthConfig } from "../index";
|
||||
|
||||
export interface PatreonOptions extends BaseOAuthProviderOptions {}
|
||||
|
||||
interface PatreonProfile {
|
||||
data: {
|
||||
id: string;
|
||||
attributes: {
|
||||
full_name: string;
|
||||
email: string;
|
||||
image_url: string;
|
||||
is_email_verified: boolean;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Patreon OAuth provider helper
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* import { genericOAuth, patreon } from "better-auth/plugins/generic-oauth";
|
||||
*
|
||||
* export const auth = betterAuth({
|
||||
* plugins: [
|
||||
* genericOAuth({
|
||||
* config: [
|
||||
* patreon({
|
||||
* clientId: process.env.PATREON_CLIENT_ID,
|
||||
* clientSecret: process.env.PATREON_CLIENT_SECRET,
|
||||
* }),
|
||||
* ],
|
||||
* }),
|
||||
* ],
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
export function patreon(options: PatreonOptions): GenericOAuthConfig {
|
||||
const defaultScopes = ["identity[email]"];
|
||||
|
||||
const getUserInfo = async (
|
||||
tokens: OAuth2Tokens,
|
||||
): Promise<OAuth2UserInfo | null> => {
|
||||
const { data: profile, error } = await betterFetch<PatreonProfile>(
|
||||
"https://www.patreon.com/api/oauth2/v2/identity?fields[user]=email,full_name,image_url,is_email_verified",
|
||||
{
|
||||
method: "GET",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens.accessToken}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
if (error || !profile) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return {
|
||||
id: profile.data.id,
|
||||
name: profile.data.attributes.full_name,
|
||||
email: profile.data.attributes.email,
|
||||
image: profile.data.attributes.image_url,
|
||||
emailVerified: profile.data.attributes.is_email_verified,
|
||||
};
|
||||
};
|
||||
|
||||
return {
|
||||
providerId: "patreon",
|
||||
authorizationUrl: "https://www.patreon.com/oauth2/authorize",
|
||||
tokenUrl: "https://www.patreon.com/api/oauth2/token",
|
||||
clientId: options.clientId,
|
||||
clientSecret: options.clientSecret,
|
||||
scopes: options.scopes ?? defaultScopes,
|
||||
redirectURI: options.redirectURI,
|
||||
pkce: options.pkce,
|
||||
disableImplicitSignUp: options.disableImplicitSignUp,
|
||||
disableSignUp: options.disableSignUp,
|
||||
overrideUserInfo: options.overrideUserInfo,
|
||||
getUserInfo,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user