auth.ts 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. import { NextAuthOptions } from 'next-auth';
  2. import CredentialsProvider from 'next-auth/providers/credentials';
  3. import { DrizzleAdapter } from '@auth/drizzle-adapter';
  4. import { db } from './db';
  5. import { users } from './db/schema';
  6. import { eq } from 'drizzle-orm';
  7. import bcrypt from 'bcryptjs';
  8. import type { Adapter } from 'next-auth/adapters';
  9. export const authOptions: NextAuthOptions = {
  10. adapter: DrizzleAdapter(db) as Adapter,
  11. providers: [
  12. CredentialsProvider({
  13. name: 'credentials',
  14. credentials: {
  15. email: { label: 'Email', type: 'email' },
  16. password: { label: 'Password', type: 'password' },
  17. },
  18. async authorize(credentials: Record<string, string> | undefined) {
  19. if (!credentials?.email || !credentials?.password) {
  20. return null;
  21. }
  22. try {
  23. const user = await db
  24. .select()
  25. .from(users)
  26. .where(eq(users.email, credentials.email))
  27. .limit(1);
  28. if (!user[0] || !user[0].isActive) {
  29. return null;
  30. }
  31. const isPasswordValid = await bcrypt.compare(
  32. credentials.password,
  33. user[0].password
  34. );
  35. if (!isPasswordValid) {
  36. return null;
  37. }
  38. return {
  39. id: user[0].id,
  40. email: user[0].email,
  41. name: `${user[0].firstName} ${user[0].lastName}`,
  42. role: user[0].role,
  43. };
  44. } catch (error) {
  45. console.error('Auth error:', error);
  46. return null;
  47. }
  48. },
  49. }),
  50. ],
  51. session: {
  52. strategy: 'jwt',
  53. },
  54. callbacks: {
  55. async jwt({ token, user }) {
  56. if (user) {
  57. token.role = user.role;
  58. }
  59. return token;
  60. },
  61. async session({ session, token }) {
  62. if (token) {
  63. session.user.id = token.sub!;
  64. session.user.role = token.role as string;
  65. }
  66. return session;
  67. },
  68. },
  69. pages: {
  70. signIn: '/auth/signin',
  71. },
  72. };