Files
hristudio/src/server/auth/config.ts
Sean O'Connor 6e3f2e1601 chore(deps): Update project dependencies and refactor authentication flow
- Upgrade Next.js to version 15.1.7
- Update Drizzle ORM and related dependencies
- Add Nodemailer and related type definitions
- Refactor authentication routes and components
- Modify user schema to include first and last name
- Update authentication configuration and session handling
- Remove deprecated login and register pages
- Restructure authentication-related components and routes
2025-02-11 23:55:27 -05:00

124 lines
3.2 KiB
TypeScript

import { DrizzleAdapter } from "@auth/drizzle-adapter";
import type { Session } from "@auth/core/types";
import type { DefaultSession } from "@auth/core/types";
import type { User } from "@auth/core/types";
import type { AuthConfig } from "@auth/core/types";
import CredentialsProvider from "@auth/core/providers/credentials";
import bcrypt from "bcryptjs";
import { eq } from "drizzle-orm";
import { db } from "~/server/db";
import {
accounts,
sessions,
users,
verificationTokens,
} from "~/server/db/schema";
/**
* Module augmentation for `next-auth` types. Allows us to add custom properties to the `session`
* object and keep type safety.
*
* @see https://next-auth.js.org/getting-started/typescript#module-augmentation
*/
declare module "@auth/core/types" {
interface Session extends DefaultSession {
user: {
id: string;
email: string;
firstName: string | null;
lastName: string | null;
} & DefaultSession["user"];
}
interface User {
id?: string;
email?: string | null;
firstName?: string | null;
lastName?: string | null;
password?: string | null;
emailVerified?: Date | null;
image?: string | null;
}
}
/**
* Options for NextAuth.js used to configure adapters, providers, callbacks, etc.
*
* @see https://next-auth.js.org/configuration/options
*/
export const authConfig = {
adapter: DrizzleAdapter(db, {
usersTable: users as any,
accountsTable: accounts,
sessionsTable: sessions,
verificationTokensTable: verificationTokens,
}),
providers: [
CredentialsProvider({
name: "credentials",
credentials: {
email: { label: "Email", type: "email" },
password: { label: "Password", type: "password" }
},
async authorize(credentials) {
if (!credentials?.email || !credentials?.password) {
throw new Error("Missing credentials");
}
const userEmail = credentials.email as string;
const userPassword = credentials.password as string;
const user = await db
.select()
.from(users)
.where(eq(users.email, userEmail))
.limit(1)
.then(rows => rows[0]);
if (!user) {
throw new Error("Invalid credentials");
}
if (!user.password) {
throw new Error("Invalid credentials");
}
const isValid = await bcrypt.compare(
userPassword,
user.password
);
if (!isValid) {
throw new Error("Invalid credentials");
}
return {
id: user.id,
email: user.email,
firstName: user.firstName,
lastName: user.lastName,
emailVerified: user.emailVerified,
image: user.image,
};
}
})
],
callbacks: {
session: ({ session, user }: { session: Session; user: User }) => ({
...session,
user: {
...session.user,
id: user.id,
email: user.email,
name: user.firstName && user.lastName ? `${user.firstName} ${user.lastName}` : null,
firstName: user.firstName,
lastName: user.lastName,
},
}),
},
pages: {
signIn: '/auth/signin',
},
} satisfies AuthConfig;