From 2d4a11b94de2fd06484e72ffa5aba7a8f699bb41 Mon Sep 17 00:00:00 2001 From: Khalim Conn-Kowlessar Date: Mon, 13 Oct 2025 18:49:06 +0000 Subject: [PATCH] login working --- .../auth/[...nextauth]/DrizzleEmailAdapter.ts | 5 +++ src/app/api/auth/[...nextauth]/route.ts | 15 +++---- src/app/auth/verify-request/page.tsx | 14 ------- .../components/signin/EmailSignInButton.tsx | 5 +++ src/middleware.ts | 42 ++++++++++++++++--- src/types/next-auth.d.ts | 1 + 6 files changed, 56 insertions(+), 26 deletions(-) delete mode 100644 src/app/auth/verify-request/page.tsx diff --git a/src/app/api/auth/[...nextauth]/DrizzleEmailAdapter.ts b/src/app/api/auth/[...nextauth]/DrizzleEmailAdapter.ts index a61c3e3..0e7cbab 100644 --- a/src/app/api/auth/[...nextauth]/DrizzleEmailAdapter.ts +++ b/src/app/api/auth/[...nextauth]/DrizzleEmailAdapter.ts @@ -31,6 +31,9 @@ import { * - Force re-login after role/permission changes * - Audit trail of login activity */ + +// We extend + export default function DrizzleEmailAdapter( db: any, tables: { @@ -54,6 +57,7 @@ export default function DrizzleEmailAdapter( name: u.firstName ?? null, image: u.image ?? null, emailVerified: u.emailVerified ?? null, + onboarded: u.onboarded ?? false, }); //---------------------------------------------------------------------- @@ -181,6 +185,7 @@ export default function DrizzleEmailAdapter( async createVerificationToken( token: VerificationToken ): Promise { + console.log("Creating verification token for:", token.identifier); const [created] = await db .insert(verificationTokens) .values({ diff --git a/src/app/api/auth/[...nextauth]/route.ts b/src/app/api/auth/[...nextauth]/route.ts index ac41de6..ce774a0 100644 --- a/src/app/api/auth/[...nextauth]/route.ts +++ b/src/app/api/auth/[...nextauth]/route.ts @@ -113,8 +113,8 @@ export const AuthOptions: NextAuthOptions = { .where(eq(users.email, normalisedEmail)); if (!dbUser) { - console.warn(`User not found for ${normalisedEmail} after sign-in.`); - return false; + console.log("New user sign up for email:", normalisedEmail); + return true; } // Link OAuth ID if missing (helps for older accounts) @@ -134,11 +134,7 @@ export const AuthOptions: NextAuthOptions = { // Pass bigint ID into NextAuth session/jwt user.dbId = dbUser.id.toString(); - - // If the user isn't onboarded yet, redirect to onboarding - if (!dbUser.onboarded) { - return "/onboarding"; - } + user.onboarded = dbUser.onboarded ?? false; return true; } catch (error) { @@ -154,6 +150,10 @@ export const AuthOptions: NextAuthOptions = { if (user?.dbId) { token.dbId = user.dbId; } + + // Fetch onboarding status from user + if (user?.onboarded !== undefined) token.onboarded = user.onboarded; + return token; }, @@ -171,6 +171,7 @@ export const AuthOptions: NextAuthOptions = { * Redirect users after login */ async redirect({ baseUrl }) { + // If the user has not onboarded, send them to onboarding return `${baseUrl}/home`; }, }, diff --git a/src/app/auth/verify-request/page.tsx b/src/app/auth/verify-request/page.tsx deleted file mode 100644 index 732fade..0000000 --- a/src/app/auth/verify-request/page.tsx +++ /dev/null @@ -1,14 +0,0 @@ -export default function VerifyRequestPage() { - return ( -
-
-

- Check your email -

-

- We’ve sent you a sign-in link. Click it to finish logging in. -

-
-
- ); -} diff --git a/src/app/components/signin/EmailSignInButton.tsx b/src/app/components/signin/EmailSignInButton.tsx index 348c840..57a6c6c 100644 --- a/src/app/components/signin/EmailSignInButton.tsx +++ b/src/app/components/signin/EmailSignInButton.tsx @@ -19,12 +19,17 @@ export default function EmailSignInButton({ e.preventDefault(); setStatus("sending"); + console.log("BEFOERE SIGN IN"); + console.log("window.location.origin:", window.location.origin); const res = await signIn("email", { email, redirect: false }); + console.log("AFTER SIGN IN"); if (res?.error) { setError("You are not a valid user."); setStatus("idle"); + console.log("Error signing in:", res.error); } else { + console.log("Sign-in link sent to:", email); setError(undefined); setStatus("sent"); } diff --git a/src/middleware.ts b/src/middleware.ts index e8158c3..b22f90b 100644 --- a/src/middleware.ts +++ b/src/middleware.ts @@ -1,12 +1,44 @@ +import { NextResponse } from "next/server"; +import type { NextRequest } from "next/server"; +import { getToken } from "next-auth/jwt"; + +export async function middleware(req: NextRequest) { + const token = await getToken({ req }); + const { pathname } = req.nextUrl; + + // If no session, send user to sign-in page + if (!token) { + return NextResponse.redirect(new URL("/", req.url)); + } + + const userEmail = token.email || ""; + + // Internal users (bypass onboarding) + // const isInternal = userEmail.endsWith("@domna.homes"); + + // Not onboarded and not internal + if (token.onboarded === false && pathname !== "/onboarding") { + return NextResponse.redirect(new URL("/onboarding", req.url)); + } + + // Already onboarded but tries to go back to onboarding page + if (token.onboarded === true && pathname === "/onboarding") { + return NextResponse.redirect(new URL("/home", req.url)); + } + + // Everything else allowed + return NextResponse.next(); +} + export const config = { matcher: [ + // Protect only your app’s authenticated areas "/home/:path*", "/portfolio/:path*", "/search/:path*", - "/addresses/:path", - "/due-considerations/:path", - "/eco-spreadsheet/:path", + "/addresses/:path*", + "/due-considerations/:path*", + "/eco-spreadsheet/:path*", + "/onboarding", // add onboarding itself ], }; - -export { default } from "next-auth/middleware"; diff --git a/src/types/next-auth.d.ts b/src/types/next-auth.d.ts index 31c6bd6..259883a 100644 --- a/src/types/next-auth.d.ts +++ b/src/types/next-auth.d.ts @@ -10,5 +10,6 @@ declare module "next-auth" { } interface User { dbId: string; + onboarded: boolean; } }