import { NextAuthOptions } from "next-auth"; import GoogleProvider from "next-auth/providers/google"; import { encryptSecret } from "./crypto/secrets"; import { prisma } from "./db"; import { getInitialQuotaResetAt } from "./quota"; import { fetchYouTubeChannel } from "./youtube/upload"; export const authOptions: NextAuthOptions = { providers: [ GoogleProvider({ clientId: process.env.GOOGLE_CLIENT_ID!, clientSecret: process.env.GOOGLE_CLIENT_SECRET!, authorization: { params: { prompt: "consent", access_type: "offline", response_type: "code", scope: [ "openid", "email", "profile", "https://www.googleapis.com/auth/youtube.upload", "https://www.googleapis.com/auth/youtube.readonly", // Required to add uploaded videos to playlists "https://www.googleapis.com/auth/youtube.force-ssl", ].join(" "), }, }, }), ], callbacks: { async signIn({ user, account }) { if (!account?.access_token || !user.email) return false; const dbUser = await prisma.user.upsert({ where: { email: user.email }, create: { email: user.email, name: user.name, image: user.image, quotaResetAt: getInitialQuotaResetAt(), }, update: { name: user.name, image: user.image, }, }); if (account.refresh_token) { const channel = await fetchYouTubeChannel( account.access_token, account.refresh_token, ); const accessToken = encryptSecret(account.access_token); const refreshToken = encryptSecret(account.refresh_token); await prisma.youTubeConnection.upsert({ where: { userId: dbUser.id }, create: { userId: dbUser.id, accessToken, refreshToken, expiresAt: account.expires_at ? new Date(account.expires_at * 1000) : new Date(Date.now() + 3600 * 1000), channelId: channel.channelId, channelTitle: channel.channelTitle, }, update: { accessToken, refreshToken, expiresAt: account.expires_at ? new Date(account.expires_at * 1000) : new Date(Date.now() + 3600 * 1000), channelId: channel.channelId, channelTitle: channel.channelTitle, }, }); } return true; }, async session({ session }) { if (session.user?.email) { const dbUser = await prisma.user.findUnique({ where: { email: session.user.email }, include: { youtubeConnection: true }, }); if (dbUser) { session.user.id = dbUser.id; session.user.plan = dbUser.plan; session.user.youtubeConnected = !!dbUser.youtubeConnection; session.user.channelTitle = dbUser.youtubeConnection?.channelTitle; } } return session; }, }, pages: { signIn: "/", }, session: { strategy: "jwt", }, secret: process.env.NEXTAUTH_SECRET, };