diff --git a/e2e/cucumber/step-definitions/common-steps.ts b/e2e/cucumber/step-definitions/common-steps.ts index 1478ef6..b0b3f8e 100644 --- a/e2e/cucumber/step-definitions/common-steps.ts +++ b/e2e/cucumber/step-definitions/common-steps.ts @@ -29,6 +29,12 @@ Given('I am on the login page', async function () { await world.page.waitForLoadState('domcontentloaded'); }); +Given('I am on the password reset page', async function () { + console.log('🌍 Navigating to password reset page'); + await world.page.goto(`${world.baseURL}/auth/password-reset`); + await world.page.waitForLoadState('domcontentloaded'); +}); + Given('I am on the {string} page', async function (pageName: string) { const pageUrls: Record = { 'home': '/', @@ -174,28 +180,18 @@ When('I click the {string} link', async function (linkText: string) { const selector = `a:has-text("${linkText}")`; console.log(`🌍 Clicking link: ${linkText}`); - // Get current URL - const currentUrl = world.page.url(); - // Click the link await world.page.click(selector); - // Wait a bit for navigation to start - await world.page.waitForTimeout(500); - - // Check if URL changed - const newUrl = world.page.url(); - if (newUrl === currentUrl) { - console.log(`🌍 URL did not change immediately after link click`); - // Wait for any navigation to complete - try { - await world.page.waitForLoadState('domcontentloaded', { timeout: 5000 }); - } catch { - console.log(`🌍 DOMContentLoaded not reached, continuing`); - } - } else { - console.log(`🌍 Page navigated to: ${newUrl}`); + // Wait for navigation to complete + try { + await world.page.waitForLoadState('networkidle', { timeout: 10000 }); + } catch { + console.log(`🌍 Networkidle not reached, continuing`); } + + const newUrl = world.page.url(); + console.log(`🌍 Page navigated to: ${newUrl}`); }); When('I click the {string} wordmark', async function (wordmarkText: string) { diff --git a/src/app/api/auth/password-reset/route.ts b/src/app/api/auth/password-reset/route.ts new file mode 100644 index 0000000..9babdf9 --- /dev/null +++ b/src/app/api/auth/password-reset/route.ts @@ -0,0 +1,37 @@ +import { NextResponse } from "next/server"; +import { prisma } from "@/lib/prisma"; + +export async function POST(request: Request) { + try { + const body = await request.json(); + const { email } = body; + + if (!email) { + return NextResponse.json( + { error: "Email is required" }, + { status: 400 } + ); + } + + const user = await prisma.user.findUnique({ + where: { email: email.toLowerCase() }, + }); + + if (!user) { + return NextResponse.json( + { error: "If an account exists with that email, a password reset link will be sent" }, + { status: 400 } + ); + } + + return NextResponse.json({ + success: true, + message: "If an account exists with that email, a password reset link will be sent" + }); + } catch (error: unknown) { + console.error("Error processing password reset request:", error); + const message = + error instanceof Error ? error.message : "Failed to process password reset request"; + return NextResponse.json({ error: message }, { status: 500 }); + } +} diff --git a/src/app/auth/password-reset/page.tsx b/src/app/auth/password-reset/page.tsx index 87dee2b..8880153 100644 --- a/src/app/auth/password-reset/page.tsx +++ b/src/app/auth/password-reset/page.tsx @@ -15,6 +15,22 @@ export default function PasswordResetPage() { setError("") try { + const response = await fetch("/api/auth/password-reset", { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ email }), + }) + + const data = await response.json() + + if (!response.ok) { + setError(data.error || "Failed to send reset link") + setLoading(false) + return + } + setSent(true) } catch (err) { console.error("Password reset error:", err)