diff --git a/.env.example b/.env.example index 394c6252..f8334410 100644 --- a/.env.example +++ b/.env.example @@ -15,6 +15,8 @@ NEXTAUTH_SECRET="your-super-secret-key-change-in-production" # AZURE_AD_TENANT_ID="" # GITHUB_CLIENT_ID=your_client_id # GITHUB_CLIENT_SECRET=your_client_secret +# AUTH_APPLE_ID="" +# AUTH_APPLE_SECRET="" # ENABLED_STORAGE="do-spaces" | "s3" | "url" diff --git a/prompts.config.ts b/prompts.config.ts index 69becd3c..e1abc1a0 100644 --- a/prompts.config.ts +++ b/prompts.config.ts @@ -29,9 +29,9 @@ export default defineConfig({ // Authentication plugins auth: { - // Available: "credentials" | "google" | "azure" | "github" | custom + // Available: "credentials" | "google" | "azure" | "github" | "apple" | custom // Use `providers` array to enable multiple auth providers - providers: ["github", "google"], + providers: ["github", "google", "apple"], // Allow public registration (only applies to credentials provider) allowRegistration: false, }, diff --git a/src/components/auth/auth-content.tsx b/src/components/auth/auth-content.tsx index 948c55be..be338c32 100644 --- a/src/components/auth/auth-content.tsx +++ b/src/components/auth/auth-content.tsx @@ -13,6 +13,7 @@ const providerNames: Record = { github: "GitHub", google: "Google", azure: "Microsoft", + apple: "Apple", credentials: "Email", }; diff --git a/src/components/auth/oauth-button.tsx b/src/components/auth/oauth-button.tsx index 64a4ea95..69bd7a26 100644 --- a/src/components/auth/oauth-button.tsx +++ b/src/components/auth/oauth-button.tsx @@ -31,6 +31,11 @@ const providerIcons: Record = { ), + apple: ( + + + + ), }; export function OAuthButton({ provider, providerName }: OAuthButtonProps) { diff --git a/src/lib/config/index.ts b/src/lib/config/index.ts index 2e51c0ce..130076ec 100644 --- a/src/lib/config/index.ts +++ b/src/lib/config/index.ts @@ -19,7 +19,7 @@ export interface ThemeConfig { }; } -export type AuthProvider = "credentials" | "google" | "azure" | "github" | string; +export type AuthProvider = "credentials" | "google" | "azure" | "github" | "apple" | string; export interface AuthConfig { /** @deprecated Use `providers` array instead */ diff --git a/src/lib/plugins/auth/apple.ts b/src/lib/plugins/auth/apple.ts new file mode 100644 index 00000000..40ee5e45 --- /dev/null +++ b/src/lib/plugins/auth/apple.ts @@ -0,0 +1,22 @@ +import Apple from "next-auth/providers/apple"; +import type { AuthPlugin } from "../types"; + +export const applePlugin: AuthPlugin = { + id: "apple", + name: "Apple", + getProvider: () => + Apple({ + clientId: process.env.AUTH_APPLE_ID!, + clientSecret: process.env.AUTH_APPLE_SECRET!, + profile(profile) { + return { + id: profile.sub, + name: profile.name?.firstName + ? `${profile.name.firstName} ${profile.name.lastName || ""}`.trim() + : profile.email?.split("@")[0] || "User", + email: profile.email, + image: null, + }; + }, + }), +}; diff --git a/src/lib/plugins/auth/index.ts b/src/lib/plugins/auth/index.ts index 6db273a7..95f85486 100644 --- a/src/lib/plugins/auth/index.ts +++ b/src/lib/plugins/auth/index.ts @@ -3,6 +3,7 @@ import { credentialsPlugin } from "./credentials"; import { googlePlugin } from "./google"; import { azurePlugin } from "./azure"; import { githubPlugin } from "./github"; +import { applePlugin } from "./apple"; // Register all built-in auth plugins export function registerBuiltInAuthPlugins(): void { @@ -10,6 +11,7 @@ export function registerBuiltInAuthPlugins(): void { registerAuthPlugin(googlePlugin); registerAuthPlugin(azurePlugin); registerAuthPlugin(githubPlugin); + registerAuthPlugin(applePlugin); } -export { credentialsPlugin, googlePlugin, azurePlugin, githubPlugin }; \ No newline at end of file +export { credentialsPlugin, googlePlugin, azurePlugin, githubPlugin, applePlugin }; \ No newline at end of file