108 lines
3.1 KiB
TypeScript
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,
|
|
};
|