108 lines
3.8 KiB
TypeScript
108 lines
3.8 KiB
TypeScript
import { PrismaAdapter } from "@auth/prisma-adapter"
|
|
import NextAuth, { NextAuthOptions, TokenSet, User } from "next-auth"
|
|
import Github from "next-auth/providers/github"
|
|
import prisma from "./prisma"
|
|
import { Adapter } from "next-auth/adapters"
|
|
import { createWorkspace } from "./deploy/workspace"
|
|
|
|
export const authOptions: NextAuthOptions = {
|
|
providers: [
|
|
Github({
|
|
clientId: process.env.GITHUB_ID as string,
|
|
clientSecret: process.env.GITHUB_SECRET as string,
|
|
profile(profile, tokens) {
|
|
return {
|
|
id: profile.id,
|
|
name: profile.name,
|
|
email: profile.email,
|
|
image: profile.avatar_url,
|
|
username: profile.login,
|
|
} as User;
|
|
},
|
|
}),
|
|
],
|
|
adapter: PrismaAdapter(prisma) as Adapter,
|
|
pages: {
|
|
signIn: "/sign-in",
|
|
},
|
|
session: {
|
|
strategy: "jwt",
|
|
},
|
|
callbacks: {
|
|
session: async ({ session, token }) => {
|
|
const [github] = await prisma.account.findMany({
|
|
where: { userId: session.user.id, provider: "github" },
|
|
})
|
|
if ((github.expires_at || 0) * 1000 < Date.now()) {
|
|
// If the access token has expired, try to refresh it
|
|
try {
|
|
|
|
const params = new URLSearchParams({
|
|
client_id: process.env.GITHUB_ID as string,
|
|
client_secret: process.env.GITHUB_SECRET as string,
|
|
grant_type: "refresh_token",
|
|
refresh_token: github.refresh_token as string,
|
|
});
|
|
|
|
const response = await fetch("https://github.com/login/oauth/access_token?" + params, {
|
|
headers: { "Accept": "application/json" },
|
|
method: "POST",
|
|
})
|
|
|
|
const tok = await response.json()
|
|
const tokens: TokenSet = tok;
|
|
|
|
if (!response.ok) throw tokens
|
|
|
|
await prisma.account.update({
|
|
data: {
|
|
access_token: tokens.access_token,
|
|
expires_at: Math.floor(Date.now() / 1000 + (tokens.expires_in as number)),
|
|
refresh_token: tokens.refresh_token ?? github.refresh_token,
|
|
},
|
|
where: {
|
|
provider_providerAccountId: {
|
|
provider: "github",
|
|
providerAccountId: github.providerAccountId,
|
|
},
|
|
},
|
|
})
|
|
} catch (error) {
|
|
console.error("Error refreshing access token", error)
|
|
// The error property will be used client-side to handle the refresh token error
|
|
session.error = "RefreshAccessTokenError"
|
|
}
|
|
}
|
|
return {
|
|
...session,
|
|
user: {
|
|
...session.user,
|
|
id: token.id,
|
|
username: token.username,
|
|
},
|
|
}
|
|
},
|
|
jwt: ({ token, user }) => {
|
|
if (user) {
|
|
const u = user as unknown as any;
|
|
return {
|
|
...token,
|
|
id: u.id,
|
|
username: u.username,
|
|
};
|
|
}
|
|
return { ...token, username: token.username };
|
|
},
|
|
},
|
|
events: {
|
|
createUser: async ({ user }) => {
|
|
const worksapce = await prisma.workspace.create({
|
|
data: {
|
|
name: user.username + "'s Personal",
|
|
ownerId: user.id,
|
|
slug: user.username.toLowerCase(),
|
|
},
|
|
});
|
|
}
|
|
},
|
|
} |