const BASE_URL = "http://localhost:5001"; const MAILHOG_API = "http://localhost:8025/api/v2"; let cookie = ""; async function request(method: string, path: string, body?: any) { const headers: any = { "Content-Type": "application/json" }; if (cookie) headers["Cookie"] = cookie; const res = await fetch(`${BASE_URL}${path}`, { method, headers, body: body ? JSON.stringify(body) : undefined, }); const setCookie = res.headers.get("set-cookie"); if (setCookie) { cookie = setCookie.split(";")[0]; } const text = await res.text(); try { const data = JSON.parse(text); return { status: res.status, data }; } catch { return { status: res.status, data: text }; } } async function getLatestEmail(toEmail: string) { try { const res = await fetch(`${MAILHOG_API}/messages`); const data = await res.json(); // MailHog returns { total: number, count: number, start: number, items: [...] } // items are sorted newest first usually in MailHog UI, but API might vary. // Let's filter by 'To' and take the first one. const messages = data.items; for (const msg of messages) { // Headers is an object like { "To": [""], ... } // Content.Headers.To const toHeader = msg.Content.Headers.To?.[0]; if (toHeader && toHeader.includes(toEmail)) { return msg; } } return null; } catch (e) { console.error("Failed to fetch from MailHog:", e); return null; } } async function run() { console.log("šŸ“§ Testing Email Flow..."); const timestamp = Date.now(); const username = `email_user_${timestamp}`; const email = `test_${timestamp}@example.com`; const password = "password123"; const newPassword = "newpassword456"; // 1. Register User console.log(`\n1. Registering user: ${username} (${email})`); let res = await request("POST", "/api/register", { username, password, email }); if (res.status === 201 || res.status === 200) { console.log("āœ… Registration successful"); } else { console.error("āŒ Registration failed:", res.data); process.exit(1); } // 2. Request Password Reset console.log("\n2. Requesting Password Reset..."); // Logout first just in case await request("POST", "/api/logout"); cookie = ""; // Clear cookie res = await request("POST", "/api/auth/forgot-password", { email }); if (res.status === 200) { console.log("āœ… Reset request sent:", res.data.message); } else { console.error("āŒ Reset request failed:", res.data); process.exit(1); } // 3. Check MailHog console.log("\n3. Checking MailHog for email..."); // Wait a bit for email to arrive await new Promise(r => setTimeout(r, 2000)); const emailMsg = await getLatestEmail(email); if (emailMsg) { console.log("āœ… Email found!", emailMsg.Content.Headers.Subject[0]); } else { console.error("āŒ Email NOT found in MailHog!"); process.exit(1); } // 4. Extract Token // We expect a link like: http://localhost:5001/reset-password?token=... // In text body: msg.Content.Body let body = emailMsg.Content.Body; // Simple QP decoding for test body = body.replace(/=\r\n/g, '').replace(/=\n/g, '').replace(/=3D/g, '='); console.log("DEBUG BODY DECODED:", body); const match = body.match(/token=([a-zA-Z0-9-]+)/); if (!match) { console.error("āŒ Token not found in email body!"); console.log("Body:", body); process.exit(1); } const token = match[1]; console.log("āœ… Token extracted:", token); // 5. Reset Password console.log("\n5. Resetting Password..."); res = await request("POST", "/api/auth/reset-password", { token, newPassword }); if (res.status === 200) { console.log("āœ… Password reset successful"); } else { console.error("āŒ Password reset failed:", res.data); process.exit(1); } // 6. Login with New Password console.log("\n6. Logging in with NEW password..."); res = await request("POST", "/api/login", { username, password: newPassword }); if (res.status === 200) { console.log("āœ… Login successful with new password!"); } else { console.error("āŒ Login failed:", res.data); process.exit(1); } // 7. Login with OLD Password (should fail) console.log("\n7. Verifying OLD password fails..."); res = await request("POST", "/api/login", { username, password }); if (res.status === 401) { console.log("āœ… Old password rejected correctly."); } else { console.error("āŒ Old password SHOULD fail but got:", res.status); } console.log("\nšŸŽ‰ Full Email Flow Test Passed!"); } run();