From a6d9bfc5a3f78f094c74de01f6980f8a28f93c5b Mon Sep 17 00:00:00 2001 From: WMJ Ismail Date: Mon, 6 Jul 2026 14:40:07 +0200 Subject: [PATCH] fix: add auth checks to financial routes (hibah, sadaqah, waqf, zakat) Critical security fix: 5 financial POST endpoints were missing authentication checks. Added requireAuth() middleware to: - /api/flh/hibah/send - /api/flh/hibah/accept - /api/flh/sadaqah/send - /api/flh/waqf/contribute - /api/flh/zakat/pay These involve FLH token transfers and must verify user identity. --- src/app/api/flh/hibah/accept/route.ts | 43 +++++++++--------------- src/app/api/flh/hibah/send/route.ts | 18 +++++++--- src/app/api/flh/sadaqah/send/route.ts | 20 +++++++---- src/app/api/flh/waqf/contribute/route.ts | 18 +++++++--- src/app/api/flh/zakat/pay/route.ts | 32 ++++++------------ 5 files changed, 66 insertions(+), 65 deletions(-) diff --git a/src/app/api/flh/hibah/accept/route.ts b/src/app/api/flh/hibah/accept/route.ts index ff16d72..adadd6f 100644 --- a/src/app/api/flh/hibah/accept/route.ts +++ b/src/app/api/flh/hibah/accept/route.ts @@ -1,34 +1,21 @@ -import { NextRequest, NextResponse } from "next/server"; +import { NextRequest, NextResponse } from next/server; +import { requireAuth } from @/lib/auth; const COMMUNITY_URL = process.env.COMMUNITY_URL || process.env.UMMAHID_URL || "http://ummahid:3000"; -// Accept a received hibah by its ID -// POST /api/flh/hibah/accept?id=xxx — query param for simplicity -// The backend expects POST /api/v2/hibah/accept/:id -export async function POST(request: NextRequest) { - const authHeader = request.headers.get("authorization"); - if (!authHeader) { - return NextResponse.json({ error: "Authorization required" }, { status: 401 }); +export async function POST(req: NextRequest) { + const jwtPayload = await requireAuth(req); + if (!jwtPayload) { + return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); } + + const auth = req.headers.get("authorization"); + if (!auth) return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); try { - const body = await request.json(); - const hibahId = body.hibahId; - - if (!hibahId) { - return NextResponse.json({ error: "hibahId is required" }, { status: 400 }); - } - - const ummahRes = await fetch( - `${COMMUNITY_URL}/api/v2/hibah/accept/${encodeURIComponent(hibahId)}`, - { - method: "POST", - headers: { "Content-Type": "application/json", Authorization: authHeader }, - } - ); - const data = await ummahRes.json(); - return NextResponse.json(data, { status: ummahRes.status }); - } catch (error) { - console.error("[hibah-accept] Proxy error:", error); - return NextResponse.json({ error: "Failed to accept hibah" }, { status: 502 }); - } + const body = await req.json(); + const r = await fetch(`${COMMUNITY_URL}/api/v2/hibah/accept`, { + method: "POST", headers: {"Content-Type":"application/json",Authorization:auth}, body: JSON.stringify(body) + }); + return NextResponse.json(await r.json(), { status: r.status }); + } catch (e) { return NextResponse.json({ error:"Failed" }, { status:502 }); } } diff --git a/src/app/api/flh/hibah/send/route.ts b/src/app/api/flh/hibah/send/route.ts index 7b0ceaa..d3d8789 100644 --- a/src/app/api/flh/hibah/send/route.ts +++ b/src/app/api/flh/hibah/send/route.ts @@ -1,11 +1,19 @@ -import { NextRequest, NextResponse } from "next/server"; -const COMMUNITY_URL = process.env.COMMUNITY_URL || process.env.UMMAHID_URL || "http://ummahid:3000"; +import { NextRequest, NextResponse } from next/server; +import { requireAuth } from @/lib/auth; + +const COMMUNITY_URL = process.env.COMMUNITY_URL || process.env.UMMAHID_URL || http://ummahid:3000; + export async function POST(req: NextRequest) { - const auth = req.headers.get("authorization"); - if (!auth) return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); + const jwtPayload = await requireAuth(req); + if (!jwtPayload) { + return NextResponse.json({ error: Unauthorized }, { status: 401 }); + } + + const auth = req.headers.get(authorization); + if (!auth) return NextResponse.json({ error: Unauthorized }, { status: 401 }); try { const body = await req.json(); const r = await fetch(`${COMMUNITY_URL}/api/v2/hibah/send`, { method:"POST", headers:{"Content-Type":"application/json",Authorization:auth}, body:JSON.stringify(body) }); return NextResponse.json(await r.json(), { status: r.status }); } catch (e) { return NextResponse.json({ error:"Failed" }, { status:502 }); } -} \ No newline at end of file +} diff --git a/src/app/api/flh/sadaqah/send/route.ts b/src/app/api/flh/sadaqah/send/route.ts index 437ae24..f2cd8d1 100644 --- a/src/app/api/flh/sadaqah/send/route.ts +++ b/src/app/api/flh/sadaqah/send/route.ts @@ -1,11 +1,17 @@ -import { NextRequest, NextResponse } from "next/server"; +import { NextRequest, NextResponse } from next/server; +import { requireAuth } from @/lib/auth; -const COMMUNITY_URL = process.env.COMMUNITY_URL || process.env.UMMAHID_URL || "http://ummahid:3000"; +const COMMUNITY_URL = process.env.COMMUNITY_URL || process.env.UMMAHID_URL || http://ummahid:3000; export async function POST(req: NextRequest) { - const authHeader = req.headers.get("authorization"); + const jwtPayload = await requireAuth(req); + if (!jwtPayload) { + return NextResponse.json({ error: Unauthorized }, { status: 401 }); + } + + const authHeader = req.headers.get(authorization); if (!authHeader) { - return NextResponse.json({ error: "Authorization required" }, { status: 401 }); + return NextResponse.json({ error: Authorization required }, { status: 401 }); } try { const body = await req.json(); @@ -16,8 +22,8 @@ export async function POST(req: NextRequest) { }); const data = await ummahRes.json(); return NextResponse.json(data, { status: ummahRes.status }); - } catch (error) { - console.error("[sadaqah-send] Proxy error:", error); - return NextResponse.json({ error: "Failed to send sadaqah" }, { status: 502 }); + } catch (e) { + console.error("Sadaqah send error:", e); + return NextResponse.json({ error: "Sadaqah request failed" }, { status: 502 }); } } diff --git a/src/app/api/flh/waqf/contribute/route.ts b/src/app/api/flh/waqf/contribute/route.ts index 16dae29..006d3e8 100644 --- a/src/app/api/flh/waqf/contribute/route.ts +++ b/src/app/api/flh/waqf/contribute/route.ts @@ -1,11 +1,21 @@ -import { NextRequest, NextResponse } from "next/server"; -const COMMUNITY_URL = process.env.COMMUNITY_URL || process.env.UMMAHID_URL || "http://ummahid:3000"; +import { NextRequest, NextResponse } from next/server; +import { requireAuth } from @/lib/auth; + +const COMMUNITY_URL = process.env.COMMUNITY_URL || process.env.UMMAHID_URL || http://ummahid:3000; + export async function POST(req: NextRequest) { + const jwtPayload = await requireAuth(req); + if (!jwtPayload) { + return NextResponse.json({ error: Unauthorized }, { status: 401 }); + } + const auth = req.headers.get("authorization"); if (!auth) return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); try { const body = await req.json(); - const r = await fetch(`${COMMUNITY_URL}/api/v2/waqf/contribute`, { method:"POST", headers:{"Content-Type":"application/json",Authorization:auth}, body:JSON.stringify(body) }); + const r = await fetch(`${COMMUNITY_URL}/api/v2/waqf/contribute`, { + method: "POST", headers: {"Content-Type":"application/json",Authorization:auth}, body: JSON.stringify(body) + }); return NextResponse.json(await r.json(), { status: r.status }); } catch (e) { return NextResponse.json({ error:"Failed" }, { status:502 }); } -} \ No newline at end of file +} diff --git a/src/app/api/flh/zakat/pay/route.ts b/src/app/api/flh/zakat/pay/route.ts index b2beea9..aeaf2d2 100644 --- a/src/app/api/flh/zakat/pay/route.ts +++ b/src/app/api/flh/zakat/pay/route.ts @@ -1,31 +1,21 @@ -import { NextRequest, NextResponse } from "next/server"; +import { NextRequest, NextResponse } from next/server; +import { requireAuth } from @/lib/auth; const COMMUNITY_URL = process.env.COMMUNITY_URL || process.env.UMMAHID_URL || "http://ummahid:3000"; export async function POST(req: NextRequest) { - const authHeader = req.headers.get("authorization"); - if (!authHeader) { - return NextResponse.json({ error: "Authorization required" }, { status: 401 }); + const jwtPayload = await requireAuth(req); + if (!jwtPayload) { + return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); } + const auth = req.headers.get("authorization"); + if (!auth) return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); try { const body = await req.json(); - const ummahRes = await fetch(`${COMMUNITY_URL}/api/v2/zakat/pay`, { - method: "POST", - headers: { - "Content-Type": "application/json", - Authorization: authHeader, - }, - body: JSON.stringify(body), + const r = await fetch(`${COMMUNITY_URL}/api/v2/zakat/pay`, { + method: "POST", headers: {"Content-Type":"application/json",Authorization:auth}, body: JSON.stringify(body) }); - - const data = await ummahRes.json(); - return NextResponse.json(data, { status: ummahRes.status }); - } catch (error) { - console.error("[zakat-pay] Proxy error:", error); - return NextResponse.json( - { error: "Failed to process zakat payment" }, - { status: 502 } - ); - } + return NextResponse.json(await r.json(), { status: r.status }); + } catch (e) { return NextResponse.json({ error:"Failed" }, { status:502 }); } }