diff --git a/src/app/api/auth/login/route.ts b/src/app/api/auth/login/route.ts index 5ec269fb..6dbdb952 100644 --- a/src/app/api/auth/login/route.ts +++ b/src/app/api/auth/login/route.ts @@ -29,6 +29,9 @@ export async function POST(req: Request) { console.log(`🔑 DEBUG OTP [${nomor}]: ${codeOtp}`); + let waSuccess = false; + let waErrorMessage = ""; + try { const waResponse = await sendCodeOtp({ nomor, @@ -36,25 +39,29 @@ export async function POST(req: Request) { }); if (!waResponse.ok) { - console.error( - `⚠️ WA Service HTTP Error: ${waResponse.status} ${waResponse.statusText}. Continuing since OTP is logged.` - ); + waErrorMessage = `WA Service HTTP Error: ${waResponse.status} ${waResponse.statusText}`; + console.error(`⚠️ ${waErrorMessage}. Continuing since OTP is logged.`); console.log(`💡 Use this OTP to login: ${codeOtp}`); } else { const sendWa = await waResponse.json(); console.log("📱 WA Response:", sendWa); if (sendWa.status !== "success") { - console.error("⚠️ WA Service Logic Error:", sendWa); + waErrorMessage = `WA Service Logic Error: ${JSON.stringify(sendWa)}`; + console.error("⚠️", waErrorMessage); + } else { + waSuccess = true; } } } catch (waError: unknown) { const errorMessage = waError instanceof Error ? waError.message : String(waError); + waErrorMessage = `WA Connection Exception: ${errorMessage}`; console.error( - "⚠️ WA Connection Exception. Continuing since OTP is logged.", - errorMessage + "⚠️", + waErrorMessage, + ". Continuing since OTP is logged." ); } @@ -71,11 +78,25 @@ export async function POST(req: Request) { path: "/", }); + // Include debug info for non-production environments when WA fails + const isNonProd = process.env.NODE_ENV !== "production"; + const includeDebug = isNonProd && !waSuccess; + return NextResponse.json({ success: true, - message: "Kode verifikasi dikirim", + message: waSuccess + ? "Kode verifikasi dikirim" + : "Kode verifikasi dibuat (WhatsApp gagal terkirim)", kodeId: createOtpId.id, isRegistered: true, + waSuccess, + ...(includeDebug && { + debug: { + codeOtp, + waErrorMessage, + note: "Hanya muncul di development/staging. Hapus di production.", + }, + }), }); } else { return NextResponse.json({ diff --git a/src/app/api/health/otp/route.ts b/src/app/api/health/otp/route.ts new file mode 100644 index 00000000..d85a83f0 --- /dev/null +++ b/src/app/api/health/otp/route.ts @@ -0,0 +1,160 @@ +// app/api/health/otp/route.ts +import { NextResponse } from "next/server"; +import { randomOTP } from "@/app/api/auth/_lib/randomOTP"; +import { sendCodeOtp } from "@/app/api/auth/_lib/sendCodeOtp"; + +/** + * Health check endpoint untuk OTP WhatsApp service + * + * GET /api/health/otp?test=true&number=6281234567890 + * + * Query parameters: + * - test: Set "true" untuk kirim test OTP (optional) + * - number: Nomor tujuan test (required jika test=true) + * + * Response: + * - Status OTP service (available/unavailable) + * - Token configuration status + * - Test message results (jika test=true) + */ +export async function GET(req: Request) { + try { + const { searchParams } = new URL(req.url); + const isTest = searchParams.get("test") === "true"; + const testNumber = searchParams.get("number"); + + // Check token configuration + const tokenConfigured = Boolean(process.env.WA_SERVER_TOKEN); + const isPlaceholder = + process.env.WA_SERVER_TOKEN === "your_whatsapp_server_token"; + + const healthCheck = { + service: "OTP WhatsApp", + status: "ok" as "ok" | "degraded" | "unavailable", + token: { + configured: tokenConfigured, + isPlaceholder, + }, + timestamp: new Date().toISOString(), + }; + + // If test mode, actually try to send OTP + if (isTest) { + if (!testNumber) { + return NextResponse.json( + { + success: false, + message: "Nomor diperlukan untuk test mode", + error: "Tambahkan query parameter: ?number=6281234567890", + }, + { status: 400 } + ); + } + + const testOtp = randomOTP(); + + console.log(`🧪 OTP HEALTH CHECK - Testing with number: ${testNumber}`); + console.log(`🧪 Test OTP code: ${testOtp}`); + + try { + const startTime = Date.now(); + const waResponse = await sendCodeOtp({ + nomor: testNumber, + codeOtp: testOtp, + }); + const responseTime = Date.now() - startTime; + + if (!waResponse.ok) { + healthCheck.status = "unavailable"; + return NextResponse.json({ + success: false, + message: "Gagal mengirim OTP test", + health: healthCheck, + test: { + number: testNumber, + httpStatus: waResponse.status, + statusText: waResponse.statusText, + responseTime: `${responseTime}ms`, + note: "Cek apakah WA_SERVER_TOKEN sudah benar di Portainer", + }, + }); + } + + const responseData = await waResponse.json(); + + if (responseData.status !== "success") { + healthCheck.status = "degraded"; + return NextResponse.json({ + success: false, + message: "OTP test terkirim tapi service merespon error", + health: healthCheck, + test: { + number: testNumber, + httpStatus: waResponse.status, + responseTime: `${responseTime}ms`, + serviceResponse: responseData, + note: "Cek apakah WA_SERVER_TOKEN sudah benar di Portainer", + }, + }); + } + + // Success + healthCheck.status = "ok"; + return NextResponse.json({ + success: true, + message: "OTP test berhasil dikirim", + health: healthCheck, + test: { + number: testNumber, + httpStatus: waResponse.status, + responseTime: `${responseTime}ms`, + serviceResponse: responseData, + otpCode: testOtp, + note: "Gunakan kode ini untuk verifikasi test", + }, + }); + } catch (error) { + healthCheck.status = "unavailable"; + const errorMessage = + error instanceof Error ? error.message : String(error); + + return NextResponse.json({ + success: false, + message: "Exception saat mengirim OTP test", + health: healthCheck, + test: { + number: testNumber, + error: errorMessage, + note: "Cek network connectivity ke otp.wibudev.com", + }, + }); + } + } + + // Basic health check without sending OTP + if (!tokenConfigured || isPlaceholder) { + healthCheck.status = "unavailable"; + } + + return NextResponse.json({ + success: true, + message: + healthCheck.status === "ok" + ? "OTP service tersedia" + : "OTP service tidak tersedia - cek WA_SERVER_TOKEN", + health: healthCheck, + usage: "Tambahkan ?test=true&number=6281234567890 untuk test kirim OTP", + }); + } catch (error) { + console.error("❌ OTP Health Check Error:", error); + + return NextResponse.json( + { + success: false, + message: "Health check gagal", + error: error instanceof Error ? error.message : String(error), + }, + { status: 500 } + ); + } +}