Enable hCaptcha verification and dynamic gateway host detection in contact API route.

This commit is contained in:
2025-06-29 18:35:28 +09:00
parent 789a20d6c7
commit d63ff0a170
2 changed files with 50 additions and 31 deletions

View File

@@ -8,6 +8,7 @@
<node-interpreter value="project" /> <node-interpreter value="project" />
<envs> <envs>
<env name="HCAPTCHA_SECRET" value="10000000-ffff-ffff-ffff-000000000001" /> <env name="HCAPTCHA_SECRET" value="10000000-ffff-ffff-ffff-000000000001" />
<env name="USE_LOCAL_GATEWAY" value="true" />
</envs> </envs>
<method v="2" /> <method v="2" />
</configuration> </configuration>

View File

@@ -1,54 +1,72 @@
import {NextRequest, NextResponse} from 'next/server'; import {NextRequest, NextResponse} from 'next/server'
const HCAPTCHA_SECRET = process.env.HCAPTCHA_SECRET ?? ''; const HCAPTCHA_SECRET = process.env.HCAPTCHA_SECRET ?? ''
const SHARED_API_KEY = process.env.SHARED_API_KEY ?? ''; const SHARED_API_KEY = process.env.SHARED_API_KEY ?? ''
// Detect whether to use localhost or Docker gateway
const useLocalGatewayEnv = process.env.USE_LOCAL_GATEWAY
const useLocalGateway = useLocalGatewayEnv?.toLowerCase() === 'true'
const gatewayHost = useLocalGateway ? 'http://localhost:8080' : 'http://gateway:8080'
export async function POST(req: NextRequest) { export async function POST(req: NextRequest) {
try { try {
const body = await req.json(); const body = await req.json()
const origin = req.headers.get("origin") || "http://localhost:3000"; const origin = req.headers.get('origin') || 'http://localhost:3000'
const captchaToken = body.captcha; const captchaToken = body.captcha
if (!captchaToken) { if (!captchaToken) {
return NextResponse.json({success: false, error: 'Captcha is required'}, {status: 400}); return NextResponse.json(
{success: false, error: 'Captcha is required'},
{status: 400}
)
} }
// Step 1: Verify hCaptcha token with their API // Step 1: Verify hCaptcha token
// const verifyResponse = await fetch('https://api.hcaptcha.com/siteverify', { const verifyResponse = await fetch('https://api.hcaptcha.com/siteverify', {
// method: 'POST', method: 'POST',
// headers: {'Content-Type': 'application/x-www-form-urlencoded'}, headers: {'Content-Type': 'application/x-www-form-urlencoded'},
// body: new URLSearchParams({ body: new URLSearchParams({
// secret: HCAPTCHA_SECRET, secret: HCAPTCHA_SECRET,
// response: captchaToken, response: captchaToken,
// }), }),
// }); })
//
// const captchaResult = await verifyResponse.json();
//
// if (!captchaResult.success) {
// return NextResponse.json({success: false, error: 'Captcha verification failed'}, {status: 403});
// }
// Step 2: Forward valid contact request to Spring Boot backend const captchaResult = await verifyResponse.json()
const backendRes = await fetch('http://localhost:8080/api/contact', { console.log('[ContactAPI] hCaptcha result:', captchaResult)
if (!captchaResult.success) {
return NextResponse.json(
{success: false, error: 'Captcha verification failed'},
{status: 403}
)
}
// Step 2: Forward to backend service
const backendRes = await fetch(`${gatewayHost}/api/contact`, {
method: 'POST', method: 'POST',
headers: { headers: {
"Origin": origin, Origin: origin,
'Content-Type': 'application/json', 'Content-Type': 'application/json',
'X-Frontend-Key': SHARED_API_KEY, 'X-Frontend-Key': SHARED_API_KEY,
}, },
body: JSON.stringify(body), body: JSON.stringify(body),
}); })
const backendText = await backendRes.text(); const backendText = await backendRes.text()
if (!backendRes.ok) { if (!backendRes.ok) {
return NextResponse.json({success: false, error: backendText}, {status: backendRes.status}); return NextResponse.json(
{success: false, error: backendText},
{status: backendRes.status}
)
} }
return NextResponse.json({success: true, message: backendText}); return NextResponse.json({success: true, message: backendText})
} catch (err: any) { } catch (err: any) {
console.error('[ContactAPI] error:', err); console.error('[ContactAPI] error:', err)
return NextResponse.json({success: false, error: err.message}, {status: 500}); return NextResponse.json(
{success: false, error: err.message},
{status: 500}
)
} }
} }