Initial open-source self-hosted Songs2YT edition
This commit is contained in:
+107
@@ -0,0 +1,107 @@
|
||||
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,
|
||||
};
|
||||
Reference in New Issue
Block a user