137 lines
3.6 KiB
TypeScript
137 lines
3.6 KiB
TypeScript
|
|
// lib/auth/config.ts
|
||
|
|
import { NextAuthOptions } from "next-auth"
|
||
|
|
import CredentialsProvider from "next-auth/providers/credentials"
|
||
|
|
import GoogleProvider from "next-auth/providers/google"
|
||
|
|
import { PrismaAdapter } from "@auth/prisma-adapter"
|
||
|
|
import { prisma } from "@/lib/prisma"
|
||
|
|
import { authenticateUser } from "./credentials"
|
||
|
|
|
||
|
|
export const authOptions: NextAuthOptions = {
|
||
|
|
adapter: PrismaAdapter(prisma) as any,
|
||
|
|
|
||
|
|
providers: [
|
||
|
|
CredentialsProvider({
|
||
|
|
name: "Credentials",
|
||
|
|
credentials: {
|
||
|
|
email: { label: "Email", type: "email" },
|
||
|
|
password: { label: "Senha", type: "password" }
|
||
|
|
},
|
||
|
|
async authorize(credentials) {
|
||
|
|
if (!credentials?.email || !credentials?.password) {
|
||
|
|
return null
|
||
|
|
}
|
||
|
|
|
||
|
|
try {
|
||
|
|
const user = await authenticateUser(credentials.email, credentials.password)
|
||
|
|
return user
|
||
|
|
} catch (error) {
|
||
|
|
console.error("Erro ao autenticar:", error)
|
||
|
|
return null
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}),
|
||
|
|
GoogleProvider({
|
||
|
|
clientId: process.env.GOOGLE_CLIENT_ID || "",
|
||
|
|
clientSecret: process.env.GOOGLE_CLIENT_SECRET || "",
|
||
|
|
}),
|
||
|
|
],
|
||
|
|
|
||
|
|
session: {
|
||
|
|
strategy: "jwt",
|
||
|
|
},
|
||
|
|
|
||
|
|
pages: {
|
||
|
|
signIn: "/login",
|
||
|
|
error: "/login",
|
||
|
|
newUser: "/onboarding",
|
||
|
|
},
|
||
|
|
|
||
|
|
callbacks: {
|
||
|
|
async signIn({ user, account, profile }) {
|
||
|
|
// Verificar se o usuário já existe
|
||
|
|
const existingUser = await prisma.user.findUnique({
|
||
|
|
where: { email: user.email! }
|
||
|
|
})
|
||
|
|
|
||
|
|
// Se não existir, criar com dados do Google
|
||
|
|
if (!existingUser) {
|
||
|
|
await prisma.user.upsert({
|
||
|
|
where: { email: user.email! },
|
||
|
|
create: {
|
||
|
|
email: user.email!,
|
||
|
|
name: user.name || user.email!.split("@")[0],
|
||
|
|
avatar: user.image,
|
||
|
|
googleId: account?.providerAccountId,
|
||
|
|
role: "EMPLOYEE"
|
||
|
|
},
|
||
|
|
update: {
|
||
|
|
googleId: account?.providerAccountId,
|
||
|
|
avatar: user.image,
|
||
|
|
lastLoginAt: new Date()
|
||
|
|
}
|
||
|
|
})
|
||
|
|
} else {
|
||
|
|
// Atualizar último login
|
||
|
|
await prisma.user.update({
|
||
|
|
where: { id: existingUser.id },
|
||
|
|
data: { lastLoginAt: new Date() }
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
return true
|
||
|
|
},
|
||
|
|
|
||
|
|
async jwt({ token, user }) {
|
||
|
|
if (user) {
|
||
|
|
const dbUser = await prisma.user.findUnique({
|
||
|
|
where: { email: user.email! }
|
||
|
|
})
|
||
|
|
|
||
|
|
if (dbUser) {
|
||
|
|
token.id = dbUser.id
|
||
|
|
token.role = dbUser.role
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return token
|
||
|
|
},
|
||
|
|
|
||
|
|
async session({ session, token }) {
|
||
|
|
if (session.user && token.id) {
|
||
|
|
const userId = String(token.id);
|
||
|
|
(session.user as any).id = userId;
|
||
|
|
(session.user as any).role = token.role;
|
||
|
|
|
||
|
|
// Buscar workspaces do usuário
|
||
|
|
try {
|
||
|
|
const user = await prisma.user.findUnique({
|
||
|
|
where: { id: userId },
|
||
|
|
include: {
|
||
|
|
workspacesAsEmployee: {
|
||
|
|
where: { status: "ACTIVE" },
|
||
|
|
select: { id: true, slug: true, managerId: true },
|
||
|
|
},
|
||
|
|
workspacesAsManager: {
|
||
|
|
where: { status: "ACTIVE" },
|
||
|
|
select: { id: true, slug: true, employeeId: true },
|
||
|
|
},
|
||
|
|
},
|
||
|
|
})
|
||
|
|
|
||
|
|
if (user) {
|
||
|
|
(session.user as any).workspaces = {
|
||
|
|
asEmployee: user.workspacesAsEmployee,
|
||
|
|
asManager: user.workspacesAsManager,
|
||
|
|
}
|
||
|
|
}
|
||
|
|
} catch (error) {
|
||
|
|
console.error("Erro ao buscar workspaces:", error)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return session
|
||
|
|
},
|
||
|
|
},
|
||
|
|
}
|
||
|
|
|
||
|
|
export { authOptions as auth }
|
||
|
|
|