import "server-only"; import type { NextAuthOptions } from "next-auth"; import DiscordProvider from "next-auth/providers/discord"; import { DrizzleAdapter } from "@auth/drizzle-adapter"; import { db } from "@/db"; import { accounts, sessions, users, verificationTokens } from "@/db/schema"; import type { SessionWithDiscord } from "@/lib/auth/auth"; import { addDiscordGuildMember } from "@/lib/discord/discord"; const discordIdCache = new Map(); export const authOptions: NextAuthOptions = { adapter: DrizzleAdapter(db, { usersTable: users, accountsTable: accounts, sessionsTable: sessions, verificationTokensTable: verificationTokens, }), providers: [ DiscordProvider({ clientId: process.env.DISCORD_CLIENT_ID!, clientSecret: process.env.DISCORD_CLIENT_SECRET!, authorization: { params: { scope: "identify email guilds.join", }, }, }), ], callbacks: { async signIn({ account }) { if (account?.provider === "discord" && account.providerAccountId && account.access_token) { await addDiscordGuildMember(account.providerAccountId, account.access_token); } return true; }, async session({ session, user }) { if (session.user) { (session as SessionWithDiscord).user!.id = user.id; let discordId = discordIdCache.get(user.id); if (!discordId) { const account = await db.query.accounts.findFirst({ where: (record, { eq, and }) => and(eq(record.userId, user.id), eq(record.provider, "discord")), columns: { providerAccountId: true }, }); if (account) { discordId = account.providerAccountId; discordIdCache.set(user.id, discordId); } } if (discordId) { (session as SessionWithDiscord).user!.discordId = discordId; } } return session; }, }, secret: process.env.NEXTAUTH_SECRET, };