diff --git a/package.json b/package.json index ef9a8c4..f720b72 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ }, "dependencies": { "@hookform/resolvers": "^3.3.2", - "@lucia-auth/adapter-drizzle": "1.0.0", + "@lucia-auth/adapter-drizzle": "1.0.0-beta.6", "@planetscale/database": "^1.11.0", "@radix-ui/react-alert-dialog": "^1.0.5", "@radix-ui/react-checkbox": "^1.0.4", diff --git a/src/app/(auth)/signup/signup.tsx b/src/app/(auth)/signup/signup.tsx index 3e838d4..3e373e5 100644 --- a/src/app/(auth)/signup/signup.tsx +++ b/src/app/(auth)/signup/signup.tsx @@ -12,11 +12,11 @@ import { CardTitle, } from "~/components/ui/card"; import { Input } from "~/components/ui/input"; -import { githubLogoIcon } from "~/components/icons"; import { APP_TITLE } from "~/lib/constants"; import { Label } from "~/components/ui/label"; import { signup } from "~/lib/auth/actions"; import { SubmitButton } from "~/components/submit-button"; +import Link from "next/link"; export function Signup() { const [state, formAction] = useFormState(signup, null); diff --git a/src/app/(auth)/verify-email/page.tsx b/src/app/(auth)/verify-email/page.tsx index 73731d7..4bb1fb5 100644 --- a/src/app/(auth)/verify-email/page.tsx +++ b/src/app/(auth)/verify-email/page.tsx @@ -9,6 +9,7 @@ import { redirect } from "next/navigation"; import { validateRequest } from "~/lib/auth/validate-request"; import { VerifyCode } from "./verify-code"; import { redirects } from "~/lib/constants"; +import type { User } from "@/server/db/schema"; export const metadata = { title: "Verify Email", @@ -16,7 +17,7 @@ export const metadata = { }; export default async function ForgotPasswordPage() { - const { user } = await validateRequest(); + const { user } = (await validateRequest()) as { user: User | null }; if (!user) redirect(redirects.toLogin); if (user.emailVerified) redirect(redirects.afterVerify); diff --git a/src/app/(main)/_components/header.tsx b/src/app/(main)/_components/header.tsx index 966256b..097bc1a 100644 --- a/src/app/(main)/_components/header.tsx +++ b/src/app/(main)/_components/header.tsx @@ -1,8 +1,8 @@ import Link from "next/link"; -import { type User } from "lucia"; import { UserDropdown } from "~/app/(main)/_components/user-dropdown"; import { FunctionSquare } from "lucide-react"; import { APP_TITLE } from "@/lib/constants"; +import type { User } from "~/server/db/schema"; const routes = [{ name: "Dashboard", href: "/dashboard" }] as const; diff --git a/src/app/(main)/account/page.tsx b/src/app/(main)/account/page.tsx index 5ab233d..b573688 100644 --- a/src/app/(main)/account/page.tsx +++ b/src/app/(main)/account/page.tsx @@ -1,3 +1,4 @@ +import type { User } from "~/server/db/schema"; import { redirect } from "next/navigation"; import { SubmitButton } from "~/components/submit-button"; import { @@ -13,7 +14,7 @@ import { validateRequest } from "~/lib/auth/validate-request"; import { redirects } from "~/lib/constants"; export default async function AccountPage() { - const { user } = await validateRequest(); + const { user } = (await validateRequest()) as { user: User | null }; if (!user) redirect(redirects.toLogin); return ( diff --git a/src/app/(main)/layout.tsx b/src/app/(main)/layout.tsx index 36c055b..decd955 100644 --- a/src/app/(main)/layout.tsx +++ b/src/app/(main)/layout.tsx @@ -3,9 +3,10 @@ import { redirect } from "next/navigation"; import { Header } from "./_components/header"; import { validateRequest } from "~/lib/auth/validate-request"; import { redirects } from "~/lib/constants"; +import type { User } from "~/server/db/schema"; const MainLayout = async ({ children }: { children: ReactNode }) => { - const { user } = await validateRequest(); + const { user } = (await validateRequest()) as { user: User | null }; if (!user) redirect(redirects.toLogin); if (user.emailVerified === false) redirect(redirects.toVerify); diff --git a/src/lib/auth/actions.ts b/src/lib/auth/actions.ts index 7111fca..d28e6b9 100644 --- a/src/lib/auth/actions.ts +++ b/src/lib/auth/actions.ts @@ -21,6 +21,7 @@ import { import { emailVerificationCodes, passwordResetTokens, + type User, users, } from "~/server/db/schema"; import { sendMail } from "~/server/send-mail"; @@ -166,7 +167,7 @@ export async function resendVerificationEmail(): Promise<{ error?: string; success?: boolean; }> { - const { user } = await validateRequest(); + const { user } = (await validateRequest()) as { user: User | null }; if (!user) { return redirect(redirects.toLogin); } @@ -201,7 +202,7 @@ export async function verifyEmail( if (typeof code !== "string" || code.length !== 8) { return { error: "Invalid code" }; } - const { user } = await validateRequest(); + const { user } = (await validateRequest()) as { user: User | null }; if (!user) { return redirect(redirects.toLogin); } diff --git a/src/lib/auth/index.ts b/src/lib/auth/index.ts index af9c2b6..c25fea9 100644 --- a/src/lib/auth/index.ts +++ b/src/lib/auth/index.ts @@ -1,14 +1,17 @@ import { Lucia, TimeSpan } from "lucia"; +import type { Adapter } from "lucia"; import { GitHub } from "arctic"; import { env } from "~/env.js"; -import { luciaAdapter } from "~/server/db"; -import { type User as DbUser } from "~/server/db/schema"; +import { sessions, users, type User as DbUser } from "@/server/db/schema"; +import { db } from "@/server/db"; +import { webcrypto } from "node:crypto"; +import { DrizzlePostgreSQLAdapter } from "@lucia-auth/adapter-drizzle"; -// Uncomment the following lines if you are using nodejs 18 or lower. Not required in Node.js 20, CloudFlare Workers, Deno, Bun, and Vercel Edge Functions. -// import { webcrypto } from "node:crypto"; -// globalThis.crypto = webcrypto as Crypto; +globalThis.crypto = webcrypto as unknown as Crypto; -export const lucia = new Lucia(luciaAdapter, { +const adapter = new DrizzlePostgreSQLAdapter(db, sessions, users); + +export const lucia = new Lucia(adapter as unknown as Adapter, { getSessionAttributes: (/* attributes */) => { return {}; }, @@ -34,8 +37,8 @@ export const lucia = new Lucia(luciaAdapter, { }); export const github = new GitHub( - env.GITHUB_CLIENT_ID as string, - env.GITHUB_CLIENT_SECRET as string, + env.GITHUB_CLIENT_ID, + env.GITHUB_CLIENT_SECRET, { redirectURI: env.NEXT_PUBLIC_APP_URL + "/login/github/callback", }, diff --git a/src/lib/auth/validate-request.ts b/src/lib/auth/validate-request.ts index 812cab5..d779f0e 100644 --- a/src/lib/auth/validate-request.ts +++ b/src/lib/auth/validate-request.ts @@ -1,7 +1,7 @@ import { cache } from "react"; import { cookies } from "next/headers"; -import type { Session, User } from "lucia"; import { lucia } from "~/lib/auth"; +import type { User, Session } from "lucia"; export const uncachedValidateRequest = async (): Promise< { user: User; session: Session } | { user: null; session: null } @@ -32,6 +32,7 @@ export const uncachedValidateRequest = async (): Promise< } catch { console.error("Failed to set session cookie"); } + return result; }; diff --git a/src/server/db/index.ts b/src/server/db/index.ts index e3a0006..312c44f 100644 --- a/src/server/db/index.ts +++ b/src/server/db/index.ts @@ -24,7 +24,7 @@ if (env.NODE_ENV === "production") { export { db }; -export const luciaAdapter = new DrizzlePostgreSQLAdapter( +export const adapter = new DrizzlePostgreSQLAdapter( db, schema.sessions, schema.users, diff --git a/src/server/db/schema.ts b/src/server/db/schema.ts index 2b83c87..58909de 100644 --- a/src/server/db/schema.ts +++ b/src/server/db/schema.ts @@ -161,3 +161,5 @@ export type NewFormData = typeof formDatas.$inferInsert; export type Form = typeof forms.$inferSelect; export type NewForm = typeof forms.$inferInsert; + +export type Session = typeof sessions.$inferSelect;