taxonomy/lib/auth.ts
2022-11-17 19:14:41 +04:00

107 lines
2.8 KiB
TypeScript

import { NextAuthOptions } from "next-auth"
import GitHubProvider from "next-auth/providers/github"
import EmailProvider from "next-auth/providers/email"
import { PrismaAdapter } from "@next-auth/prisma-adapter"
import { Client } from "postmark"
import { db } from "@/lib/db"
const postmarkClient = new Client(process.env.POSTMARK_API_TOKEN)
const POSTMARK_SIGN_IN_TEMPLATE = 29559329
const POSTMARK_ACTIVATION_TEMPLATE = 29559329
export const authOptions: NextAuthOptions = {
// huh any! I know.
// This is a temporary fix for prisma client.
// @see https://github.com/prisma/prisma/issues/16117
adapter: PrismaAdapter(db as any),
session: {
strategy: "jwt",
},
pages: {
signIn: "/login",
},
providers: [
GitHubProvider({
clientId: process.env.GITHUB_CLIENT_ID,
clientSecret: process.env.GITHUB_CLIENT_SECRET,
}),
EmailProvider({
server: {
host: process.env.SMTP_HOST,
port: Number(process.env.SMTP_PORT),
auth: {
user: process.env.SMTP_USER,
pass: process.env.SMTP_PASSWORD,
},
},
from: process.env.SMTP_FROM,
sendVerificationRequest: async ({ identifier, url, provider }) => {
const user = await db.user.findUnique({
where: {
email: identifier,
},
select: {
emailVerified: true,
},
})
const result = await postmarkClient.sendEmailWithTemplate({
TemplateId: user?.emailVerified
? POSTMARK_SIGN_IN_TEMPLATE
: POSTMARK_ACTIVATION_TEMPLATE,
To: identifier,
From: provider.from,
TemplateModel: {
action_url: url,
product_name: "Taxonomy",
},
Headers: [
{
// Set this to prevent Gmail from threading emails.
// See https://stackoverflow.com/questions/23434110/force-emails-not-to-be-grouped-into-conversations/25435722.
Name: "X-Entity-Ref-ID",
Value: new Date().getTime() + "",
},
],
})
if (result.ErrorCode) {
throw new Error(result.Message)
}
},
}),
],
callbacks: {
async session({ token, session }) {
if (token) {
session.user.id = token.id
session.user.name = token.name
session.user.email = token.email
session.user.image = token.picture
}
return session
},
async jwt({ token, user }) {
const dbUser = await db.user.findFirst({
where: {
email: token.email,
},
})
if (!dbUser) {
token.id = user.id
return token
}
return {
id: dbUser.id,
name: dbUser.name,
email: dbUser.email,
picture: dbUser.image,
}
},
},
}