diff --git a/src/app/api/auth/login/route.ts b/src/app/api/auth/login/route.ts index e7b25da4..75bf1b07 100644 --- a/src/app/api/auth/login/route.ts +++ b/src/app/api/auth/login/route.ts @@ -3,6 +3,7 @@ import prisma from "@/lib/prisma"; import { NextResponse } from "next/server"; import { randomOTP } from "../_lib/randomOTP"; import { cookies } from "next/headers"; +import { sendWhatsAppOtp } from "@/lib/wa-service"; export async function POST(req: Request) { if (req.method !== "POST") { @@ -34,31 +35,22 @@ export async function POST(req: Request) { const otpNumber = Number(codeOtp); const waMessage = `Website Desa Darmasaba - Kode ini bersifat RAHASIA dan JANGAN DI BAGIKAN KEPADA SIAPAPUN, termasuk anggota ataupun Admin lainnya.\n\n>> Kode OTP anda: ${codeOtp}.`; - const waUrl = `https://wa.wibudev.com/code?nom=${encodeURIComponent(nomor)}&text=${encodeURIComponent(waMessage)}`; - - console.log("🔍 Debug WA URL:", waUrl); - - try { - const res = await fetch(waUrl); - const sendWa = await res.json(); - console.log("📱 WA Response:", sendWa); - if (sendWa.status !== "success") { - console.error("❌ WA Service Error:", sendWa); - return NextResponse.json( - { - success: false, - message: "Gagal mengirim OTP via WhatsApp", - debug: sendWa - }, - { status: 400 } - ); - } - } catch (waError) { - console.error("❌ Fetch WA Error:", waError); + // Send OTP via WhatsApp using authenticated API + const waResult = await sendWhatsAppOtp({ + nomor, + message: waMessage, + }); + + if (!waResult.success) { + console.error("❌ WA Service Error:", waResult); return NextResponse.json( - { success: false, message: "Terjadi kesalahan saat mengirim WA" }, - { status: 500 } + { + success: false, + message: waResult.message || "Gagal mengirim OTP via WhatsApp", + debug: waResult.data + }, + { status: 400 } ); } diff --git a/src/app/api/auth/register/route.ts b/src/app/api/auth/register/route.ts index 0ffac336..f2483c24 100644 --- a/src/app/api/auth/register/route.ts +++ b/src/app/api/auth/register/route.ts @@ -2,6 +2,7 @@ import { NextResponse } from 'next/server'; import { cookies } from 'next/headers'; import prisma from '@/lib/prisma'; import { randomOTP } from '../_lib/randomOTP'; +import { sendWhatsAppOtp } from '@/lib/wa-service'; export async function POST(req: Request) { try { @@ -24,12 +25,18 @@ export async function POST(req: Request) { const otpNumber = Number(codeOtp); const waMessage = `Website Desa Darmasaba - Kode verifikasi Anda: ${codeOtp}`; - const waUrl = `https://wa.wibudev.com/code?nom=${encodeURIComponent(nomor)}&text=${encodeURIComponent(waMessage)}`; - const waRes = await fetch(waUrl); - const waData = await waRes.json(); - if (waData.status !== "success") { - return NextResponse.json({ success: false, message: 'Gagal mengirim OTP via WhatsApp' }, { status: 400 }); + // Send OTP via WhatsApp using authenticated API + const waResult = await sendWhatsAppOtp({ + nomor, + message: waMessage, + }); + + if (!waResult.success) { + return NextResponse.json( + { success: false, message: waResult.message || 'Gagal mengirim OTP via WhatsApp', debug: waResult.data }, + { status: 400 } + ); } // ✅ Simpan OTP ke database diff --git a/src/app/api/auth/resend/route.ts b/src/app/api/auth/resend/route.ts index 5824057c..4c0842f7 100644 --- a/src/app/api/auth/resend/route.ts +++ b/src/app/api/auth/resend/route.ts @@ -3,6 +3,7 @@ import prisma from "@/lib/prisma"; import { NextResponse } from "next/server"; import { randomOTP } from "../_lib/randomOTP"; +import { sendWhatsAppOtp } from "@/lib/wa-service"; export async function POST(req: Request) { try { @@ -18,15 +19,17 @@ export async function POST(req: Request) { const codeOtp = randomOTP(); const otpNumber = Number(codeOtp); - // Kirim OTP via WhatsApp + // Kirim OTP via WhatsApp menggunakan API terautentikasi const waMessage = `Website Desa Darmasaba - Kode ini bersifat RAHASIA dan JANGAN DI BAGIKAN KEPADA SIAPAPUN, termasuk anggota ataupun Admin lainnya.\n\n>> Kode OTP anda: ${codeOtp}.`; - const waUrl = `https://wa.wibudev.com/code?nom=${encodeURIComponent(nomor)}&text=${encodeURIComponent(waMessage)}`; - const waRes = await fetch(waUrl); - const waData = await waRes.json(); - if (waData.status !== "success") { + const waResult = await sendWhatsAppOtp({ + nomor, + message: waMessage, + }); + + if (!waResult.success) { return NextResponse.json( - { success: false, message: "Gagal mengirim OTP via WhatsApp" }, + { success: false, message: waResult.message || "Gagal mengirim OTP via WhatsApp", debug: waResult.data }, { status: 400 } ); } diff --git a/src/app/api/auth/send-otp-register/route.ts b/src/app/api/auth/send-otp-register/route.ts index 501ea316..ebe1eb7e 100644 --- a/src/app/api/auth/send-otp-register/route.ts +++ b/src/app/api/auth/send-otp-register/route.ts @@ -1,6 +1,7 @@ import prisma from "@/lib/prisma"; import { NextResponse } from "next/server"; import { randomOTP } from "../_lib/randomOTP"; +import { sendWhatsAppOtp } from "@/lib/wa-service"; export async function POST(req: Request) { try { @@ -22,13 +23,18 @@ export async function POST(req: Request) { const codeOtp = randomOTP(); const otpNumber = Number(codeOtp); - // Kirim WA - const waUrl = `https://wa.wibudev.com/code?nom=${encodeURIComponent(nomor)}&text=Website Desa Darmasaba - Kode verifikasi Anda: ${codeOtp}`; - const res = await fetch(waUrl); - const sendWa = await res.json(); + // Kirim WA menggunakan API terautentikasi + const waMessage = `Website Desa Darmasaba - Kode verifikasi Anda: ${codeOtp}`; + const waResult = await sendWhatsAppOtp({ + nomor, + message: waMessage, + }); - if (sendWa.status !== "success") { - return NextResponse.json({ success: false, message: 'Gagal mengirim OTP' }, { status: 400 }); + if (!waResult.success) { + return NextResponse.json( + { success: false, message: waResult.message || 'Gagal mengirim OTP', debug: waResult.data }, + { status: 400 } + ); } // Simpan OTP diff --git a/src/lib/wa-service.ts b/src/lib/wa-service.ts new file mode 100644 index 00000000..e5da3891 --- /dev/null +++ b/src/lib/wa-service.ts @@ -0,0 +1,122 @@ +/** + * WhatsApp Service - Send OTP via WhatsApp using otp.wibudev.com API + * Uses API Key authentication for secure access + */ + +interface SendWaOtpParams { + nomor: string; + message: string; +} + +interface SendWaOtpResponse { + success: boolean; + message?: string; + data?: any; +} + +/** + * Send WhatsApp message using otp.wibudev.com API with authentication + * @param params - { nomor: string, message: string } + * @returns Promise + */ +export async function sendWhatsAppOtp({ + nomor, + message, +}: SendWaOtpParams): Promise { + const apiKey = process.env.WIBU_WA_API_KEY; + const waApiUrl = process.env.WIBU_WA_API_URL || 'https://otp.wibudev.com'; + + if (!apiKey) { + console.error('❌ WIBU_WA_API_KEY is not configured'); + return { + success: false, + message: 'WhatsApp API key not configured', + }; + } + + try { + // Using the new API endpoint with authentication + // Format: POST https://otp.wibudev.com/code?nom=...&text=... + const url = `${waApiUrl}/code?nom=${encodeURIComponent(nomor)}&text=${encodeURIComponent(message)}`; + + const response = await fetch(url, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'Authorization': `Bearer ${apiKey}`, + 'X-API-Key': apiKey, + }, + }); + + const result = await response.json(); + + if (!response.ok) { + console.error('❌ WA API Error:', result); + return { + success: false, + message: result.message || 'Failed to send WhatsApp message', + data: result, + }; + } + + // Check if response has success status + if (result.status !== 'success') { + console.error('❌ WA API Status Error:', result); + return { + success: false, + message: result.message || 'Failed to send WhatsApp message', + data: result, + }; + } + + console.log('✅ WA Response:', result); + return { + success: true, + message: 'WhatsApp sent successfully', + data: result, + }; + } catch (error) { + console.error('❌ Fetch WA API Error:', error); + return { + success: false, + message: error instanceof Error ? error.message : 'Unknown error occurred', + }; + } +} + +/** + * Legacy function for backward compatibility (deprecated) + * @deprecated Use sendWhatsAppOtp instead + */ +export async function sendWhatsAppOtpLegacy({ + nomor, + message, +}: SendWaOtpParams): Promise { + const waUrl = `https://wa.wibudev.com/code?nom=${encodeURIComponent(nomor)}&text=${encodeURIComponent(message)}`; + + try { + const res = await fetch(waUrl); + const result = await res.json(); + + if (result.status !== 'success') { + console.error('❌ WA Legacy Error:', result); + return { + success: false, + message: result.message || 'Failed to send WhatsApp message', + data: result, + }; + } + + return { + success: true, + message: 'WhatsApp sent successfully', + data: result, + }; + } catch (error) { + console.error('❌ Fetch WA Legacy Error:', error); + return { + success: false, + message: error instanceof Error ? error.message : 'Unknown error occurred', + }; + } +}