From 0bca394c93490f445864cd75441209d9a36453c4 Mon Sep 17 00:00:00 2001 From: aamoghS Date: Sun, 15 Feb 2026 15:26:14 -0500 Subject: [PATCH] hello --- packages/auth/src/adapter.ts | 39 +++++- .../app/(portal)/api/debug-auth/route.ts | 112 +++++++++++------- 2 files changed, 109 insertions(+), 42 deletions(-) diff --git a/packages/auth/src/adapter.ts b/packages/auth/src/adapter.ts index 61d74a9..88922e2 100644 --- a/packages/auth/src/adapter.ts +++ b/packages/auth/src/adapter.ts @@ -11,12 +11,49 @@ function createAdapter(): Adapter | undefined { } try { - return DrizzleAdapter(db, { + const baseAdapter = DrizzleAdapter(db, { usersTable: users, accountsTable: accounts, sessionsTable: sessions, verificationTokensTable: verificationTokens, }); + + // DEBUG: Wrap token methods with logging + const wrappedAdapter: Adapter = { + ...baseAdapter, + async createVerificationToken(data) { + console.log("[AUTH-DEBUG] createVerificationToken called:", { + identifier: data.identifier, + tokenHash: data.token?.substring(0, 20) + "...", + expires: data.expires, + }); + const result = await baseAdapter.createVerificationToken!(data); + console.log("[AUTH-DEBUG] createVerificationToken result:", result ? "SUCCESS" : "NULL"); + return result; + }, + async useVerificationToken(params) { + console.log("[AUTH-DEBUG] useVerificationToken called:", { + identifier: params.identifier, + tokenHash: params.token?.substring(0, 20) + "...", + }); + const result = await baseAdapter.useVerificationToken!(params); + console.log("[AUTH-DEBUG] useVerificationToken result:", result ? "FOUND" : "NOT_FOUND (THIS CAUSES VERIFICATION_FAILED)"); + if (!result) { + // Extra debug: check if any tokens exist for this identifier + const { eq } = await import("drizzle-orm"); + const existing = await db.select().from(verificationTokens).where(eq(verificationTokens.identifier, params.identifier)); + console.log("[AUTH-DEBUG] tokens for this identifier:", existing.length); + if (existing.length > 0) { + console.log("[AUTH-DEBUG] stored token starts with:", existing[0].token?.substring(0, 20)); + console.log("[AUTH-DEBUG] lookup token starts with:", params.token?.substring(0, 20)); + console.log("[AUTH-DEBUG] tokens match:", existing[0].token === params.token); + } + } + return result; + }, + }; + + return wrappedAdapter; } catch (error) { console.error("Auth adapter: Failed to create Drizzle adapter:", error); return undefined; diff --git a/sites/mainweb/app/(portal)/api/debug-auth/route.ts b/sites/mainweb/app/(portal)/api/debug-auth/route.ts index 193fe86..13643a8 100644 --- a/sites/mainweb/app/(portal)/api/debug-auth/route.ts +++ b/sites/mainweb/app/(portal)/api/debug-auth/route.ts @@ -1,46 +1,76 @@ import { NextResponse } from "next/server"; -import { createHash } from "crypto"; +import { db, verificationTokens } from "@query/db"; +import { eq, and } from "drizzle-orm"; -// Temporary debug endpoint to check auth configuration +// Temporary debug endpoint — tests the complete token flow // DELETE THIS AFTER DEBUGGING export async function GET() { - const authSecret = process.env.AUTH_SECRET; - const nextAuthSecret = process.env.NEXTAUTH_SECRET; - const nextAuthUrl = process.env.NEXTAUTH_URL; - const authUrl = process.env.AUTH_URL; - const dbUrl = process.env.DATABASE_URL; - const emailHost = process.env.EMAIL_SERVER_HOST; - const emailUser = process.env.EMAIL_SERVER_USER; - const emailPass = process.env.EMAIL_SERVER_PASSWORD; - - // Test hash with each secret - const testToken = "test123"; - const hashWithAuth = authSecret - ? createHash("sha256").update(`${testToken}${authSecret}`).digest("hex").substring(0, 16) - : "N/A"; - const hashWithNextAuth = nextAuthSecret - ? createHash("sha256").update(`${testToken}${nextAuthSecret}`).digest("hex").substring(0, 16) - : "N/A"; - - return NextResponse.json({ - env: { - AUTH_SECRET_set: !!authSecret, - AUTH_SECRET_first5: authSecret ? authSecret.substring(0, 5) : null, - NEXTAUTH_SECRET_set: !!nextAuthSecret, - NEXTAUTH_SECRET_first5: nextAuthSecret ? nextAuthSecret.substring(0, 5) : null, - NEXTAUTH_URL: nextAuthUrl, - AUTH_URL: authUrl, - DATABASE_URL_set: !!dbUrl, - EMAIL_HOST: emailHost, - EMAIL_USER: emailUser, - EMAIL_PASS_set: !!emailPass, - secrets_match: authSecret === nextAuthSecret, - }, - hash_test: { - with_AUTH_SECRET: hashWithAuth, - with_NEXTAUTH_SECRET: hashWithNextAuth, - hashes_match: hashWithAuth === hashWithNextAuth, - }, - node_env: process.env.NODE_ENV, - }); + const logs: string[] = []; + + try { + // Step 1: Generate a test token the same way NextAuth does (Web Crypto) + const rawToken = "debug_test_" + Date.now(); + const secret = process.env.AUTH_SECRET || process.env.NEXTAUTH_SECRET || ""; + const testEmail = "debug_test@test.com"; + + logs.push(`Raw token: ${rawToken}`); + logs.push(`Secret first 5: ${secret.substring(0, 5)}`); + + // Hash using Web Crypto (same as @auth/core createHash) + const data = new TextEncoder().encode(`${rawToken}${secret}`); + const hashBuffer = await crypto.subtle.digest("SHA-256", data); + const hashedToken = Array.from(new Uint8Array(hashBuffer)) + .map((b) => b.toString(16).padStart(2, "0")) + .join(""); + + logs.push(`Hashed token: ${hashedToken.substring(0, 30)}...`); + + // Step 2: Insert token into DB + try { + await db.insert(verificationTokens).values({ + identifier: testEmail, + token: hashedToken, + expires: new Date(Date.now() + 86400000), + }); + logs.push("✅ Insert: SUCCESS"); + } catch (e: any) { + logs.push(`❌ Insert: FAILED — ${e.message}`); + return NextResponse.json({ logs, status: "INSERT_FAILED" }); + } + + // Step 3: Look up token (same as useVerificationToken) + try { + const result = await db + .delete(verificationTokens) + .where( + and( + eq(verificationTokens.identifier, testEmail), + eq(verificationTokens.token, hashedToken) + ) + ) + .returning(); + + if (result.length > 0) { + logs.push("✅ Lookup: FOUND AND DELETED — token flow WORKS"); + } else { + logs.push("❌ Lookup: NOT FOUND — this is the bug!"); + } + } catch (e: any) { + logs.push(`❌ Lookup: ERROR — ${e.message}`); + } + + // Step 4: Check if there are ANY tokens currently in the DB + const allTokens = await db.select().from(verificationTokens); + logs.push(`\nAll tokens in DB: ${allTokens.length}`); + for (const t of allTokens) { + const expired = new Date(t.expires) < new Date(); + logs.push(` - ${t.identifier} | hash: ${t.token.substring(0, 16)}... | expired: ${expired}`); + } + + return NextResponse.json({ logs, status: "COMPLETE" }); + + } catch (e: any) { + logs.push(`Fatal error: ${e.message}`); + return NextResponse.json({ logs, status: "ERROR" }); + } }