diff --git a/docs/components/sidebar-content.tsx b/docs/components/sidebar-content.tsx
index 04f29cc6..e59d6a4b 100644
--- a/docs/components/sidebar-content.tsx
+++ b/docs/components/sidebar-content.tsx
@@ -601,6 +601,23 @@ export const contents: Content[] = [
),
},
+ {
+ title: "Reddit",
+ href: "/docs/authentication/reddit",
+ icon: () => (
+
+ ),
+ },
],
},
{
diff --git a/docs/content/docs/authentication/reddit.mdx b/docs/content/docs/authentication/reddit.mdx
new file mode 100644
index 00000000..f4afdc60
--- /dev/null
+++ b/docs/content/docs/authentication/reddit.mdx
@@ -0,0 +1,81 @@
+---
+title: Reddit
+description: Reddit provider setup and usage.
+---
+
+
+
+ ### Get your Reddit Credentials
+ To use Reddit sign in, you need a client ID and client secret. You can get them from the [Reddit Developer Portal](https://www.reddit.com/prefs/apps).
+
+ 1. Click "Create App" or "Create Another App"
+ 2. Select "web app" as the application type
+ 3. Set the redirect URL to `http://localhost:3000/api/auth/callback/reddit` for local development
+ 4. For production, set it to your application's domain (e.g. `https://example.com/api/auth/callback/reddit`)
+ 5. After creating the app, you'll get the client ID (under the app name) and client secret
+
+ If you change the base path of the auth routes, make sure to update the redirect URL accordingly.
+
+
+
+ ### Configure the provider
+ To configure the provider, you need to import the provider and pass it to the `socialProviders` option of the auth instance.
+
+ ```ts title="auth.ts"
+ import { betterAuth } from "better-auth"
+
+ export const auth = betterAuth({
+ socialProviders: {
+ reddit: {
+ clientId: process.env.REDDIT_CLIENT_ID as string,
+ clientSecret: process.env.REDDIT_CLIENT_SECRET as string,
+ },
+ },
+ })
+ ```
+
+
+
+ ### Sign In with Reddit
+ To sign in with Reddit, you can use the `signIn.social` function provided by the client. The `signIn` function takes an object with the following properties:
+ - `provider`: The provider to use. It should be set to `reddit`.
+
+ ```ts title="auth-client.ts"
+ import { createAuthClient } from "better-auth/client"
+ const authClient = createAuthClient()
+
+ const signIn = async () => {
+ const data = await authClient.signIn.social({
+ provider: "reddit"
+ })
+ }
+ ```
+
+
+
+## Additional Configuration
+
+### Scopes
+By default, Reddit provides basic user information. If you need additional permissions, you can specify scopes in your auth configuration:
+
+```ts title="auth.ts"
+export const auth = betterAuth({
+ socialProviders: {
+ reddit: {
+ clientId: process.env.REDDIT_CLIENT_ID as string,
+ clientSecret: process.env.REDDIT_CLIENT_SECRET as string,
+ duration: "permanent",
+ scopes: ["identity", "read", "submit"] // Add required scopes
+ },
+ },
+})
+```
+
+Common Reddit scopes include:
+- `identity`: Access basic account information
+- `read`: Access posts and comments
+- `submit`: Submit posts and comments
+- `subscribe`: Manage subreddit subscriptions
+- `history`: Access voting history
+
+For a complete list of available scopes, refer to the [Reddit OAuth2 documentation](https://www.reddit.com/dev/api/oauth).
diff --git a/packages/better-auth/src/oauth2/create-authorization-url.ts b/packages/better-auth/src/oauth2/create-authorization-url.ts
index 387c508c..9baf5539 100644
--- a/packages/better-auth/src/oauth2/create-authorization-url.ts
+++ b/packages/better-auth/src/oauth2/create-authorization-url.ts
@@ -10,6 +10,7 @@ export async function createAuthorizationURL({
scopes,
claims,
redirectURI,
+ duration,
}: {
id: string;
options: ProviderOptions;
@@ -19,6 +20,7 @@ export async function createAuthorizationURL({
codeVerifier?: string;
scopes: string[];
claims?: string[];
+ duration?: string;
}) {
const url = new URL(authorizationEndpoint);
url.searchParams.set("response_type", "code");
@@ -47,5 +49,9 @@ export async function createAuthorizationURL({
}),
);
}
+ if (duration) {
+ url.searchParams.set("duration", duration);
+ }
+
return url;
}
diff --git a/packages/better-auth/src/social-providers/index.ts b/packages/better-auth/src/social-providers/index.ts
index 12231214..e8ab1a5b 100644
--- a/packages/better-auth/src/social-providers/index.ts
+++ b/packages/better-auth/src/social-providers/index.ts
@@ -11,7 +11,7 @@ import { twitter } from "./twitter";
import { dropbox } from "./dropbox";
import { linkedin } from "./linkedin";
import { gitlab } from "./gitlab";
-
+import { reddit } from "./reddit";
export const socialProviders = {
apple,
discord,
@@ -25,6 +25,7 @@ export const socialProviders = {
dropbox,
linkedin,
gitlab,
+ reddit,
};
export const socialProviderList = Object.keys(socialProviders) as [
@@ -54,3 +55,4 @@ export * from "./twitter";
export * from "./dropbox";
export * from "./linkedin";
export * from "./gitlab";
+export * from "./reddit";
diff --git a/packages/better-auth/src/social-providers/reddit.ts b/packages/better-auth/src/social-providers/reddit.ts
new file mode 100644
index 00000000..fb690f97
--- /dev/null
+++ b/packages/better-auth/src/social-providers/reddit.ts
@@ -0,0 +1,104 @@
+import { betterFetch } from "@better-fetch/fetch";
+import type { OAuthProvider, ProviderOptions } from "../oauth2";
+import {
+ createAuthorizationURL,
+ getOAuth2Tokens,
+ validateAuthorizationCode,
+} from "../oauth2";
+
+export interface RedditProfile {
+ id: string;
+ name: string;
+ icon_img: string | null;
+ has_verified_email: boolean;
+ oauth_client_id: string;
+ verified: boolean;
+}
+
+export interface RedditOptions extends ProviderOptions {
+ duration?: string;
+}
+
+export const reddit = (options: RedditOptions) => {
+ return {
+ id: "reddit",
+ name: "Reddit",
+ createAuthorizationURL({ state, scopes, redirectURI }) {
+ const _scopes = scopes || ["identity"];
+ options.scope && _scopes.push(...options.scope);
+
+ return createAuthorizationURL({
+ id: "reddit",
+ options,
+ authorizationEndpoint: "https://www.reddit.com/api/v1/authorize",
+ scopes: _scopes,
+ state,
+ redirectURI,
+ duration: options.duration,
+ });
+ },
+ validateAuthorizationCode: async ({ code, redirectURI }) => {
+ const body = new URLSearchParams({
+ grant_type: "authorization_code",
+ code,
+ redirect_uri: options.redirectURI || redirectURI,
+ });
+ const headers = {
+ "content-type": "application/x-www-form-urlencoded",
+ accept: "text/plain",
+ "user-agent": "better-auth",
+ Authorization: `Basic ${Buffer.from(
+ `${options.clientId}:${options.clientSecret}`,
+ ).toString("base64")}`,
+ };
+
+ const { data, error } = await betterFetch