Files
songs2yt/lib/auth.ts
T
2026-07-17 02:23:59 +02:00

108 lines
3.1 KiB
TypeScript

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,
};